rtoss - Blame information for rev 358

Subversion Repositories:
Rev:
Rev Author Line No. Line
2 roytam 1 <?php
2 /*
3  * tropy.php - PHP version of tropy.cgi
4  *
5  * # tropy.cgi - Version 20051105.
6  * #
7  * # Copyright (C) 2005 by Hiroshi Yuki.
8  * # <hyuki@hyuki.com>
9  * # http://www.hyuki.com/tropy/
10  * #
11  * # This program is free software; you can redistribute it and/or
12  * # modify it under the same terms as Perl itself.
13  */
14  
15 /* Config section */
16  
358 roytam 17 $thisurl_absolute = ''; //'http://'.$_SERVER['HTTP_HOST'].preg_replace('/'.preg_replace('/.*\/+/','',$_SERVER['PHP_SELF']).'$/','',$_SERVER['PHP_SELF']); //Auto Setting
2 roytam 18 $site_name = 'Tropy';
19 $dir_html = 'html'; # Directory for Cached HTML files.
20 $dir_files = 'files'; # Directory for user-written text files and the index file.
21 $file_index = "$dir_files/index.txt";
22 $tropy_self = 'tropy.php';
23 /******************/
24 $sendmail = 0;
25 $adminmail = "";
26 # $adminmail = 'somebody@example.com';
27 $maxidlen = 8;
44 roytam 28 $id_pattern = '[0-9]{'.$maxidlen.'}';
2 roytam 29 $maxlength = 1000;
30 $maxlines = 20;
31 $maxcols = 80;
32 $maxrows = $maxlines;
33 $maxtitle = $maxcols - 3;
34 $maxpages = 10000;
35 $session_digest = md5(microtime().uniqid('Tropy',true));
36 $random_seed = hexdec(substr($session_digest, 0, 8));
37 $create_id = substr(sprintf("%0${maxidlen}u", $random_seed), 0, $maxidlen);
44 roytam 38 $time_visible_msec = '3000';
39 $time_jumpto_sec = '3';
40 $content_type = 'Content-type: text/html; charset=utf-8\n\n';
2 roytam 41 $allow_rebuild = 1;
42 $allow_toc = 1;
43 $allow_html = 0;
44 $show_plink = 1;
45 $auto_link = 1;
46 $allow_edit = 1;
44 roytam 47 $return_url='../';
2 roytam 48 $form=array_merge($_GET,$_POST);
49 $allid=array();
50  
51 main();
52 exit(0);
53  
54 function main() {
55         global $main_command,$form,$id_pattern,$random_seed,$allow_toc,$allow_rebuild,$show_plink,$allid;
56  
57         # Random init.
58         srand($random_seed);
59         rand(); rand(); rand();
60         TIEHASH();
61  
62         foreach ($form as $key => $val) {
44 roytam 63                 if (preg_match('/^c$/',$key)) {
2 roytam 64                         $main_command = 'create';
65                         do_create();
66                         break;
44 roytam 67                 } elseif (preg_match('/^e('.$id_pattern.')$/',$key,$matches)) {
2 roytam 68                         $main_command = 'edit';
69                         do_edit($matches[1]);
70                         break;
44 roytam 71                 } elseif (preg_match('/^w('.$id_pattern.')$/',$key,$matches)) {
2 roytam 72                         $main_command = 'write';
73                         do_write($matches[1]);
74                         break;
44 roytam 75                 } elseif (preg_match('/^toc$/',$key)) {
2 roytam 76                         if ($allow_toc) {
77                                 $main_command = 'toc';
78                                 $show_plink=0;
79                                 show_toc();
80                         }
81                         break;
44 roytam 82                 } elseif (preg_match('/^rebuild$/',$key)) {
2 roytam 83                         if ($allow_rebuild) {
84                                 foreach ($allid as $id => $val) {
44 roytam 85                                         if (preg_match('/^'.$id_pattern.'$/',$id)) {
2 roytam 86                                                 unlink_html($id);
87                                                 build_html($id);
88                                         }
89                                 }
90                         }
91                 }
92         }
93         if (! $main_command) {
94                 $main_command = 'random';
95                 do_random();
96         }
97 }
98  
99 function do_edit($id) {
100         global $main_command,$allid,$show_plink;
101         if ($main_command == 'create' || isset($allid[$id])) {
102                 $show_plink=0;
44 roytam 103                 $title = isset($allid[$id]) ? get_subject($id) : 'New Page';
2 roytam 104                 print_header($id, $title);
105                 print_editform($id, @implode('',FETCH($id)));
106                 echo get_footer();
107         } else {
44 roytam 108                 print_error('edit non id');
2 roytam 109         }
110 }
111  
112 function print_editform($id,$msg) {
113         global $maxrows,$maxcols,$tropy_self;
114         $mymsg = htmlspecialchars($msg);
115         echo <<<EOD
116   <form action="$tropy_self" method="post">
117         <input type="hidden" name="w$id" value="1">
358 roytam 118         <textarea cols="$maxcols" rows="$maxrows" name="mymsg" id="msg">$mymsg</textarea><br><input type="submit" value="Write">&emsp;&emsp;<button onclick='document.getElementById("preview").innerHTML="<p>"+document.getElementById("msg").value.replace(/\\n\\n/g,"</p><p>").replace(/\\n/g,"<br>")+"</p>";return false;'>Preview</button>
2 roytam 119   </form>
358 roytam 120   <div id="preview"></div>
2 roytam 121 EOD;
122 }
123  
124 function do_write($id) {
125         global $form,$maxlength,$maxlines,$maxpages,$allid;
126         $msg = $form['mymsg'];
44 roytam 127         $msg = preg_replace('/\n+$/',"\n",$msg);
2 roytam 128         $msglen = strlen($msg);
129         $cr = $msglen -  strlen(str_replace("\n","",$msg));
130  
131         if ($maxpages < count($allid)) {
132                 DELETE_random_page();
133         }
134  
135         if ($msglen > $maxlength) {
136                 print_header($id, "length > $maxlength");
137                 print_editform($id, $msg);
138                 echo get_footer();
139         } elseif ($cr >= $maxlines) {
140                 print_header($id, "lines > $maxlines");
141                 print_editform($id, $msg);
142                 echo get_footer();
143         } else {
144                 if ($form['mymsg']) {
45 roytam 145  
146                         // =date -> real date
147                         $msg = preg_replace('/=date/i',date('r'),$msg);
148  
2 roytam 149                         STORE($id,$msg);
150                         send_mail($id, get_subject($id), 'edit', $msg);
151                         unlink_html($id);
152                         build_html($id);
153                         print_jumpto($id);
154                 } else {
155                         send_mail($id, get_subject($id), 'delete', FETCH($id));
156                         DELETE($id);
157                         unlink_html($id);
158                         do_random();
159                 }
160         }
161 }
162  
163 function delete_random_page() {
164         $id = get_random_id();
165         DELETE($id);
166         unlink_html($id);
167 }
168  
169 function print_jumpto($id) {
170         global $content_type,$time_jumpto_sec,$thisurl_absolute,$dir_html,$site_name;
358 roytam 171         $meta = "<meta http-equiv='refresh' content='$time_jumpto_sec; url=${thisurl_absolute}${dir_html}/${id}.html?t=".time()."'>\n";
44 roytam 172         $navi = '<div id="navi"></div>';
2 roytam 173         header($content_type);
44 roytam 174         header('Cache-Control: no-cache, must-revalidate'); // HTTP/1.1
2 roytam 175         echo get_header("$site_name...", "", 'black', 'white', $navi, $meta);
176         echo get_footer();
177 }
178  
179 function print_error($msg) {
180         $msg = htmlspecialchars($msg);
181         print_header(null, '?');
182         echo "<h1>$msg</h1>";
183         echo get_footer();
184         exit(0);
185 }
186  
187 function print_header($id,$title) {
188         global $content_type,$form,$site_name,$allow_edit;
189         list($color, $bgcolor) = get_style($id);
190         $navi = get_navi($id, $allow_edit);
191         header($content_type);
192         echo get_header("$title - $site_name", $title, $color, $bgcolor, $navi, "");
193 }
194  
195 function get_navi($id, $editable) {
196         global $tropy_self,$allow_toc,$show_plink,$return_url,$dir_html;
197         $mod = 17;
198         $random_url = "$tropy_self";
199         if ($id % $mod > 0) {
200                 for ($x=1;$x<$mod * 3;$x++) {
201                         $nextid = get_random_id();
202                         if (($id + 1) % $mod == $nextid % $mod) {
203                                 # Found.
204                                 $random_url = "$dir_html/$nextid.html";
205                                 break;
206                         }
207                 }
208         }
209         $return = $return_url ? "<a href='$return_url' title='Return to Home'>Return</a>" : '';
210         $toc = $allow_toc ? "<a href='$tropy_self?toc' title='Table of Contents'>TOC</a>" : '';
211         $edit = $editable ? "<a href='$tropy_self?e$id' title='Edit this tropy'>Edit</a>" : '';
212         $create = "<a href='$tropy_self?c' title='Create new tropy'>Create</a>";
213         $random = "<a href='$random_url' title='Jump to random tropy'>Random</a>";
214         $plink = $show_plink ? "<a href='$dir_html/$id.html' title='Permalink of this tropy'>Permalink</a>" : '';
215         return "<p id='navi'>$return $toc $edit $create $random $plink</p>";
216 }
217  
218 function do_random() {
219         global $id_pattern,$main_command,$id_pattern;
220         $random_id = get_random_id();
44 roytam 221         if (preg_match('/^'.$id_pattern.'$/',$random_id)) {
2 roytam 222                 build_html($random_id);
223                 print_jumpto($random_id);
224         } else {
225                 $main_command = 'create';
226                 do_create();
227         }
228 }
229  
230 function get_random_id() {
231         global $allid;
232         $id = array_keys($allid);
233         $rid = array_rand($id);
234         return isset($id[$rid])?$id[$rid]:null;
235 }
236  
237 function unlink_html($id) {
238         global $dir_html;
239         @unlink("$dir_html/$id.html");
240 }
241  
242 function build_html($id) {
358 roytam 243         global $dir_html,$allow_html,$site_name,$allow_edit,$auto_link,$return_url;
2 roytam 244         list($color, $bgcolor) = get_style($id);
245         $navi = get_navi($id, $allow_edit);
246  
247         # Check.
248         if (file_exists("$dir_html/$id.html")) {
249                 return;
250         }
251  
252         # Read.
253         $fil=FETCH($id);
254         $caption=array_shift($fil);
255         $caption=rtrim(htmlspecialchars($caption));
256         $content = implode('',$fil);
44 roytam 257  
2 roytam 258         if (!$allow_html) {
259                 $content = htmlspecialchars($content);
44 roytam 260  
358 roytam 261                 if (strpos(strtolower($content),'=nbsp\n') > -1) {
44 roytam 262                         $content = preg_replace('/=nbsp\n/i','',$content);
358 roytam 263                         $content = str_replace(' ',chr(0xc2).chr(0xa0),$content); // C2 A0 = nbsp in UTF-8
44 roytam 264                 }
45 roytam 265                 $content = preg_replace("/=pre\n?/i",'<pre>',$content);
266                 $content = preg_replace('/=\/pre\n?/i','</pre>',$content);
44 roytam 267  
268                 $content = preg_replace('/(\n\n+)/',"\n\n",$content);
45 roytam 269                 $content = str_replace("\n\n",'</p><p>',$content);
270                 $content = str_replace("\n",'<br />',$content);
2 roytam 271         }
44 roytam 272         if ($auto_link) $content = preg_replace('/(https?|ftp|news)(\:\/\/[[:alnum:]\+\$\;\?\.%,!#~*\/\:@&=_-]+)/i','<a href="$1$2" target="_blank">$1$2</a>',$content);
2 roytam 273  
274         # Write.
275         if (!$wfil=fopen("$dir_html/$id.html","wb")) {
276                 print_error("build to $id");
277         }
358 roytam 278         fwrite($wfil,get_header("$caption - $site_name", $caption, $color, $bgcolor, $navi, "<base href=\"$return_url\">"));
2 roytam 279         fwrite($wfil,"<p>$content</p>");
280         fwrite($wfil,get_footer());
281         fclose($wfil);
282 }
283  
284 function show_toc() {
285         global $dir_html,$site_name,$allow_edit,$auto_link,$allid;
286         $content='';
287  
288         # Read.
289         foreach ($allid as $id => $val) {
290                 $fil=FETCH($id);
291                 $caption=array_shift($fil);
292                 $caption=rtrim(htmlspecialchars($caption));
293                 $content.="<a href='$dir_html/$id.html'>$id - $caption</a><br />";
294         }
295  
44 roytam 296         echo get_header("TOC - $site_name", 'Table Of Contents', 'black', 'white', get_navi(null,0), '');
2 roytam 297         echo "<p>$content</p>";
298         echo get_footer();
299 }
300  
301 function get_header($title, $caption, $color, $bgcolor, $navi, $meta) {
358 roytam 302         global $time_visible_msec;
2 roytam 303         return <<<EOD
304 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
305    "http://www.w3.org/TR/html4/loose.dtd">
306 <html lang="ja">
307 <head>
308 <meta http-equiv="content-type" content="text/html; charset=utf-8">
309 <meta http-equiv="content-style-type" content="text/css">
358 roytam 310 $meta
2 roytam 311 <style type="text/css"><!--
312 body{font-family:Verdana,sans-serif;margin:2% 20% 10% 20%;color:$color;background-color:$bgcolor;}
313 input{font-family:Verdana,sans-serif;}
314 #navi{text-align:right;}
315 p{line-height:150%;}
316 a{color:gray;background-color:$bgcolor;text-decoration:none;}
317 a:hover{text-decoration:underline;color:white;background-color:gray;}
318 --></style>
319 <script type="text/javascript">
320 <!--
321 function onLoad(){
322   document.getElementById("navi").style.visibility="hidden";
323   setTimeout("onTimeout()", $time_visible_msec);
324 }
325 function onTimeout(){
326   document.getElementById("navi").style.visibility="visible";
327 }
328 // -->
329 </script>
330 <title>$title</title>
331 </head>
332 <body onLoad="onLoad()">
333 $navi<h1>$caption</h1>
334 EOD;
335 }
336  
337 function get_footer() {
338         return "</body></html>\n";
339 }
340  
341 function send_mail($pagename, $subject, $mode, $content) {
342         global $sendmail,$adminmail,$allid;
343         if(!$sendmail) return;
344         $pages = count($allid);
345         $header = <<<EOD
346 To: $adminmail
347 From: $adminmail
348 Subject: [Tropy/$mode] $subject
349 MIME-Version: 1.0
350 Content-type: text/plain; charset=UTF-8
351 Content-Transfer-Encoding: 8bit
352 EOD;
353  
354         $message = <<<EOD
355 --------
356 MODE = $mode
357 REMOTE_ADDR = $_SERVER[REMOTE_ADDR]
358 REMOTE_HOST = $_SERVER[REMOTE_HOST]
359 --------
360 ${thisurl_absolute}$pagename.html
361 --------
362 $content
363 --------
364 pages = $pages
365 --------
366 EOD;
367         mail($adminmail,"[Tropy/$mode] $subject",$message,$header);
368 }
369  
370 function get_style($id) {
371         global $main_command;
372         list($color, $bgcolor) = array('black', 'white');
373         if ($main_command != 'create') {
374                 $digest = md5($id);
375                 $range = 32;
376                 $r = 255 - (hexdec(substr($digest, 0, 2)) % $range);
377                 $g = 255 - (hexdec(substr($digest, 2, 2)) % $range);
378                 $b = 255 - (hexdec(substr($digest, 4, 2)) % $range);
379                 $color = 'black';
44 roytam 380                 $bgcolor = sprintf('#%02X%02X%02X', $r, $g, $b);
2 roytam 381         }
382         return array($color, $bgcolor);
383 }
384  
385 function do_create() {
386         global $create_id;
387         do_edit($create_id);
388 }
389  
390 function get_subject($id) {
391         global $maxtitle;
392         $item=FETCH($id);
44 roytam 393         if (preg_match('/^(.*)/',$item[0],$matches)) {
2 roytam 394                 $caption = $matches[1];
395                 if (strlen($caption) > $maxtitle) {
44 roytam 396                         $caption = preg_replace('/^(.{'.$maxtitle.'}).*/','$1...',$caption);
2 roytam 397                 }
398                 return htmlspecialchars($caption);
399         } else {
400                 return "";
401         }
402 }
403  
404 function TIEHASH() {
405         global $file_index,$allid;
406         _make_index();
407         $keys = array_map('rtrim',file($file_index));
408         foreach($keys as $v) if($v) $allid[$v]=1;
409 }
410  
411 function STORE($id, $value) {
412         global $file_index,$dir_files,$id_pattern,$allid;
44 roytam 413         if (!preg_match('/^('.$id_pattern.')$/',$id)) {
2 roytam 414                 die("store nonid");
415         }
416  
417         # Replace file.
418         $filename = "$dir_files/$id.txt";
419         if (!$fil= fopen("$filename","wb")) {
420                 die("store $id file");
421         }
422         fwrite($fil,str_replace("\r\n","\n",$value));
423         fclose($fil);
424  
425         # Append $id.
426         if (!isset($allid[$id])) {
427                 if (!$idx= fopen("$file_index","a")) {
44 roytam 428                         die('store index');
2 roytam 429                 }
430                 fwrite($idx,"$id\n");
431                 fclose($idx);
432                 $allid[$id] = 1;
433         }
434  
435         return $value;
436 }
437  
438 function FETCH($key) {
439         global $file_index,$dir_files;
440         $filename = "$dir_files/$key.txt";
441         return @file($filename);
442 }
443  
444 function DELETE($key) {
445         global $file_index,$dir_files,$allid;
446         $filename = "$dir_files/$key.txt";
447         unlink($filename);
448         unset($allid[$key]);
449  
450         # Write index.
451         $id = array_keys($allid);
44 roytam 452                 if (!$idx= fopen("$file_index",'wb')) {
2 roytam 453                 die("delete index");
454         }
455         fwrite($idx,implode("\n", $id)."\n");
456         fclose($idx);
457 }
458  
459 function _make_index() {
460         global $file_index,$dir_files,$id_pattern;
461         if (file_exists($file_index)) {
462                 return;
463         }
464         if (!$di=opendir($dir_files)) {
44 roytam 465                 print_error('build index dir');
2 roytam 466         }
467         $index=array();
468         $entry='';
469         while ($entry = readdir($di)) {
44 roytam 470                 if (preg_match('/^('.$id_pattern.')\.txt$/',$entry,$matches)) {
2 roytam 471                         $id = $matches[1];
472                         if (-s("$dir_files/$id.txt") > 0) {
473                                 $index[]=$id;
474                         }
475                 }
476         }
477         closedir($di);
478         if (!$idx=fopen("$file_index","wb")) {
44 roytam 479                 print_error('build index open');
2 roytam 480         }
481         fwrite($idx,implode("\n", $index)."\n");
482         fclose($idx);
483 }
484  
358 roytam 485 ?>