This repository has been archived on 2020-05-24. You can view files and clone it, but cannot push or open issues or pull requests.
codesite/rebuild.php

389 lines
10 KiB
PHP

<?php
// Code-hosting website
// ````````````````````
// CONFIGURATION
// `````````````
define('BASEDIR', __DIR__.'\\');
define('SITE_TITLE', 'code.ivysaur.me');
define('PAGE_THUMB_W', 60);
define('PAGE_THUMB_H', 60);
define('INDEX_THUMB_W', 90);
define('INDEX_THUMB_H', 32); // recommend a multiple of the jpg iDCT block size
/**
* Create a thumbnail of an image. It overscales, centers, and crops to fit the
* target dimensions.
*
* @param string $src_file
* @param string $dest_file Null to return an image handle
* @param int $width
* @param int $height
* @return boolean
*/
function mkthumbnail($src_file, $dest_file, $width, $height) {
list($src_width, $src_height) = getimagesize($src_file);
$im = imagecreatefromstring(file_get_contents($src_file));
$dest = imagecreatetruecolor($width, $height);
$scale = max( $width/$src_width, $height/$src_height ); // overscale + crop
$box_w = $width/$scale;
$box_h = $height/$scale;
$box_xoff = floor(($src_width - $box_w)/2);
$box_yoff = floor(($src_height - $box_h)/2);
imagecopyresampled(
$dest, $im,
0, 0,
$box_xoff, $box_yoff,
$width, $height, $box_w, $box_h
);
imagedestroy($im);
if (is_null($dest_file)) {
return $dest;
} else {
return imagejpeg($dest, $dest_file);
}
}
function mkspritesheet(array $handles, $dest_file, $width, $height) {
$im = imagecreatetruecolor($width, $height * count($handles));
for($i = 0, $e = count($handles); $i != $e; ++$i) {
imagecopy($im, $handles[$i], 0, $i * $height, 0, 0, $width, $height);
}
if (is_null($dest_file)) {
return $dest_file;
} else {
return imagejpeg($im, $dest_file);
}
}
/**
* Remove a directory tree and all its contents.
*
* @author http://www.php.net/manual/en/function.rmdir.php#110489
* @param string $dir
* @return boolean
*/
function rmdir_recursive($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
if (is_dir("$dir/$file")) {
rmdir_recursive("$dir/$file");
} else {
unlink("$dir/$file");
}
}
return rmdir($dir);
}
function fbytes($size, $suffixes='B|KiB|MiB|GiB|TiB') {
$sxlist = explode('|', $suffixes);
if ($size < 1024) {
return $size.$sxlist[0];
}
while ($size > 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) {
$base = hesc($sz);
$base = preg_replace('~(https?://[^ \\r\\n\\t]+)~i', '<a href="\\1">\\1</a>', $base);
return nl2br($base);
}
/**
*
*/
class CProject {
private $dir;
public $projname;
public $shortdesc = '(no description)';
public $subtag = '';
private $longdesc = '';
private $images = array();
private $downloads = 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->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], ' .');
}
$this->shortdesc = array_shift(explode("\n", $this->longdesc));
$this->shortdesc[0] = strtolower($this->shortdesc[0]); // cosmetic lowercase
continue;
}
if (is_image($file)) {
$this->images[] = $file;
} else {
$this->downloads[] = $file;
}
}
}
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);
}
if (count($this->images)) {
$this->homeimage = mkthumbnail(
BASEDIR.'wwwroot/srv/'.$this->projname.'_0.'.str_ext($this->images[0]),
null, // raw handle
INDEX_THUMB_W, INDEX_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 index() {
?>
<h2><a href="index.html"><?=hesc(SITE_TITLE)?></a> &gt; <?=hesc($this->projname)?></h2>
<div class="projinfo">
<div class="projbody projbody_<?=(count($this->images) ? 'half' : 'full')?>w">
<strong>ABOUT</strong>
<p><?=text2html($this->longdesc)?></p>
<?php if (count($this->downloads)) { ?>
<strong>DOWNLOAD</strong>
<ul>
<?php foreach($this->downloads as $filename) { ?>
<li>
<a href="srv/<?=hesc(urlencode($filename))?>"><?=hesc($filename)?></a>
<small>
<?=hesc(fbytes(filesize(BASEDIR.'wwwroot/srv/'.$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>
<?php } ?>
</div>
<?php
}
}
function template($title, $content) {
ob_start();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
<meta name="viewport" content="width=768px" >
<link type="text/css" rel="stylesheet" href="style.css">
<title><?=hesc($title)?></title>
</head>
<body>
<div id="container">
<div id="content">
<?=$content?>
</div>
</div>
</body>
</html>
<?php
return ob_get_clean();
}
function buildall() {
// Clean up webroot
if (file_exists(BASEDIR.'wwwroot')) {
rmdir_recursive(BASEDIR.'wwwroot');
}
echo "Creating directories...\n";
mkdir(BASEDIR.'wwwroot');
mkdir(BASEDIR.'wwwroot/srv');
// Copy in static files
foreach(scandir(BASEDIR.'static') as $static) {
if ($static[0] == '.' || is_dir($static) /* fixme */) continue;
copy(BASEDIR.'static/'.$static, BASEDIR.'wwwroot/'.$static);
}
// List projects
$ls = scandir(BASEDIR.'data');
rsort($ls);
$projects = array();
foreach($ls as $dirname) {
if ($dirname[0] == '.') continue;
$matches = array();
if (preg_match('~(?:\d+-)?(.+)~', $dirname, $matches)) {
$projects[$dirname] = $matches[1];
}
}
// Build all projects
$plist = array();
$count = 0;
$handles = array();
$handle_lookup = array();
foreach($projects as $dirname => $projectname) {
echo sprintf("[%2d/%2d] ".$projectname."...", ++$count, count($projects));
$pr = new CProject($dirname, $projectname);
$pr->write();
$plist[] = $pr;
if (is_null($pr->homeimage)) {
$handle_lookup[$projectname] = null;
} else {
$handle_lookup[$projectname] = count($handles);
$handles[] = $pr->homeimage;
}
echo " done\n";
}
// 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();
?>
<h2><?=hesc(SITE_TITLE)?></h2>
<img src="overview.jpg" class="headimg">
<p>
This page contains several assorted projects, which no longer have any relation. They are listed in roughly chronological order (newest first). <strong>Unless specified otherwise</strong>, you may feel free to use and modify both the binaries and any source code, for any purpose, on the general condition you do not misrepresent who the author is (BSD license).
</p>
<p>
Some of these projects formerly appeared on Google Code <a href="https://code.google.com/p/mappy/">here</a>, but were moved following the discontinuation of the Google Code binary download system.
</p>
<p>
For bug reports, feature requests, or if you need any help, please
<a
href="http://www.google.com/recaptcha/mailhide/d?k=01GuAWzMc9JjSdooo-2KCMQA==&amp;c=kgR3dBrP39yhPIy8FvLFbuBLmWqorQBDc_Zjbw6NAmU="
onclick="window.open('http://www.google.com/recaptcha/mailhide/d?k\07501GuAWzMc9JjSdooo-2KCMQA\75\75\46c\75kgR3dBrP39yhPIy8FvLFbuBLmWqorQBDc_Zjbw6NAmU\075', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;"
title="Reveal this e-mail address"
>click here</a> to email me.
</p>
<img src="projects.jpg" class="headimg">
<table class="projtable">
<?php foreach ($plist as $pr) { ?>
<tr>
<td>
<a href="<?=hesc(urlencode($pr->projname))?>.html"><?=(is_null($handle_lookup[$pr->projname]) ? '<img src="no_image.png" class="homeimage">' : '<div class="homeimage homeimage-sprite" style="background-position:0 -'.($handle_lookup[$pr->projname]*INDEX_THUMB_H).'px"></div>')?></a>
</td>
<td>
<strong><?=hesc($pr->projname)?></strong>,
<?=hesc($pr->shortdesc)?>
<a href="<?=hesc(urlencode($pr->projname))?>.html">more...</a>
<?php if (strlen($pr->subtag)) { ?>
<br>
<small><?=hesc($pr->subtag)?></small>
<?php } ?>
</td>
</tr>
<?php } ?>
</table>
<?php
$index = template(SITE_TITLE, ob_get_clean());
file_put_contents(BASEDIR.'wwwroot/index.html', $index);
echo "All processes complete.\n";
}
buildall();