Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/usr/bin/env ruby
#
# IMDB Trivia & Goofs Growler
# By Henrik Nyh <http://henrik.nyh.se> 2008-01-27.
# Free to modify and redistribute with credit.
#
# USAGE
#
# Run this command like
#   trivia http://www.imdb.com/title/tt0056937/
# before starting to watch a movie. Any IMDB URL containing a "tt..." type id is fine.
#
# If IMDB has any trivia and goofs listed for this movie, they will appear in pop-ups
# at even intervals for the duration of the movie. Does not work with Front Row. :(
#
# If you need to pause the movie, press ctrl+C once in the Terminal running the command. 
# Press the Return key to resume.
# Press ctrl+C twice to quit the program. If quits itself when done.
#
# Run like
#   DEBUG=true trivia http://www.imdb.com/title/tt0056937/
# to show things at short intervals instead of spread out over the duration of the movie.
#
#
# PREREQUISITES/INSTALLATION
#
# OS X Leopard has the prerequisite Ruby with all necessary libraries.
#
# You need to install Growl and growlnotify: http://growl.info/
#
# Configure (in the Growl preference pane) Growl to have a 10 second duration.
# I recommend the "Music Video" style at the "Huge" size.
# You can configure this style for the "IMDBTrivia" app only, once Growl's learned
# about that app -- i.e. once you've used this command or done this in a Terminal:
#   growlnotify -n IMDBTrivia -m w00t
#
# To be able to run the command with just "trivia", this file needs to be executable
# (chmod +x trivia) and put inside a directory listed in your PATH environment variable.

start_padding = 3  # minutes -- give the user some time to get started
end_padding   = 10 # minutes -- complete before credits
MAX_LENGTH    = 30 # words   -- if longer, split across multiple pop-ups
DURATION      = 10 # seconds -- The Growl duration setting

require "open-uri"
require "enumerator"  # for enum_slice
require "rubygems"
require "hpricot"


# Handle Ctrl+C quitting

handler = lambda {
  trap(:SIGINT) { exit }
  
  puts
  puts "Paused. Press the Return key to resume or type Ctrl+C again to quit."
  
  STDIN.readline  # since _gets_ will pick the argument off ARGV
  
  trap(:SIGINT, handler)
}
trap(:SIGINT, handler)


class Numeric
  def minutes() self * 60 end
end


def bail(message)
  puts message
  exit
end

# Used to pluralize
def s_for(count)
 "s" unless count == 1
end


def parse_items(url, header)
  Hpricot(open(url)).
    search('ul.trivia li').map {|li| [header, li.inner_text.strip] }
end

def parse_runtime(url)
  Hpricot(open(url)).
    search("h5").find {|h5| h5.inner_text == "Runtime:" }.parent.inner_text[/\d+/].to_i
rescue
  90  # default to 90 minutes
end

def growl(title, message)
  parts = message.split.enum_slice(MAX_LENGTH).to_a.map {|message| message.join(' ') }
  parts.each_with_index do |part, index|
    part_number = index + 1
    last = part_number == parts.length
    part_title = title
    if parts.length > 1
      part_title += " (part %s of %s)" % [part_number, parts.length]
      part = [("... " if part_number > 1), part, (" ... (cont'd)" unless last)].join
    end
    system("growlnotify", "-m", part, "-t", part_title, "-a", "Front Row.app", "-n", "IMDBTrivia")
    sleep DURATION unless last  # This throws off the time count, but it's probably not a big deal
  end
end


return unless $0 == __FILE__  # When run directly (and not included), do this:

puts "IMDB Trivia & Goofs Growler"
puts "By Henrik Nyh <http://henrik.nyh.se>"
puts

begin
  id = ARGV.first[/tt\d+/]
rescue
  bail "Please specify a valid IMDB URL, e.g.: http://www.imdb.com/title/tt0088323/"
end

puts "Retrieving data..."
puts

trivia = parse_items("http://www.imdb.com/title/#{id}/trivia", "Trivia")
goofs  = parse_items("http://www.imdb.com/title/#{id}/goofs", "Goof")

items = (trivia + goofs).sort_by { rand }
bail("No trivia or goofs available! Sorry.") if items.empty?

runtime = parse_runtime("http://www.imdb.com/title/#{id}/")
showtime = runtime - start_padding - end_padding - DURATION/60.0*items.length
if showtime < 1
  showtime = runtime
  start_padding = end_padding = 0
end

inside_padding = showtime/items.length.to_f

if ENV['DEBUG'] == "true"
  start_padding = 0
  inside_padding = 0.1
end

popuptime = (DURATION/60.0 + inside_padding) * items.length - inside_padding

puts "Showing %s piece%s of trivia/goofs at %.2f minute intervals over %.2f minute%s. Starting in %s minute%s; ending %s minute%s before the movie ends." % [
  items.length,  s_for(items.length),
  inside_padding,
  popuptime,      s_for(popuptime),
  start_padding, s_for(start_padding),
  end_padding,   s_for(end_padding)
]
puts
puts "Ware spoilers!"
puts

sleep start_padding.minutes

puts "Starting."

items.each_with_index do |item, index|
  growl(*item)
  print "."
  # can't just compare item == items.last, since there could be duplicates
  sleep inside_padding.minutes unless (index + 1 == items.length)
end

puts
puts "Done. Exiting."