letteropend 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a6cdb0d4f3c01c57f54e2ec50cf5e6a4db37ac1e
4
- data.tar.gz: 9ebe34eea4c67947da344db67b8dea136c3ef0e6
3
+ metadata.gz: d5e35304268f8c5572b2229b6e9f1b652fc85558
4
+ data.tar.gz: 5ca98b6f08d5095cabe6c4f13a42baabdc01d024
5
5
  SHA512:
6
- metadata.gz: ccd759632bc898725b6293eb53e3f3145e4a492d3894a8e20d8fb581e0cc6ddcc82613e065246284609a911b5752100cfdadad244ddb3001baa64efada72e8cf
7
- data.tar.gz: 896f9ba1a0f915169d1ed6d4621cad9060208296cf93375178fc9942b628b9d8b2cb3ffc0577a61ad65431eb6657e3a5e557fe43013d669cd0f7d255fb29fa59
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
+ [![Gem Version](https://badge.fury.io/rb/letteropend.svg)](http://badge.fury.io/rb/letteropend)
5
+ [![Dependency Status](https://gemnasium.com/JRJurman/Letteropend.svg)](https://gemnasium.com/JRJurman/Letteropend)
6
+ [![Code Climate](https://codeclimate.com/github/JRJurman/Letteropend/badges/gpa.svg)](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
- ## Contributing
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
- callbacks = {
4
- :new_page => lambda{ |list| puts "Getting page {#{list.pages.length}} from #{list.username}'s #{list.list}" }
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", callbacks)
13
- user2_wl = Letteropend::List.new(user2, "watchlist", callbacks)
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|
@@ -19,13 +19,24 @@ def pulled_film(film)
19
19
  end
20
20
  end
21
21
 
22
- callbacks = {
23
- :new_page => lambda{ |l| puts "pulling data from {#{l.pages.last}}" },
24
- :pulling_film => lambda{ |f| puts "pulling data from {#{f.url}}" },
25
- :pulled_film => lambda{ |f| Object.send(:pulled_film, f) }
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, callbacks)
29
- total = l.get_total_time
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"
@@ -1,14 +1,46 @@
1
1
  require_relative "../lib/letteropend"
2
2
 
3
- title = "Chopping Mall"
4
- url = "/film/chopping-mall/"
5
- f = Letteropend::Film.new(title, url)
3
+ Letteropend::Film.config do
4
+ on :model_updated do
5
+ puts "Model was updated"
6
+ end
7
+ end
6
8
 
7
- runtime = f.runtime
8
- puts "#{title}'s runtime is: #{runtime} minutes"
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
- tagline = f.tagline
11
- puts "#{title}'s tagline is: #{tagline}"
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
- overview = f.overview
14
- puts "#{title}'s overview is: #{overview}"
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
- callbacks = {
9
- :new_page => lambda{ |l| puts "pulling data from " + l.pages.last},
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, callbacks)
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"
@@ -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 :title, :url, :runtime, :tagline, :overview
7
- def initialize(title, url, callbacks={})
8
- @title = title
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
- @callbacks = callbacks
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
- def runtime
15
- if !@pulled
16
- pull_data
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
- def tagline
22
- if !@pulled
23
- pull_data
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
- def overview
29
- if !@pulled
30
- pull_data
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
- if @callbacks[:pulling_film]
37
- @callbacks[:pulling_film].call(self)
38
- end
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#{@url}"))
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
- @runtime = runtime_cap.captures[0].to_i
95
+ runtime = runtime_cap.captures[0].to_i
48
96
  else
49
- @runtime = 0
97
+ runtime = 0
50
98
  end
99
+ define_singleton_method(:runtime, lambda{runtime})
51
100
 
52
101
  # get the tagline for the film
53
- @tagline = page.css(".tagline").text
102
+ tagline = page.css(".tagline").text
103
+ define_singleton_method(:tagline, lambda{tagline})
54
104
 
55
105
  # get the overview for the film
56
- @overview = page.css("div.truncate").text.strip
106
+ overview = page.css("div.truncate").text.strip
107
+ define_singleton_method(:overview, lambda{overview})
57
108
 
58
- if @callbacks[:pulled_film]
59
- @callbacks[:pulled_film].call(self)
60
- end
109
+ @pulled = true
110
+ @pulling = false
111
+
112
+ model_updated
61
113
  end
62
114
 
115
+ # Equivalence operator
63
116
  def ==(film)
64
- @title == film.title and @url == film.url
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
@@ -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
- def initialize(username, list="films", callbacks={})
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
- if callbacks[:new_page]
18
- callbacks[:new_page].call(self)
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
- url = film.css("a")[0].attr("href")
26
- @films.push( Film.new(title, url, callbacks) )
27
- if callbacks[:new_film]
28
- callbacks[:new_film].call(self)
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
- def get_total_time
41
- total_runtime = 0
42
- @films.each do |film|
43
- total_runtime += film.runtime
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
@@ -1,3 +1,3 @@
1
1
  module Letteropend
2
- VERSION = "1.2.0"
2
+ VERSION = "2.0.0"
3
3
  end
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: 1.2.0
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-13 00:00:00.000000000 Z
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