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);
$base = preg_replace('~\\[b\\](.+?)\\[/b\\]~m', '\\1', $base);
$base = preg_replace('~\\[i\\](.+?)\\[/i\\]~m', '\\1', $base);
$base = preg_replace('~\\[spoiler\\](.+?)\\[/spoiler\\]~m', '\\1', $base);
$base = preg_replace('~\\[entry=([^\\]]+?)\\](.+?)\\[/entry\\]~m', '\\2', $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();
private $downloads_hashes = 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
// Filter longdesc
$prefix_html = '';
$this->longdesc = preg_replace_callback('~Written in ([^\\r\\n]+)~', function($matches) use (&$prefix_html) {
$prefix_html .= (
''.
(SHIELDS_PREFIX ? mkshield('build', 'success', 'brightgreen').' ' : '').
mkshield('written in', $matches[1], 'blue').
'
'.
''
);
return '';
}, $this->longdesc);
$this->longdesc = $prefix_html.$this->longdesc;
continue;
}
$this->lastupdate = max(
$this->lastupdate,
// filectime($this->dir.$file),
filemtime($this->dir.$file)
);
if (is_image($file)) {
$this->images[] = $file;
} else {
$this->downloads[] = $file;
}
}
natcasesort($this->downloads);
$this->downloads = array_reverse($this->downloads);
for($i = 0, $e = count($this->downloads); $i !== $e; ++$i) {
$this->downloads_hashes[] = (
sha1_file($this->dir.$this->downloads[$i])
);
}
}
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) {
$cmkdir = @mkdir( BASEDIR.'wwwroot/srv/'.$this->downloads_hashes[$idx] );
if (! $cmkdir) {
fputs(
STDOUT,
"WARNING: Couldn't create directory ".$this->downloads_hashes[$idx].
" for file '${filename}'".
" in project '".$this->projname."'!\n"
);
}
copy(
$this->dir.$filename,
BASEDIR.'wwwroot/srv/'.$this->downloads_hashes[$idx].'/'.$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() {
?>
=text2html($this->longdesc)?>
=file_get_contents(BASEDIR.'/footer.htm')?> downloads)) { ?> DOWNLOAD=(is_null($handle_lookup[$pr->projname]) ? '' : '')?> |
=hesc(str_replace('_', ' ', $pr->projname))?>,
=hesc($pr->shortdesc)?>
more...
subtag) || count($pr->tags)) { ?>
=hesc($pr->subtag)?> subtag) && count($pr->tags)) { ?> :: tags as $tag) { ?> =hesc($tag)?> |