#! /usr/bin/perl #* ============================================================ # * File : apple.pl # * Release : 3 # * Author : Michael Knoll # * Description : Parses Apple Movie Trailers and Categories # * Date : 2005-07-20 # * Last Change : 2009-08-30 by Paul Bender # * ============================================================ # * # * Copyright 2005 by Michael Knoll # # * This program is free software; you can redistribute it # * and/or modify it under the terms of the GNU General # * Public License as published bythe Free Software Foundation; # * either version 2, or (at your option) # * any later version. # * # * This program is distributed in the hope that it will be useful, # * but WITHOUT ANY WARRANTY; without even the implied warranty of # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # * GNU General Public License for more details. # * # * ============================================================ # * # * sept 2007: apple.pl edit by Eric. Removed all except category # * listing. Revert to pre v0.18_1 to see original code # * from Michael. # * aug 2009: adopted patch from Paul Bender - now listing different # * trailer resolutions # * # * Note: as of 20 aug 2009 Apple trailer site only accepts players # * passing a QuickTime user agent string. as workaround, # * change player.xml to include the custom player option # * -user-agent like this: # * # * # * -user-agent # * QuickTime/0 # * # * # * Note that this changes the mplayer user agent for all # * streams and files played from MythStream. The QT4 # * version of MythStream (> 0.18_1) will include a # * user agent field in the parser interface. # * use HTML::Parser; use LWP::UserAgent; use XML::DOM; use XML::XQL; use XML::XQL::DOM; use Data::Dumper; my $USER_AGENT = 'iTunes/4.7'; my $HANDLER = "*apple"; my $BASE_URL = 'http://www.apple.com'; my $START_URL = '/moviesxml/h/index.xml'; my $MAIN_INDEX_URL = $BASE_URL . $START_URL; my %stream_names = ( "large.xml" => "Large", "medium.xml" => "Medium" , "small.xml" => "Small", ); my $line = $ARGV[1]; # remove quotes from sname $line =~ s/^\"?(.*?)\"?$/$1/; my $command; my $url; if(defined $line and $line =~ /^(.*?):(.*)$/) { $command = $1; $url = $2; } else { $command = 'start'; $url = $MAIN_INDEX_URL; } my $output_doc = XML::DOM::Document->new; my $output_head = $output_doc->createXMLDecl ('1.0'); my $output_items = $output_doc->createElement('items'); my $ua = new LWP::UserAgent(agent => $USER_AGENT); my $response = $ua->request(HTTP::Request->new(GET => $url)); if(!$response->is_success) { print STDERR $response->status_line, "\n"; exit(0); } my $parser = new XML::DOM::Parser; my $maindoc = $parser->parse($response->content); # print $response->content; if($command eq 'start') { # last node MatrixView is directly below my $ROOT_XQL = '/Document/View/ScrollView/MatrixView/View/VBoxView[0]/MatrixView'; # VBoxView[2] is directly below my $CATAGORIES_XQL = $ROOT_XQL . '/VBoxView[0]/VBoxView[2]/View/VBoxView/MatrixView/GotoURL'; getCatagories($maindoc, $CATAGORIES_XQL); } elsif($command eq 'category') { my $TRAILERS_XQL = '/Document/ScrollView/View/MatrixView/VBoxView/HBoxView/VBoxView/VBoxView/View/VBoxView[1]/MatrixView/VBoxView/MatrixView/HBoxView'; # dit is toch niet normaal meer mensen... my $TRAILERS_URL_XQL = 'VBoxView/MatrixView/VBoxView/HBoxView/TextView/GotoURL'; my $TRAILERS_TITLE_XQL = 'SetFontStyle/B/textNode()[0]'; getTrailers($maindoc, $TRAILERS_XQL, $TRAILERS_TITLE_XQL, '', $TRAILERS_URL_XQL); } elsif($command eq 'trailer') { my $TRAILER_XQL = '/Document/TrackList/plist/dict/array/dict'; my $TRAILER_URL_KEY = 'previewURL'; my $TRAILER_TITLE_KEY = 'songName'; getTrailer($maindoc, $TRAILER_XQL, $TRAILER_TITLE_KEY, $TRAILER_URL_KEY); } print $output_head->toString; print $output_items->toString; print "\n"; sub getCatagories { my $doc = shift; my $cat_xql = shift; foreach my $category ($doc->xql($cat_xql)) { my $url = $BASE_URL . $category->getAttribute('url'); my $category_title = "category - " . $category->getAttribute('draggingName'); newItem( name => $category_title, url => 'category:' . $url, handler => $HANDLER); } } sub getTrailers { my $doc = shift; my $root_xql = shift; my $title_xql = shift; my $title_prepend = shift; my $url_xql = shift; foreach my $trailer ($doc->xql($root_xql)) { next if $trailer->getAttribute('inhibitDragging'); my ($url_node) = ($trailer->xql($url_xql)); my $url = $BASE_URL . $url_node->getAttribute('url'); my ($title_node) = ($url_node->xql($title_xql)); my $title = $title_prepend . trimText($title_node->getData()); newItem( name => $title, url => 'trailer:' . $url, handler => $HANDLER); } } sub getTrailer { my $doc = shift; my $root_xql = shift; my $title_key = shift; my $url_key = shift; foreach my $instance ($doc->xql($root_xql)) { my $string = $instance->toString(); my ($title) = $string =~ /$title_key<\/key>(.*?)<\/string>/; my ($url) = $string =~ /$url_key<\/key>(.*?)<\/string>/; if (($title) && ($url)) { newItem( name => $title, url => $url, handler => ''); } } } sub trimText { my $text = shift; $text =~ s/^\s+//; $text =~ s/\s+$//; return $text; } sub newItem { my %elements = @_; my $new_item = $output_doc->createElement('item'); $output_items->appendChild($new_item); foreach(keys %elements) { my $node = $output_doc->createElement($_); my $text = $output_doc->createTextNode($elements{$_}); $node->appendChild($text); $new_item->appendChild( $node ); } }