#! /usr/bin/perl
#* ============================================================
# * File        : apple.pl
# * Release     : 3
# * Author      : Michael Knoll <michaelDOTknollATgmailDOTcom>
# * 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:
# *
# *              <item>
# *                <name>-user-agent</name>
# *                <value>QuickTime/0</value>
# *              </item>
# *
# *            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 <!--MASTER MATRIX-->
	my $ROOT_XQL = '/Document/View/ScrollView/MatrixView/View/VBoxView[0]/MatrixView';

   # VBoxView[2] is directly below <!-- BEGIN GENRES 2.0 -->
	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 =~ /<key>$title_key<\/key><string>(.*?)<\/string>/;
		my ($url)   = $string =~ /<key>$url_key<\/key><string>(.*?)<\/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 );
	}
}

