[Clipart] r32 - in makerelease: . template template/css template/images
noreply at openclipart.org
noreply at openclipart.org
Sat Mar 28 01:46:18 PDT 2009
Author: jstaerk
Date: Sat Mar 28 08:46:17 2009
New Revision: 32
Log:
by jstaerk at usegroup.de, new script to create file releases as of 0.19
Added:
makerelease/
makerelease/downloader.php
makerelease/template/
makerelease/template/css/
makerelease/template/css/main.css
makerelease/template/images/
makerelease/template/images/bg.png (contents, props changed)
makerelease/template/images/bgl.png (contents, props changed)
makerelease/template/images/bullet.gif (contents, props changed)
makerelease/template/images/logo.jpg (contents, props changed)
makerelease/template/images/openclipart.png (contents, props changed)
makerelease/template/images/publicdomain.png (contents, props changed)
makerelease/template/images/s-b.png (contents, props changed)
makerelease/template/index.html
Added: makerelease/downloader.php
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ makerelease/downloader.php Sat Mar 28 08:46:17 2009 (r32)
@@ -0,0 +1,792 @@
+<?php
+
+/**
+ * @author Jochen Stärk <jstaerk at usegroup.de>
+ * @version 1.1
+ * @date 2009-03-19
+ *
+ * This php shell script creates a openclipart file release.
+ *
+ * It uses wget to download the daily SVG tarball from openclipart.org,
+ * fires inkscape to rasterize all images and create thumbnails,
+ * creates a HTML-Gallery for offline viewing, creates .zip, .tar.gz and .tar.bz2
+ * bundles and uploads them with rsync.
+ * A log with all messages is stored in lastrun.log
+ *
+ * It has been developed for windows and linux
+ *
+ * It requires the following tools to be installed:
+ * - php (obviously, to run this script, fire <path to your php>\php downloader.php). For windows you can also use xampp, http://www.apachefriends.org/en/xampp-windows.html
+ * - the GD-extension of PHP
+ * - a high memory_limit in the php.ini file. 32mb didn't suffice for big PNGs but I never had any issue with 320...
+ * - wget, tar, bzip2 (for windows: http://getgnuwin32.sourceforge.net/)
+ * - the templates for the HTML gallery in a subdirectory called template
+ * - inkscape (www.inkcape.org) to create png thumbnails
+ * - optional: rsync to upload, for windows e.g. cwrsync, http://www.rsync.net/resources/howto/windows_rsync.html
+ * in case you want to use this feature you will have to setup cwrsync so that it connects to the remote host
+ * w/o asking for a password or host authentication confirmation. Ted Ruegsegger has written a documentation
+ * on that on http://www.tux.org/~tbr/rsync/#What1 but I think it's even easier:
+ * the home directory on vista is automatically c:\users\<username>.
+ * On XP and older your homedir might be somewhere else, e.g. "c:\documents and settings"
+ * run rsync once manually from the rsync path, rsyncing anything you like to
+ * your destination host to get the .ssh directory and confirm host authentity:
+ * Step 1 (confirm host):
+ * cd "\program files\cwrsync\bin"
+ * rsync -avzP plink.exe <yourusername>@<yourhostname>:/tmp/
+ * (confirm host identity and type your password manually)
+ * (this should transmit plink.exe to <yourhostname>/tmp/ just as a test)
+ * Step 2 (generate and submit keys):
+ * (still in "\program files\cwrsync\bin")
+ * ssh-keygen -t dsa -N "" -f \users\<username>\.ssh\id_dsa
+ * rsync -avzP \users\<username>\.ssh\id_dsa.pub <yourusername>@<yourhostname>:/tmp/id_dsa.pub
+ * Step 3 (host to accept the keys):
+ * ssh to your host, e.g. via putty, with <yourusername>
+ * rm /tmp/plink.exe (as this was just a test)
+ * cat /tmp/id_dsa.pub >> ~/.ssh/authorized_keys
+ * (keep this window open, I'll call it remote window)
+ * Step 4 (test)
+ * (back on local window in "\program files\cwrsync\bin")
+ * rsync -avzP plink.exe <yourusername>@<yourhostname>:/tmp/
+ * (this should now NOT ask for host authentication NOR password)
+ * (on remote window)
+ * rm /tmp/plink.exe
+ * exit
+ * (and you can also exit your local window)
+ *
+ * see also http://www.openclipart.org/wiki/Release_Procedure
+ * */
+
+/**
+ * This class was just a test for obtaining metadata but it never worked properly
+ * and is not used at all at this time
+
+class tagParser {
+
+ // XML parser variables
+ var $parser;
+ var $name;
+ var $attr;
+ private $lastContent;
+ private $numItemsRetrieved;
+ private $numItemsToRetrieve=300;
+ private $chop=0;
+ private $tag;
+ private $completeContent="";
+ private $emptyTranslations=array();
+
+
+ // function with the default parameter value
+ // it will automatically add &limit=300&chop=0
+ function __construct($tag) {
+ $this->tag = $tag;
+
+ $translations = get_html_translation_table(HTML_ENTITIES);
+ $this->emptyTranslations=array();
+ foreach ($translations as $key=>$translation) {
+ $this->emptyTranslations[$translation]="?";
+ }
+
+ }
+
+ // parse XML data
+ function parse()
+ {
+ $this->numItemsRetrieved=0;
+ $this->parser = xml_parser_create ("UTF-8");
+ xml_set_object($this->parser, $this);
+ xml_set_element_handler($this->parser, 'startXML', 'endXML');
+ xml_set_character_data_handler($this->parser, 'charXML');
+
+ xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
+
+
+// die(strtr("dies ist alles & nichts ", $emptyTranslations));
+ do {
+ $completeURL="http://openclipart.org/media/api/query?f=rss&tags=".$this->tag."&limit=300&offset=".$this->chop;
+ // if use type = 'url' now we open the XML with fopen
+
+ if (!($fp = @fopen($completeURL, 'rb'))) {
+ $this->error("Cannot open {$this->url}");
+ }
+
+ while (($data = fread($fp, 8192))) {
+ $data=strtr($data, $this->emptyTranslations);
+ $this->completeContent.=$data;
+ if (!xml_parse($this->parser, $data, feof($fp))) {
+ $this->error(sprintf('XML error at line %d column %d',
+ xml_get_current_line_number($this->parser),
+ xml_get_current_column_number($this->parser)),$data);
+ }
+ }
+ fclose($fp);
+ $this->chop+=$this->numItemsRetrieved;
+ echo "$completeURL\n";
+ } while (!$this->isCompleted());
+
+ echo "retrieved ".$this->numItemsRetrieved." items for tag ".$this->tag."\n";
+ }
+
+ function startXML($parser, $name, $attr) {
+ $this->lastContent="";
+ if ($name=="item") {
+ $this->numItemsRetrieved++;
+ }
+
+ }
+
+ function endXML($parser, $name) {
+ if ($name=="guid") {
+ //$progFile=fopen("prog.txt","a");
+ print($this->chop." ".$this->lastContent."\n");
+ //fclose ($progFile);
+ }
+
+ }
+
+ function isCompleted() {
+ return $this->numItemsRetrieved<$this->numItemsToRetrieve;
+ }
+
+ function charXML($parser, $data) {
+ $this->lastContent.=$data;
+ }
+
+ function error($msg, $data=null) {
+ echo "$msg";
+ if ($data!=null) {
+ $errFile=fopen("err.txt","w");
+ fwrite($errFile, $data);
+ fclose ($errFile);
+ }
+ exit();
+ }
+}
+
+//$tags=array("abstract","activity","anatomy","ancient","animal","apple","arcade","architecture","armor","arrow","art","baby","ball","barbering","bear","beer","beverage","bird","birthday","black","blue","boat","book","border","bottle","box","boy","building","button","calligraphic","callout","camera","candle","car","card","cartography","cartoon","castle","cat","character","chicken","child","christmas","circuit","city","clock","clothing","cloud","coat_of_arms","color","colouring_book","comic","computer","container","contour","costume","country","cow","crest","danger","decoration","decorative","design","dessert","diagram","dog","drink","earth","egg","electric","electrical_appliances","electricity","electronics","epa","epa_sunwise","equipment","europe","eye","face","fantasy","farm","feline","female","figure","fire","fish","flag","flower","fly","food","frame","france","fruit","funny","furniture","fws","fws_lineart","game","geography","germany","girl","glass","globe","glossy","god
","greek","green","guitar","guy","hair","halloween","hand","happy","hardware","hat","head","heart","helmet","heraldry","historical","history","holiday","home","horse","house","household","human","icon","iec","illustration","inkscape","insect","instrument","japanese","jigsaw","key","kitchen","land","landscape","leaf","letter","line_art","literature","loc","logo","love","mammal","man","map","maritime","meat","medical","medicine","medieval","metal","military","money","monitor","mouse","music","mythology","nation","nature","night","no_contour","ocean","office","orange","outline","paper","party","pc_for_alla","pen","penguin","people","person","pet","phone","photorealistic","pink","pirate","plane","planet","plant","play","poland","portrait","puzzle","rabbit","reading","red","religion","roadsign","sailing","santa","scene","school","science","screen","sea","season","semaphore","shape","ship","sign","signal","silhouette","skull","sky","smiley","smiling","snow","sound","space","sport"
,"star","storage","sun","sweden","swiss","sword","symbol","tangram","technology","time","tool","tower","toy","traffic","transportation","tree","united_nations_member","uspto","valentine","vegetable","vehicle","war","warning","water","weapon","weather","white","wikimedia_commons","wine","wing","winter","woman","wood","work","world","worldlabel","writing","yellow");
+
+foreach ($tags as $tag) {
+
+ $rp=new tagParser($tag);
+ $rp->parse();
+
+
+}*/
+
+class opsysDependendEntity{
+ protected $opsys; // 1=windows, 0=linux, adjusted in checkOpsys
+ protected $opsysQuotes;//quotes around directories with spaces (and commands with multiple directories with spaces), none in linux, " in windows, adjusted in checkOpsys
+ protected $opsysDirSep;//delimiter between directories and subdirectories or files, "/" in linux, "\" in windows, adjusted in checkOpsys
+ protected $path_wget; // the full path and file name of the "wget" executable. Default assigned in checkOpsys, user will be prompted if not found there
+ protected $path_tar; // where "wget" is found. Default assigned in..., user will be prompted...
+ protected $path_bunzip;
+ protected $path_gzip;
+ protected $path_bzip;
+ protected $path_zip;
+ protected $path_inkscape;
+ protected $path_rsync;
+
+ public function checkOpsys() {
+ if (file_exists("/etc")) {
+ //unixoid opsys, lets assume it's linuxoid...
+ $this->opsys=0;
+ $this->opsysQuotes="";
+ $this->opsysDirSep="/";
+
+
+ $this->path_wget="/usr/bin/wget";
+ $this->path_tar="/bin/tar";
+ $this->path_bunzip="/bin/bunzip2";
+ $this->path_gzip="/bin/gzip";
+ $this->path_bzip="/bin/bzip2";
+ $this->path_zip="/usr/bin/zip";
+ $this->path_inkscape="/usr/bin/inkscape";
+ $this->path_rsync="/usr/bin/rsync";
+ } else {
+ $this->opsys=1;
+ $this->opsysQuotes="\"";
+ $this->opsysDirSep="\\";
+
+ $this->path_wget="c:\\program files\\gnu\\gnuwin32\\bin\\wget.exe";
+ $this->path_tar="c:\\program files\\gnu\\gnuwin32\\bin\\tar.exe";
+ $this->path_bunzip="c:\\program files\\gnu\\gnuwin32\\bin\\bunzip2.exe";
+ $this->path_gzip="c:\\program files\\gnu\\gnuwin32\\bin\\gzip.exe";
+ $this->path_bzip="c:\\program files\\gnu\\gnuwin32\\bin\\bzip2.exe";
+ $this->path_zip="c:\\program files\\gnu\\gnuwin32\\bin\\zip.exe";
+ $this->path_inkscape="c:\\program files\\inkscape\\inkscape.exe";
+ $this->path_rsync="c:\\program files\\cwRsync\\bin\\rsync.exe";
+
+ }
+ }
+
+
+}
+
+class logger extends opsysDependendEntity {
+ private $logfile; // the file handle of the open lastrun.log file
+ private $startTime; // the microtime (true) when the run started. Used to calculate runtime in status messages
+
+ public function __construct() {
+ $this->logfile=fopen("lastrun.log", "w");
+ $this->startTime=microtime(true);
+ $this->checkOpsys();
+
+ }
+ /**
+ * this function will give an echo and log on the logfile
+ * */
+ function shout($message) {
+ echo $message;
+ fwrite($this->logfile, $message);
+
+ }
+
+ function shoutNewStatus($message) {
+ $time=microtime(true);
+ $runTime=$time-$this->startTime;
+ $this->shout("===$message===\n");
+ $this->shout("@$runTime\n");
+ }
+ public function __destruct() {
+ $this->shoutNewStatus("done");
+
+ fclose($this->logfile);
+ }
+
+
+}
+
+class HTMLPreviewBuilder extends opsysDependendEntity {
+ private $images;
+ private $logger;
+ private $destinationPath;
+ private $thumbsProPage=50;
+ private $currentPageIndex=0;
+ private $numPages=0;
+ private $templateLines=array();
+ private $version;
+ private $pagesLinked;
+
+ public function __construct(logger $logger, $version) {
+ $this->images=array();
+ $this->logger=$logger;
+ $this->version=$version;
+ $this->checkOpsys();
+ }
+
+ public function addImage($filepath) {
+ $this->images[]=$filepath;
+ }
+
+ private function dir_copy($srcdir, $dstdir, $offset = '', $verbose = false)
+ {// source: http://de3.php.net/copy#89299
+ // A function to copy files from one directory to another one, including subdirectories and
+ // nonexisting or newer files. Function returns number of files copied.
+ // This function is PHP implementation of Windows xcopy A:\dir1\* B:\dir2 /D /E /F /H /R /Y
+ // Syntaxis: [$returnstring =] dircopy($sourcedirectory, $destinationdirectory [, $offset] [, $verbose]);
+ // Example: $num = dircopy('A:\dir1', 'B:\dir2', 1);
+
+ // Original by SkyEye. Remake by AngelKiha.
+ // Linux compatibility by marajax.
+ // ([danbrown AT php DOT net): *NIX-compatibility noted by Belandi.]
+ // Offset count added for the possibilty that it somehow miscounts your files. This is NOT required.
+ // Remake returns an explodable string with comma differentiables, in the order of:
+ // Number copied files, Number of files which failed to copy, Total size (in bytes) of the copied files,
+ // and the files which fail to copy. Example: 5,2,150000,\SOMEPATH\SOMEFILE.EXT|\SOMEPATH\SOMEOTHERFILE.EXT
+ // If you feel adventurous, or have an error reporting system that can log the failed copy files, they can be
+ // exploded using the | differentiable, after exploding the result string.
+ //
+ if(!isset($offset)) $offset=0;
+ $num = 0;
+ $fail = 0;
+ $sizetotal = 0;
+ $fifail = '';
+ if(!is_dir($dstdir)) mkdir($dstdir);
+ if($curdir = opendir($srcdir)) {
+ while($file = readdir($curdir)) {
+ if($file != '.' && $file != '..') {
+ // $srcfile = $srcdir . '\\' . $file; # deleted by marajax
+ // $dstfile = $dstdir . '\\' . $file; # deleted by marajax
+ $srcfile = $srcdir . '/' . $file; # added by marajax
+ $dstfile = $dstdir . '/' . $file; # added by marajax
+ if(is_file($srcfile)) {
+ if(is_file($dstfile)) $ow = filemtime($srcfile) - filemtime($dstfile); else $ow = 1;
+ if($ow > 0) {
+ if($verbose) echo "Copying '$srcfile' to '$dstfile'...<br />";
+ if(copy($srcfile, $dstfile)) {
+ touch($dstfile, filemtime($srcfile)); $num++;
+ chmod($dstfile, 0777); # added by marajax
+ $sizetotal = ($sizetotal + filesize($dstfile));
+ if($verbose) echo "OK\n";
+ }
+ else {
+ echo "Error: File '$srcfile' could not be copied!<br />\n";
+ $fail++;
+ $fifail = $fifail.$srcfile.'|';
+ }
+ }
+ }
+ else if(is_dir($srcfile)) {
+ $res = explode(',',$ret);
+ // $ret = dircopy($srcfile, $dstfile, $verbose); # deleted by patrick
+ $ret = $this->dir_copy($srcfile, $dstfile, $verbose); # added by patrick
+ $mod = explode(',',$ret);
+ $imp = array($res[0] + $mod[0],$mod[1] + $res[1],$mod[2] + $res[2],$mod[3].$res[3]);
+ $ret = implode(',',$imp);
+ }
+ }
+ }
+ closedir($curdir);
+ }
+ $red = explode(',',$ret);
+ $ret = ($num + $red[0]).','.(($fail-$offset) + $red[1]).','.($sizetotal + $red[2]).','.$fifail.$red[3];
+ return $ret;
+ }
+
+ private function copyTemplateFiles() {
+ $this->dir_copy("template",$this->destinationPath);
+ }
+
+ private function getFilenameForIndex($idx) {
+ $filenameSuffix="_".$idx;
+ if ($idx==1) {
+ $filenameSuffix="";
+ }
+ return "index".$filenameSuffix.".html";
+ }
+
+ private function calculateLink($fromWhere, $distance, $ascending) {
+ $target=null;
+ if ($fromWhere%$distance==0) {
+ if ($ascending) {
+ $target=$fromWhere+$distance;
+ } else {
+ $target=$fromWhere-$distance;
+ }
+
+ } else {
+ if ($ascending) {
+ $target=ceil($fromWhere/$distance)*$distance;
+ } else {
+ $target=floor($fromWhere/$distance)*$distance;
+ }
+
+ }
+ return $target;
+
+ }
+ /**
+ * will return 1 for OK, 0 for try again and -1 for not ok
+ * */
+ private function checkAndInsertLink($toWhere) {
+ $possible=($toWhere>0)&&($toWhere<=count($this->images));
+ if (!$possible) {
+ return -1;
+ }
+ if (in_array($toWhere, $this->pagesLinked)) {
+ return 0;
+ } else {
+ $this->pagesLinked[]=$toWhere;
+ return 1;
+ }
+ }
+
+ private function linkFarAway($distance, $ascending) {
+ //can only link to e.g. the last 10 if page number >10
+
+ $target=$this->calculateLink($this->currentPageIndex, $distance, $ascending);
+ $successful=$this->checkAndInsertLink($target);
+ while ($successful===0) {
+ // was already there
+ if ($ascending) {
+ $target+=$distance;
+ } else {
+ $target-=$distance;
+
+ }
+ $successful=$this->checkAndInsertLink($target);
+ }
+
+
+ }
+ /**
+ * Copies the dependencies (.css, .js, .jpg files) to the directory specified
+ * in $path and generates the index .html file and the .html files for all pages
+ * */
+ public function writeHTML($path) {
+ $this->destinationPath=$path;
+ $this->logger->shoutNewStatus("Generating HTML");
+ $this->copyTemplateFiles();
+ $this->templateLines=file("template".$this->opsysDirSep."index.html");
+ unlink($path.$this->opsysDirSep."index.html");
+ $this->numPages =ceil(count($this->images)/$this->thumbsProPage);
+ for($pageStartIndex=0; $pageStartIndex<count($this->images); $pageStartIndex+=$this->thumbsProPage) {
+ $this->currentPageIndex++;
+
+ $f=fopen($path.$this->opsysDirSep.$this->getFilenameForIndex($this->currentPageIndex), "w");
+
+ $contentHTML="";
+ for ($thumbIndex=$pageStartIndex; (($thumbIndex<count($this->images))&&($thumbIndex<$pageStartIndex+$this->thumbsProPage));$thumbIndex++) {
+ $image=$this->images[$thumbIndex];
+ $svgFile=substr($image,strlen($path));
+ $svgFile=str_replace($this->opsysDirSep,"/",$svgFile);
+ $dirParts=explode($this->opsysDirSep,$image);
+ $artist="undefined";
+ $artistDisplayName=$artist;
+ $title="undefined";
+ if (count($dirParts)>2) {
+ // the lower most directory name is also the name of the artist
+ $artist=$dirParts[count($dirParts)-2];
+ $artistDisplayName=str_replace("_"," ",$artist);
+
+ }
+ if (count($dirParts)>1) {
+ // the lower most directory name is also the name of the artist
+ $title=substr($dirParts[count($dirParts)-1], strlen($artist)+1);
+ $title=str_replace("_"," ", $title);
+ $title=substr($title,0,strrpos($title, "."));
+
+ }
+ $pngFile=str_replace(".svg",".png",$svgFile);
+ $contentHTML.="
+ <div class='r-img'>
+ <div>
+ <a href='$svgFile' title='$title'><img src='$pngFile' alt='#'></a>
+ </div>
+ <h4><a href='$svgFile'>$title</a></h4>
+ <p>by <a href='http://openclipart.org/media/people/$artist'>$artistDisplayName</a></p>
+ </div> \n";
+ }
+ // page navi: e.g. for page 136 we want links like
+ // 1 100 130 134 135 *136* 137 138 140 200 236
+ // means: the current page is always visible w/o link
+ // if the page>1 insert link to page one
+ // if the page>2 insert link to previous page as well
+ // if the page>3 insert link to pre-previous page as well
+
+ // if the page>50, insert link to last 50er (floor(page/50))*50 and, if available, to the next 50er
+ // if the page%100>0 insert link to last 10er (floor(page%100/10))*10 and, if available, to the next 10er
+
+ // if the page<last page insert link to last page
+
+ $this->pagesLinked=array();
+ // first: link first, last, next 2 and previous 2 pages
+ $this->checkAndInsertLink(1);
+ $this->checkAndInsertLink($this->numPages);
+ $this->checkAndInsertLink($this->currentPageIndex);
+ $this->checkAndInsertLink($this->currentPageIndex-1);
+ $this->checkAndInsertLink($this->currentPageIndex-2);
+ $this->checkAndInsertLink($this->currentPageIndex+1);
+ $this->checkAndInsertLink($this->currentPageIndex+2);
+
+ // now find out what to do with 10ers and 50ers, and keep in mind
+ // next 10er or 50er page might already be linked via the "next two"
+ // pages e.g. on pg 48 (49,50...)
+
+ // link to next 50er have lower priority than to next 10er, i.e. on 99 link to 100 (10) and 150
+ $this->linkFarAway(10,false);
+ $this->linkFarAway(10,true);
+ $this->linkFarAway(50,false);
+ $this->linkFarAway(50,true);
+
+
+ $pageNavi="";
+ sort($this->pagesLinked);
+ foreach ($this->pagesLinked as $pageLink) {
+ $prefix="<li><a href='".$this->getFilenameForIndex($pageLink)."'>";
+ $suffix="</a></li>";
+ if ($pageLink==$this->currentPageIndex) {
+ $prefix="<li id='active'>";
+ $suffix="</li>";
+ }
+ $pageNavi.=$prefix.$pageLink.$suffix;
+ }
+
+ foreach ($this->templateLines as $indexLine) {
+ $indexLine=str_replace("[title]","OpenClipart $this->version",$indexLine);
+ $indexLine=str_replace("[subtitle]","Page {$this->currentPageIndex} of {$this->numPages}",$indexLine);
+ $indexLine=str_replace("[pages]",$pageNavi,$indexLine);
+ $indexLine=str_replace("[thumbnails]",$contentHTML,$indexLine);
+ fwrite($f, $indexLine);
+ }
+ }
+
+
+
+ fclose($f);
+ }
+}
+
+class releaser extends opsysDependendEntity {
+
+ private $maxWidth=64; // maximal thumbnail width
+ private $maxHeight=64; // max thumbnail height
+ // technically maxWidth and maxHeight form a bounding box in
+ // which the thumbnail will always fit (usually with free space around)
+
+
+ private $rsyncUser; // upload user name entered by the user
+ private $rsyncHost; // upload host name entered by the user
+ private $rsyncDir; // upload directory entered by the user
+
+ private $numSVGsAvailable; // the total number of svgs
+ private $numThumbsGenerated; // the number of SVGs generated in this run. If a run is stopped(killed) and continued afterwards this can differ from the total number of svg files
+ private $version; // version nr of this release, e.g. 0.19
+ private $doDownload; // boolean if daily_svg_snapshot is to be downloaded (otherwise we just continue a previous run)
+ private $doUnzip; // boolean if daily_svg_snapshot is to be unzipped again
+ private $doRsync; // boolean if release is to be uploaded
+
+ private $files; // in the end contains an array of all files, to be passed to a HTMLPreviewBuilder
+ private $HTMLpreview;
+ private $logger;
+
+ function __construct() {
+ if (!empty($_SERVER['SERVER_NAME'])) {
+ die("This is a command line script. Please run it from the shell with 'php downloader.php'.");
+ }
+ $this->numThumbsGenerated=0;
+ $this->numSVGsAvailable=0;
+ $this->checkOpsys();
+ $this->logger=new logger();
+
+ }
+
+
+ private function generate_thumbnails($dir) {
+
+ if (is_dir($dir)) {
+ if ($dh = opendir($dir)) {
+ while (($file = readdir($dh)) !== false) {
+ if (($file!=".")&&($file!="..")) {
+ $completeFileLocation=$dir.$this->opsysDirSep.$file;
+ if (is_dir($completeFileLocation)) {
+ $this->generate_thumbnails($completeFileLocation);
+ } else {
+ if (strpos($file,".svg")!==false) {
+ $this->numSVGsAvailable++;
+ echo "File {$this->numSVGsAvailable} Creating thumbnail #{$this->numThumbsGenerated} for: $completeFileLocation \n";
+ // my inkscape 0.46 for windows and linux crashes on orangeobject_background-ribbon.svg which destroys the overnight batch run, so lets leave it out
+ if (strpos($completeFileLocation,"orangeobject_background-ribbon.svg")===false) {
+ $this->HTMLpreview->addImage($completeFileLocation);
+ $pngFilename=str_replace(".svg",".png",$completeFileLocation);
+ $this->files[]=$completeFileLocation;
+ if (!file_exists($pngFilename)) {
+ $this->numThumbsGenerated++;
+ $this->myExec($this->path_inkscape,'-f "'.$completeFileLocation.'" -e "'.$pngFilename.'" -w '.$this->maxWidth);
+ list($width, $height)=getimagesize($pngFilename);
+ // the GD library cant determine the aspect ratio of a SVG and I would not know how to do it in pure PHP, so
+ // we create a png thumbnail with maxWidth, use the GD library on the thumbnail to find out if it was
+ // a vertical image (height>maxHeigth) and if so, overwrite the thumbnail with a version enforcing maxHeigth
+ if ($height>$this->maxHeight) {
+ $this->myExec($this->path_inkscape,'-f "'.$completeFileLocation.'" -e "'.$pngFilename.'" -h '.$this->maxHeight);
+
+ }
+
+/* if we had a png version which was guranteedly bigger than maxsize or minsize, we could create the thumb using gd as follows:
+ * // the GD library cant determine the aspect ratio of a SVG and I would not know how to do it in pure PHP, so
+ // we create a png thumbnail with maxWidth, use the GD library on the thumbnail to find out if it was
+ // a vertical image (height>maxHeigth) and if so, overwrite the thumbnail with a version enforcing maxHeigth
+ if ($height>$width) {
+ $newHeight=$this->maxHeight;
+ $newWidth=$width/$height*$newHeight;
+ } else {
+ $newWidth=$this->maxWidth;
+ $newHeight=$height/$width*$newWidth;
+ }
+ $big= ImageCreateFromPNG($pngFilename);
+ $thumb= imagecreatetruecolor($newWidth,$newHeight);
+ // true color images seem to have by default bgcolor black: change this to transparent
+ imagesavealpha($thumb, true);
+ $trans_colour = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
+ imagefill($thumb, 0, 0, $trans_colour);
+
+ imagecopyresampled($thumb,$big,0,0,0,0,$newWidth,$newHeight,$width,$height);
+ imagepng($thumb,$pngThumbFilename);*/
+
+ }
+ }
+
+ }
+ }
+
+ }
+ }
+ closedir($dh);
+ }
+ }
+
+ }
+ /**
+ * This function will run a command and show the output as soon as it receives anything
+ * from the program invoked.
+ * It also shows error out (also used for status info), as it redirects stderr to stdout (2>&1)
+ * In windows, it takes care of inserting the quotes to handle directories with spaces
+ *
+ * */
+ private function myExec($cmd, $args, $message=null) {
+
+ if (strpos($cmd," ")!==false) {
+ $cmd=$this->opsysQuotes.$cmd.$this->opsysQuotes;
+ }
+ $args=$args." 2>&1"; //info on inkscape command line on windows http://kaioa.com/node/42, http://kaioa.com/node/63
+ $msgToOutput="";
+ if ($message!=null) {
+ $msgToOutput="($message)";
+ }
+ $this->logger->shout("\nExecuting: $cmd $args $msgToOutput\n");
+
+ $fp = popen("{$this->opsysQuotes}$cmd $args{$this->opsysQuotes}", "r"); //the args can contain paths, so they have to be quoted,
+ // but the whole command has to be quoted as well in case both the cmd and the args contain directories with spaces.
+ while(!feof($fp))
+ {
+ // send what has been read from the program to the console
+ $this->logger->shout(fread($fp, 1024));
+ // flush, in case any output should be cached somewhere
+ flush();
+ }
+ fclose($fp);
+
+ }
+
+ private function prompt($prompt) {
+ echo $prompt;
+ $fp = fopen('php://stdin', 'r');
+ return trim(fgets(STDIN));
+ }
+
+ private function checkProgramme($name, $defaultPath) {
+ if (!file_exists($defaultPath)) {
+ return $this->prompt("Where is your $name (not found in $defaultPath)?");
+ } else {
+ return $defaultPath;
+ }
+ }
+
+ private function checkPrerequisites() {
+ $this->path_wget=$this->checkProgramme("wget", $this->path_wget);
+ $this->path_tar=$this->checkProgramme("tar", $this->path_tar);
+ $this->path_bunzip=$this->checkProgramme("bunzip2", $this->path_bunzip);
+ $this->path_gzip=$this->checkProgramme("gzip", $this->path_gzip);
+ $this->path_bzip=$this->checkProgramme("bzip", $this->path_bzip);
+ $this->path_zip=$this->checkProgramme("zip", $this->path_zip);
+ $this->path_inkscape=$this->checkProgramme("inkscape", $this->path_inkscape);
+ if ($this->doRsync) {
+ $this->path_rsync=$this->checkProgramme("rsync", $this->path_rsync);
+ }
+
+
+ }
+
+
+ public function run() {
+ $this->version=$this->prompt("Release version (e.g. 0.19):");
+ $this->HTMLpreview=new HTMLPreviewBuilder($this->logger, $this->version);
+ $this->doDownload=true;
+ $this->doUnzip=true;
+ if (file_exists("daily_SVG_snapshot.tar.bz2")) {
+ $this->doDownload=false;
+ $shallDownload=$this->prompt("Create n)ew release, u)nzip and continue already downloaded daily_SVG_snapshot.tar.bz2 or c)ontinue previous run after unzip:");
+
+ if (($shallDownload=="n")||($shallDownload=="N")) {
+ $this->doDownload=true;
+ $this->doUnzip=true;
+ }
+ if (($shallDownload=="u")||($shallDownload=="U")) {
+ $this->doDownload=false;
+ $this->doUnzip=true;
+ }
+ if (($shallDownload=="c")||($shallDownload=="C")) {
+ $this->doDownload=false;
+ $this->doUnzip=false;
+ }
+ }
+ $rsyncResponse=$this->prompt("Upload release after creation? This will require a non-interactive rsync connection to your host (y/n)?:");
+ if (($rsyncResponse=="y")||($rsyncResponse=="Y")) {
+ $this->rsyncUser=$this->prompt("Upload user name:");
+ $this->rsyncHost=$this->prompt("Upload host name:");
+ $this->rsyncDir=$this->prompt("Upload directory (please include trailing slash, e.g. /var/www/):");
+ $this->doRsync=true;
+ }
+ $this->checkPrerequisites();
+
+ if ($this->doDownload) {
+ $this->logger->shoutNewStatus("Downloading");
+ if (file_exists("daily_SVG_snapshot.tar.bz2")) {
+ unlink("daily_SVG_snapshot.tar.bz2");
+ }
+ $this->myExec($this->path_wget,"http://download.openclipart.org/downloads/daily_SVG_snapshot.tar.bz2");
+ }
+
+ $subdirname="openclipart";
+ if (!file_exists($subdirname)) {
+ mkdir($subdirname);
+ }
+
+ if ($this->doUnzip) {
+ $this->logger->shoutNewStatus("Unzipping");
+ $this->myExec($this->path_bunzip,"-v daily_SVG_snapshot.tar.bz2", "This will take 5 minutes");
+ }
+ chdir($subdirname);
+ if ($this->doUnzip) {
+ $this->logger->shoutNewStatus("Untaring");
+ $this->myExec($this->path_tar,"xvf ..{$this->opsysDirSep}daily_SVG_snapshot.tar ");
+ }
+
+ $this->logger->shoutNewStatus("Thumbnailing");
+ $this->generate_thumbnails(getcwd());
+ $this->logger->shout("Generated {$this->numThumbsGenerated} new thumbnails for {$this->numSVGsAvailable} files");
+ chdir("..");
+ $this->HTMLpreview->writeHTML(getcwd().$this->opsysDirSep."openclipart".$this->opsysDirSep);
+ $this->logger->shoutNewStatus("Taring");
+ $tarFile="openclipart{$this->version}.tar";
+ if (file_exists($tarFile)) {
+ unlink($tarFile);
+ }
+ $this->myExec($this->path_tar,"cvf $tarFile openclipart");
+ $this->logger->shoutNewStatus("BZipping");
+ $bzFile="openclipart{$this->version}.tar.bz2";
+ if (file_exists($bzFile)) {
+ unlink($bzFile);
+ }
+ $this->myExec($this->path_bzip,"-k $tarFile");
+ $this->logger->shoutNewStatus("GZipping");
+ $tgzFile="openclipart{$this->version}.tar.gz";
+ if (file_exists($tgzFile)) {
+ unlink($tgzFile);
+ }
+ $this->myExec($this->path_gzip,$tarFile);
+
+ $this->logger->shoutNewStatus("Zipping");
+ $zipFile="openclipart{$this->version}.zip";
+ if (file_exists($zipFile)) {
+ unlink($zipFile);
+ }
+ $this->myExec($this->path_zip,"-r openclipart{$this->version}.zip openclipart");
+ if ($this->doRsync) {
+ $this->logger->shoutNewStatus("Uploading");
+ $sourceDir=getcwd();
+ $rsyncDir=substr($this->path_rsync,0,strrpos($this->path_rsync,$this->opsysDirSep));
+ chdir($rsyncDir);
+ $RsyncSourceDir=$sourceDir;
+ if ($this->opsys==1) {
+ // windows cwrsync requires ssh.exe to be in the local path which is only the case if
+ // one changes dir to the rsync programme
+ $RsyncSourceDir=str_replace("\\","/",$sourceDir);
+ // additionally, d:\\xyz would be /cygdrive/d in cwrsync
+ if ($RsyncSourceDir{1}==':') {
+ $RsyncSourceDir="/cygdrive/".$RsyncSourceDir{0}.substr($RsyncSourceDir,2);
+ }
+ }
+
+ $this->myExec($this->path_rsync,"-avzP {$RsyncSourceDir}/$bzFile {$this->rsyncUser}@{$this->rsyncHost}:{$this->rsyncDir}");
+ $this->myExec($this->path_rsync,"-avzP {$RsyncSourceDir}/$tgzFile {$this->rsyncUser}@{$this->rsyncHost}:{$this->rsyncDir}");
+ $this->myExec($this->path_rsync,"-avzP {$RsyncSourceDir}/$zipFile {$this->rsyncUser}@{$this->rsyncHost}:{$this->rsyncDir}");
+ chdir($sourceDir);
+ }
+ }
+
+
+}
+
+$rel=new releaser();
+$rel->run();
+?>
Added: makerelease/template/css/main.css
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ makerelease/template/css/main.css Sat Mar 28 08:46:17 2009 (r32)
@@ -0,0 +1,335 @@
+html, body, div, span, applet, object, h1, h2, h3, h4, h5, h6, p, a, em, img, strong, ol, ul, li, dl, dd, dt, form, label, input {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-style: inherit;
+ font-size: 100%;
+ font-family: inherit;
+ vertical-align: baseline;
+ background: transparent;
+}
+:focus {
+ outline: 0;
+}
+ul, ol {
+ list-style: none;
+}
+body {
+ padding: 0;
+ margin: 0;
+ font-family: Arial, Tahoma, sans-serif;
+ font-size: 9pt;
+ color: #000;
+ height: 100%;
+ background: #FFF;
+ text-align: center;
+ line-height: 1;
+}
+img {
+ border: 0;
+}
+a:link, a:visited {
+ outline: none;
+ text-decoration: none;
+ color: #ce5c00;
+}
+a:hover, a:active {
+ text-decoration: underline;
+}
+.clear {
+ clear: both;
+ font-size: 0.3pt;
+}
+.clearfix:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0;
+}
+.clearfix {
+ display: inline-block;
+}
+html[xmlns] .clearfix {
+ display: block;
+}
+* html .clearfix {
+ height: 1%;
+}
+#main {
+ width: 960px;
+ text-align: left;
+ margin: 0 auto;
+ background: url(../images/bg.png) 50% 0% repeat-y;
+}
+#header {
+ height: 122px;
+ background: #e58620 url(../images/bgl.png) 0 0 repeat-x;
+ margin: 0 16px;
+ position: relative;
+}
+#logo {
+ position: absolute;
+ top: 18px;
+ left: 15px;
+ color: #FFF;
+ font-size: 30pt;
+ font-weight: bold;
+ line-height: 2;
+}
+#logo a:link, #logo a:visited {
+ color: #FFF;
+}
+#logged {
+ color: #FFF;
+ font-size: 11pt;
+ text-align: right;
+ padding: 14px 20px 20px 10px;
+}
+#mainnav {
+ border-top: 1px solid #d6792e;
+ border-bottom: 1px solid #b8bab7;
+ background: #e2e2e2 url(../images/bgl.png) 0 -123px repeat-x;
+ margin: 0 16px;
+}
+#mainnav li {
+ height: 39px;
+ line-height: 39px;
+ overflow: hidden;
+ float: left;
+ color: #2e3436;
+}
+#mainnav li a:link, #mainnav li a:visited {
+ color: #2e3436;
+ text-decoration: none;
+ display: block;
+ padding: 0 28px 0 25px;
+ font-size: 11pt;
+ background: url(../images/fornav.png) 100% 0 no-repeat;
+}
+#mainnav li a:hover, #mainnav li a:active {
+ color: #000;
+ background-color: #FFF;
+}
+#mainnav li#active {
+ color: #000;
+ background-color: #FFF;
+ text-decoration: underline;
+ font-size: 150%;
+ font-weight: bold;
+ padding: 0 28px 0 25px;
+}
+#content {
+ margin: 0 16px;
+ padding: 30px 20px;
+ background: url(../images/shadow-rb.jpg) 50% 0 no-repeat;
+}
+#content h2 {
+ color: #ce5c00;
+ font-size: 21pt;
+ font-weight: normal;
+ letter-spacing: 1px;
+ padding: 0 0 23px 0;
+}
+#content h2 img {
+ position: relative;
+ top: 3px;
+}
+#sidebar-nav li a:link, #sidebar-nav li a:visited {
+ color: #555753;
+}
+#recent {
+ padding: 0 0 20px 0;
+ margin-left: 30px;
+}
+#recent strong {
+ display: block;
+ font-weight: normal;
+ font-size: 13.5pt;
+ line-height: 1.2;
+}
+#recent li {
+ color: #888a85;
+ padding: 0 0 5px 20px;
+ min-height: 1%;
+ background: url(../images/dot.png) 0 6px no-repeat;
+}
+* html #recent li {
+ height: 1%;
+}
+#recent li a:link, #recent li a:visited {
+ color: #888a85;
+}
+#recent li a:hover, #recent li a:active {
+ color: #000;
+ text-decoration: none;
+}
+#footer {
+ margin: 0 16px;
+ clear: both;
+}
+#forfooter {
+ height: 150px;
+ background: #e17f1a url(../images/bgl.png) 0 -357px repeat-x;
+}
+#forfooter dl {
+ float: left;
+ width: 33%;
+ padding: 34px 0 0 0;
+ color: #FFF;
+ font-size: 8.5pt;
+ line-height: 1.2;
+}
+#forfooter dt {
+ text-align: center;
+ height: 50px;
+ padding: 0 20px;
+}
+#forfooter dt a:link, #forfooter dt a:visited {
+ color: #FFF;
+ font-size: 9pt;
+}
+#forfooter dd {
+ padding: 10px 20px 5px;
+ text-align: justify;
+}
+#links {
+ height: 50px;
+ background: #4f514d url(../images/bgl.png) 0 -510px repeat-x;
+ color: #FFF;
+ line-height: 50px;
+ font-size: 7.5pt;
+ text-align: center;
+}
+#links a:link, #links a:visited {
+ color: #FFF;
+ text-decoration: none;
+}
+#links a:hover, #links a:active {
+ text-decoration: underline;
+}
+
+/* For recent */
+
+#sidebar-r {
+ width: 322px;
+ float: right;
+ margin-right: -14px;
+}
+* html #sidebar-r {
+ display: inline;
+}
+#p-tags, #categories, #stats {
+ background: url(../images/s-b.png) -322px 0 repeat-y;
+ margin: 0 0 18px 0;
+}
+#p-tags h3, #categories h3, #stats h3 {
+ background: url(../images/s-b.png) 0 0 no-repeat;
+ color: #888a85;
+ font-size: 11pt;
+ font-weight: bold;
+ line-height: 1.5;
+ padding: 12px 17px 0;
+}
+#p-tags ul {
+ background: url(../images/s-b.png) -644px 100% no-repeat;
+ padding: 0 17px 12px;
+ font-size: 16pt;
+}
+#p-tags ul li {
+ display: inline;
+ padding: 0 12px 0 0;
+ line-height: 1.3;
+}
+#p-tags ul a:link, #p-tags ul a:visited {
+ text-decoration: underline;
+}
+#p-tags ul a:hover, #p-tags ul a:active {
+ text-decoration: none;
+}
+#p-tags .t1 {
+ font-size: 100%;
+}
+#p-tags .t2 {
+ font-size: 80%;
+}
+#p-tags .t3 {
+ font-size: 60%;
+}
+#p-tags .t4 {
+ font-size: 40%;
+}
+#categories div {
+ background: url(../images/s-b.png) -644px 100% no-repeat;
+}
+#categories a:link, #categories a:visited {
+ color: #000;
+}
+#categories a:hover, #categories a:active {
+ text-decoration: underline;
+}
+#categories ul {
+ float: left;
+ padding: 5px 0 15px 17px;
+ font-size: 10pt;
+ line-height: 1.5;
+}
+#categories ul li {
+ width: 89px;
+}
+#stats div {
+ background: url(../images/s-b.png) -644px 100% no-repeat;
+ padding: 5px 0 15px;
+}
+#stats h3 {
+ color: #ce5c00;
+ font-size: 10.5pt;
+}
+#stats div dl {
+ background: url(../images/stat.png) 26px 8px no-repeat;
+ padding: 0 25px 0 115px;
+ line-height: 1.5;
+ font-size: 10.5pt;
+}
+#stats div dt {
+ width: 130px;
+ float: left;
+ clear: both;
+ color: #555753;
+ font-weight: bold;
+}
+#stats div dd {
+ text-align: right;
+ color: #b2b3b0;
+}
+.r-img {
+ width: 280px;
+ float: left;
+ padding: 0 0 15px;
+ border-right: 5px solid #FFF;
+}
+.r-img div {
+ float: left;
+ width: 110px;
+}
+.r-img h4 {
+ font-size: 11pt;
+ line-height: 1.2;
+ padding: 3px 0 3px;
+ font-weight: bold;
+}
+.r-img p {
+ color: #555753;
+ font-size: 9pt;
+ line-height: 1.1;
+}
+.r-img p a:link, .r-img p a:visited {
+ color: #555753;
+ font-weight: bold;
+}
+.r-img .stars {
+ display: block;
+ margin-top: 5px;
+}
Added: makerelease/template/images/bg.png
==============================================================================
Binary file. No diff available.
Added: makerelease/template/images/bgl.png
==============================================================================
Binary file. No diff available.
Added: makerelease/template/images/bullet.gif
==============================================================================
Binary file. No diff available.
Added: makerelease/template/images/logo.jpg
==============================================================================
Binary file. No diff available.
Added: makerelease/template/images/openclipart.png
==============================================================================
Binary file. No diff available.
Added: makerelease/template/images/publicdomain.png
==============================================================================
Binary file. No diff available.
Added: makerelease/template/images/s-b.png
==============================================================================
Binary file. No diff available.
Added: makerelease/template/index.html
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ makerelease/template/index.html Sat Mar 28 08:46:17 2009 (r32)
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en"><head>
+
+
+ <title>Open ClipArt Library</title>
+ <link href="css/main.css" type="text/css" rel="stylesheet">
+
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
+
+</head><body>
+<div id="main">
+ <div id="header">
+ <h1 id="logo">
+ <a href="http://www.openclipart.org"><img src="images/logo.jpg" alt="Open ClipArt Library"></a>
+ </h1>
+ <div id='logged'>
+ [title]
+ </div>
+ </div>
+ <ul id="mainnav" class="clearfix">
+ [pages]
+ </ul>
+ <div id="content" class="clearfix">
+ <h2>[subtitle]</h2>
+ <div id="recent-img">
+ [thumbnails]
+
+
+ </div>
+ </div>
+ <div id="footer">
+ <div id="forfooter" class="clearfix">
+ <dl>
+ <dt><a href="http://creativecommons.org/licenses/publicdomain/"><img src="images/publicdomain.png" alt="Public Domain"></a></dt>
+ <dd>The actual clipart content on open clipart library is Public domain</dd>
+ </dl>
+ <dl>
+ <dt><a href="http://www.openclipart.org"><img src="images/openclipart.png" alt="Open ClipArt Library"></a></dt>
+ <dd>Open Clipart Library is made with ccHost, licensed under CC-GNU-GPL</dd>
+ </dl>
+ </div>
+ <div id="links">
+ </div>
+ </div>
+</div>
+</body></html>
More information about the clipart
mailing list