[Hiki-dev:00918] hiki-mode.el

Back to archive index

Takeshi UME Imai takes****@tt*****
2005年 7月 9日 (土) 01:15:02 JST


今井といいます。

#usersの話題ですが、今、devにしか登録していないので、こちらに投げます。

hiki-mode.elでログイン/ログアウトできるようにしてみました。

ログインは一覧表示で"I"を押すとUsernameとPasswordを聞いてくるので、そ
れぞれ入力して下さい。

ログアウトは一覧表示で"O"です。

http.elを修正する必要があったので、http.elのコードをhiki-mode.elに取り
込んで、hiki-mode.el単体で動作するようにしました。

Emacs Lispをいじるのはほとんど初めてみたいなものなので、あまりよいコー
ドではないかもしれませんが、よかったら使ってやって下さい。

--- hiki-mode.el.orig	2005-07-09 00:13:54.000000000 +0900
+++ hiki-mode.el	2005-07-09 01:01:11.000000000 +0900
@@ -35,8 +35,18 @@
 ;;
 
 ;;; Variable:
+(require 'pces)
+
+(defvar hiki-http-proxy-server nil "Proxy server for HTTP.")
+(defvar hiki-http-proxy-port   nil "Proxy port for HTTP.")
+
+(defvar hiki-http-timeout 10
+  "Timeout for HTTP.")
+
+(defvar hiki-http-cookie nil)
+
+(defvar hiki-freeze nil)
 
-(require 'http)
 (if (or (featurep 'xemacs) (not (boundp 'emacs-major-version)) (< emacs-major-version 21))
     (progn
       (require 'poe)
@@ -243,10 +253,10 @@
   (let (url buf)
     (setq url (concat (format "%s?c=%s" site-url cmd)
 		      (if pagename 
-			  (format ";p=%s" (http-url-hexify-string pagename hiki-coding-system)))
+			  (format ";p=%s" (hiki-http-url-hexify-string pagename hiki-coding-system)))
 		      ""))
-    (setq buf (http-fetch url mode nil nil 
-			  (http-url-hexify-alist post-data hiki-coding-system)))
+    (setq buf (hiki-http-fetch url mode nil nil 
+			  (hiki-http-url-hexify-alist post-data hiki-coding-system)))
     (if (bufferp buf)
 	(save-excursion
 	  (set-buffer buf)
@@ -318,7 +328,7 @@
 	(error "Illegal URL. (%s)" str)))
     (setq site-info (list url url))
     (hiki-edit-page 
-     (http-url-unhexify-string pagename hiki-coding-system) site-info)))
+     (hiki-http-url-unhexify-string pagename hiki-coding-system) site-info)))
 
 (defun hiki-edit-quit ()
   (interactive)
@@ -404,6 +414,8 @@
   (define-key hiki-index-mode-map "R" 'hiki-index-refetch-index)
   (define-key hiki-index-mode-map "q" 'hiki-index-suspend)
   (define-key hiki-index-mode-map "Q" 'hiki-index-quit)
+  (define-key hiki-index-mode-map "I" 'hiki-index-login)
+  (define-key hiki-index-mode-map "O" 'hiki-index-logout)
   )
 
 (defun hiki-index (&optional site-info refetch pagename)
@@ -599,6 +611,33 @@
     (setq hiki-page-buffer-alist tmp)
     (kill-buffer (current-buffer))))
 
+(defun hiki-index-login ()
+  (interactive)
+  (let (username password post-data buf)
+    (sit-for 0.1)
+    (setq username (read-from-minibuffer (format "Username for %s: " (car hiki-site-info))))
+    (setq password (read-passwd (format "Password for %s: " (car hiki-site-info))))
+    (add-to-list 'post-data (cons "c" "login"))
+    (add-to-list 'post-data (cons "name" username))
+    (add-to-list 'post-data (cons "password" password))
+    (setq buf (hiki-http-request 'post nil nil (hiki-site-url) post-data))
+    (set-buffer buf)
+    (goto-char (point-min))
+    (if (re-search-forward "HTTP/1.[01] \\([0-9][0-9][0-9]\\) \\(.*\\)" nil t)
+	(let ((code (match-string 1))
+	      (desc (match-string 2)))
+	  (cond ((equal code "302")
+		 (message "Logged in."))
+		(t
+		 (message "Username and/or Password is wrong!!.")))))))
+
+(defun hiki-index-logout ()
+  (interactive)
+  (let (post-data buf)
+    (add-to-list 'post-data (cons "c" "logout"))
+    (setq buf (hiki-http-request 'post nil nil (hiki-site-url) post-data))
+    (message "Logged out.")))
+
 ;;; func
 
 (defun hiki-display-page (pagename site-info &optional refetch)
@@ -654,10 +693,6 @@
   "PAGENAME の編集モードに入る。バッファを返す。"
   (let ((result (hiki-display-page pagename site-info t)))
     (when result
-      (if (setq password (cdr (assq 'password result)))
-	  (or (hiki-password-read (car site-info) pagename)
-	      (hiki-password-store  (car site-info) pagename t))
-	(hiki-password-store (car site-info) pagename nil))
       (setq hiki-md5hex (cdr (assq 'md5hex result)))
       (setq hiki-pagename pagename)
       (setq hiki-pagetitle (or (cdr (assq 'pagetitle result)) pagename))
@@ -681,7 +716,7 @@
 	  (re-search-forward "<a[^?]*\\?\\([^\"]*\\)\"[^>]*>\\([^<]*\\)</a>: \\([^<]*\\)</li>" nil t nil)
 	  (setq indexes 
 		(cons
-		 (list i (http-url-unhexify-string (match-string 1) hiki-coding-system)
+		 (list i (hiki-http-url-unhexify-string (match-string 1) hiki-coding-system)
 
 		       (hiki-replace-entity-refs (match-string 2))
 		       (hiki-replace-entity-refs (match-string 3))) indexes))
@@ -726,8 +761,8 @@
 	  (setq result (cons (cons 'keyword (hiki-replace-entity-refs (buffer-substring start end))) result)))
 	;; frozen?
 	(if (re-search-forward "<input type=\"checkbox\" name=\"freeze\" value=\"on\" checked>" nil t nil)
-	    (setq result (cons (cons 'password t) result))
-	  (setq result (cons (cons 'password nil) result)))))
+	    (setq hiki-freeze t)
+	  (setq hiki-freeze nil))))
     result))
 
 (defun hiki-edit-save-page (&optional toggle)
@@ -735,10 +770,6 @@
   (let (buf contents post-data pagetitle password freeze keywords result)
     (message "Sending... ")
     (sit-for 0.1)
-    (setq password (hiki-password-read (car hiki-site-info) hiki-pagename)
-	  freeze (if toggle (not password) (if password t)))
-    (if (or (eq t password) (and freeze (not password)))
-	(setq password (read-passwd (format "Password for [%s] %s: " (car hiki-site-info) hiki-pagename))))
     (setq pagetitle (read-from-minibuffer
 		     (format "Page title for [%s] %s: " (car hiki-site-info) hiki-pagename)
 		     (or hiki-pagetitle hiki-pagename) nil nil nil (or hiki-pagetitle hiki-pagename)))
@@ -755,8 +786,8 @@
     (add-to-list 'post-data (cons "keyword" (or keywords "")))
     (add-to-list 'post-data (cons "md5hex" hiki-md5hex))
     (add-to-list 'post-data (cons "password" password))
-    (and password freeze
-	 (add-to-list 'post-data (cons "freeze" "on")))
+    (if (not (null hiki-freeze))
+	(add-to-list 'post-data (cons "freeze" "on")))
     (add-to-list 'post-data (cons "contents" contents))
     (add-to-list 'post-data (cons "save" "save"))
     (setq buf 
@@ -901,7 +932,6 @@
   "STR の先頭を WIDTH文字を取り出す。
 
 WIDTH に満たない場合は、末尾に空白がパディングされる。"
-
   (let (l (result "")
 	(w (string-width str)))
     (if (< w width)
@@ -916,7 +946,7 @@
 
 ;;; Util (http-*)
 
-(defun http-url-unhexify-string (str coding)
+(defun hiki-http-url-unhexify-string (str coding)
   "Unescape characters in a string."
   (save-match-data
     (let ((result (string-as-unibyte str)) (pos -1))
@@ -932,11 +962,113 @@
 	       t t result)))
       (decode-coding-string result coding))))
 
-(defun http-url-hexify-alist (alist coding)
+(defun hiki-http-url-hexify-alist (alist coding)
   (mapcar 
    (lambda (c) 
-     (cons (car c) (and (cdr c) (http-url-hexify-string (cdr c) coding))))
+     (cons (car c) (and (cdr c) (hiki-http-url-hexify-string (cdr c) coding))))
    alist))
 
+;; derived from url.el
+(defconst hiki-http-url-unreserved-chars
+  '(
+    ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
+    ?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z
+    ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
+    ?$ ?- ?_ ?. ?! ?~ ?* ?' ?\( ?\) ?,)
+  "A list of characters that are _NOT_ reserve in the URL spec.
+This is taken from draft-fielding-url-syntax-02.txt - check your local
+internet drafts directory for a copy.")
+
+;; derived from url.el
+(defun hiki-http-url-hexify-string (str coding)
+  "Escape characters in a string.
+At first, encode STR using CODING, then url-hexify."
+  (mapconcat
+   (function
+    (lambda (char)
+      (if (not (memq char hiki-http-url-unreserved-chars))
+          (if (< char 16)
+              (upcase (format "%%0%x" char))
+            (upcase (format "%%%x" char)))
+        (char-to-string char))))
+   (encode-coding-string str coding) ""))
+
+(defun hiki-http-fetch (url method &optional user pass data)
+  "Fetch via HTTP.
+
+URL is a url to be POSTed.
+METHOD is 'get or 'post.
+USER and PASS must be a valid username and password, if required.  
+DATA is an alist, each element is in the form of (FIELD . DATA).
+
+If no error, return a buffer which contains output from the web server.
+If error, return a cons cell (ERRCODE . DESCRIPTION)."
+  (let (connection server port path buf str len)
+    (string-match "^http://\\([^/:]+\\)\\(:\\([0-9]+\\)\\)?\\(/.*$\\)" url)
+    (setq server (match-string 1 url)
+          port (string-to-int (or (match-string 3 url) "80"))
+          path (if hiki-http-proxy-server url (match-string 4 url)))
+    (setq str (mapconcat
+               '(lambda (x)
+                  (concat (car x) "=" (cdr x)))
+               data "&"))
+    (setq len (length str))
+    (save-excursion
+      (setq buf (get-buffer-create (concat "*result from " server "*")))
+      (set-buffer buf)
+      (erase-buffer)
+      (setq connection
+            (as-binary-process
+             (open-network-stream (concat "*request to " server "*")
+                                  buf
+                                  (or hiki-http-proxy-server server)
+                                  (or hiki-http-proxy-port port))))
+      (process-send-string
+       connection
+       (concat (if (eq method 'post)
+                   (concat "POST " path)
+                 (concat "GET " path (if (> len 0)
+                                         (concat "?" str))))
+               " HTTP/1.0\r\n"
+               (concat "Host: " server "\r\n")
+	       (if (not (null hiki-http-cookie))
+		   (concat "Cookie: session_id=" (cdr (assoc 'session-id hiki-http-cookie))
+			   "\r\n"))
+               "Connection: close\r\n"
+               "Content-type: application/x-www-form-urlencoded\r\n"
+               (if (and user pass)
+                   (concat "Authorization: Basic "
+                           (base64-encode-string
+                            (concat user ":" pass))
+                           "\r\n"))
+               (if (eq method 'post)
+		   (concat "Content-length: " (int-to-string len) "\r\n"
+			   "\r\n"
+			   str))
+               "\r\n"))
+      (goto-char (point-min))
+      (while (not (search-forward "</body>" nil t))
+        (unless (accept-process-output connection hiki-http-timeout)
+          (error "HTTP fetch: Connection timeout!"))
+        (goto-char (point-min)))
+      (goto-char (point-min))
+      (save-excursion
+        (if (re-search-forward "HTTP/1.[01] \\([0-9][0-9][0-9]\\) \\(.*\\)" nil t)
+            (let ((code (match-string 1))
+                  (desc (match-string 2)))
+	      (if (re-search-forward "Set-Cookie: session_id=\\([^;]+\\);.*" nil t)
+		  (let ((session-id (match-string 1)))
+		    (setq hiki-http-cookie (list
+					    (cons 'session-id session-id)))))
+	      (cond ((equal code "200")
+                     buf)
+		    ((equal code "302")
+		     buf)
+		    (t
+                     (cons code desc)))))))))
+
+(defun hiki-http-cookie-expired ()
+  (setq hiki-http-cookie nil))
+
 (provide 'hiki-mode)
 ;;; hiki-mode.el ends here









Hiki-dev メーリングリストの案内
Back to archive index