<?php class CProject { private $dir; public $projname; public $shortdesc = '(no description)'; public $subtag = ''; public $lastupdate = 0; private $longdesc = ''; private $prefix_html = ''; 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); $found_real_lastupdate = false; foreach($ls as $file) { if ($file[0] == '.') continue; if ($file == 'README.txt') { // Guess 'last update' time $matches = []; if (preg_match('~\n(\d\d\d\d-\d\d-\d\d)~', $this->longdesc, $matches)) { // Use first date entry (assumed to be a CHANGELOG) $this->lastupdate = strtotime($matches[1]); $found_real_lastupdate = true; } $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 $this->longdesc = str_replace("\r", "", $this->longdesc); // filter windows CR $prefix_html = ''; $this->longdesc = preg_replace_callback('~\r?\nWritten in ([^\\n]+)~ms', function($matches) use (&$prefix_html) { $prefix_html .= ( (SHIELDS_PREFIX ? mkshield('build', 'success', 'brightgreen').' ' : ''). mkshield('written in', rtrim($matches[1], '.'), 'blue') ); return ''; }, $this->longdesc); while(strpos($this->longdesc, "\n\n\n") !== false) { $this->longdesc = str_replace("\n\n\n", "\n\n", $this->longdesc); } $this->longdesc = rtrim($this->longdesc, "\n"); $this->prefix_html = $prefix_html; continue; } if (! $found_real_lastupdate) { $this->lastupdate = max( $this->lastupdate, // filectime($this->dir.$file), ($file == 'README.txt' ? filectime($this->dir.$file) : filemtime($this->dir.$file)) // Don't count README updates ); } 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() { ?> <h2><?=hesc(str_replace('_', ' ', $this->projname))?></h2> <div class="projinfo"> <div class="projbody projbody_<?=(count($this->images) ? 'half' : 'full')?>w"> <?php if (strlen($this->prefix_html)) { ?> <p style="margin-top:0;"><?=$this->prefix_html?></p> <?php } ?> <strong><?=hesc(strtoupper(ARTICLE_HEADER))?></strong> <p><?=text2html($this->longdesc)?></p> <?=file_get_contents(BASEDIR.'/footer.htm')?> <?php if (count($this->downloads)) { ?> <strong>DOWNLOAD</strong> <ul> <?php foreach($this->downloads as $idx => $filename) { ?> <li> <a href="srv/<?=hesc($this->downloads_hashes[$idx])?>/<?=hesc(rawurlencode($filename))?>"><?=hesc($filename)?></a> <small> <?=hesc(fbytes(filesize(BASEDIR.'wwwroot/srv/'.$this->downloads_hashes[$idx].'/'.$filename)))?> </small> </li> <?php } ?> </ul> <?php } ?> </div> <?php if (count($this->images)) { ?> <div class="projimg"> <?php foreach($this->images as $idx => $origname) { ?> <a href="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>.<?=str_ext($origname)?>"><img src="srv/<?=hesc(urlencode($this->projname))?>_<?=$idx?>_thumb.jpg" class="thumbimage"></a> <?php } ?> </div> <div style="clear:both;"></div> <?php } ?> </div> <?php } }