PageRenderTime 70ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/v2-105/bin/dailystrips

#
Perl | 1542 lines | 1297 code | 164 blank | 81 comment | 181 complexity | e26724b92feada07464009feb73cb7f9 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, GPL-3.0
  1. #!/usr/bin/perl
  2. #
  3. # Program Summary:
  4. #
  5. # Name: dailystrips
  6. # Description: creates an HTML page containing a number of online comics, with an easily exensible framework
  7. # Author: Andrew Medico <amedico@amedico.dhs.org>
  8. # Created: 23 Nov 2000, 23:33 EST
  9. # Last Modified: 24 Aug 2003, 16:55
  10. # Current Revision: 1.0.28-patched
  11. #
  12. # This copy of dailystrips has been patched by Matthew Williams
  13. # to bypass the United Comics Flash based DRM scheme.
  14. # Set up
  15. use strict;
  16. no strict qw(refs);
  17. use LWP::UserAgent;
  18. use HTTP::Request;
  19. use POSIX qw(strftime);
  20. use Getopt::Long;
  21. use File::Copy;
  22. # Variables
  23. my (%options, $version, $time_today, @localtime_today, @localtime_yesterday, @localtime_tomorrow, $long_date, $short_date,
  24. $short_date_yesterday, $short_date_tomorrow, @get, @strips, %defs, $known_strips, %groups, $known_groups, %classes, $val,
  25. $link_tomorrow, $no_dateparse, @base_dirparts);
  26. $version = "1.0.28";
  27. $time_today = time;
  28. # Get options
  29. GetOptions(\%options, 'quiet|q','verbose','output=s','lite','local|l','noindex',
  30. 'archive|a','dailydir|d','stripdir','save|s','nostale','date=s',
  31. 'new|n','defs=s','nopersonal','basedir=s','list','proxy=s',
  32. 'proxyauth=s','noenvproxy','nospaces','useragent=s','version|v','help|h',
  33. 'avantgo', 'random','nosystem','stripnav','nosymlinks','titles=s',
  34. 'retries=s','clean=s','updates=s','noupdates') or exit 1;
  35. # Process options:
  36. # Note: Blocks have been ordered so that we only do as much as absolutely
  37. # necessary if an error is encountered (i.e. do not load defs if --version
  38. # specified)
  39. # Help and version override anything else
  40. if ($options{'help'}) {
  41. print
  42. "Usage: $0 [OPTION] STRIPS
  43. STRIPS can be a mix of strip names and group names
  44. (group names must be preceeded by an '\@' symbol)
  45. 'all' may be used to retrieve all known strips,
  46. or use option --list to list available strips and groups
  47. Options:
  48. -q --quiet Turn off progress messages
  49. --verbose Turn on extra progress information, overrides -q
  50. --list List available strips
  51. --random Download a random strip
  52. --defs FILE Use alternate strips definition file
  53. --nopersonal Ignore ~/.dailystrips.defs
  54. --nosystem Ignore system-wide definitions
  55. --updates Read updated defs from FILE instead of
  56. ~/.dailystrips-updates.def
  57. --noupdates Ignore updated defs file
  58. --output FILE Output HTML to FILE instead of STDOUT
  59. (does not apply to local mode)
  60. --lite Output a reduced HTML page
  61. --stripnav Add links for navigation within the page
  62. --titles STRING Customize HTML output
  63. -l --local Output HTML to file and save strips locally
  64. --noindex Disable symlinking current page to index.html
  65. (local mode only)
  66. -a --archive Generate archive.html as a list of all days,
  67. (local mode only)
  68. -d --dailydir Create a separate directory for each day's images
  69. (local mode only)
  70. --stripdir Create a separate directory for each strip's
  71. images (local mode only)
  72. -s --save If it appears that a particular strip has been
  73. downloaded, does not attempt to re-download it
  74. (local mode only)
  75. --nostale If a new strip is not available, displays an error
  76. in the HTML output instead of showing the old image
  77. --nosymlinks Do not use symlinks for day-to-day duplicates
  78. --date DATE Use value DATE instead of local time
  79. (DATE is parsed by Date::Parse function)
  80. --avantgo Format images for viewing with Avantgo on PDAs
  81. (local mode only)
  82. --basedir DIR Work in specified directory instead of current
  83. directory (program will look here for previous HTML
  84. file and save new files here, etc.)
  85. --proxy host:port Use specified HTTP proxy server (overrides
  86. environment proxy, if set)
  87. --proxyauth user:pass Set username and password for proxy server
  88. --noenvproxy Ignore the http_proxy environment variable, if set
  89. --nospaces Remove spaces from image filenames (local mode
  90. only)
  91. --useragent STRING Set User-Agent: header to STRING (default is none)
  92. --retries NUM When downloading items, retry NUM times instead of
  93. default 3 times
  94. --clean NUM Keep only the latest NUM days of files; remove all
  95. older files
  96. -v --version Print version number
  97. ";
  98. if ($^O =~ /Win32/ ) {
  99. print
  100. "Additional Win32 Notes:
  101. Windows lacks a number of features and programs found on *NIX, so a number of
  102. changes must be made to the program's operation:
  103. 1. --date and --avantgo are not available
  104. 2. Personal and update definition files may or may not work
  105. 3. System-wide definition files are not supported
  106. ";
  107. } # ' please emacs perlmode
  108. print "\nBugs and comments to dailystrips\@amedico.dhs.org\n";
  109. exit;
  110. }
  111. if ($options{'version'}) {
  112. print "dailystrips version $version\n";
  113. exit;
  114. }
  115. if ($options{'date'}) {
  116. eval "require Date::Parse";
  117. if ($@ ne "") {
  118. die "Error: cannot use --date - Date::Parse not installed\n";
  119. } else {
  120. import Date::Parse;
  121. }
  122. unless ($time_today = str2time($options{'date'})) {
  123. die "Error: invalid date specified\n";
  124. }
  125. }
  126. # setup time variables (needed during defs parsing)
  127. @localtime_today = localtime $time_today;
  128. #long_date = strftime("\%A, \%B \%e, \%Y", @localtime_today);
  129. $long_date = strftime("\%A, \%B \%d, \%Y", @localtime_today);
  130. $short_date = strftime("\%Y.\%m.\%d", @localtime_today);
  131. @localtime_yesterday = localtime($time_today - ( 24 * 60 * 60 ));
  132. $short_date_yesterday = strftime("\%Y.\%m.\%d", @localtime_yesterday);
  133. @localtime_tomorrow = localtime ($time_today + 24 * 60 * 60);
  134. $short_date_tomorrow = strftime("\%Y.\%m.\%d", @localtime_tomorrow);
  135. # Get strip definitions now - info used below
  136. unless ($options{'defs'}) {
  137. if ($^O =~ /Win32/ ) {
  138. $options{'defs'} = 'strips.def';
  139. } else {
  140. $options{'defs'} = '/usr/share/dailystrips/strips.def';
  141. }
  142. }
  143. &get_defs($options{'defs'});
  144. # Load updated defs file
  145. unless (defined $options{'updates'})
  146. {
  147. $options{'updates'} = &get_homedir() . "/.dailystrips-updates.def";
  148. }
  149. unless($options{'noupdates'})
  150. {
  151. if (-r $options{'updates'}) {
  152. &get_defs($options{'updates'});
  153. }
  154. }
  155. # Get system configurable strip definitions now
  156. unless ($options{'nosystem'}) {
  157. unless (($^O =~ /Win32/) or (! -r '/etc/dailystrips.defs')) {
  158. &get_defs('/etc/dailystrips.defs');
  159. }
  160. }
  161. unless ($options{'nopersonal'}){
  162. my $personal_defs = &get_homedir() . "/.dailystrips.defs";
  163. if (-r $personal_defs) {
  164. &get_defs($personal_defs);
  165. }
  166. }
  167. $known_strips = join('|', sort keys %defs);
  168. $known_groups = join('|', sort keys %groups);
  169. if ($options{'random'}) {
  170. my @known_strips_array = keys %defs;
  171. push(@get, $known_strips_array[(rand $#known_strips_array)]);
  172. undef @known_strips_array;
  173. } else {
  174. # Only strips/groups to download remain in @ARGV
  175. # Unconfigured options were already trapped by Getopts with an 'unknown option'
  176. # error
  177. for (@ARGV) {
  178. if (/^($known_strips|all)$/io) {
  179. if ($_ eq "all") {
  180. push (@get, split(/\|/, $known_strips));
  181. } else {
  182. push(@get, $_);
  183. }
  184. } elsif (/^@/) {
  185. if (/^@($known_groups)$/io) {
  186. push(@get, split(/;/, $groups{$1}{'strips'}));
  187. } else {
  188. die "Error: unknown group: $_\n";
  189. }
  190. } else {
  191. die "Error: unknown strip: $_\n";
  192. }
  193. }
  194. }
  195. if ($options{'list'}) {
  196. format =
  197. @<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  198. $_, $val
  199. .
  200. print "Available strips:\n";
  201. for (split(/\|/, $known_strips)) {
  202. $val = $defs{$_}{'name'};
  203. write;
  204. }
  205. print "\nAvailable groups:\n";
  206. for (split(/\|/, $known_groups)) {
  207. $val = $groups{$_}{'desc'};
  208. write;
  209. }
  210. exit;
  211. }
  212. if ($options{'dailydir'} and $options{'stripdir'}) {
  213. die "Error: --dailydir and --stripdir cannot be used together\n";
  214. }
  215. #Set proxy
  216. if ($options{'proxy'}) {
  217. $options{'proxy'} =~ /^(http:\/\/)?(.*?):(.+?)\/?$/i;
  218. unless ($2 and $3) {
  219. die "Error: incorrectly formatted proxy server ('http://server:port' expected)\n";
  220. }
  221. $options{'proxy'} = "http://$2:$3";
  222. }
  223. if (!$options{'noenvproxy'} and !$options{'proxy'} and $ENV{'http_proxy'} ) {
  224. $ENV{'http_proxy'} =~ /(http:\/\/)?(.*?):(.+?)\/?$/i;
  225. unless ($2 and $3) {
  226. die "Error: incorrectly formatted proxy server environment variable\n('http://server:port' expected)\n";
  227. }
  228. $options{'proxy'} = "http://$2:$3";
  229. }
  230. if ($options{'proxyauth'}) {
  231. unless ($options{'proxyauth'} =~ /^.+?:.+?$/) {
  232. die "Error: incorrectly formatted proxy credentials ('user:pass' expected)\n";
  233. }
  234. }
  235. # Handle/validate other options
  236. if ($options{'clean'} =~ m/\D/) {
  237. die "Error: 'clean' value must be numeric\n";
  238. }
  239. if ($options{'retries'} =~ m/\D/) {
  240. die "Error: 'retries' value must be numeric\n";
  241. }
  242. unless ($options{'retries'}) {
  243. $options{'retries'} = 3;
  244. }
  245. if ($options{'basedir'}) {
  246. unless (chdir $options{'basedir'}) {
  247. die "Error: could not change directory to $options{'basedir'}\n";
  248. }
  249. }
  250. if ($options{'titles'}) {
  251. $options{'titles'} .= " ";
  252. }
  253. unless (@get) {
  254. die "Error: no strip specified (--list to list available strips)\n";
  255. }
  256. # verbose overrides quiet
  257. if ($options{'verbose'} and $options{'quiet'}) {
  258. undef $options{'quiet'};
  259. }
  260. # Un-needed vars
  261. undef $known_strips; undef $known_groups; undef $val;
  262. # Go
  263. unless ($options{'quiet'}) {
  264. warn "dailystrips $version starting:\n";
  265. }
  266. # Report proxy settings
  267. if ($options{'proxy'}) {
  268. if ($options{'verbose'}) {
  269. warn "Using proxy server $options{'proxy'}\n";
  270. }
  271. if ($options{'verbose'} and $options{'proxy_auth'}) {
  272. warn "Using proxy server authentication\n";
  273. }
  274. }
  275. if ($options{'local'}) {
  276. unless ($options{'quiet'}) {
  277. warn "Operating in local mode\n";
  278. }
  279. if ($options{'dailydir'}) {
  280. unless ($options{'quiet'}) {
  281. warn "Operating in daily directory mode\n";
  282. }
  283. unless (-d $short_date) {
  284. # any issues with masks and Win32?
  285. unless(mkdir ($short_date, 0755)) {
  286. die "Error: could not create today's directory ($short_date/)\n";
  287. }
  288. }
  289. }
  290. unless(open(STDOUT, ">dailystrips-$short_date.html")) {
  291. die "Error: could not open HTML file (dailystrips-$short_date.html) for writing\n";
  292. }
  293. unless ($options{'date'}) {
  294. unless ($options{'noindex'}) {
  295. unless ($^O =~ /Win32/) {
  296. unlink("index.html");
  297. system("ln -s dailystrips-$short_date.html index.html");
  298. }
  299. }
  300. }
  301. if ($options{'archive'}) {
  302. unless (-e "archive.html") {
  303. # Doesn't exist.. create
  304. open(ARCHIVE, ">archive.html") or die "Error: could not create archive.html\n";
  305. print ARCHIVE
  306. "<html>
  307. <head>
  308. <title>$options{'titles'}dailystrips archive</title>
  309. </head>
  310. <body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ff\" vlink=\"#ff00ff\" alink=\"#ff0000\">
  311. <p align=\"center\">\n
  312. <font face=\"helvetica,arial\" size=\"14pt\">$options{'titles'}dailystrips archive</font>
  313. </p>
  314. <p>
  315. <font face=\"helvetica,arial\">
  316. <!--insert below-->
  317. </font>
  318. </p>
  319. </body>
  320. </html>";
  321. close(ARCHIVE);
  322. }
  323. open(ARCHIVE, "<archive.html") or die "Error: could not open archive.html for reading\n";
  324. my @archive = <ARCHIVE>;
  325. close(ARCHIVE);
  326. unless (grep(/<a href="dailystrips-$short_date.html">/, @archive)) {
  327. for (@archive) {
  328. if (s/(<!--insert below-->)/$1\n<a href="dailystrips-$short_date.html">$long_date<\/a><br>/) {
  329. unless(open(ARCHIVE, ">archive.html")) {
  330. die "Error: could not open archive.html for writing\n";
  331. }
  332. print ARCHIVE @archive;
  333. close(ARCHIVE);
  334. last;
  335. }
  336. }
  337. }
  338. }
  339. # Update previous day's file with a "Next Day" link to today's file
  340. if (open(PREVIOUS, "<dailystrips-$short_date_yesterday.html")) {
  341. my @previous_page = <PREVIOUS>;
  342. close(PREVIOUS);
  343. # Don't bother if no tag exists in the file (because it has already been updated)
  344. if (grep(/<!--nextday-->/, @previous_page)) {
  345. my $match_count;
  346. for (@previous_page) {
  347. if (s/<!--nextday-->/ | <a href="dailystrips-$short_date.html">Next day<\/a>/) {
  348. $match_count++;
  349. last if ($match_count == 2);
  350. }
  351. }
  352. if (open(PREVIOUS, ">dailystrips-$short_date_yesterday.html")) {
  353. print PREVIOUS @previous_page;
  354. close(PREVIOUS);
  355. } else {
  356. warn "Warning: could not open dailystrips-$short_date_yesterday.html for writing\n";
  357. }
  358. } else {
  359. warn "Warning: did not find any tag in previous day's file to make today's link\n";
  360. }
  361. } else {
  362. warn "Warning: could not open dailystrips-$short_date_yesterday.html for reading\n";
  363. }
  364. } elsif ($options{'output'}) {
  365. unless ($options{'quiet'}) {
  366. warn "Writing to file $options{'output'}\n";
  367. }
  368. unless (open(STDOUT, ">$options{'output'}")) {
  369. die "Error: Could not open output file ($options{'output'}) for writing\n";
  370. }
  371. }
  372. # Download image URLs
  373. unless ($options{'quiet'}) {
  374. if ($options{'verbose'}) {
  375. warn "\nRetrieving URLS:\n"
  376. } else {
  377. print STDERR "\nRetrieving URLS..."
  378. }
  379. }
  380. for (@get) {
  381. if ($options{'verbose'}) { warn "Retrieving URL for $_\n" }
  382. &get_strip($_);
  383. }
  384. unless ($options{'quiet'}) {
  385. if ($options{'verbose'}) {
  386. warn "Retrieving URLS: done\n"
  387. } else {
  388. warn "done\n"
  389. }
  390. }
  391. if (-e "dailystrips-$short_date_tomorrow.html") {
  392. $link_tomorrow = " | <a href=\"dailystrips-$short_date_tomorrow.html\">Next day</a>"
  393. } else {
  394. $link_tomorrow = "<!--nextday-->"
  395. }
  396. # Generate HTML page
  397. if ($options{'lite'}) {
  398. print "<font face=\"helvetica\" size=\"+2\"><b><u>$options{'titles'}dailystrips for $long_date</u></b></font><br><br>\n";
  399. } else {
  400. my $topanchor;
  401. if ($options{'stripnav'}) {
  402. $topanchor = "\n<a name=\"top\">\n";
  403. }
  404. print
  405. "<html>
  406. <head>
  407. <title>$options{'titles'}dailystrips for $long_date</title>
  408. </head>
  409. <body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#ff00ff\">
  410. $topanchor
  411. <center>
  412. <font face=\"helvetica\" size=\"+2\"><b><u>$options{'titles'}dailystrips for $long_date</u></b></font>
  413. </center>
  414. <p><font face=\"helvetica\">
  415. &lt; <a href=\"dailystrips-$short_date_yesterday.html\">Previous day</a>$link_tomorrow";
  416. if ($options{'archive'}) {
  417. print " | <a href=\"archive.html\">Archives</a>";
  418. }
  419. print
  420. " &gt;
  421. </font></p>
  422. ";
  423. if ($options{'stripnav'}) {
  424. print "<font face=\"helvetica\">Strips:</font><br>\n";
  425. for (@strips) {
  426. my ($strip, $name) = (split(/;/, $_))[0,1];
  427. print "<a href=\"#$strip\">$name</A>&nbsp;&nbsp;";
  428. }
  429. print "\n<br><br>";
  430. }
  431. print "\n\n<table border=\"0\">\n";
  432. }
  433. if ($options{'local'} and !$options{'quiet'}) {
  434. if ($options{'verbose'}) {
  435. warn "\nDownloading strip files:\n"
  436. } else {
  437. print STDERR "Downloading strip files...";
  438. }
  439. }
  440. for (@strips) {
  441. my ($strip, $name, $homepage, $img_addr, $referer, $prefetch, $artist) = split(/;/, $_);
  442. my ($img_line, $local_name, $local_name_dir, $local_name_file, $local_name_ext, $image, $ext,
  443. $local_name_yesterday, $local_name_yesterday_dir, $local_name_yesterday_file, $local_name_yesterday_ext);
  444. if ($options{'verbose'} and $options{'local'}) {
  445. warn "Downloading strip file for " . lc((split(/;/, $_))[0]) . "\n";
  446. }
  447. if ($img_addr =~ "^unavail") {
  448. if ($options{'verbose'}) {
  449. warn "Error: $strip: could not retrieve URL\n";
  450. }
  451. $img_line = "[Error - unable to retrieve URL]";
  452. } else {
  453. if ($options{'local'}) {
  454. # local mode - download strips
  455. $img_addr =~ /http:\/\/(.*)\/(.*)\.(.*?)([?&].+)?$/;
  456. if (defined $3) { $ext = ".$3" }
  457. # prepare file names
  458. if ($options{'stripdir'}) {
  459. $local_name_yesterday = "$name/$short_date_yesterday$ext";
  460. $local_name_yesterday_dir = "$name/";
  461. $local_name_yesterday_file = $short_date_yesterday;
  462. $local_name_yesterday_ext = $ext;
  463. $local_name = "$name/$short_date$ext";
  464. $local_name_dir = "$name/";
  465. $local_name_file = "$short_date";
  466. $local_name_ext = "$ext";
  467. } elsif ($options{'dailydir'}) {
  468. $local_name_yesterday = "$short_date_yesterday/$name-$short_date_yesterday$ext";
  469. $local_name_yesterday_dir = "$short_date_yesterday/";
  470. $local_name_yesterday_file = "$name-$short_date_yesterday";
  471. $local_name_yesterday_ext = "$ext";
  472. $local_name = "$short_date/$name-$short_date$ext";
  473. $local_name_dir = "$short_date/";
  474. $local_name_file = "$name-$short_date";
  475. $local_name_ext = "$ext";
  476. } else {
  477. $local_name_yesterday = "$name-$short_date_yesterday$ext";
  478. $local_name_yesterday_dir = "./";
  479. $local_name_yesterday_file = "$name-$short_date_yesterday";
  480. $local_name_yesterday_ext = "$ext";
  481. $local_name = "$name-$short_date$ext";
  482. $local_name_dir = "./";
  483. $local_name_file = "$name-$short_date";
  484. $local_name_ext = "$ext";
  485. }
  486. if ($options{'nospaces'}) {
  487. # impossible to tell for sure if previous day's file
  488. # used --nospaces or not, but this should work more
  489. # often
  490. $local_name_yesterday =~ s/\s+//g;
  491. $local_name_yesterday_dir =~ s/\s+//g;
  492. $local_name_yesterday_file =~ s/\s+//g;
  493. $local_name =~ s/\s+//g;
  494. $local_name_dir =~ s/\s+//g;
  495. $local_name_file =~ s/\s+//g;
  496. }
  497. # do ops that depend on file name
  498. if ($options{'stripdir'}) {
  499. unless (-d $local_name_dir) {
  500. # any issues with masks and Win32?
  501. mkdir $local_name_dir, 0755;
  502. }
  503. }
  504. if ($options{'save'} and -e $local_name) {
  505. # already have a suitable local file - skip downloading
  506. if ($options{'avantgo'}) {
  507. $img_line = &make_avantgo_table($local_name, $ext);
  508. } else {
  509. $img_addr = $local_name;
  510. $img_addr =~ s/ /\%20/go;
  511. if ($options{'stripnav'}) {
  512. $img_line = "<img src=\"$img_addr\" alt=\"$name\"><br><a href=\"#top\">Return to top</a>";
  513. } else {
  514. $img_line = "<img src=\"$img_addr\" alt=\"$name\">";
  515. }
  516. }
  517. } else {
  518. # need to download
  519. if ($prefetch) {
  520. if (&http_get($prefetch, $referer) =~ m/^ERROR/) {
  521. warn "Error: $strip: could not download prefetch URL\n";
  522. $image = "ERROR";
  523. } else {
  524. $image = &http_get($img_addr, $referer);
  525. }
  526. } else {
  527. $image = &http_get($img_addr, $referer);
  528. #$image = &http_get($img_addr, "");
  529. }
  530. if ($image =~ /^ERROR/) {
  531. # couldn't get the image
  532. # FIXME: what to do if a file for the day has already been
  533. # downloaded, but downloading fails when script is run again
  534. # that day? maybe reuse existing file instead of throwing
  535. # error?
  536. if (-e $local_name) {
  537. # an image file for today already exists.. jump to outputting code
  538. #warn "DEBUG: couldn't download strip, but we already have it\n";
  539. goto HAVE_IMAGE;
  540. } else {
  541. if ($options{'verbose'}) {
  542. warn "Error: $strip: could not download strip\n";
  543. }
  544. }
  545. $img_line = "[Error - unable to download image]";
  546. } else {
  547. HAVE_IMAGE:
  548. # got the image
  549. if ($^O =~ /Win32/) {
  550. # can't do any diff checking on windows (easily, that is - it is doable)
  551. open(IMAGE, ">$local_name");
  552. binmode(IMAGE);
  553. print IMAGE $image;
  554. close(IMAGE);
  555. $img_addr = $local_name;
  556. $img_addr =~ s/ /\%20/go;
  557. if ($options{'stripnav'}) {
  558. $img_line = "<img src=\"$img_addr\" alt=\"$name\"><br><a href=\"#top\">Return to top</a>";
  559. } else {
  560. $img_line = "<img src=\"$img_addr\" alt=\"$name\">";
  561. }
  562. } else {
  563. # FIXME: only download to .tmp if earlier file exists
  564. open(IMAGE, ">$local_name.tmp");
  565. binmode(IMAGE);
  566. print IMAGE $image;
  567. close(IMAGE);
  568. if (-e $local_name and system("diff \"$local_name\" \"$local_name.tmp\" >/dev/null 2>&1") == 0) {
  569. # already downloaded the same strip earlier today
  570. unlink("$local_name.tmp");
  571. if ($options{'avantgo'}) {
  572. $img_line = &make_avantgo_table($local_name, $ext);
  573. } else {
  574. $img_addr = $local_name;
  575. $img_addr =~ s/ /\%20/go;
  576. if ($options{'stripnav'}) {
  577. $img_line = "<img src=\"$img_addr\" alt=\"$name\"><br><a href=\"#top\">Return to top</a>";
  578. } else {
  579. $img_line = "<img src=\"$img_addr\" alt=\"$name\">";
  580. }
  581. }
  582. } elsif (system("diff \"$local_name_yesterday\" \"$local_name.tmp\" >/dev/null 2>&1") == 0) {
  583. # same strip as yesterday
  584. if ($options{'nosymlinks'}) {
  585. system("mv","$local_name.tmp","$local_name");
  586. } else {
  587. unlink("$local_name.tmp");
  588. if ($options{'stripdir'} or $options{'dailydir'}) {
  589. system("ln -s \"../$local_name_yesterday\" \"$local_name\" >/dev/null 2>&1");
  590. } else {
  591. system("ln -s \"$local_name_yesterday\" \"$local_name\" >/dev/null 2>&1");
  592. }
  593. }
  594. if ($options{'nostale'}) {
  595. $img_line = "[Error - new strip not available]";
  596. } else {
  597. $img_addr = $local_name;
  598. $img_addr =~ s/ /\%20/go;
  599. if ($options{'stripnav'}) {
  600. $img_line = "<img src=\"$img_addr\" alt=\"$name\"><br><a href=\"#top\">Return to top</a>";
  601. } else {
  602. $img_line = "<img src=\"$img_addr\" alt=\"$name\">";
  603. }
  604. }
  605. } else {
  606. # completely new strip
  607. # possible to get here by:
  608. # -downloading a strip for the first time in a day
  609. # -downloading an updated strip that replaces an old one downloaded at
  610. # an earlier time on the same day
  611. system("mv","$local_name.tmp","$local_name");
  612. if ($options{'avantgo'}) {
  613. &make_avantgo_files($local_name, $local_name_ext);
  614. $img_line = &make_avantgo_table($local_name, $ext);
  615. } else {
  616. $img_addr = $local_name;
  617. $img_addr =~ s/ /\%20/go;
  618. if ($options{'stripnav'}) {
  619. $img_line = "<img src=\"$img_addr\" alt=\"$name\"><br><a href=\"#top\">Return to top</a>";
  620. } else {
  621. $img_line = "<img src=\"$img_addr\" alt=\"$name\">";
  622. }
  623. }
  624. }
  625. }
  626. }
  627. }
  628. } else {
  629. # regular mode - just give addresses to strips on their webserver
  630. if ($options{'stripnav'}) {
  631. $img_line = "<img src=\"$img_addr\" alt=\"$name\"><br><a href=\"#top\">Return to top</a>";
  632. } else {
  633. $img_line = "<img src=\"$img_addr\" alt=\"$name\">";
  634. }
  635. }
  636. }
  637. if ($artist) {
  638. $artist = " by $artist";
  639. }
  640. if ($options{'lite'}){
  641. print
  642. "<font face=\"helvetica\" size=\"+1\"><b><a href=\"$homepage\">$name</a>$artist</b></font><br>
  643. $img_line<br>
  644. <br>
  645. ";
  646. } else {
  647. my $stripanchor;
  648. if ($options{'stripnav'}) {
  649. $stripanchor = "<a name=\"$strip\">";
  650. }
  651. print
  652. " <tr>
  653. <td>
  654. <font face=\"helvetica\" size=\"+1\"><b>$stripanchor<a href=\"$homepage\">$name</a>$artist</b></font>
  655. </td>
  656. </tr>
  657. <tr>
  658. <td>
  659. $img_line
  660. <p>&nbsp;</p>
  661. </td>
  662. </tr>
  663. ";
  664. }
  665. }
  666. if ($options{'local'} and !$options{'quiet'}) {
  667. if ($options{'verbose'}) {
  668. warn "Downloading strip files: done\n"
  669. } else {
  670. warn "done\n"
  671. }
  672. }
  673. unless ($options{'lite'}) {
  674. print
  675. "</table>
  676. <p><font face=\"helvetica\">
  677. &lt; <a href=\"dailystrips-$short_date_yesterday.html\">Previous day</a>$link_tomorrow";
  678. if ($options{'archive'}) {
  679. print " | <a href=\"archive.html\">Archives</a>";
  680. }
  681. print
  682. " &gt;
  683. </font></p>
  684. <font face=\"helvetica\">Generated by dailystrips $version</font>
  685. </body>
  686. </html>
  687. ";
  688. }
  689. if (!$options{'date'} and !$options{'noindex'} and $^O =~ /Win32/) {
  690. # no symlinks on windows.. just make a copy of the file
  691. close(STDOUT);
  692. copy("dailystrips-$short_date.html","index.html");
  693. }
  694. # Clean out old files, if requested
  695. if ($options{'clean'}) {
  696. unless ($options{'quiet'}) {
  697. print STDERR "Cleaning files older than $options{'clean'} days...";
  698. }
  699. unless (system("perl -S dailystrips-clean --quiet $options{'clean'}")) {
  700. unless ($options{'quiet'}) {
  701. print STDERR "done\n";
  702. }
  703. }
  704. else {
  705. warn "failed\nWarning: could not run dailystrips-clean script\n";
  706. }
  707. }
  708. sub http_get {
  709. my ($url, $referer) = @_;
  710. my ($request, $response, $status);
  711. # default value
  712. #unless ($retries) {
  713. # $retries = 3;
  714. #}
  715. if ($referer eq "") {$referer = $url;}
  716. my $headers = new HTTP::Headers;
  717. $headers->proxy_authorization_basic(split(/:/, $options{'proxyauth'}));
  718. $headers->referer($referer);
  719. my $ua = LWP::UserAgent->new;
  720. $ua->agent($options{'useragent'});
  721. $ua->proxy('http', $options{'proxy'});
  722. for (1 .. $options{'retries'}) {
  723. # main request
  724. $request = HTTP::Request->new('GET', $url, $headers);
  725. $response = $ua->request($request);
  726. ($status = $response->status_line()) =~ s/^(\d+)/$1:/;
  727. if ($response->is_error()) {
  728. if ($options{'verbose'}) {
  729. warn "Warning: could not download $url: $status (attempt $_ of $options{'retries'})\n";
  730. }
  731. } else {
  732. return $response->content;
  733. }
  734. }
  735. # if we get here, URL retrieval completely failed
  736. warn "Warning: failed to download $url\n";
  737. return "ERROR: $status";
  738. }
  739. sub get_strip {
  740. my ($strip) = @_;
  741. my ($page, $addr);
  742. if ($options{'date'} and $defs{$strip}{'provides'} eq "latest") {
  743. if ($options{'verbose'}) {
  744. warn "Warning: strip $strip not compatible with --date, skipping\n";
  745. }
  746. next;
  747. }
  748. if ($defs{$strip}{'type'} eq "search") {
  749. $page = &http_get($defs{$strip}{'searchpage'});
  750. if ($page =~ /^ERROR/) {
  751. if ($options{'verbose'}) {
  752. warn "Error: $strip: could not download searchpage $defs{$strip}{'searchpage'}\n";
  753. }
  754. $addr = "unavail-server";
  755. } else {
  756. $page =~ /$defs{$strip}{'searchpattern'}/si;
  757. my @regexmatch;
  758. for (1..9) {
  759. $regexmatch[$_] = ${$_};
  760. #warn "regex match #$_: ${$_}\n";
  761. }
  762. unless (${$defs{$strip}{'matchpart'}}) {
  763. if ($options{'verbose'}) {
  764. warn "Error: $strip: searchpattern $defs{$strip}{'searchpattern'} did not match anything in searchpage $defs{$strip}{'searchpage'}\n";
  765. }
  766. $addr = "unavail-nomatch";
  767. } else {
  768. my $match = ${$defs{$strip}{'matchpart'}};
  769. if ($defs{$strip}{'imageurl'}) {
  770. $addr = $defs{$strip}{'imageurl'};
  771. $addr =~ s/\$match_(\d)/$regexmatch[$1]/ge;
  772. $addr =~ s/\$match/$match/ge;
  773. } else {
  774. $addr = $defs{$strip}{'baseurl'} . $match . $defs{$strip}{'urlsuffix'};
  775. }
  776. }
  777. }
  778. } elsif ($defs{$strip}{'type'} eq "generate") {
  779. $addr = $defs{$strip}{'baseurl'} . $defs{$strip}{'imageurl'};
  780. } elsif ($defs{$strip}{'type'} eq "flashdrm") {
  781. $page = &http_get($defs{$strip}{'searchpage'});
  782. if ($page =~ /^ERROR/) {
  783. if ($options{'verbose'}) {
  784. warn "Error: $strip: could not download searchpage $defs{$strip}{'searchpage'}\n";
  785. }
  786. $addr = "unavail-server";
  787. } else {
  788. $page =~ /$defs{$strip}{'searchpattern'}/si;
  789. my @regexmatch;
  790. for (1..9) {
  791. $regexmatch[$_] = ${$_};
  792. #warn "regex match #$_: ${$_}\n";
  793. }
  794. unless ($regexmatch[1]) {
  795. warn "didn't match\n";
  796. if ($options{'verbose'}) {
  797. warn "Error: $strip: searchpattern $defs{$strip}{'searchpattern'} did not match anything in searchpage $defs{$strip}{'searchpage'}\n";
  798. }
  799. $addr = "unavail-nomatch";
  800. } else {
  801. $page = &http_get($defs{$strip}{'drmurl'});
  802. if ($page =~ /^ERROR/) {
  803. warn "Error: $strip: can't download drmurl\n";
  804. $addr = "unavail-server";
  805. } else {
  806. my ($drmkey) = $page =~ m!<key>(.+)</key>!s;
  807. if ($drmkey eq '') {
  808. warn "Error: $strip: unable to locate drmkey\n";
  809. } else {
  810. my $match = ${$defs{$strip}{'matchpart'}};
  811. if ($defs{$strip}{'imageurl'}) {
  812. $addr = $defs{$strip}{'imageurl'};
  813. $addr =~ s/\$match_(\d)/$regexmatch[$1]/ge;
  814. $addr =~ s/\$match/$match/ge;
  815. $addr =~ s/\$drmkey/$drmkey/ge;
  816. } else {
  817. warn "Error: $strip: You must supply an imageurl\n";
  818. }
  819. }
  820. }
  821. }
  822. }
  823. } elsif ($defs{$strip}{'type'} eq "doublesearch") {
  824. $page = &http_get($defs{$strip}{'searchpage'});
  825. if ($page =~ /^ERROR/) {
  826. if ($options{'verbose'}) {
  827. warn "Error: $strip: could not download searchpage $defs{$strip}{'searchpage'}\n";
  828. }
  829. $addr = "unavail-server";
  830. } else {
  831. $page =~ /$defs{$strip}{'searchpattern'}/si;
  832. my @regexmatch;
  833. for (1..9) {
  834. $regexmatch[$_] = ${$_};
  835. #warn "regex match #$_: ${$_}\n";
  836. }
  837. unless ($regexmatch[2]) {
  838. warn "didn't match\n";
  839. if ($options{'verbose'}) {
  840. warn "Error: $strip: searchpattern $defs{$strip}{'searchpattern'} did not match anything in searchpage $defs{$strip}{'searchpage'}\n";
  841. }
  842. $addr = "unavail-nomatch";
  843. } else {
  844. $addr=$defs{$strip}{'baseurl'}.$regexmatch[1].$regexmatch[2];
  845. $addr =~ s/%3D/=/g;
  846. $addr =~ s/%26/&/g;
  847. #warn "downloading $addr\n";
  848. $page = &http_get($addr);
  849. if ($page =~ /^ERROR/) {
  850. warn "Error: $strip: can't download drmurl\n";
  851. $addr = "unavail-server";
  852. } else {
  853. $regexmatch[1]='';
  854. $page =~ /$defs{$strip}{'searchpattern2'}/si;
  855. for (1..9) {
  856. $regexmatch[$_] = ${$_};
  857. #warn "regex match #$_: ${$_}\n";
  858. }
  859. unless ($regexmatch[1]) {
  860. warn "didn't match 2\n";
  861. if ($options{'verbose'}) {
  862. warn "Error: $strip: searchpattern $defs{$strip}{'searchpattern2'} did not match anything in searchpage $defs{$strip}{'baseurl'}.$regexmatch[1].$regexmatch[2]\n";
  863. }
  864. } else {
  865. $addr=$regexmatch[1];
  866. }
  867. }
  868. }
  869. }
  870. } elsif ($defs{$strip}{'type'} eq "search2pages") {
  871. # Search pattern for when it takes two pages to get to the image file
  872. # Pull down the first page
  873. $page = &http_get($defs{$strip}{'searchpage'});
  874. if ($page =~ /^ERROR/) {
  875. if ($options{'verbose'}) {
  876. warn "Error: $strip: could not download searchpage $defs{$strip}{'searchpage'}\n";
  877. }
  878. $addr = "unavail-server";
  879. } else { # And dig through it for the URL for the second page
  880. $page =~ /$defs{$strip}{'searchpattern'}/si;
  881. my @regexmatch;
  882. for (1..9) { $regexmatch[$_] = ${$_};
  883. }
  884. unless ($regexmatch[1]) {
  885. warn "didn't match\n";
  886. if ($options{'verbose'}) {
  887. warn "Error: $strip: searchpattern $defs{$strip}{'searchpattern'} did not match anything in searchpage $defs{$strip}{'searchpage'}\n";
  888. }
  889. $addr = "unavail-nomatch";
  890. } else {
  891. # Now go to the second page, and dig through it for the image URL
  892. $addr = $defs{$strip}{'baseurl'} . $regexmatch[1];
  893. $page = &http_get($addr);
  894. if ($page =~ /^ERROR/) {
  895. warn "Error: $strip: can't download 2nd page\n";
  896. $addr = "unavail-server";
  897. } else {
  898. # find the information in the second page
  899. my ($searchkey) = $page =~ /$defs{$strip}{'searchpattern2'}/;
  900. if ($searchkey eq '') {
  901. warn "Error: $strip: unable to locate searchkey2\n";
  902. } else {
  903. # and build the image url from it and the base.
  904. if ($defs{$strip}{'baseurl'}) {
  905. $addr = $defs{$strip}{'baseurl'} . $searchkey;
  906. } else {
  907. warn "Error: $strip: You must supply a baseurl\n";
  908. }
  909. }
  910. }
  911. }
  912. }
  913. }
  914. unless ($addr =~ /^(http:\/\/|unavail)/io) { $addr = "http://" . $addr }
  915. push(@strips,"$strip;$defs{$strip}{'name'};$defs{$strip}{'homepage'};$addr;$defs{$strip}{'referer'};$defs{$strip}{'prefetch'};$defs{$strip}{'artist'}");
  916. }
  917. sub get_defs {
  918. my $defs_file = shift;
  919. my ($strip, $class, $sectype, $group);
  920. my $line;
  921. unless(open(DEFS, "<$defs_file")) {
  922. die "Error: could not open strip definitions file $defs_file\n";
  923. }
  924. my @defs_file = <DEFS>;
  925. close(DEFS);
  926. if ($options{'verbose'}) {
  927. warn "Loading definitions from file $defs_file\n";
  928. }
  929. for (@defs_file) {
  930. $line++;
  931. chomp;
  932. s/#(.*)//; s/^\s*//; s/\s*$//;
  933. next if $_ eq "";
  934. if (!$sectype) {
  935. if (/^strip\s+(\w+)$/i)
  936. {
  937. if (defined ($defs{$1}))
  938. {
  939. undef $defs{$1};
  940. }
  941. $strip = $1;
  942. $sectype = "strip";
  943. }
  944. elsif (/^class\s+(.*)$/i)
  945. {
  946. if (defined ($classes{$1}))
  947. {
  948. undef $classes{$1};
  949. }
  950. $class = $1;
  951. $sectype = "class";
  952. }
  953. elsif (/^group\s+(.*)$/i)
  954. {
  955. if (defined ($groups{$1}))
  956. {
  957. undef $groups{$1};
  958. }
  959. $group = $1;
  960. $sectype = "group";
  961. }
  962. elsif (/^(.*)/)
  963. {
  964. die "Error: Unknown keyword '$1' at $defs_file line $line\n";
  965. }
  966. }
  967. elsif (/^end$/i)
  968. {
  969. if ($sectype eq "class")
  970. {
  971. undef $class
  972. }
  973. elsif ($sectype eq "strip")
  974. {
  975. if ($defs{$strip}{'useclass'}) {
  976. my $using_class = $defs{$strip}{'useclass'};
  977. # import vars from class
  978. for (qw(homepage searchpage searchpattern baseurl imageurl urlsuffix referer prefetch artist drmurl searchpattern2)) {
  979. if ($classes{$using_class}{$_} and !$defs{$strip}{$_}) {
  980. my $classvar = $classes{$using_class}{$_};
  981. $classvar =~ s/(\$[0-9])/$defs{$strip}{$1}/g;
  982. $classvar =~ s/\$strip/$strip/g;
  983. $defs{$strip}{$_} = $classvar;
  984. }
  985. }
  986. for (qw(type matchpart provides)) {
  987. if ($classes{$using_class}{$_} and !$defs{$strip}{$_}) {
  988. $defs{$strip}{$_} = $classes{$using_class}{$_};
  989. }
  990. }
  991. }
  992. #substitute auto vars for real vals here/set defaults
  993. unless ($defs{$strip}{'searchpage'}) {$defs{$strip}{'searchpage'} = $defs{$strip}{'homepage'}}
  994. unless ($defs{$strip}{'referer'}) {
  995. if ($defs{$strip}{'searchpage'}) {
  996. $defs{$strip}{'referer'} = $defs{$strip}{'searchpage'}
  997. } else {
  998. $defs{$strip}{'referer'} = $defs{$strip}{'homepage'}
  999. }
  1000. }
  1001. #other vars in definition
  1002. for (qw(homepage searchpage searchpattern imageurl baseurl urlsuffix referer prefetch)) {
  1003. if ($defs{$strip}{$_}) {
  1004. $defs{$strip}{$_} =~ s/\$(name|homepage|searchpage|searchpattern|imageurl|baseurl|referer|prefetch)/$defs{$strip}{$1}/g;
  1005. }
  1006. }
  1007. #dates
  1008. for (qw(homepage searchpage searchpattern imageurl baseurl urlsuffix referer prefetch)) {
  1009. if ($defs{$strip}{$_}) {
  1010. $defs{$strip}{$_} =~ s/(\%(-?)[a-zA-Z])/strftime("$1", @localtime_today)/ge;
  1011. }
  1012. }
  1013. # <code:> stuff
  1014. for (qw(homepage searchpage searchpattern imageurl baseurl urlsuffix referer)) {
  1015. if ($defs{$strip}{$_}) {
  1016. $defs{$strip}{$_} =~ s/<code:(.*?)(?<!\\)>/&my_eval($1)/ge;
  1017. }
  1018. }
  1019. #sanity check vars
  1020. for (qw(name homepage type)) {
  1021. unless ($defs{$strip}{$_}) {
  1022. die "Error: strip $strip has no '$_' value\n";
  1023. }
  1024. }
  1025. for (qw(homepage searchpage baseurl imageurl)){
  1026. if ($defs{$strip}{$_} and $defs{$strip}{$_} !~ /^http:\/\//io) {
  1027. die "Error: strip $strip has invalid $_\n"
  1028. }
  1029. }
  1030. if ($defs{$strip}{'type'} eq "search") {
  1031. unless ($defs{$strip}{'searchpattern'}) {
  1032. die "Error: strip $strip has no 'searchpattern' value in $defs_file\n";
  1033. }
  1034. unless ($defs{$strip}{'searchpattern'} =~ /\(.+\)/) {
  1035. die "Error: strip $strip has no parentheses in searchpattern\n";
  1036. }
  1037. unless ($defs{$strip}{'matchpart'}) {
  1038. #die "Error: strip $strip has no 'matchpart' value in $defs_file\n";
  1039. $defs{$strip}{'matchpart'} = 1;
  1040. }
  1041. if ($defs{$strip}{'imageurl'} and ($defs{$strip}{'baseurl'} or $defs{$strip}{'urlsuffix'})) {
  1042. die "Error: strip $strip: cannot use both 'imageurl' at the same time as 'baseurl'\nor 'urlsuffix'\n";
  1043. }
  1044. } elsif ($defs{$strip}{'type'} eq "generate") {
  1045. unless ($defs{$strip}{'imageurl'}) {
  1046. die "Error: strip $strip has no 'imageurl' value in $defs_file\n";
  1047. }
  1048. }
  1049. unless ($defs{$strip}{'provides'}) {
  1050. die "Error: strip $strip has no 'provides' value in $defs_file\n";
  1051. }
  1052. #debugger
  1053. #foreach my $strip (keys %defs) {
  1054. # foreach my $key (qw(homepage searchpage searchpattern imageurl baseurl referer prefetch)) {
  1055. # warn "DEBUG: $strip:$key=$defs{$strip}{$key}\n";
  1056. # }
  1057. # #warn "DEBUG: $strip:name=$defs{$strip}{'name'}\n";
  1058. #}
  1059. undef $strip;
  1060. }
  1061. elsif ($sectype eq "group")
  1062. {
  1063. chop $groups{$group}{'strips'};
  1064. unless ($groups{$group}{'desc'}) {
  1065. $groups{$group}{'desc'} = "[No description]";
  1066. }
  1067. undef $group;
  1068. }
  1069. undef $sectype;
  1070. }
  1071. elsif ($sectype eq "class") {
  1072. if (/^homepage\s+(.+)$/i) {
  1073. $classes{$class}{'homepage'} = $1;
  1074. }
  1075. elsif (/^type\s+(.+)$/i)
  1076. {
  1077. unless ($1 =~ /^(search|generate|flashdrm)$/io) {
  1078. die "Error: invalid type at $defs_file line $line\n";
  1079. }
  1080. $classes{$class}{'type'} = $1;
  1081. }
  1082. elsif (/^searchpage\s+(.+)$/i)
  1083. {
  1084. $classes{$class}{'searchpage'} = $1;
  1085. }
  1086. elsif (/^searchpattern\s+(.+)$/i)
  1087. {
  1088. $classes{$class}{'searchpattern'} = $1;
  1089. }
  1090. elsif (/^matchpart\s+(.+)$/i)
  1091. {
  1092. unless ($1 =~ /^(\d)$/) {
  1093. die "Error: invalid 'matchpart' at $defs_file line $line\n";
  1094. }
  1095. $classes{$class}{'matchpart'} = $1;
  1096. }
  1097. elsif (/^baseurl\s+(.+)$/i)
  1098. {
  1099. $classes{$class}{'baseurl'} = $1;
  1100. }
  1101. elsif (/^urlsuffix\s+(.+)$/i)
  1102. {
  1103. $classes{$class}{'urlsufix'} = $1;
  1104. }
  1105. elsif (/^imageurl\s+(.+)$/i)
  1106. {
  1107. $classes{$class}{'imageurl'} = $1;
  1108. }
  1109. elsif (/^referer\s+(.+)$/i)
  1110. {
  1111. $classes{$class}{'referer'} = $1;
  1112. }
  1113. elsif (/^prefetch\s+(.+)$/i)
  1114. {
  1115. $classes{$class}{'prefetch'} = $1;
  1116. }
  1117. elsif (/^provides\s+(.+)$/i)
  1118. {
  1119. unless ($1 =~ /^(any|latest)$/i) {
  1120. die "Error: invalid 'provides' at $defs_file line $line\n";
  1121. }
  1122. $classes{$class}{'provides'} = $1;
  1123. }
  1124. elsif (/^artist\s+(.+)$/i)
  1125. {
  1126. $classes{$class}{'artist'} = $1;
  1127. }
  1128. elsif (/^drmurl\s+(.+)$/i)
  1129. {
  1130. $classes{$class}{'drmurl'} = $1;
  1131. }
  1132. elsif (/^(.+)\s+?/)
  1133. {
  1134. die "Unknown keyword '$1' at $defs_file line $line\n";
  1135. }
  1136. }
  1137. elsif ($sectype eq "strip") {
  1138. if (/^name\s+(.+)$/i)
  1139. {
  1140. $defs{$strip}{'name'} = $1;
  1141. }
  1142. elsif (/^useclass\s+(.+)$/i)
  1143. {
  1144. unless (defined $classes{$1}) {
  1145. die "Error: strip $strip references invalid class $1 at $defs_file line $line\n";
  1146. }
  1147. $defs{$strip}{'useclass'} = $1;
  1148. }
  1149. elsif (/^homepage\s+(.+)$/i) {
  1150. $defs{$strip}{'homepage'} = $1;
  1151. }
  1152. elsif (/^type\s+(.+)$/i)
  1153. {
  1154. unless ($1 =~ /^(search|generate|flashdrm|search2pages|doublesearch)$/i) {
  1155. die "Error: invalid 'type' at $defs_file line $line\n";
  1156. }
  1157. $defs{$strip}{'type'} = $1;
  1158. }
  1159. elsif (/^searchpage\s+(.+)$/i)
  1160. {
  1161. $defs{$strip}{'searchpage'} = $1;
  1162. }
  1163. elsif (/^searchpattern\s+(.+)$/i)
  1164. {
  1165. $defs{$strip}{'searchpattern'} = $1;
  1166. }
  1167. elsif (/^searchpattern2\s+(.+)$/i)
  1168. {
  1169. $defs{$strip}{'searchpattern2'} = $1;
  1170. }
  1171. elsif (/^matchpart\s+(.+)$/i)
  1172. {
  1173. unless ($1 =~ /^(\d+)$/) {
  1174. die "Error: invalid 'matchpart' at $defs_file line $line\n";
  1175. }
  1176. $defs{$strip}{'matchpart'} = $1;
  1177. }
  1178. elsif (/^baseurl\s+(.+)$/i)
  1179. {
  1180. $defs{$strip}{'baseurl'} = $1;
  1181. }
  1182. elsif (/^urlsuffix\s+(.+)$/i)
  1183. {
  1184. $defs{$strip}{'urlsuffix'} = $1;
  1185. }
  1186. elsif (/^imageurl\s+(.+)$/i)
  1187. {
  1188. $defs{$strip}{'imageurl'} = $1;
  1189. }
  1190. elsif (/^referer\s+(.+)$/i)
  1191. {
  1192. $defs{$strip}{'referer'} = $1;
  1193. }
  1194. elsif (/^prefetch\s+(.+)$/i)
  1195. {
  1196. $defs{$strip}{'prefetch'} = $1;
  1197. }
  1198. elsif (/^(\$\d)\s+(.+)$/)
  1199. {
  1200. $defs{$strip}{$1} = $2;
  1201. }
  1202. elsif (/^provides\s+(.+)$/i)
  1203. {
  1204. unless ($1 =~ /^(any|latest)$/i) {
  1205. die "Error: invalid 'provides' at $defs_file line $line\n";
  1206. }
  1207. $defs{$strip}{'provides'} = $1;
  1208. }
  1209. elsif (/^artist\s+(.+)$/i)
  1210. {
  1211. $defs{$strip}{'artist'} = $1;
  1212. }
  1213. elsif (/^(.+)\s+?/)
  1214. {
  1215. die "Error: Unknown keyword '$1' at $defs_file line $line, in strip $strip\n";
  1216. }
  1217. } elsif ($sectype eq "group") {
  1218. if (/^desc\s+(.+)$/i)
  1219. {
  1220. $groups{$group}{'desc'} = $1;
  1221. }
  1222. elsif (/^include\s+(.+)$/i)
  1223. {
  1224. $groups{$group}{'strips'} .= join(';', split(/\s+/, $1)) . ";";
  1225. }
  1226. elsif (/^exclude\s+(.+)$/i)
  1227. {
  1228. $groups{$group}{'nostrips'} .= join(';', split(/\s+/, $1)) . ";";
  1229. }
  1230. elsif (/^(.+)\s+?/)
  1231. {
  1232. die "Error: Unknown keyword '$1' at $defs_file line $line, in group $group\n";
  1233. }
  1234. }
  1235. }
  1236. # Post-processing validation
  1237. for $group (keys %groups) {
  1238. my (@strips, %nostrips, @okstrips);
  1239. if (defined($groups{$group}{'nostrips'})) {
  1240. @strips = sort(keys(%defs));
  1241. foreach (split (/;/,$groups{$group}{'nostrips'})) {
  1242. $nostrips{$_} = 1;
  1243. }
  1244. } else {
  1245. @strips = split(/;/, $groups{$group}{'strips'});
  1246. %nostrips = (); #empty
  1247. }
  1248. foreach (@strips) {
  1249. unless ($defs{$_}) {
  1250. warn "Warning: group $group references non-existant strip $_\n";
  1251. }
  1252. next if ($nostrips{$_});
  1253. push (@okstrips,$_);
  1254. }
  1255. $groups{$group}{'strips'} = join(';',@okstrips);
  1256. }
  1257. }
  1258. sub my_eval {
  1259. my ($code) = @_;
  1260. $code =~ s/\\\>/\>/g;
  1261. return eval $code;
  1262. #print STDERR "DEBUG: eval returned: " . scalar(eval $code) . ", errors: $!\n";
  1263. }
  1264. sub make_avantgo_table {
  1265. my ($file, $file_ext) = @_;
  1266. my ($rows, $cols, $table);
  1267. my $dimensions = `identify \"$file\"`;
  1268. $dimensions =~ m/^$file (\d+)x(\d+)/;
  1269. my $width = $1; my $height = $2;
  1270. if (int($width/160) != ($width/160)) {
  1271. $cols = int($width/160) + 1;
  1272. } else {
  1273. $cols = $width/160;
  1274. }
  1275. if (int($height/160) != ($height/160)) {
  1276. $rows = int($height/160) + 1;
  1277. } else {
  1278. $rows = $height/160;
  1279. }
  1280. my $file_base = $file; $file_base =~ s/$file_ext$//;
  1281. $file_base =~ s/ /\%20/g;
  1282. $table = "<table border=0 cellspacing=0 cellpadding=0>";
  1283. foreach my $row (0 .. ($rows-1)) {
  1284. $table .= "<tr>";
  1285. foreach my $col (0 .. ($cols-1)) {
  1286. $table .= "<td><img src=$file_base-" . (($row * $cols) + $col) . "$file_ext></td>";
  1287. }
  1288. $table .= "</tr>";
  1289. }
  1290. $table .= "</table>";
  1291. return $table;
  1292. }
  1293. sub make_avantgo_files {
  1294. my ($file, $file_ext) = @_;
  1295. my $file_base = $file; $file_base =~ s/$file_ext$//;
  1296. system("convert -crop 160x160 \"$file\" \"$file_base-\%d$file_ext\"");
  1297. }
  1298. sub get_homedir
  1299. {
  1300. if ($^O =~ /Win32/ )
  1301. {
  1302. my $dir = $ENV{'USERPROFILE'};
  1303. if ($dir eq "") {$dir = $ENV{'WINDIR'};}
  1304. $dir =~ s|\\|/|g;
  1305. return $dir;
  1306. }
  1307. else
  1308. {
  1309. return (getpwuid($>))[7];
  1310. }
  1311. }