Last active
November 14, 2018 05:05
-
-
Save pyrmont/ed8277c5d07e76458c13e883261b4bd6 to your computer and use it in GitHub Desktop.
A script to generate an RSS feed for a Letterboxd watchlist.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@username = # Enter username as a String | |
# Editing below this line should not be required | |
require 'net/http' | |
require 'rss' | |
require 'uri' | |
class Watchlist | |
PATTERNS = { | |
title: /<meta property="og:title" content="([^"]+)" \/>/, | |
desc: /<meta property="og:description" content="([^"]+)" \/>/, | |
imdb: /<a href="([^"]+)maindetails" [^>]+ data-track-action="IMDb">/, poster: /(<div\s(?:[^>]+\s+)*class=["|'](?:[^"|']+\s+)*poster(?:\s+[^"|']+)*["|'](?:\s+[^>]+)*>)/im, | |
link: /data\-target\-link="([^"]+)"/ | |
} | |
def initialize(username:) | |
@username = username | |
end | |
def rss() | |
RSS::Maker.make("rss2.0") do |maker| | |
maker.channel.title = "Letterboxd Watchlist for @#{@username}" | |
maker.channel.link = "https://letterboxd.com/#{@username}/watchlist/" | |
maker.channel.description = "An RSS feed of the movies in the Letterboxd Watchlist for @#{@username}." | |
maker.channel.generator = "Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" | |
maker.channel.lastBuildDate = Time.now.to_s | |
movies.each do |movie| | |
maker.items.new_item do |item| | |
item.title = movie[:title] | |
item.link = movie[:imdb_url] | |
item.description = movie[:description] | |
item.guid.yield_self do |guid| | |
guid.permanent_link = false | |
guid.content = movie[:imdb_url] | |
end | |
end | |
end | |
end | |
end | |
def movies() | |
movie_pages.map do |page| | |
{ title: attr_title(page), | |
description: attr_desc(page), | |
imdb_url: attr_imdb(page) } | |
end | |
end | |
private def attr_title(html) | |
first_match html, PATTERNS[:title] | |
end | |
private def attr_desc(html) | |
first_match html, PATTERNS[:desc] | |
end | |
private def attr_imdb(html) | |
first_match html, PATTERNS[:imdb] | |
end | |
private def first_match(string, pattern) | |
result = string.match(pattern) | |
raise unless result | |
result[1] | |
rescue | |
msg = "The pattern #{pattern} did not match in the following:\n\n#{string}" | |
raise msg | |
end | |
private def movie_pages() | |
movie_urls.map { |url| read url } | |
end | |
private def movie_urls() | |
html = read "#{@username}/watchlist/" | |
results = html.scan PATTERNS[:poster] | |
results.map { |result| first_match(result[0], PATTERNS[:link]) } | |
end | |
private def read(fragment) | |
base_url = 'https://letterboxd.com/' | |
Net::HTTP.get(URI.parse(base_url + fragment)) | |
end | |
end | |
rss = Watchlist.new(username: @username).rss | |
File.write 'feed.xml', rss |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment