* mixi.el (mixi-post-error): New error symbol.
authorbg66 <bg66>
Tue, 26 Dec 2006 06:59:29 +0000 (06:59 +0000)
committerbg66 <bg66>
Tue, 26 Dec 2006 06:59:29 +0000 (06:59 +0000)
(mixi-post-error): New macro.
(mixi-post-form): New macro.
(mixi-make-form-data): New function.
(mixi-url-retrieve): Add optional argument `extra-headers'.
(mixi-url-post-form): New function.
(mixi-w3m-post-form): Ditto.
(with-mixi-post-form): New macro.
(mixi-post-diary-key-regexp): New constant.
(mixi-post-diary-id-regexp): Ditto.
(mixi-post-diary-title-regexp): Ditto.
(mixi-post-diary-body-regexp): Ditto.
(mixi-post-diary-succeed-regexp): Ditto.
(mixi-post-diary): New function.

ChangeLog
mixi.el

index dd543e7..77ec275 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2006-12-26  OHASHI Akira  <bg66@koka-in.org>
 
+       * mixi.el (mixi-post-error): New error symbol.
+       (mixi-post-error): New macro.
+       (mixi-post-form): New macro.
+       (mixi-make-form-data): New function.
+       (mixi-url-retrieve): Add optional argument `extra-headers'.
+       (mixi-url-post-form): New function.
+       (mixi-w3m-post-form): Ditto.
+       (with-mixi-post-form): New macro.
+       (mixi-post-diary-key-regexp): New constant.
+       (mixi-post-diary-id-regexp): Ditto.
+       (mixi-post-diary-title-regexp): Ditto.
+       (mixi-post-diary-body-regexp): Ditto.
+       (mixi-post-diary-succeed-regexp): Ditto.
+       (mixi-post-diary): New function.
+
+2006-12-26  OHASHI Akira  <bg66@koka-in.org>
+
        * mixi.el (mixi-url-retrieve): Simplify.
 
 2006-12-25  OHASHI Akira  <bg66@koka-in.org>
diff --git a/mixi.el b/mixi.el
index fc7abf0..e5af222 100644 (file)
--- a/mixi.el
+++ b/mixi.el
@@ -211,12 +211,23 @@ Increase this value when unexpected error frequently occurs."
 (put 'mixi-realization-error
      'error-conditions '(mixi-realization-error error))
 
+(put 'mixi-post-error
+     'error-message (mixi-message "Cannot post"))
+(put 'mixi-post-error
+     'error-conditions '(mixi-post-error error))
+
 (defmacro mixi-realization-error (type object)
   `(let ((data (if (and (boundp 'buffer) debug-on-error)
                   (list ,type ,object buffer)
                 (list ,type ,object))))
      (signal 'mixi-realization-error data)))
 
+(defmacro mixi-post-error (type)
+  `(let ((data (if (and (boundp 'buffer) debug-on-error)
+                  (list ,type buffer)
+                (list ,type))))
+     (signal 'mixi-post-error data)))
+
 (defconst mixi-message-adult-contents
   "¤³¤Î¥Ú¡¼¥¸¤«¤éÀè¤Ï¥¢¥À¥ë¥È¡ÊÀ®¿Í¸þ¤±¡Ë¥³¥ó¥Æ¥ó¥Ä¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£<br>
 ±ÜÍ÷¤ËƱ°Õ¤µ¤ì¤¿Êý¤Î¤ß¡¢Àè¤Ø¤ª¿Ê¤ß¤¯¤À¤µ¤¤¡£")
@@ -232,6 +243,14 @@ Increase this value when unexpected error frequently occurs."
 (defmacro mixi-retrieve (url &optional post-data)
   `(funcall mixi-retrieve-function ,url ,post-data))
 
+;; FIXME: Change `mixi-retrieve-function' to `mixi-backend'.
+(defmacro mixi-post-form (url fields)
+  `(let ((name (symbol-name mixi-retrieve-function)))
+     (when (string-match "-\\([a-z]+\\)-" name)
+       (let ((func (intern (concat "mixi-" (match-string 1 name)
+                                  "-post-form"))))
+        (funcall func ,url ,fields)))))
+
 (defun mixi-parse-buffer (url buffer &optional post-data)
   (when (string-match mixi-message-adult-contents buffer)
     (if mixi-accept-adult-contents
@@ -251,10 +270,27 @@ Increase this value when unexpected error frequently occurs."
        ,url
      (concat mixi-url ,url)))
 
-(defun mixi-url-retrieve (url &optional post-data)
+;; FIXME: Support file, checkbox and so on.
+(defun mixi-make-form-data (fields)
+  "Make form data and eturn (CONTENT-TYPE . FORM-DATA)."
+  (let* ((boundary (apply 'format "--_%d_%d_%d" (current-time)))
+        (content-type (concat "multipart/form-data; boundary=" boundary))
+        (form-data
+         (mapconcat
+          (lambda (field)
+            (concat "--" boundary "\r\n"
+                    "Content-Disposition: form-data; name=\""
+                    (car field) "\"\r\n"
+                    "\r\n"
+                    (encode-coding-string (cdr field) mixi-coding-system)))
+          fields "\r\n")))
+    (cons content-type (concat form-data "\r\n--" boundary "--"))))
+
+(defun mixi-url-retrieve (url &optional post-data extra-headers)
   "Retrieve the URL and return gotten strings."
   (let* ((url-request-method (if post-data "POST" "GET"))
         (url-request-data post-data)
+        (url-request-extra-headers extra-headers)
         (url (mixi-expand-url url))
         (buffer (url-retrieve-synchronously url))
         ret)
@@ -271,6 +307,11 @@ Increase this value when unexpected error frequently occurs."
       (kill-buffer buffer)
       (mixi-parse-buffer url ret post-data))))
 
+(defun mixi-url-post-form (url fields)
+  (let* ((form-data (mixi-make-form-data fields))
+        (extra-headers `(("Content-Type" . ,(car form-data)))))
+    (mixi-url-retrieve url (cdr form-data) extra-headers)))
+
 (defun mixi-w3m-retrieve (url &optional post-data)
   "Retrieve the URL and return gotten strings."
   (let ((url (mixi-expand-url url)))
@@ -281,6 +322,10 @@ Increase this value when unexpected error frequently occurs."
        (let ((ret (buffer-substring-no-properties (point-min) (point-max))))
          (mixi-parse-buffer url ret post-data))))))
 
+(defun mixi-w3m-post-form (url fields)
+  (let ((form-data (mixi-make-form-data fields)))
+    (mixi-w3m-retrieve url form-data)))
+
 (defun mixi-curl-retrieve (url &optional post-data)
   "Retrieve the URL and return gotten strings."
   (with-temp-buffer
@@ -357,6 +402,18 @@ Increase this value when unexpected error frequently occurs."
 (put 'with-mixi-retrieve 'lisp-indent-function 'defun)
 (put 'with-mixi-retrieve 'edebug-form-spec '(form body))
 
+(defmacro with-mixi-post-form (url fields &rest body)
+  `(let (buffer)
+     (when ,url
+       (setq buffer (mixi-post-form ,url ,fields))
+       (when (string-match "<form action=\"login\\.pl\" method=\"post\">"
+                          buffer)
+        (mixi-login)
+        (setq buffer (mixi-post-form ,url ,fields))))
+     ,@body))
+(put 'with-mixi-post-form 'lisp-indent-function 'defun)
+(put 'with-mixi-post-form 'edebug-form-spec '(form body))
+
 (defun mixi-get-matched-items (url regexp &optional range)
   "Get matched items to REGEXP in URL."
   (let ((page 1)
@@ -1195,6 +1252,51 @@ Increase this value when unexpected error frequently occurs."
              (mixi-make-diary (mixi-make-friend (nth 1 item)) (nth 0 item)))
            items)))
 
+(defconst mixi-post-diary-key-regexp
+  "<input type=hidden name=post_key value=\"\\([a-z0-9]+\\)\">")
+(defconst mixi-post-diary-id-regexp
+  "<input type=\"hidden\" name=\"id\" value=\"\\([0-9]+\\)\">")
+(defconst mixi-post-diary-title-regexp
+  "<input type=hidden name=diary_title value=\"\\([^\"]+\\)\">")
+(defconst mixi-post-diary-body-regexp
+  "<input type=hidden name=diary_body value=\"\\([^\"]+\\)\">")
+(defconst mixi-post-diary-succeed-regexp
+  "<b>ºîÀ®¤¬´°Î»¤·¤Þ¤·¤¿¡£È¿±Ç¤Ë»þ´Ö¤¬¤«¤«¤ë¤³¤È¤¬¤¢¤ê¤Þ¤¹¤Î¤Ç¡¢É½¼¨¤µ¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤Ï¾¯¡¹¤ªÂÔ¤Á¤¯¤À¤µ¤¤¡£</b>")
+
+;; FIXME: Support photos.
+(defun mixi-post-diary (title content)
+  "Post a diary."
+  (unless (stringp title)
+    (signal 'wrong-type-argument (list 'stringp title)))
+  (unless (stringp title)
+    (signal 'wrong-type-argument (list 'stringp content)))
+  (let ((fields `(("id" . ,(mixi-friend-id (mixi-make-me)))
+                 ("diary_title" . ,title)
+                 ("diary_body" . ,content)
+                 ("submit" . "main")))
+       post-key id diary-title diary-body)
+    (with-mixi-post-form "/add_diary.pl" fields
+      (if (string-match mixi-post-diary-key-regexp buffer)
+         (setq post-key (match-string 1 buffer))
+       (mixi-post-error 'cannot-find-key))
+      (if (string-match mixi-post-diary-id-regexp buffer)
+         (setq id (match-string 1 buffer))
+       (mixi-error 'cannot-find-id))
+      (if (string-match mixi-post-diary-title-regexp buffer)
+         (setq diary-title (match-string 1 buffer))
+       (mixi-error 'cannot-find-title))
+      (if (string-match mixi-post-diary-body-regexp buffer)
+         (setq diary-body (match-string 1 buffer))
+       (mixi-error 'cannot-find-body)))
+    (setq fields `(("post_key" . ,post-key)
+                  ("id" . ,id)
+                  ("diary_title" . ,diary-title)
+                  ("diary_body" . ,diary-body)
+                  ("submit" . "confirm")))
+    (with-mixi-post-form "/add_diary.pl" fields
+      (unless (string-match mixi-post-diary-succeed-regexp buffer)
+       (mixi-error 'cannot-find-succeed)))))
+
 ;; Community object.
 (defvar mixi-community-cache (make-hash-table :test 'equal))
 (defun mixi-make-community (id &optional name birthday owner category members