1024 && count($sxlist) >= 2) { array_shift($sxlist); $size /= 1024; } return number_format($size, 2).array_shift($sxlist); } function str_ext($sz) { $dpos = strrpos($sz, '.'); return substr($sz, $dpos+1); } function is_image($sz) { return in_array(strtolower(str_ext($sz)), ['jpg', 'png', 'jpeg']); } function hesc($sz) { return @htmlentities($sz, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } function text2html($sz) { $identity = function($sz) { return $sz; }; $splitInside = function($begin, $end, $sz) { $parts = explode($begin, $sz); if (count($parts) == 1) return [$sz]; $ret = [$parts[0]]; for($i = 1, $e = count($parts); $i !== $e; ++$i) { $inner = explode($end, $parts[$i], 2); $ret = array_merge($ret, $inner); } return $ret; }; $oddEven = function(array $parts, $odd, $even, $join='') { $ret = []; for($i = 0, $e = count($parts); $i != $e; ++$i) { $ret[] = ($i % 2) ? $odd($parts[$i]) : $even($parts[$i]); } return implode($join, $ret); }; $sectionFmt = function($sz) use($oddEven, $identity) { $base = hesc($sz); $base = preg_replace('~^=+(.+)=+~m', '\\1', $base); $base = preg_replace('~(https?://[^ \\r\\n\\t]+)~i', '\\1', $base); $btparts = explode('`', $base); if (count($btparts) > 1 && (count($btparts) % 2)) { for ($i = 1, $e = count($btparts); $i < $e; $i += 2) { $btparts[$i] = ''.$btparts[$i].''; } } return $oddEven($btparts, $identity, 'nl2br'); }; $htmlSections = $splitInside('', '', $sz); return $oddEven($htmlSections, $identity, $sectionFmt); } function array_decimate($array, $total, $partno) { $ct = 0; $ret = []; foreach($array as $k => $v) { if (++$ct % $total == ($partno - 1)) { $ret[$k] = $v; } } return $ret; } /** * */ class CProject { private $dir; public $projname; public $shortdesc = '(no description)'; public $subtag = ''; public $lastupdate = 0; private $longdesc = ''; private $images = array(); private $downloads = array(); public $tags = array(); public $homeimage = null; public function __construct($dirname, $projname) { $this->dir = BASEDIR.'data/'.$dirname.'/'; $this->projname = $projname; // Identify resources in folder $ls = scandir($this->dir); foreach($ls as $file) { if ($file[0] == '.') continue; if ($file == 'README.txt') { $this->lastupdate = max($this->lastupdate, filectime($this->dir.$file)); // don't count README updates $this->longdesc = file_get_contents($this->dir.'README.txt'); $matches = array(); if (preg_match('~Written in ([^\\r\\n]+)~', $this->longdesc, $matches)) { $this->subtag = rtrim($matches[1], ' .'); } if (preg_match('~Tags: ([^\\r\\n]+)~', $this->longdesc, $matches)) { $this->tags = array_map('trim', explode(',', $matches[1])); } $parts = explode("\n", $this->longdesc); $this->shortdesc = array_shift($parts); $this->shortdesc[0] = strtolower($this->shortdesc[0]); // cosmetic lowercase continue; } $this->lastupdate = max( $this->lastupdate, filemtime($this->dir.$file), filectime($this->dir.$file) ); if (is_image($file)) { $this->images[] = $file; } else { $this->downloads[] = $file; } } natcasesort($this->downloads); $this->downloads = array_reverse($this->downloads); } public function genHomeImage() { if (count($this->images)) { $this->homeimage = mkthumbnail( $this->dir.$this->images[0], null, // raw handle INDEX_THUMB_W, INDEX_THUMB_H ); } } public function write() { // Generate image thumbnails foreach($this->images as $idx => $image) { $outfile = BASEDIR.'wwwroot/srv/'.$this->projname.'_'.$idx; copy($this->dir.$image, $outfile.'.'.str_ext($image)); mkthumbnail($outfile.'.'.str_ext($image), $outfile.'_thumb.jpg', PAGE_THUMB_W, PAGE_THUMB_H); } // Copy downloads to wwwroot foreach($this->downloads as $idx => $filename) { copy($this->dir.$filename, BASEDIR.'wwwroot/srv/'.$filename); } // Generate index page ob_start(); $this->index(); $idxfile = template($this->projname.' | '.SITE_TITLE, ob_get_clean()); file_put_contents(BASEDIR.'wwwroot/'.$this->projname.'.html', $idxfile); } public function getClassAttr() { if (count($this->tags)) { return 'taggedWith-'.implode(' taggedWith-', $this->tags); } else { return ''; } } public function index() { ?>

projname)?>

ABOUT

longdesc)?>

downloads)) { ?> DOWNLOAD
images)) { ?>
images as $idx => $origname) { ?>
<?=hesc($title)?>
$projectname) { echo sprintf("@%1d [%3d/%3d] ".$projectname."...\n", $id, ++$count, count($projects)); $pr = new CProject($dirname, $projectname); $pr->write(); } } function buildcommon() { echo "@0 [ 0/ ?] Common files...\n"; $projects = listprojects(); // Build all projects $plist = array(); $handles = array(); $handle_lookup = array(); $alphasort = []; foreach($projects as $dirname => $projectname) { $pr = new CProject($dirname, $projectname); $pr->genHomeImage(); // thumbnail $plist[] = $pr; if (is_null($pr->homeimage)) { $handle_lookup[$projectname] = null; } else { $handle_lookup[$projectname] = count($handles); $handles[] = $pr->homeimage; } $alphasort[] = [$pr->projname, count($plist)-1]; } usort($alphasort, function($a, $b) { return strcasecmp($a[0], $b[0]); }); $alphaidx = []; foreach($alphasort as $a) { $alphaidx[ $a[1] ] = count($alphaidx); } // Build homepage spritesheet mkspritesheet($handles, BASEDIR.'wwwroot/logos.jpg', INDEX_THUMB_W, INDEX_THUMB_H); array_map('imagedestroy', $handles); // free // Build index page ob_start(); ?> $pr) { ?>
projname]) ? '
' : '
')?>
projname)?>, shortdesc)?> more... subtag) || count($pr->tags)) { ?>
subtag)?> subtag) && count($pr->tags)) { ?> :: tags as $tag) { ?>