letteropend 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +9 -1
- data/examples/compareWatchlist.rb +8 -5
- data/examples/getAllTime.rb +18 -7
- data/examples/getDirectedFilms.rb +13 -0
- data/examples/getFilmDetails.rb +41 -9
- data/examples/getNumberOfFilms.rb +9 -4
- data/lib/letteropend/film.rb +105 -32
- data/lib/letteropend/list.rb +63 -15
- data/lib/letteropend/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5e35304268f8c5572b2229b6e9f1b652fc85558
|
4
|
+
data.tar.gz: 5ca98b6f08d5095cabe6c4f13a42baabdc01d024
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f80309d6f2665d12fa045e36fb9fb212685468d8574f45b63dd9d47d2bd8e52f602f4b3079645de13c9d53b595f29ec2f235c1eea2e24514f174a3039043f09d
|
7
|
+
data.tar.gz: b9737ce23e168e491c00d6f579939378a4b51a7debb096b7d9abd224990ecfe7653c456533e7dc02b434fcfea828db2215083c295adb3b3b685069657eb5e9e0
|
data/README.md
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
LetterOpend
|
2
2
|
===========
|
3
3
|
|
4
|
+
[](http://badge.fury.io/rb/letteropend)
|
5
|
+
[](https://gemnasium.com/JRJurman/Letteropend)
|
6
|
+
[](https://codeclimate.com/github/JRJurman/Letteropend)
|
7
|
+
|
4
8
|
Scripts and Functions that let you peek at letterboxd films.
|
5
9
|
|
6
10
|
Sadly, with no API publicly available, this is a quick-hack way of exposing the films that you and your friends have seen, listed, or watchlisted on letterboxd.com
|
7
11
|
|
8
12
|
This is not associated with letterboxd, nor is it guaranteed to work once an official API is released
|
9
13
|
|
14
|
+
Installation
|
15
|
+
------------
|
16
|
+
|
10
17
|
Add this line to your application's Gemfile:
|
11
18
|
|
12
19
|
```ruby
|
@@ -21,7 +28,8 @@ Or install it yourself as:
|
|
21
28
|
|
22
29
|
$ gem install letteropend
|
23
30
|
|
24
|
-
|
31
|
+
Contributing
|
32
|
+
------------
|
25
33
|
|
26
34
|
1. Fork it ( https://github.com/jrjurman/letteropend/fork )
|
27
35
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
@@ -1,16 +1,19 @@
|
|
1
1
|
require_relative "../lib/letteropend"
|
2
2
|
|
3
|
-
|
4
|
-
:new_page
|
5
|
-
}
|
3
|
+
Letteropend::List.config do
|
4
|
+
on :new_page do
|
5
|
+
puts "Getting page {#{pages.length}} from #{username}'s #{list}"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
6
9
|
print "First username: "
|
7
10
|
user1 = gets.chomp
|
8
11
|
|
9
12
|
print "Second username: "
|
10
13
|
user2 = gets.chomp
|
11
14
|
|
12
|
-
user1_wl = Letteropend::List.new(user1, "watchlist"
|
13
|
-
user2_wl = Letteropend::List.new(user2, "watchlist"
|
15
|
+
user1_wl = Letteropend::List.new(user1, "watchlist")
|
16
|
+
user2_wl = Letteropend::List.new(user2, "watchlist")
|
14
17
|
|
15
18
|
user2_wl.films.delete_if { |film| !user1_wl.films.include? film }
|
16
19
|
user2_wl.films.each do |film|
|
data/examples/getAllTime.rb
CHANGED
@@ -19,13 +19,24 @@ def pulled_film(film)
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
:
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
Letteropend::Film.config do
|
23
|
+
on :model_updating do
|
24
|
+
puts "pulling data from {#{url}}"
|
25
|
+
end
|
26
|
+
on :model_updated do
|
27
|
+
Object.send(:pulled_film, self)
|
28
|
+
end
|
29
|
+
end
|
27
30
|
|
28
|
-
l = Letteropend::List.new(un, ul
|
29
|
-
|
31
|
+
l = Letteropend::List.new(un, ul) do
|
32
|
+
on :new_page do
|
33
|
+
puts "pulling data from {#{pages.last}}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
total = 0
|
38
|
+
l.films.each do |film|
|
39
|
+
total += film.runtime
|
40
|
+
end
|
30
41
|
|
31
42
|
puts "Total Runtime: #{total} minutes"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative "../lib/letteropend"
|
2
|
+
|
3
|
+
puts "Looking at films directed by Alfred Hitchcock"
|
4
|
+
|
5
|
+
username = "director"
|
6
|
+
list = "alfred-hitchcock"
|
7
|
+
l = Letteropend::List.new(username, list) do
|
8
|
+
on :new_page do
|
9
|
+
puts "pulling data from " + pages.last
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
puts "There are #{l.films.length} number of films on #{username} #{list}'s list"
|
data/examples/getFilmDetails.rb
CHANGED
@@ -1,14 +1,46 @@
|
|
1
1
|
require_relative "../lib/letteropend"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
Letteropend::Film.config do
|
4
|
+
on :model_updated do
|
5
|
+
puts "Model was updated"
|
6
|
+
end
|
7
|
+
end
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
+
url = "chopping-mall"
|
10
|
+
a = Letteropend::Film.new url do
|
11
|
+
on :model_updating do
|
12
|
+
puts "Runtime: #{runtime}"
|
13
|
+
end
|
14
|
+
end
|
9
15
|
|
10
|
-
|
11
|
-
|
16
|
+
url = "ghostbusters"
|
17
|
+
b = Letteropend::Film.new url, title: "The Real Ghostbusters", runtime: 107 do
|
18
|
+
on :model_updating do
|
19
|
+
puts "Runtime: #{runtime}"
|
20
|
+
end
|
21
|
+
end
|
12
22
|
|
13
|
-
|
14
|
-
|
23
|
+
url = "duck-soup-1933"
|
24
|
+
c = Letteropend::Film.new url do
|
25
|
+
on :model_updated do
|
26
|
+
puts "We have Duck Soup"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def we_got_movie_sign(movie)
|
31
|
+
puts "The title is : #{movie.title}"
|
32
|
+
|
33
|
+
runtime = movie.runtime
|
34
|
+
puts "#{movie.title}'s runtime is: #{movie.runtime} minutes"
|
35
|
+
|
36
|
+
tagline = movie.tagline
|
37
|
+
puts "#{movie.title}'s tagline is: #{movie.tagline}"
|
38
|
+
|
39
|
+
overview = movie.overview
|
40
|
+
puts "#{movie.title}'s overview is: #{movie.overview}"
|
41
|
+
puts "\n\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
we_got_movie_sign(a)
|
45
|
+
we_got_movie_sign(b)
|
46
|
+
we_got_movie_sign(c)
|
@@ -5,10 +5,15 @@ un = gets().chomp
|
|
5
5
|
print "Enter list: "
|
6
6
|
ul = gets().chomp
|
7
7
|
|
8
|
-
|
9
|
-
:new_page
|
10
|
-
|
8
|
+
Letteropend::List.config do
|
9
|
+
on :new_page do
|
10
|
+
puts "Loading "+ pages.last
|
11
|
+
end
|
12
|
+
on :new_film do
|
13
|
+
puts "Got "+films.last.url
|
14
|
+
end
|
15
|
+
end
|
11
16
|
|
12
|
-
l = Letteropend::List.new(un, ul
|
17
|
+
l = Letteropend::List.new(un, ul)
|
13
18
|
|
14
19
|
puts "There are #{l.films.length} number of films on #{un}'s #{ul} list"
|
data/lib/letteropend/film.rb
CHANGED
@@ -2,66 +2,139 @@ require "nokogiri"
|
|
2
2
|
require "open-uri"
|
3
3
|
|
4
4
|
module Letteropend
|
5
|
+
# The Film class
|
5
6
|
class Film
|
6
|
-
attr_reader :
|
7
|
-
|
8
|
-
|
7
|
+
attr_reader :url
|
8
|
+
@@valid_attributes = [:title, :tagline, :overview, :runtime]
|
9
|
+
@@valid_events = [:model_updated, :model_updating]
|
10
|
+
|
11
|
+
# Creates a new film instance
|
12
|
+
#
|
13
|
+
# @param url - the url letterboxd assigns the film
|
14
|
+
# @param details - the attributes the user assigns the film (instead of pulling from letterboxd)
|
15
|
+
# @param events - block of user defined events
|
16
|
+
def initialize(url, *details, &events)
|
9
17
|
@url = url
|
10
18
|
@pulled = false
|
11
|
-
@
|
19
|
+
@pulling = false
|
20
|
+
@events = {}
|
21
|
+
|
22
|
+
# assign each detail to a method
|
23
|
+
details.each do |detail|
|
24
|
+
detail.each do |key, value|
|
25
|
+
|
26
|
+
# only assign valid attributes to a film
|
27
|
+
if @@valid_attributes.include? key
|
28
|
+
define_singleton_method(key, lambda{value})
|
29
|
+
else
|
30
|
+
puts "Error: trying to assign invalid film data | film: #{@url}, attribute: #{key}"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# assign events to film object
|
37
|
+
if block_given?
|
38
|
+
instance_eval(&events)
|
39
|
+
end
|
12
40
|
end
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
41
|
+
|
42
|
+
# Assign events to instance
|
43
|
+
#
|
44
|
+
# @param event - symbol of event to be triggered
|
45
|
+
# @param block - user defined function to be triggered on event
|
46
|
+
def on(event, &block)
|
47
|
+
if block_given?
|
48
|
+
if (@@valid_events.include? event)
|
49
|
+
define_singleton_method(event, block)
|
50
|
+
else
|
51
|
+
puts "Error: trying to assign invalid event | Letteropend::Film, event: #{event}"
|
52
|
+
end
|
17
53
|
end
|
18
|
-
@runtime
|
19
54
|
end
|
20
55
|
|
21
|
-
|
22
|
-
|
23
|
-
|
56
|
+
# Method to declare class events
|
57
|
+
#
|
58
|
+
# @param events - block of user defined events
|
59
|
+
def self.config(&events)
|
60
|
+
if block_given?
|
61
|
+
class_eval(&events)
|
24
62
|
end
|
25
|
-
@tagline
|
26
63
|
end
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
64
|
+
|
65
|
+
# Assign events to class
|
66
|
+
#
|
67
|
+
# @param event - symbol of event to be triggered
|
68
|
+
# @param block - user defined function to be triggered on event
|
69
|
+
def self.on(event, &block)
|
70
|
+
if block_given?
|
71
|
+
if (@@valid_events.include? event)
|
72
|
+
define_method(event, block)
|
73
|
+
else
|
74
|
+
puts "Error: trying to assign invalid class event | Letteropend::Film, event: #{event}"
|
75
|
+
end
|
31
76
|
end
|
32
|
-
@overview
|
33
77
|
end
|
34
78
|
|
79
|
+
# Goes to Letterboxd and pulls html page with nokogiri
|
35
80
|
def pull_data
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
81
|
+
@pulling = true
|
82
|
+
|
83
|
+
model_updating
|
84
|
+
|
40
85
|
# pull the page from the url
|
41
|
-
page = Nokogiri::HTML(open("http://www.letterboxd.com
|
42
|
-
@pulled = true
|
86
|
+
page = Nokogiri::HTML(open("http://www.letterboxd.com/film/#{@url}/"))
|
43
87
|
|
88
|
+
# get the title for the film
|
89
|
+
title = page.css("h1.film-title").text
|
90
|
+
define_singleton_method(:title, lambda{title})
|
91
|
+
|
44
92
|
# get the runtime for the film
|
45
93
|
runtime_cap = page.css(".text-link").text.match(/(\d+) mins/)
|
46
94
|
if runtime_cap
|
47
|
-
|
95
|
+
runtime = runtime_cap.captures[0].to_i
|
48
96
|
else
|
49
|
-
|
97
|
+
runtime = 0
|
50
98
|
end
|
99
|
+
define_singleton_method(:runtime, lambda{runtime})
|
51
100
|
|
52
101
|
# get the tagline for the film
|
53
|
-
|
102
|
+
tagline = page.css(".tagline").text
|
103
|
+
define_singleton_method(:tagline, lambda{tagline})
|
54
104
|
|
55
105
|
# get the overview for the film
|
56
|
-
|
106
|
+
overview = page.css("div.truncate").text.strip
|
107
|
+
define_singleton_method(:overview, lambda{overview})
|
57
108
|
|
58
|
-
|
59
|
-
|
60
|
-
|
109
|
+
@pulled = true
|
110
|
+
@pulling = false
|
111
|
+
|
112
|
+
model_updated
|
61
113
|
end
|
62
114
|
|
115
|
+
# Equivalence operator
|
63
116
|
def ==(film)
|
64
|
-
@
|
117
|
+
@url == film.url
|
118
|
+
end
|
119
|
+
|
120
|
+
# Method Missing implementation
|
121
|
+
#
|
122
|
+
# @param sym - method trying to be called
|
123
|
+
# @param args - arguments passed into the method call
|
124
|
+
def method_missing(sym, *args)
|
125
|
+
if (@@valid_attributes.include? sym)
|
126
|
+
if !@pulled and !@pulling
|
127
|
+
pull_data
|
128
|
+
self.send(sym)
|
129
|
+
elsif !@pulled and @pulling
|
130
|
+
puts "Error: trying to get film data prematurely | film: #{@url}, method: #{sym}"
|
131
|
+
end
|
132
|
+
elsif (@@valid_events.include? sym)
|
133
|
+
# no method was defined for this event
|
134
|
+
else
|
135
|
+
super
|
136
|
+
end
|
65
137
|
end
|
138
|
+
|
66
139
|
end
|
67
140
|
end
|
data/lib/letteropend/list.rb
CHANGED
@@ -3,30 +3,41 @@ require 'open-uri'
|
|
3
3
|
require_relative './film'
|
4
4
|
|
5
5
|
module Letteropend
|
6
|
+
# The List class
|
6
7
|
class List
|
7
8
|
attr_reader :username, :list, :films, :pages
|
9
|
+
@@valid_events = [:new_page, :new_film]
|
8
10
|
|
9
|
-
|
11
|
+
# Created a new list instance
|
12
|
+
#
|
13
|
+
# @param username - the username for the list
|
14
|
+
# @param list - name of list, defaults to "films" (watched movies)
|
15
|
+
# @param events - block of user defined events
|
16
|
+
def initialize(username, list="films", &events)
|
10
17
|
@username = username
|
11
18
|
@list = list
|
12
19
|
|
13
20
|
@films = []
|
14
21
|
@pages = ["/#{username}/#{list}/page/1/"]
|
22
|
+
|
23
|
+
# assign events to list object
|
24
|
+
if block_given?
|
25
|
+
instance_eval(&events)
|
26
|
+
end
|
27
|
+
|
15
28
|
begin
|
16
29
|
# get page using Nokogiri
|
17
|
-
|
18
|
-
|
19
|
-
end
|
30
|
+
new_page
|
31
|
+
|
20
32
|
page = Nokogiri::HTML(open("http://www.letterboxd.com#{@pages.last}"))
|
21
33
|
|
22
34
|
# append visible films to @films
|
23
35
|
page.css(".poster").each do |film|
|
24
36
|
title = film.css(".frame-title").text
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
37
|
+
url_full = film.css("a")[0].attr("href")
|
38
|
+
url = /\/film\/(\S+)\//.match(url_full).captures[0]
|
39
|
+
@films.push( Film.new(url, title: title) )
|
40
|
+
new_film
|
30
41
|
end
|
31
42
|
|
32
43
|
# see if there is a next page
|
@@ -36,13 +47,50 @@ module Letteropend
|
|
36
47
|
end
|
37
48
|
end while ( next_page )
|
38
49
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
50
|
+
|
51
|
+
# Assign events to instance
|
52
|
+
#
|
53
|
+
# @param event - symbol of event to be triggered
|
54
|
+
# @param block - user defined function to be triggered on event
|
55
|
+
def on(event, &block)
|
56
|
+
if block_given?
|
57
|
+
if (@@valid_events.include? event)
|
58
|
+
define_singleton_method(event, block)
|
59
|
+
else
|
60
|
+
puts "Error: trying to assign invalid event | Letteropend::List, event: #{event}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Method to declare class events
|
66
|
+
#
|
67
|
+
# @param events - block of user defined events
|
68
|
+
def self.config(&events)
|
69
|
+
if block_given?
|
70
|
+
class_eval(&events)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# Assign events to class
|
75
|
+
#
|
76
|
+
# @param event - symbol of event to be triggered
|
77
|
+
# @param block - user defined function to be triggered on event
|
78
|
+
def self.on(event, &block)
|
79
|
+
if block_given?
|
80
|
+
if (@@valid_events.include? event)
|
81
|
+
define_method(event, block)
|
82
|
+
else
|
83
|
+
puts "Error: trying to assign invalid class event | Letteropend::List, event: #{event}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def method_missing(sym, *args)
|
89
|
+
if (@@valid_events.include? sym)
|
90
|
+
# no method was defined for this event
|
91
|
+
else
|
92
|
+
super
|
44
93
|
end
|
45
|
-
return total_runtime
|
46
94
|
end
|
47
95
|
|
48
96
|
end
|
data/lib/letteropend/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: letteropend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jesse Jurman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -66,6 +66,7 @@ files:
|
|
66
66
|
- Rakefile
|
67
67
|
- examples/compareWatchlist.rb
|
68
68
|
- examples/getAllTime.rb
|
69
|
+
- examples/getDirectedFilms.rb
|
69
70
|
- examples/getFilmDetails.rb
|
70
71
|
- examples/getNumberOfFilms.rb
|
71
72
|
- letteropend.gemspec
|