--- /dev/null
+<?php
+
+// ファイルブラウザ
+
+include_once('./config/site.inc.php');
+
+// とりあえず/抜いとけば安全?
+$request__d = check_request('d','/^[^\/]+$/','');
+
+if ($request__d == '') {
+
+ // ディレクトリインデックスを出力
+
+ $dirs = array();
+
+ $files = scandir(PATH_COMIC);
+ foreach ($files as $one) {
+ if (is_dir(PATH_COMIC.'/'.$one) && $one!='.' && $one!='..') {
+ $dirs[config__get_dir_index($one)][] = $one;
+ }
+ }
+
+ $comic = '';
+ $index = array();
+ $idx = 0;
+ foreach ($dirs as $var => $val) {
+ $comic .= '<a id="'.$idx.'"></a><h3>'.htmlspecialchars($var).'</h3>';
+ $index[] = '<a href="#'.$idx.'">'.$var.'</a>';
+ foreach ($val as $one) {
+ $comic .= '<a href="./browse.php?d='.urlencode($one).'">'.htmlspecialchars($one).'</a><br />';
+ }
+ $idx++;
+ }
+
+ $_HTML['indexlist'] = implode('|',$index);
+ $_HTML['comiclist'] = $comic;
+
+} else {
+
+ // ファイルリストを出力
+
+ $files = scandir(PATH_COMIC.'/'.$request__d);
+
+ $html = '<a href="./browse.php">戻る</a>';
+ $html .= '<h3>'.htmlspecialchars($request__d).'</h3>';
+ foreach ($files as $one) {
+ if (preg_match('/.+\.zip$/us',$one)) {
+ $path = $request__d.'/'.$one;
+ $hash = md5($path);
+ if (!file_exists(PATH_CACHE.'/'.$hash.CACHE_EXT_INDEX)) {
+ file_put_contents(PATH_CACHE.'/'.$hash.CACHE_EXT_INDEX,$path);
+ }
+ $cap = mb_substr($one,0,mb_strlen($one)-4);
+ $html .= '<a href="./viwer.php?ix='.urlencode($hash).'">'.htmlspecialchars($cap).'</a><br />';
+ }
+ }
+
+ $_HTML['comiclist'] = $html;
+}
+
+echo $obj_html->apply('browse.html');
+
+?>
\ No newline at end of file
--- /dev/null
+このディレクトリは、システムが書き込みます。
+下記のコマンドなどにて権限を設定してください。
+chmod 777 cache
+
+※このディレクトリの内容は削除しても差し支えありません
+※ページ送りに不具合がある場合は、このディレクトリをクリアしてください
+※このファイルは削除しても構いません
--- /dev/null
+<?php
+
+// ライブラリの読み込み
+include_once(PATH_LIB.'/common.inc.php');
+include_once(PATH_LIB.'/debug.inc.php');
+include_once(PATH_LIB.'/html.inc.php');
+
+
+// テンプレート用インスタンスの生成
+$obj_html = new html();
+
+
+// 各テーマ構成ファイルへのパス
+$files = scandir(PATH_THEMES.'/default');
+foreach ($files as $one) {
+ if ($one=='.' || $one=='..') continue;
+ if (file_exists(PATH_THEMES.'/'.SITE_THEME.'/'.$one)) {
+ $path = PATH_THEMES.'/'.SITE_THEME.'/'.$one;
+ $url = URL_THEMES.'/'.SITE_THEME.'/'.$one;
+ } else {
+ $path = PATH_THEMES.'/default/'.$one;
+ $url = URL_THEMES.'/default/'.$one;
+ }
+ $obj_html->regist_theme_file($one,$path,$url);
+}
+
+// ディレクトリインデックス作成用
+$config__dir_index = array(
+ 'あ~お' => 'あいうえおアイウエオ',
+ 'か~こ' => 'かきくけこがぎぐげごカキクケコガギグゲゴ',
+ 'さ~そ' => 'さしすせそざじずぜぞサシスセソザジズゼゾ',
+ 'た~と' => 'たちつてとだぢづでどタチツテトダヂヅデド',
+ 'な~の' => 'なにぬねのナニヌネノ',
+ 'は~ほ' => 'はひふへほばびぶべぼぱぴぷぺぽハヒフヘホバビブベボパピプペポ',
+ 'ま~も' => 'まみむめもマミムメモ',
+ 'や~よ' => 'やゐゆゑよヤヰユヱヨ',
+ 'ら~ろ' => 'らりるれろラリルレロ',
+ 'わ~ん' => 'わをんワオン',
+ 'その他' => '',
+);
+
+
+// キャッシュファイル識別用
+define('CACHE_EXT_INDEX','_idx.txt');
+define('CACHE_EXT_LIST' ,'_lst.txt');
+
+
+// 定義した定数をすべてHTMLリソースに格納する
+$vars = get_defined_constants(true);
+$_HTML = $vars['user'];
+
+//echo var_export($GLOBALS,true);
+
+//
+function config__get_dir_index($name) {
+ global $config__dir_index;
+
+ $ret = '';
+
+ $f = mb_substr($name,0,1);
+ foreach ($config__dir_index as $var => $val) {
+ if (mb_strpos($val,$f) !== false) {
+ $ret = $var;
+ break;
+ }
+ if ($val == '') {
+ $ret = $var;
+ }
+ }
+
+ return $ret;
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php\r
+\r
+mb_internal_encoding('UTF-8');\r
+\r
+//\r
+// カスタマイズ設定項目\r
+// ファイル名を site.inc.php にリネームしてください\r
+//\r
+\r
+// サイト名\r
+define('SITE_NAME' ,'Cosmic Server');\r
+\r
+// システムのルートディレクトリ(絶対パス指定、最後のスラッシュは不要)\r
+define('PATH_ROOT' ,'/home/landhere/public_html/!_private_!/comic');\r
+\r
+// サイトURLのルート(URL絶対パス指定、最後のスラッシュは不要)\r
+define('URL_ROOT' ,'/!_private_!/comic');\r
+\r
+// コミックを置いたディレクトリ(絶対パス指定、最後のスラッシュは不要)\r
+// <おすすめ配置方法>\r
+// /path/to/comics/て テストコミック 全2巻/テストコミック 第01巻.zip\r
+// /path/to/comics/て テストコミック 全2巻/テストコミック 第02巻.zip\r
+// ※必ずサブディレクトリの下にzipを置いて下さい\r
+define('PATH_COMIC' ,'/path/to/comics');\r
+\r
+// サイトのデザインテーマ(themesディレクトリのサブディレクトリ名)\r
+// サブディレクトリに見つからないファイルは、defaultのものが使用される\r
+define('SITE_THEME','default');\r
+\r
+// パス構成(通常は変更する必要はありません)\r
+define('PATH_THEMES',PATH_ROOT.'/themes');\r
+define('PATH_LIB' ,PATH_ROOT.'/lib');\r
+define('PATH_INDEX' ,PATH_ROOT.'/index');\r
+define('PATH_CACHE' ,PATH_ROOT.'/cache'); // 書き込み権限が必要(chmod 777 cache)\r
+\r
+// URL構成(通常は変更する必要はありません)\r
+define('URL_THEMES',URL_ROOT.'/themes');\r
+\r
+// システムを設定します\r
+include_once('version.inc.php');\r
+include_once('init.inc.php');\r
+\r
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+define('SYSTEM_NAME' ,'Cosmic Server');
+define('SYSTEM_VERSION','0.11');
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+//
+// ウェブ関連
+//
+
+// GET, POST チェック用正規表現
+define('CV_TEXT' ,'/^.+$/');
+define('CV_ALNUM' ,'/^[[:alnum:]]+$/'); // アルファベットと数値、[:alpha:] + [:digit:]
+define('CV_ALPHA' ,'/^[[:alpha:]]+$/'); // 大小文字アルファベット、 [:lower:] + [:upper:]
+define('CV_LOWER' ,'/^[[:lower:]]+$/'); // 小文字アルファベット
+define('CV_UPPER' ,'/^[[:upper:]]+$/'); // 大文字アルファベット
+define('CV_DIGIT' ,'/^[[:digit:]]+$/'); // 数値
+define('CV_BLANK' ,'/^[[:blank:]]+$/'); // 空白文字、スペースとタブ
+define('CV_CNTRL' ,'/^[[:cntrl:]]+$/'); // 制御文字(000-037, 177('DEL')
+define('CV_GRAPH' ,'/^[[:graph:]]+$/'); // グラフィカル文字 ([:alnum:] と [:punct:])|
+define('CV_PRINT' ,'/^[[:print:]]+$/'); // 印字可能な文字、[:alnum:] + [:punct:] + space
+define('CV_PUNCT' ,'/^[[:punct:]]+$/'); // パンクチュエーション文字 ! " # $ % & ' ( ) * + , - . /
+define('CV_SPACE' ,'/^[[:space:]]+$/'); // 空白文字、タブ、改行、水平タブ、給紙、キャリッジリターン、空白
+define('CV_XDIGIT','/^[[:xdigit:]]+$/'); // 16進数 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
+define('CV_MD5' ,'/^[a-z0-9]{32}$/'); // md5ハッシュ値
+define('CV_EMAIL' ,'/^[\w.-]+\@([\w-]+\.)+\w+$/'); // メールアドレス
+
+// GET, POST パラメータチェック
+function check_request($var,$chk='',$def='') {
+
+ $val = isset($_REQUEST[$var]) ? $_REQUEST[$var] : $def;
+ if ($chk!='') {
+ if (preg_match($chk,$val)==0) {
+ $val = $def;
+ }
+ }
+
+ $_REQUEST[$var] = $val;
+
+ return $val;
+}
+
+// 一般変数の内容チェック
+function check_value(&$val,$pat,$def) {
+
+ if (preg_match($pat,$val)==0) {
+ $val = $def;
+ }
+
+ return $val;
+}
+
+
+//
+// ファイル操作関連
+//
+
+// ファイルパスより拡張子を返す
+function common__get_fileext($path) {
+
+ $p = strrpos($path,'.');
+ if ($p!==false) {
+ $ext = substr($path,$p+1);
+ } else {
+ $ext = '';
+ }
+
+ return $ext;
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+function debug__out($var) {
+ echo '<pre>'.var_export($var,true).'</pre>';
+}
+
+function debug__halt($var) {
+ debug__out($var);
+ exit;
+}
+
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+
+//-------------------------------------------------------------------
+// テンプレート
+//-------------------------------------------------------------------
+
+$_HTML = array();
+
+class html {
+
+ // テーマファイル格納用
+ public $theme_files = array();
+
+ // テーマファイルの登録
+ public function regist_theme_file($name,$path,$url) {
+ $this->theme_files[$name] = array(
+ 'path' => $path,
+ 'url' => $url,
+ );
+ }
+
+ // テンプレートファイルパスを戻す
+ public function get_theme_file_path($name) {
+ return $this->theme_files[$name]['path'];
+ }
+
+ // テンプレートファイルURLを戻す
+ public function get_theme_file_url($name) {
+ return $this->theme_files[$name]['url'];
+ }
+
+ // テンプレートの適用
+ public function apply($tmpl) {
+
+ $tmpl = $this->get_theme_file_path($tmpl);
+
+ if (file_exists($tmpl)) {
+ $html = file_get_contents($tmpl);
+ } else {
+ $html = '{{doc}}';
+ }
+
+ $html = $this->_apply_include($html);
+ $html = $this->_apply_replace($html);
+
+ return $html;
+ }
+
+ // インクルード処理
+ private function _apply_include($html) {
+
+ $html = preg_replace_callback(
+ '/{{include:(.+?)}}/',
+ array($this,'_apply_include_callback'),
+ $html
+ );
+
+ return $html;
+
+ }
+
+ // インクルード処理(コールバック関数)
+ private function _apply_include_callback($matches) {
+
+ $path = $this->get_theme_file_path($matches[1]);
+ if (file_exists($path)) {
+ return file_get_contents($path);
+ } else {
+ return '';
+ }
+
+ }
+
+ // 置き換え処理
+ private function _apply_replace($html) {
+
+ $html = preg_replace_callback(
+ '/{{(.+?)}}/',
+ array($this,'_apply_replace_callback'),
+ $html
+ );
+
+ return $html;
+
+ }
+
+ // 置き換え処理(コールバック関数)
+ private function _apply_replace_callback($matches) {
+
+ if (array_key_exists($matches[1],$GLOBALS['_HTML'])) {
+ return $GLOBALS['_HTML'][$matches[1]];
+ } else {
+ return '';
+ }
+
+ }
+
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+
+include_once('./config/site.inc.php');
+
+$request__ix = check_request('ix',CV_MD5 ,'');
+$request__pg = check_request('pg',CV_DIGIT,0);
+
+$fid_index = PATH_CACHE.'/'.$request__ix.CACHE_EXT_INDEX;
+$fid_list = PATH_CACHE.'/'.$request__ix.CACHE_EXT_LIST;
+
+if (!file_exists($fid_index)) {
+ die('error:ix not found');
+}
+
+$path = file_get_contents($fid_index);
+$fid_comic = PATH_COMIC.'/'.$path;
+
+if ($request__ix=='') {
+ die('error:empty ix');
+}
+
+
+// zipファイルのエントリリストを取得(画像ファイルに限定)
+if (!file_exists($fid_list) || true) {
+ $entry_data = array();
+ $entry_name = array();
+ $zip = zip_open($fid_comic);
+ $no = -1;
+ $img = array(NULL,NULL);
+ while(($zip_entry = zip_read($zip)) !== false){
+ $no++;
+ $zip_entry_name = zip_entry_name($zip_entry);
+ $zip_entry_type = common__get_fileext($zip_entry_name);
+ if ($zip_entry_type=='' || mb_strpos('jpg/jpeg/png/gif',$zip_entry_type)===false) continue;
+ $entry_data[] = array(
+ 'no' => $no,
+ 'name' => $zip_entry_name,
+ 'size' => zip_entry_filesize($zip_entry),
+ );
+ $entry_name[] = $zip_entry_name;
+ }
+ zip_close($zip);
+ array_multisort($entry_name, SORT_ASC, $entry_data);
+ file_put_contents($fid_list,serialize($entry_data));
+} else {
+ $entry_data = unserialize(file_get_contents($fid_list));
+}
+
+// ページ番号からzip内番号に変換する
+$zip_no[0] = isset($entry_data[$request__pg ]) ? $entry_data[$request__pg ]['no'] : -1;
+$zip_no[1] = isset($entry_data[$request__pg+1]) ? $entry_data[$request__pg+1]['no'] : -1;
+
+// zipファイルから指定されたページとその次ページを持ってくる
+$zip = zip_open($fid_comic);
+$no = 0;
+$img = array(NULL,NULL);
+while(($zip_entry = zip_read($zip)) !== false){
+ foreach ($zip_no as $pgid => $target_no) {
+ if ($no==$target_no) {
+ $img[$pgid] = zip_entry_read($zip_entry,zip_entry_filesize($zip_entry));
+ }
+ }
+ if (!is_null($img[0]) && !is_null($img[1])) break;
+ $no++;
+}
+zip_close($zip);
+
+
+// 画像を作成して出力する
+if (is_null($img[0])) {
+
+ // ページが無かった場合
+ echo "no image";
+
+} else if (is_null($img[1])) {
+
+ // 1ページしか無かった場合
+ header("Content-type: image/jpeg");
+ echo $img[0];
+
+} else {
+
+ // 2ページある
+
+ // GDイメージを作成
+ for ($pgid=0;$pgid<=1;$pgid++) {
+ $img[$pgid] = imagecreatefromstring($img[$pgid]);
+ $sx[$pgid] = imagesx($img[$pgid]);
+ $sy[$pgid] = imagesy($img[$pgid]);
+ }
+
+ //
+ if ($sx[0]>$sy[0] || $sx[1]>$sy[1]) {
+ // 横長ページが含まれるときは、1ページ目のみを戻す
+ header("Content-type: image/jpeg");
+ imagejpeg($img[0]);
+ } else {
+ // 2ページを並べる
+ $vx = $sx[0]+$sx[1];
+ $vy = ($sy[0]>$sy[1] ? $sy[0] : $sy[1]);
+ $view = imagecreatetruecolor($vx,$vy);
+ header("Content-type: image/jpeg");
+ imagecopy($view,$img[0],$sx[1],($vy-$sy[0])/2,0,0,$sx[0],$sy[0]);
+ imagecopy($view,$img[1],0,($vy-$sy[1])/2,0,0,$sx[1],$sy[1]);
+ imagejpeg($view);
+ }
+
+
+}
+
+?>
\ No newline at end of file
--- /dev/null
+</body>
+</html>
--- /dev/null
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
+ <link rel="stylesheet" type="text/css" href="{{URL_THEMES}}/{{SITE_THEME}}/screen.css" />
+ <title>{{SITE_NAME}}</title>
+ <script type="text/javascript" src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
+ {{head_additional}}
+</head>
+<body>
+ <div id="header" style="text-align:center;">
+ {{SITE_NAME}}
+ </div>
--- /dev/null
+{{include:_html_header.inc.html}}
+
+<div id="indexlist">{{indexlist}}</div>
+<div id="comiclist">{{comiclist}}</div>
+
+{{include:_html_footer.inc.html}}
--- /dev/null
+@charset "utf-8";
+
+/* HTML基本構造 */
+html {
+ overflow-y: scroll;
+}
+
+body {
+ margin: 0px;
+ font-size: 100%;
+ background-color: #ffffff;
+ color: #555555;
+}
+
+table,textarea {
+ font-size: 100%;
+}
+
+/* システムが使用するエリア(非表示にしておきます) */
+div#system {
+ display: none;
+}
+
+/* 蔵書ブラウザの索引部分 */
+div#indexlist {
+ text-align: center;
+}
+
+/* 蔵書ブラウザの一覧部分 */
+div#comiclist {
+ text-align: left;
+ padding: 1em;
+}
+
+/* コミックビューアのナビゲーション部分 */
+div#navigator {
+ text-align: center;
+}
+
+div#backlink {
+ position: absolute;
+ padding-left: 1em;
+}
+
+/* コミックビューアの表示部分 */
+div#viewbox {
+ clear: both;
+ text-align: center;
+}
+
+/* コミックビューアの表示部分画像本体(高さはjQueryによって制御されます) */
+img#viewbox_canvas {
+ border: 1px solid silver;
+}
--- /dev/null
+{{include:_html_header.inc.html}}
+
+<div id="navigator">
+ <div id="backlink"><a href="javascript://" onclick="javascript:history.back();">戻る</a></div>
+ <a id="next2" href="javascript://" title="2ページ進む"><<</a>|<a id="next" href="javascript://" title="1ページ進む"><</a>|<a id="prior" href="javascript://" title="1ページ戻る">></a>|<a id="prior2" href="javascript://" title="2ページ戻る">>></a>
+</div>
+
+<div id="viewbox"><img id="viewbox_canvas" src="" /></div>
+
+<div id="system">
+ <p id="request_ix">{{ix}}</p>
+</div>
+
+{{include:_html_footer.inc.html}}
--- /dev/null
+
+pg = 0;
+
+$(function(){
+ page_read();
+ $(window).trigger("resize");
+});
+
+$( document ).keydown( function( e ) {
+ if( e.which === 37 ){
+ $("a#next").trigger("click");
+ }
+ if( e.which === 39 ){
+ $("a#prior").trigger("click");
+ }
+});
+
+
+$( window ).resize(function(){
+
+ h = $(window).height()*0.95 - $("div#header").height();
+
+ $("#viewbox_canvas").attr("height",h);
+
+});
+
+
+$(function() {
+ $("a#next").click(function(){
+ pg++;
+ page_read();
+ });
+});
+
+$(function() {
+ $("a#prior").click(function(){
+ pg--;
+ page_read();
+ });
+});
+
+$(function() {
+ $("a#next2").click(function(){
+ pg += 2;
+ page_read();
+ });
+});
+
+$(function() {
+ $("a#prior2").click(function(){
+ pg -= 2;
+ page_read();
+ });
+});
+
+
+function page_read() {
+
+ $("#viewbox_canvas").fadeOut("fast",function() {
+ $(this).attr("src","./page.php?ix="+$("#request_ix").html()+"&pg="+pg);
+ $(this).load(function () {
+ $(this).fadeIn("fast");
+ });
+ });
+
+}
+
+
--- /dev/null
+<?php
+
+include_once('./config/site.inc.php');
+
+$request__ix = check_request('ix',CV_MD5,'');
+
+$_HTML['ix'] = $request__ix;
+$_HTML['head_additional'] = '<script type="text/javascript" src="'.$obj_html->get_theme_file_url('viewer.js').'"></script>';
+
+echo $obj_html->apply('viewer.html');
+
+?>
\ No newline at end of file