Class: Letteropend::Film

Inherits:
Object
  • Object
show all
Defined in:
lib/letteropend/film.rb

Overview

The Film class

Constant Summary collapse

@@valid_attributes =
[:title, :tagline, :overview, :runtime]
@@valid_events =
[:model_updated, :model_updating]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(slug, details = {}, &events) ⇒ Film

Creates a new film instance

Parameters:

  • id
    • the title letterboxd assigns the film for the url

  • details (defaults to: {})
    • the attributes the user assigns the film (instead of pulling from letterboxd)

  • events
    • block of user defined events



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/letteropend/film.rb', line 16

def initialize(slug, details={}, &events)
  @slug = slug.split("/").last
  @url = "http://letterboxd.com/film/#{@slug}/"
  @pulled = false
  @pulling = false
  @events = {}

  # assign each detail to a method
  details.each do |key, value|

    # only assign valid attributes to a film
    if @@valid_attributes.include? key
      define_singleton_method(key, lambda{value})
    else
      puts "Error: trying to assign invalid film data | film: #{@slug}, attribute: #{key}"
    end

  end

  # assign events to film object
  if block_given?
    instance_eval(&events)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args) ⇒ Object

Method Missing implementation

Parameters:

  • sym
    • method trying to be called

  • args
    • arguments passed into the method call



123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/letteropend/film.rb', line 123

def method_missing(sym, *args)
  if (@@valid_attributes.include? sym)
    if !@pulled and !@pulling
      pull_data
      self.send(sym)
    elsif !@pulled and @pulling
      puts "Error: trying to get film data prematurely | film: #{@slug}, method: #{sym}"
    end
  elsif (@@valid_events.include? sym)
    # no method was defined for this event
  else
    super
  end
end

Instance Attribute Details

#slugObject (readonly)

Returns the value of attribute slug.



7
8
9
# File 'lib/letteropend/film.rb', line 7

def slug
  @slug
end

#urlObject (readonly)

Returns the value of attribute url.



7
8
9
# File 'lib/letteropend/film.rb', line 7

def url
  @url
end

Class Method Details

.config(&events) ⇒ Object

Method to declare class events

Parameters:

  • events
    • block of user defined events



58
59
60
61
62
# File 'lib/letteropend/film.rb', line 58

def self.config(&events)
  if block_given?
    class_eval(&events)
  end
end

.on(event, &block) ⇒ Object

Assign events to class

Parameters:

  • event
    • symbol of event to be triggered

  • block
    • user defined function to be triggered on event



68
69
70
71
72
73
74
75
76
# File 'lib/letteropend/film.rb', line 68

def self.on(event, &block)
  if block_given?
    if (@@valid_events.include? event)
      define_method(event, block)
    else
      puts "Error: trying to assign invalid class event | Letteropend::Film, event: #{event}"
    end
  end
end

Instance Method Details

#==(film) ⇒ Object

Equivalence operator



115
116
117
# File 'lib/letteropend/film.rb', line 115

def ==(film)
  @slug == film.slug
end

#on(event, &block) ⇒ Object

Assign events to instance

Parameters:

  • event
    • symbol of event to be triggered

  • block
    • user defined function to be triggered on event



45
46
47
48
49
50
51
52
53
# File 'lib/letteropend/film.rb', line 45

def on(event, &block)
  if block_given?
    if (@@valid_events.include? event)
      define_singleton_method(event, block)
    else
      puts "Error: trying to assign invalid event | Letteropend::Film, event: #{event}"
    end
  end
end

#pull_dataObject

Goes to Letterboxd and pulls html page with nokogiri



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/letteropend/film.rb', line 79

def pull_data
  @pulling = true

  model_updating

  # pull the page from the url
  page = Nokogiri::HTML(open(@url))
  
  # get the title for the film
  title = page.css("h1.film-title").text
  define_singleton_method(:title, lambda{title})

  # get the runtime for the film
  runtime_cap = page.css(".text-link").text.match(/(\d+) mins/)
  if runtime_cap
    runtime = runtime_cap.captures[0].to_i
  else
    runtime = 0
  end
  define_singleton_method(:runtime, lambda{runtime})

  # get the tagline for the film
  tagline = page.css(".tagline").text
  define_singleton_method(:tagline, lambda{tagline})

  # get the overview for the film
  overview = page.css("div.truncate").text.strip
  define_singleton_method(:overview, lambda{overview})
  
  @pulled = true
  @pulling = false

  model_updated
end