1 # Blosxom Plugin: netflix
2 # Author: Todd Larason (jtl@molehill.org)
4 # Blosxom Home/Docs/Licensing: http://www.raelity.org/blosxom
5 # Netflix plugin Home/Docs/Licensing:
6 # http://molelog.molehill.org/blox/Computers/Internet/Web/Blosxom/Netflix/
9 # -------------- Configuration Variables --------------
11 # Get this from your browser's cookie file. I don't know (yet) how often it
12 # will need to be updated
14 unless defined $ShopperID;
16 # how long to go between re-fetching the data, in seconds
17 # default value is 1 day
18 $max_cache_age = 60 * 60 * 24
19 unless defined $max_cache_age;
22 unless defined $debug_level;
24 # -----------------------------------------------------
32 use vars qw/$ShopperID $debug_level $max_cache_age $have $queue/;
37 my $package = "netflix";
38 my $cachefile = "$blosxom::plugin_state_dir/.$package.cache";
40 my $url = 'http://www.netflix.com/Queue?';
41 my $main_re = qr!DVDs\sYou\sHave\sOut
43 </table> .* DVDs\sin\sYour\sQueue
46 my $item_re = qr!href="http://www\.netflix\.com/MovieDisplay\?movieid=
53 my ($level, @msg) = @_;
55 if ($debug_level >= $level) {
56 print STDERR "$package debug $level: @msg\n";
62 return $blosxom::template->('', "$package.$bit", $blosxom::flavour);
66 my ($bit, $list, $id, $title) = @_;
67 my $f = load_template($bit);
68 $f =~ s/((\$[\w:]+)|(\$\{[\w:]+\}))/$1 . "||''"/gee;
73 $cache = (-r $cachefile ? Storable::lock_retrieve($cachefile) : undef);
74 if ($cache && time - $cache->{timestamp} < $max_cache_age) {
75 debug(1, "Using cached state");
78 $cache = {timestamp => time};
83 return if (!$save_cache);
84 debug(1, "Saving cache");
85 Storable::lock_store($cache, $cachefile);
89 return $cache->{text} if defined $cache->{text};
90 my $jar = HTTP::Cookies->new;
91 my $req = HTTP::Request->new(GET => $url);
92 my $ua = LWP::UserAgent->new;
93 $jar->set_cookie(0, 'NetflixShopperId', $ShopperID, '/', '.netflix.com');
94 $jar->add_cookie_header($req);
95 my $res = $ua->request($req);
96 if (!$res->is_success) {
97 my $error = $res->status_line;
98 debug(0, "HTTP error: $error");
101 $cache->{text} = $res->content;
103 # don't set $save_cache, because we only want to save the text
104 # if it's valid & parsable
106 return $cache->{text};
110 return if $#{$cache->{items}{have}} >= 0;
111 return if $#{$cache->{items}{queue}} >= 0;
113 my ($out_text, $queue_text) = (m/$main_re/);
114 push @{$cache->{items}{have}}, [$1,$2] while ($out_text =~ m/$item_re/g);
115 push @{$cache->{items}{queue}},[$1,$2] while ($queue_text =~ m/$item_re/g);
119 my ($name, $items) = @_;
122 return $cache->{list}{$name}{$blosxom::flavour}
123 if defined $cache->{list}{$name}{$blosxom::flavour};
125 $results = report("head", "$name");
126 $results .= report("item", "$name", $_->[0], $_->[1]) foreach (@$items);
127 $results .= report("foot", "$name");
129 $cache->{list}{$name}{$blosxom::flavour} = $results;
130 $save_cache = 1 if $#{$items} >= 0;
136 return 0 unless defined $netflix::ShopperID;
138 last if /^(__END__)?$/;
140 my ($flavour, $comp, $txt) = split ' ',$_,3;
142 $blosxom::template{$flavour}{"$package.$comp"} = $txt;
149 my $text = get_page();
150 return 0 unless defined $text;
152 $have = build_list('have', $cache->{items}{have});
153 $queue = build_list('queue', $cache->{items}{queue});
160 error head <ul class="netflix $list">\n
161 error item <li><a href="http://www.netflix.com/MovieDisplay?movieid=$id">$title</a></li>\n
167 Blosxom Plug-in: netflix
171 Purpose: Lets you easily share your Netflix queue information
173 * $netflix::have -- list of DVDs currently checked out (or on the way))
174 * $netflix::queue -- list of DVDs in your queue
184 Todd Larason <jtl@molehill.org>, http://molelog.molehill.org/
188 None known; address bug reports and comments to me or to the Blosxom
189 mailing list [http://www.yahoogroups.com/groups.blosxom].
193 =head2 Configuration variables
195 C<$ShopperID> is the key to your Netflix identity; it's a cookie set by the
196 login process. If your browser keeps its cookies in the historical Netscape
197 format, look in C<cookies.txt> for a line like:
199 .netflix.com TRUE / FALSE 1050405980 NetflixShopperId P0000000000000000000000445557579205
201 The long value starting with "P000" is the ShopperID. Until you define this,
202 the plugin does nothing at all.
204 C<$max_cache_age> sets how long to cache the queue information for.
206 C<$debug_level> can be set to a value between 0 and 5; 0 will output
207 no debug information, while 5 will be very verbose. The default is 1,
208 and should be changed after you've verified the plugin is working
211 =head2 Classes for CSS control
213 There's are some classes used, available for CSS customization.
215 * C<netflix> -- both lists are in the netflix class
216 * C<have> -- the 'have' list is also in the have class
217 * C<queue> -- the 'queue' list is also in the queue class
219 =head2 Flavour-style files
221 If you want a format change that can't be made by CSS, you can
222 override the HTML generated by creating files similar to Blosxom's
223 flavour files. They should be named netflix.I<bit>.I<flavour>; for
224 available I<bit>s and their default meanings, see the C<__DATA__>
225 section in the plugin.
229 Because fetching the queue information is relatively slow, I don't believe
230 anyone would want to use it without caching. Thus, this module requires
231 Storable, and caching is always on.
236 Copyright 2003, Todd Larason
238 (This license is the same as Blosxom's)
240 Permission is hereby granted, free of charge, to any person obtaining a
241 copy of this software and associated documentation files (the "Software"),
242 to deal in the Software without restriction, including without limitation
243 the rights to use, copy, modify, merge, publish, distribute, sublicense,
244 and/or sell copies of the Software, and to permit persons to whom the
245 Software is furnished to do so, subject to the following conditions:
247 The above copyright notice and this permission notice shall be included
248 in all copies or substantial portions of the Software.
250 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
251 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
252 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
253 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
254 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
255 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
256 OTHER DEALINGS IN THE SOFTWARE.