Skip to content

Instantly share code, notes, and snippets.

@hryk
Last active August 29, 2015 13:56
Show Gist options
  • Save hryk/9063878 to your computer and use it in GitHub Desktop.
Save hryk/9063878 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require "nokogiri"
require "excon"
require "thor"
# Tasks related to maintain my subscriptions.
class FeedTask < Thor
OPML = <<-EOF
<?xml version="1.0" encoding="UTF-8" ?>
<opml version="1.0">
<head><title>Subscriptions list from jottit.</title></head>
<body></body>
</opml>
EOF
desc "opml_to_md FILE", "Output OPML content as markdown"
def opml_to_md(opml_file)
opml = File.open(opml_file)
doc = Nokogiri::XML::Document.parse(opml)
doc.xpath("//outline[@xmlUrl]").each do |outline|
puts "* [#{outline.attr("text")}](#{outline.attr("xmlUrl")})"
end
end
desc "export_jottit URL", "Create OPML from jottit page."
option :tag, type: :string, default: :all
option :output, type: :string
def export_jottit(url)
Excon.defaults[:ssl_verify_peer] = false
subscriptions = get_feeds_from_jottit(url)
opml = generate_opml(feeds: subscriptions, tag: options[:tag])
output = if options[:output]
open(options[:output], "w")
else
$stdout
end
output.puts opml
end
protected
def add_outline_element(doc, feed)
outline = Nokogiri::XML::Node.new("outline", doc)
outline.set_attribute("text", feed[:title])
outline.set_attribute("title", feed[:title])
outline.set_attribute("type", "rss")
outline.set_attribute("xmlUrl", feed[:xml_url])
doc.css("body").first.add_child(outline)
end
def generate_opml(feeds: {}, tag: :all)
export_feeds = if tag == :all
feeds.values.flatten
elsif feeds.key? tag
feeds[tag]
else
fail "[generate_opml] tag `#{tag}` not found."
end
doc = Nokogiri::XML.parse(OPML)
export_feeds.each { |feed| add_outline_element(doc, feed) }
doc
end
def get_feeds_from_jottit(url)
feeds, feed_stub = {}, {}
response = Excon.new(url).request(method: :get, expects: [200])
html = Nokogiri::HTML.parse(response.body)
html.css("#content").children.each do |node|
if node.name == "h1"
if feed_stub.key?(:feeds) && feed_stub[:feeds].size > 0
feeds[feed_stub[:label]] = feed_stub[:feeds]
end
feed_stub = { label: node.text, feeds: [] }
elsif node.name == "ul"
feed_stub[:feeds] = node.css("li>a")
.map { |a| { title: a.text, xml_url: a.attr(:href) } }
end
end
feeds
rescue => e
raise "[get_feeds_from_jottit] Failed to fetch jottit page #{e}"
end
end
FeedTask.start(ARGV)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment