javascriptをいじってたらIEで動かなくなってしまった。
Win7 64nit + CCL + Chrome で動作確認。
いまいちセッションの取り扱いがわからない。
一人用だし、グローバル変数にぶち込んで使うのもありかな?
parenscriptを使ってみようと呼び出してるけど使っていない。
*default-directory* を設定して、ファイルを配置して load したら、(2ch-editor:start-2ch-server)で localhost:8080で使用可能。
名前がeditorってなってるのは、まとめブログの支援ツールにしようと思ったんだけど、セッションがわからなかったので断念したから。。。
2ch-view.lisp
(eval-when (:compile-toplevel :load-toplevel :execute)
(require :hunchentoot)
(require :cl-who)
(require :drakma)
(require :jp)
(require :cl-ppcre)
(require :parenscript))
(defpackage :2ch-editor
(:use :cl :hunchentoot :cl-who :drakma :jp :cl-ppcre :parenscript)
(:shadow :COOKIE-VALUE
:*HEADER-STREAM*
:PARAMETER-ERROR
:COOKIE-NAME
:COOKIE-DOMAIN
:COOKIE-PATH
:COOKIE-EXPIRES)
(:export #:main #:start-2ch-server #:stop-2ch-server))
;; 参考
;; Common Lisp で Web アプリを作るためのブランクプロジェクト
;; http://read-eval-print.blogspot.com/2011/02/common-lisp-web.html
(in-package :2ch-editor)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 環境設定
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defparameter *default-directory*
(pathname "c:/export/home/clisp/2ch-web/")
"このファイルがあるディレクトリを指定")
(defparameter *js-path* (merge-pathnames "js/" *default-directory*)
"JavaScript 用ディレクトリ")
(defparameter *css-path* (merge-pathnames "css/" *default-directory*)
"スタイルシート用ディレクトリ")
;; 文字コードを設定
(setf
;; for utf-8
hunchentoot:*hunchentoot-default-external-format* (flexi-streams:make-external-format :utf-8)
hunchentoot:*default-content-type* "text/html; charset=utf-8"
;; for debug
hunchentoot:*catch-errors-p* nil)
;; スタイルシートと、javascriptディレクトリをアクセス可能にする。
(setf hunchentoot:*dispatch-table*
(list
'hunchentoot:dispatch-easy-handlers
(hunchentoot:create-folder-dispatcher-and-handler "/css/" *css-path*)
(hunchentoot:create-folder-dispatcher-and-handler "/js/" *js-path*)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 汎用関数
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar *port8080-acceptor* (make-instance 'hunchentoot:acceptor :port 8080)
"hunchentootの起動ポートを指定する")
(defun start-2ch-server ()
"Web サーバ起動"
(start *port8080-acceptor*))
(defun stop-2ch-server ()
"Web サーバ停止"
(stop *port8080-acceptor*))
(defmacro with-default-template ((&key (title "題名")
(charset "UTF-8")) &body body)
"ページのテンプレート"
`(with-html-output-to-string (out nil :indent t :prologue t)
(htm (:html :lang "ja"
(:head
(:meta :charset ,charset :http-equiv "Content-Type" :content="text/html")
(:title ,title)
(:link :rel "stylesheet" :href "css/main.css" :media "all")
(:script :type "text/javascript" :scr "js/prototype.js")
(:script :type "text/javascript" :src "js/main.js"))
(:body ,@body)))))
;; 各スレッドの情報を格納する
(defclass res ()
((num :initarg :num)
(name :initarg :name)
(mail :initarg :mail)
(date :initarg :date)
(text :initarg :text)
(flag :initarg :flag)))
(defun http-request-jp (url)
"ページをバイナリで取得しデコードして表示する。たまに変な文字コードが混ざるので消しておく"
(delete #\Return (jp:decode (http-request url :force-binary t) :guess)))
(defun delete-html-tag (text)
"タグを除去する"
(cl-ppcre:regex-replace-all "<[/a-zA-Z]+>" text ""))
(defvar *thread-db* nil
"編集済みのスレッド情報を格納する変数")
(defvar *thread-db-path* "thread.db"
"スレッドDBのパス")
(defun load-thread-db ()
"スレッドDBをロードする。"
)
(defun save-thread-db ()
"スレッドDBをセーブする。"
)
(defun main ()
"メイン処理を開始する"
(load-thread-db)
(start-2ch-server))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; トップページ /
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun get-bbslist-from-bbmenu ()
"bbsmenuから余分なHTMLを削除したリストのリストを得る。この時点ではアンカータグは残っている"
(mapcar #'(lambda (x) (cl-ppcre:split #\Linefeed x))
(remove-if #'(lambda (x) (cl-ppcre:scan "(<HTML>|</HTML>|まちBBS|ツール類|チャット|-->)" x))
(cl-ppcre:split "<BR><BR>" (http-request-jp "http://menu.2ch.net/bbsmenu.html")))))
(defun edit-bbssublist (bbslist)
"カテゴリ別のリストを受け取り、タグを削除する"
(loop for i in bbslist
collect (mapcar #'(lambda (x) (delete-tag-from-a-bbsmenu x)) i)))
(defun delete-tag-from-a-bbsmenu (text)
"BBSMENUのタグを削除する"
(cond
((cl-ppcre:scan "(<B>|</B>)" text)
(cl-ppcre:register-groups-bind (first) ("<B>(.+)</B>" text)
first))
((cl-ppcre:scan "<A HREF=http://.+\\.2ch\\.net/.+/>" text)
(cl-ppcre:register-groups-bind (url bkey name) ("<A HREF=(http://.+\\.2ch\\.net/)(.+)/>(.+)</A>" text)
(list name url bkey)))
((cl-ppcre:scan "<A HREF=http://.+\\.bbspink\\.com/.+>" text)
(cl-ppcre:register-groups-bind (url bkey name) ("<A HREF=(http://.+\\.bbspink\\.com/)(.+)/>(.+)</A>" text)
(list name url bkey)))
(t nil)))
(defun root-html ()
"トップページを生成"
(with-default-template (:title "板一覧")
(loop for category in (edit-bbssublist (get-bbslist-from-bbmenu))
for counter from 1 to 1000
do (progn
(htm
(:table :border 0 ;; :style "float:left;"
(loop for i in category
for j from 1 to 1000
do (if i
(if (not (listp i))
(htm (:tr (:td (:div :onclick (concatenate 'string
"javascript:menushow(" (princ-to-string counter) ");")
(:b (:font :color "gray" (str "■") (str i)))))))
(htm (:tr :style "display:none;"
:name (concatenate 'string "counter" (princ-to-string counter))
:id (concatenate 'string "counter_" (princ-to-string counter) "_" (princ-to-string j))
(:td (:a :href (concatenate 'string
"index?url="
(url-encode (second i))
"&bkey="
(url-encode (third i))
"&title="
(url-encode (first i)))
(str (first i)))))))))))
))))
;; トップページを作成
(define-easy-handler (top :uri "/") ()
(setf (hunchentoot:content-type*) "text/html; charset=utf-8")
(root-html))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; スレッド一覧 /index
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun get-thread-subject (url bkey)
"スレッド一覧を取得する"
(let ((burl (concatenate 'string url bkey "/subject.txt")))
(http-request-jp burl)))
(defun make-thread-list (text)
"取得したスレッドをリストに分解する"
(let ((var (mapcar #'(lambda (x) (cl-ppcre:split "<>" x))
(cl-ppcre:split #\LineFeed text))))
(loop for i in var
collect (cl-ppcre:register-groups-bind (title num)
("\(\^.+\)\\(\([0-9]+\)\\)$" (second i))
(list (first i) title num)))))
(defun make-thread-html (list url bkey title)
"スレッド一覧を表示するHTMLを構築"
(with-default-template (:title "スレッド一覧")
(htm (:font :color "red" (str title)) :br)
(htm (:table :border 0
(loop for (dat title num) in list
do (htm (:tr
:onmouseover "this.style.background=\"#FFFACD\""
:onmouseout "this.style.background=\"#ffffff\""
(htm (:td :align "right" (str num)))
;; (htm (:td (:a :href (concatenate 'string "edit?"
;; "dat=" (url-encode dat)
;; "&url=" (url-encode url)
;; "&bkey=" (url-encode bkey))
;; :target "_blank" (:font :size "-1" (str "編集")))))
(htm (:td))
(htm (:td (:a :href (concatenate 'string "view?"
"dat=" (url-encode dat)
"&url=" (url-encode url)
"&bkey=" (url-encode bkey))
:target "_blank" (str title)))))))
))))
(defun index-html (url bkey title)
"スレッド一覧を表示する。"
(make-thread-html (make-thread-list (get-thread-subject url bkey)) url bkey title))
(define-easy-handler (index :uri "/index") (url bkey title)
(setf (hunchentoot:content-type*) "text/html; charset=utf-8")
(index-html url bkey title))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; スレッドビュー /view
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun get-thread-dat (url bkey dat)
"スレッドDATを取得する。"
(let ((burl (concatenate 'string
(url-decode url)
(url-decode bkey) "/dat/"
(url-decode dat))))
(http-request-jp burl)))
(defun make-thread-res-list (text)
"DATを分解して配列に格納する。"
(let ((i 1)
(result nil))
(loop for res in (cl-ppcre:split #\LineFeed text)
do (let ((temp (cl-ppcre:split "<>" res)))
(when (= i 1)
(push (make-instance 'res :num 0 :text (car (last temp))) result)
(push (make-instance 'res
:num i
:name (delete-html-tag (first temp))
:mail (second temp)
:date (third temp)
:text (fourth temp)
:flag nil) result))
(when (not (= i 1))
(push (make-instance 'res
:num i
:name (delete-html-tag (first temp))
:mail (second temp)
:date (third temp)
:text (fourth temp)
:flag nil) result))
(incf i)))
(reverse result)))
(defun thread-html (url bkey dat)
"スレッドを展開してHTML化"
(let ((res (make-thread-res-list (get-thread-dat url bkey dat))))
(setf (session-value 'thread-data) res)
(with-default-template (:title "スレエディット")
(htm
(loop for i in res
do (cond
((= 0 (slot-value i 'num))
(htm (:a :href
(concatenate 'string url "test/read.cgi/" bkey "/" (cl-ppcre:regex-replace "\\.dat$" dat ""))
:target "_blank"
(:font :color "red" (:b (str (slot-value i 'text)))) :br :br)))
(t (progn
(htm (:hr)
(:div :id (concatenate 'string "thread" (princ-to-string (slot-value i 'num)))
:onmouseover "this.style.background=\"#FFFACD\""
:onmouseout "this.style.background=\"#ffffff\""
(:dl (:dt
(htm (str (slot-value i 'num))
(:b :style "color:forestgreen;" (str (slot-value i 'name)))
(str (concatenate 'string "[" (slot-value i 'mail) "] "))
(str (slot-value i 'date)) :br))
(htm (:dd (str (slot-value i 'text)) :br :br)))))))))))))
(define-easy-handler (view :uri "/view") (url bkey dat)
(setf (hunchentoot:content-type*) "text/html; charset=utf-8")
(thread-html url bkey dat))
main.js
function resDispSwitch(num)
{
var foo = document.getElementById('thread' + num);
foo.style.display =
(foo.style.display == 'none')
? 'block' : 'none';
}
function selectRes(num)
{
var foo = document.getElementById('selectRes' + num);
foo.checked =
(foo.checked == true)
? false : true;
}
function menushow(num)
{
var elements = document.getElementsByName('counter' + num);
for (var i = 0; i < elements.length; i ++) {
elements[i].style.display =
(elements[i].style.display == 'none' )
? 'block' : 'none';
}
}
0 件のコメント:
コメントを投稿