--- /dev/null
+<?php
+
+include_once('./config/site.inc.php');
+
+$request__q = $my_cgi->check_request('q' ,'/^get|mark|remove|clear$/','get');
+$request__ix = $my_cgi->check_request('ix',cgi::CV_MD5,'');
+
+$request__pg = $my_cgi->check_request('pg' ,cgi::CV_DIGIT,'');
+$request__com = $my_cgi->check_request('com',cgi::CV_TEXT ,'');
+
+
+if (!file_exists(PATH_CACHE_IX.'/'.$request__ix.CACHE_IX_EXT_CX)) {
+ die('error');
+}
+
+
+$cx = file_get_contents(PATH_CACHE_IX.'/'.$request__ix.CACHE_IX_EXT_CX);
+
+
+switch ($request__q) {
+
+case 'mark':
+ // q = mark ブックマークの登録
+
+ $fid_mark = PATH_CACHE_CX.'/'.$cx.str_replace('?',$request__pg,CACHE_CX_EXT_MARK);
+
+ $mark = array(
+ 'pg' => $request__pg,
+ 'comment' => $request__com
+ );
+
+ file_put_contents($fid_mark,serialize($mark));
+
+ break;
+
+case 'remove':
+ // q = remove ブックマークの削除
+
+ $fid_mark = PATH_CACHE_CX.'/'.$cx.str_replace('?',$request__pg,CACHE_CX_EXT_MARK);
+ unlink($fid_mark);
+
+ break;
+
+case 'clear':
+ // q = clear ブックマークの全消去
+
+ foreach (glob(PATH_CACHE_CX.'/'.$cx.str_replace('?','*',CACHE_CX_EXT_MARK)) as $one) {
+ unlink($one);
+ }
+
+ break;
+
+}
+
+
+// q = get (省略可能) ブックマークリストの取得
+
+$json = array();
+$cnt = 0;
+
+foreach (glob(PATH_CACHE_CX.'/'.$cx.str_replace('?','*',CACHE_CX_EXT_MARK)) as $one) {
+
+ $mark = unserialize(file_get_contents($one));
+
+ $json['mark'][] = $mark;
+
+ $cnt++;
+}
+
+$json['count'] = $cnt;
+
+echo json_encode($json);
+
+?>
\ No newline at end of file
$index = array();
$idx = 0;
foreach ($dirs as $var => $val) {
- $comic .= '<a id="'.$idx.'"></a><h3>'.htmlspecialchars($var).'</h3>';
$index[] = '<a href="#'.$idx.'">'.$var.'</a>';
+ $series = '';
foreach ($val as $one) {
$hash = md5($one);
- file_put_contents(PATH_CACHE.'/index/'.$hash.'_dir.txt',$one);
- $comic .= '<a href="./browse.php?ix='.$hash.'">'.htmlspecialchars($one).'</a><br />';
+ file_put_contents(PATH_CACHE_IX.'/'.$hash.CACHE_IX_EXT_DIR,$one);
+ $series .= '<li><a href="./browse.php?ix='.$hash.'">'.htmlspecialchars($one).'</a></li>';
}
+ $comic .= '<a id="'.$idx.'"></a><h3>'.htmlspecialchars($var).'</h3>';
+ $comic .= '<ul class="series_list">'.$series.'</ul>';
$idx++;
}
// ファイルリストを出力
- $dir = file_get_contents(PATH_CACHE.'/index/'.$request__ix.'_dir.txt');
+ $dir = file_get_contents(PATH_CACHE_IX.'/'.$request__ix.CACHE_IX_EXT_DIR);
$files = scandir(PATH_COMIC.'/'.$dir);
- $html = '<a href="./browse.php">戻る</a>';
+ $html = '<a href="./browse.php">↵戻る</a>';
$html .= '<h3>'.htmlspecialchars($dir).'</h3>';
+ $html .= '<ul class="comic_list">';
foreach ($files as $one) {
if (preg_match('/.+\.zip$/usi',$one)) {
$path = $dir.'/'.$one;
$hash = md5($path);
- file_put_contents(PATH_CACHE.'/index/'.$hash.'_zip.txt',$path);
+ file_put_contents(PATH_CACHE_IX.'/'.$hash.CACHE_IX_EXT_ZIP,$path);
+
+ // ブックマークリストを作成する
+ $bookmark = '';
+ if (file_exists(PATH_CACHE_IX.'/'.$hash.CACHE_IX_EXT_CX)) {
+ $cx = file_get_contents(PATH_CACHE_IX.'/'.$hash.CACHE_IX_EXT_CX);
+ foreach (glob(PATH_CACHE_CX.'/'.$cx.str_replace('?','*',CACHE_CX_EXT_MARK)) as $path_to_mark) {
+ $mark = unserialize(file_get_contents($path_to_mark));
+ $bookmark .=
+ '<a href="./viewer.php?ix='.urlencode($hash).'&pg='.$mark['pg'].'" title="'.htmlspecialchars('P.'.$mark['pg'].' '.$mark['comment']).'">¶</a>'
+ ;
+ }
+ }
+ if ($bookmark!='') {
+ $bookmark = '<div class="bookmark_list">'.$bookmark.'</div>';
+ }
+
$title = mb_substr($one,0,mb_strlen($one)-4);
- $html .= '<a href="./viwer.php?ix='.urlencode($hash).'">'.htmlspecialchars($title).'</a><br />';
+ $html .= '<li><a href="./viewer.php?ix='.urlencode($hash).'&re='.htmlspecialchars('./browse.php?ix='.$request__ix).'">'.htmlspecialchars($title).'</a>'.$bookmark.'</li>';
}
}
+ $html .= '</ul>';
$my_html->set_value('comiclist',$html);
}
// キャッシュファイル識別用
-define('CACHE_EXT_INDEX','_idx.txt');
-define('CACHE_EXT_LIST' ,'_lst.txt');
+define('CACHE_IX_EXT_DIR' ,'_dir.txt'); // ディレクトリ、ハッシュ格納用
+define('CACHE_IX_EXT_ZIP' ,'_zip.txt'); // コミックZIP、ハッシュ格納用
+define('CACHE_IX_EXT_CX' ,'_cx.txt'); // コミックZIP、ハッシュ変換用(cache/comic)
+define('CACHE_CX_EXT_LIST','_list.txt'); // コミックZIP内エントリリスト保持用
+define('CACHE_CX_EXT_MARK','_mark#?.txt'); // ブックマーク保持用(?はページ番号に置き換わる)
// 定義した定数をすべてHTMLリソースに格納する
Cosmic : Simple Comic Server
===============================================================================
+■概要
+ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
+このシステムは、主にコミックを自炊してスキャニングしてる人、たくさんのZIP形式で
+コレクションしている人向けのコミックサーバーです。ZIPファイルを展開する必要はな
+く、コミック用に指定したディレクトリに置くだけで、ウェブ上で読むことのできるサ
+イトを提供します。 自宅サーバーや、VPSを借りている方なら、設置にかかる時間も僅
+か数分とお手軽です。
+
+Cosmic プロジェクトホーム
+http://landhere.info/cosmic.html
+
+※インターネット上で公開利用は、配信データの著作権に十分注意してください。
+
+※ZIP展開およびイメージ合成を都度行なっている関係上、不特定多数への配信には不向
+ きな仕様となっております。
+
+
+■システム要求
+ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
+・PHP5 が動作しているサーバー(ZIP、Image関数が利用可能なこと)
+・PHP5 の利用メモリ上限値 memory_limit = 128M (扱うコミックデータにより調整)
+
+
■インストール
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
1.ダウンロードしたアーカイブを展開してサーバーに転送してください
・キャッシュ生成方法の見直し
・ビューアキー割り当て追加
・自動ページ送りの実装
+・ビューアーのスペルミスを修正
+・ブックマークの実装
+・初期表示時のチラツキを改善
v0.12 2012-02-21
・libが含まれていなかった問題を修正
padding: 1em;
}
+/* ブックマークリスト */
+div.bookmark_list {
+ display: inline;
+}
+
+div.bookmark_list a {
+ margin: 0 0 0 1em;
+}
+
/* viewer.html -----------------------------------------------------*/
padding: 0 0.5em 0 0.5em;
}
-#toolbar a:link {
+#bookmark_menu a {
+ text-decoration: none;
+}
+
+#toolbar a:link,
+#bookmark_menu a:link {
color: gray;
}
-#toolbar a:visited {
+#toolbar a:visited,
+#bookmark_menu a:visited {
color: gray;
}
-#toolbar a:hover {
+#toolbar a:hover,
+#bookmark_menu a:hover {
color: orange;
background-color: #DDDDDD;
}
background-color: #DDDDDD;
cursor: pointer;
}
+
+#bookmark {
+ border: 1px solid gray;
+ background-color: white;
+ position: fixed;
+ top: -20.5em;
+ left: 10%;
+ height: 20em;
+ width: 80%;
+}
+
+ul#bookmark_menu {
+ list-style: none;
+ margin: 0.5em 0.5em 0 0.5em;
+ padding: 0;
+ background-color: silver;
+}
+
+ul#bookmark_menu li {
+ display: inline;
+ margin: 0 0.5em 0 0.5em;
+}
+
+#bookmark_body {
+ margin: 0 0.5em 0.5em 0.5em;
+ padding: 0.5em;
+ height: 16.5em;
+ overflow: scroll;
+ border: 1px solid silver;
+}
+
{{include:html_header.inc.html}}
+<div id="overlay_shadow"></div>
+
<div id="toolbar" class="_shadow" style="background-color:silver;overflow:hidden;">
<table class="layout _wfull"><tr>
<td class="_left _middle _nowrap">
- <a id="next2" href="javascript://" title="2ページ進む">«</a>
- <a id="next" href="javascript://" title="1ページ進む">‹</a>
- <span id="page" href="javascript://" title="">999 / 999</span>
- <a id="prior" href="javascript://" title="1ページ戻る">›</a>
- <a id="prior2" href="javascript://" title="2ページ戻る">»</a>
+ <a id="cmd_next2" href="javascript://" title="2ページ進む">«</a>
+ <a id="cmd_next" href="javascript://" title="1ページ進む">‹</a>
+ <span id="cmd_page" href="javascript://" title="">999 / 999</span>
+ <a id="cmd_prior" href="javascript://" title="1ページ戻る">›</a>
+ <a id="cmd_prior2" href="javascript://" title="2ページ戻る">»</a>
</td>
<td class="_left _middle">
<span id="title">{{SITE_NAME}}</span>
</td>
<td class="_right _middle _nowrap">
- <a id="auto" href="javascript://" title="自動ページ送り">▶</a>
- <!-- <a id="bookmark" href="javascript://" title="ブックマーク" onclick="">¶</a> -->
- <a id="back" href="javascript://" title="戻る" onclick="javascript:history.back();">↵</a>
+ <a id="cmd_auto" href="javascript://" title="自動ページ送り">▶</a>
+ <a id="cmd_bookmark" href="javascript://" title="ブックマーク" onclick="">¶</a>
+ <a id="cmd_back" href="javascript://" title="戻る" onclick="javascript:goback();">↵</a>
</td>
</tr></table>
</div>
+<div id="bookmark">
+ <div id="bookmark_header">
+ <ul id="bookmark_menu">
+ <li><a href="javascript://" onclick="javascript:bookmark_create();">+新規追加</a></li>
+ <li><a href="javascript://" onclick="javascript:bookmark_clear();">*すべて消去</a></li>
+ <li><a href="javascript://" onclick="javascript:$('#cmd_bookmark').trigger('click');">×閉じる</a></li>
+ </ul>
+ </div>
+ <div id="bookmark_body">
+ <ul id="bookmark_list">
+ </ul>
+ </div>
+</div>
+
<table id="viewbox" class="layout _wfull"><tr><td style="text-align:center;vertical-align:middle;">
<img class="_shadow" id="viewbox_canvas" src="" />
</td></tr></table>
<div id="system">
<p id="request_ix">{{ix}}</p>
+ <p id="request_pg">{{pg}}</p>
+ <p id="request_re">{{re}}</p>
</div>
{{include:html_footer.inc.html}}
+// 表示しているコミック識別用
+request__ix = '';
+request__pg = 1;
+request__re = '';
+
+
// ページ保持用変数
pg_cur = 1;
pg_max = 1;
auto_icon_off = "■";
+// 前のページに戻る
+function goback() {
+
+ if (request__re=='') {
+ history.back();
+ } else {
+ location.href = request__re;
+ }
+
+
+}
+
// ページロード時の処理
$(function() {
+ // 初期表示のチラツキを無くすために、ロード直後にフェードアウト
+ $("img#viewbox_canvas").fadeOut(0);
+
+ request__ix = $("#request_ix").html();
+ request__pg = Number($("#request_pg").html());
+ request__re = $("#request_re").html();
+
+ pg_cur = request__pg;
page_read();
});
// J
case 74:
- $("span#page").trigger("click");
+ $("#cmd_page").trigger("click");
break;
// A
});
-// ã\83\9aã\83¼ã\82¸ã\83£ã\82¤ã\83³ã\82¿ã\83¼ã\83\95ã\82§ã\82¤ã\82¹
+// ã\82¤ã\83\99ã\83³ã\83\88ã\83\8fã\83³ã\83\89ã\83©ã\81®å®\9a義
$(function() {
- $("a#next").click(function(){
+ $("#cmd_next").click(function(){
page_change(+1);
});
- $("a#prior").click(function(){
+ $("#cmd_prior").click(function(){
page_change(-1);
});
- $("a#next2").click(function(){
+ $("#cmd_next2").click(function(){
page_change(+2);
});
- $("a#prior2").click(function(){
+ $("#cmd_prior2").click(function(){
page_change(-2);
});
- $("span#page").click(function(){
+ $("#viewbox_canvas").click(function(){
+ page_change(+1);
+ });
+
+ $("#cmd_page").click(function(){
pg_new = prompt('移動するページ番号を入力してください',pg_cur);
if (pg_new != null) {
if (isNaN(pg_new)) {
alert('有効な数値を入力してください');
} else {
- pg_cur = 0;
- page_change(Number(pg_new));
+ page_jump(Number(pg_new));
}
}
});
- $("a#auto").click(function(){
+ $("#cmd_auto").click(function(){
if (auto_timerid == null) {
interval = prompt('自動ページ送り:表示間隔を秒数で入力してください','20');
if (interval != null) {
}
});
- $("a#bookmark").click(function(){
- comment = prompt('ブックマーク(Page='+pg_cur+'):コメントを入力して下さい','');
- if (comment != null) {
+ $("#cmd_bookmark").toggle(
+ function(){
+ $("#bookmark").css("display","block");
+ $("#bookmark").animate({
+ top: "0"
+ },300);
+ },
+ function(){
+ $("#bookmark").animate({
+ top: "-20.5em"
+ },300);
}
- });
+ );
});
}
+// ページ指定ジャンプ
+function page_jump(pg) {
+ pg_cur = 0;
+ page_change(pg);
+}
+
+
// ページを読み込んで表示する
function page_read() {
$("#viewbox_canvas").fadeOut("fast",function() {
- $(this).attr("src","./page.php?ix="+$("#request_ix").html()+"&pg="+pg_cur);
+ $(this).attr("src","./page.php?ix="+request__ix+"&pg="+pg_cur);
$(this).load(function () {
// 最初のページ読み込み後にコミックの情報を取得する
if (info_read==0) {
- $.getJSON("./info.json.php?q=page&ix="+$("#request_ix").html(), function(json){
+ $.getJSON("./comic.json.php?q=page&ix="+$("#request_ix").html(), function(json){
$("#title").text(json.path);
pg_max = json.page.max;
page_change_after();
});
+
+ $.getJSON("./bookmark.json.php?q=get&ix="+$("#request_ix").html(), function(json){
+ bookmark_parse(json);
+ });
+
info_read = 1;
} else {
function page_change_after() {
- $("#page").text(pg_cur + " / " + pg_max);
+ $("#cmd_page").text(pg_cur + " / " + pg_max);
$(window).trigger("resize");
}
}
+
+
+/* 新しいブックマークを追加 */
+function bookmark_create() {
+
+ comment = prompt('ブックマーク(P.'+pg_cur+'):コメントを入力して下さい','');
+ if (comment != null) {
+ $.post(
+ './bookmark.json.php',
+ {
+ 'q' : 'mark',
+ 'ix' : request__ix,
+ 'pg' : pg_cur,
+ 'com' : comment
+ },
+ function(data) {
+ json = $.parseJSON(data);
+ bookmark_parse(json);
+ }
+ );
+ }
+
+}
+
+/* ブックマークを削除 */
+function bookmark_remove(pg) {
+
+ $.post(
+ './bookmark.json.php',
+ {
+ 'q' : 'remove',
+ 'ix' : request__ix,
+ 'pg' : pg_cur
+ },
+ function(data) {
+ json = $.parseJSON(data);
+ bookmark_parse(json);
+ }
+ );
+
+}
+
+/* ブックマーク全消去 */
+function bookmark_clear() {
+
+ if (confirm('登録されているブックマークをすべて消去しますか?')) {
+ $.post(
+ './bookmark.json.php',
+ {
+ 'q' : 'clear',
+ 'ix' : request__ix
+ },
+ function(data) {
+ json = $.parseJSON(data);
+ bookmark_parse(json);
+ }
+ );
+ }
+
+}
+
+// 受け取ったjsonデータをメニューに表示
+function bookmark_parse(json) {
+
+ $("#bookmark_list").empty();
+
+ for (i=0;i<json.count;i++) {
+ li =
+ "<li><a href=\"javascript://\" onclick=\"javascript:bookmark_click("+json.mark[i].pg+");\">"+
+ json.mark[i].comment+"(P."+json.mark[i].pg+")</a> "+
+ "<a href=\"javascript://\" onclick=\"javascript:bookmark_remove("+json.mark[i].pg+");\">×削除</a>"+
+ "</li>"
+ ;
+ $("#bookmark_list").append(li);
+ }
+
+}
+
+// ブックマークの全消去
+function bookmark_click(pg) {
+ page_jump(pg);
+ $('#cmd_bookmark').trigger('click');
+}
include_once('./config/site.inc.php');
-$request__ix = $my_cgi->check_request('ix',cgi::CV_MD5,'');
+$request__ix = $my_cgi->check_request('ix',cgi::CV_MD5 ,'');
+$request__pg = $my_cgi->check_request('pg',cgi::CV_DIGIT,1);
+$request__re = $my_cgi->check_request('re',cgi::CV_TEXT,'');
$my_html->set_value('head_additional',$my_html->mktag_script($my_html->get_theme_file_url('viewer.js')));
$my_html->set_value('ix',$request__ix);
+$my_html->set_value('pg',$request__pg);
+$my_html->set_value('re',$request__re);
$my_html->apply_template('viewer.html',html::REMOVE_UNDEF_TAGS,html::OUTPUT_HTML);