#! /usr/bin/tclsh # Location of the raw XML movie index. set FeedsURL "http://www.apple.com/trailers/home/xml/current.xml" # Download to the current directory. set TargetDir [pwd] # We'll use this global variable for the raw XML. set FeedsXML "" # And this will be for our organized movie data. array set Movies [list] # Load this standard Tcl package. package require http # Parses all relevant data for the next listed movie in the XML data, starting at the specified character index. proc parseNextMovie {index} { global FeedsXML Movies set startIndex [string first {} $xml $index] incr index 2 set end [string first {" flush stdout } # Calculate the number of progress bars that should be displayed. set bytesPerBar [expr { 1.0 * $total / 20 }] set bars [expr { int($current / $bytesPerBar) }] while { $ProgressBar < $bars } { puts -nonewline "|" flush stdout incr ProgressBar } return } # Replaces undesirable or incompatible characters with friendlier ones. proc cleanTitle {title} { set title [string map { > > < < " \" ” \" „ \" ‘ \" ’ \" ‚ , & & > ) < ( : - / - \\ - ? "" | - * + } $title] } # Download the movie index. set token [http::geturl $FeedsURL] set FeedsXML [encoding convertfrom utf-8 [http::data $token]] http::cleanup $token # Loop through the XML, parsing movie data until there are no more movies to parse. set index 0 while { $index > -1 } { set index [parseNextMovie $index] } # Let's see which movies we already have downloaded and remove them from our Movies array. # We'll see what directories are in our $TargetDir, and assume each is the name of a movie. foreach file [glob -directory $TargetDir -nocomplain -tails *] { if { [file isdirectory $file] } { if { [info exists Movies($file)] } { unset Movies($file) } } } # Now our Movies array only contains movies which haven't been downloaded yet. Let's download them one by one. set titles [lsort -dictionary -increasing [array names Movies]] set count 0 foreach title $titles { incr count puts "\nDownloading $count/[llength $titles] \"$title\"" downloadMovie $title }