;; * mixi-get-new-comments
;; * mixi-get-messages
;; * mixi-get-introductions
+;; * mixi-get-news
;;
;; API for posting:
;;
(eval-when-compile (require 'cl))
+;; Functions and variables which should be defined in the other module
+;; at run-time.
+(eval-when-compile
+ (defvar w3m-use-cookies)
+ (defvar url-request-method)
+ (defvar url-request-data)
+ (defvar url-request-extra-headers)
+ (autoload 'w3m-decode-buffer "w3m")
+ (autoload 'w3m-retrieve "w3m")
+ (autoload 'url-retrieve-synchronously "url"))
+
(defgroup mixi nil
"API library for accessing to mixi."
:group 'hypermedia)
(symbol :tag "The other backend"))
:group 'mixi)
+(defcustom mixi-login-use-ssl nil
+ "*If non-ni, login using SSL."
+ :type 'boolean
+ :group 'mixi)
+
(defcustom mixi-default-email nil
"*Default E-mail address that is used to login automatically."
:type '(radio (string :tag "E-mail address")
'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)
+ `(let ((data (if debug-on-error
+ (list ,type ,object (buffer-string))
(list ,type ,object))))
(signal 'mixi-realization-error data)))
(defmacro mixi-post-error (type &optional object)
- `(let ((data (when (and (boundp 'buffer) debug-on-error)
- (list buffer))))
+ `(let ((data (when debug-on-error (list (buffer-string)))))
(if ,object
(setq data (cons ,type (cons ,object data)))
(setq data (cons ,type data)))
(mixi-retrieve url post-data)))
(defmacro mixi-expand-url (url)
- `(if (string-match (concat "^" mixi-url) ,url)
+ `(if (string-match "^http" ,url)
,url
(concat mixi-url ,url)))
(read-from-minibuffer (mixi-message "Login Email: "))))
(password (or password mixi-default-password
(read-passwd (mixi-message "Login Password: ")))))
- (let ((buffer (mixi-retrieve "/login.pl"
- (concat "email=" email
- "&password=" password
- "&next_url=/home.pl"
- "&sticky=on"))))
- (unless (string-match "url=/check\\.pl\\?n=" buffer)
- (error (mixi-message "Cannot login")))
- (setq buffer (mixi-retrieve "/check.pl?n=home.pl"))
- (if (string-match mixi-my-id-regexp buffer)
- (setq mixi-me (mixi-make-friend (match-string 1 buffer)))
- (error (mixi-message "Cannot login"))))))
+ (let ((url "/login.pl"))
+ (when mixi-login-use-ssl
+ (setq url (concat "https://mixi.jp" url)))
+ (let ((buffer (mixi-retrieve url
+ (concat "email=" email
+ "&password=" password
+ "&next_url=/home.pl"
+ "&sticky=on"))))
+ (unless (string-match "url=/check\\.pl\\?n=" buffer)
+ (error (mixi-message "Cannot login")))
+ (setq buffer (mixi-retrieve "/check.pl?n=home.pl"))
+ (if (string-match mixi-my-id-regexp buffer)
+ (setq mixi-me (mixi-make-friend (match-string 1 buffer)))
+ (error (mixi-message "Cannot login")))))))
(defun mixi-logout ()
(mixi-retrieve "/logout.pl"))
(defmacro with-mixi-retrieve (url &rest body)
- `(let (buffer)
- (when ,url
- (setq buffer (mixi-retrieve ,url))
- (when (string-match "<form action=\"login\\.pl\" method=\"post\">"
- buffer)
+ `(when ,url
+ (with-temp-buffer
+ (insert (mixi-retrieve ,url))
+ (goto-char (point-min))
+ (when (search-forward
+ "<form action=\"login.pl\" method=\"post\">" nil t)
(mixi-login)
- (setq buffer (mixi-retrieve ,url))))
- ,@body))
+ (erase-buffer)
+ (insert (mixi-retrieve ,url))
+ (goto-char (point-min)))
+ ,@body)))
(put 'with-mixi-retrieve 'lisp-indent-function 'defun)
-(put 'with-mixi-retrieve 'edebug-form-spec '(form body))
+(put 'with-mixi-retrieve 'edebug-form-spec '(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)
+ `(when ,url
+ (with-temp-buffer
+ (insert (mixi-post-form ,url ,fields))
+ (goto-char (point-min))
+ (when (search-forward
+ "<form action=\"login.pl\" method=\"post\">" nil t)
(mixi-login)
- (setq buffer (mixi-post-form ,url ,fields))))
- ,@body))
+ (erase-buffer)
+ (insert (mixi-post-form ,url ,fields))
+ (goto-char (point-min)))
+ ,@body)))
(put 'with-mixi-post-form 'lisp-indent-function 'defun)
-(put 'with-mixi-post-form 'edebug-form-spec '(form body))
+(put 'with-mixi-post-form 'edebug-form-spec '(body))
-(defun mixi-get-matched-items (url regexp &optional range)
+(defun mixi-get-matched-items (url regexp &optional range reverse)
"Get matched items to REGEXP in URL."
(let ((page 1)
ids)
(catch 'end
(while (or (null range) (< (length ids) range))
(with-mixi-retrieve (format url page)
- (let ((pos 0)
+ (let ((func (if reverse (progn
+ (goto-char (point-max))
+ 're-search-backward)
+ 're-search-forward))
found)
- (while (and (string-match regexp buffer pos)
+ (while (and (funcall func regexp nil t)
(or (null range) (< (length ids) range)))
(let ((num 1)
list)
- (while (match-string num buffer)
- (setq list (cons (match-string num buffer) list))
+ (while (match-string num)
+ (setq list (cons (match-string num) list))
(incf num))
(when (not (member (reverse list) ids))
(setq found t)
- (setq ids (cons (reverse list) ids)))
- (setq pos (match-end (1- num)))))
+ (setq ids (cons (reverse list) ids)))))
(when (not found)
(throw 'end ids))))
(incf page)))
"Return a my object."
(unless mixi-me
(with-mixi-retrieve "/home.pl"
- (if (string-match mixi-my-id-regexp buffer)
- (setq mixi-me (mixi-make-friend (match-string 1 buffer)))
+ (if (re-search-forward mixi-my-id-regexp)
+ (setq mixi-me (mixi-make-friend (match-string 1)))
(signal 'error (list 'who-am-i)))))
mixi-me)
`(eq (mixi-object-class ,friend) 'mixi-friend))
(defmacro mixi-friend-page (friend)
- `(concat "/show_friend.pl?id=" (mixi-friend-id ,friend)))
+ `(concat "/show_profile.pl?id=" (mixi-friend-id ,friend)))
(defconst mixi-friend-nick-regexp
- "<img alt=\"\\*\" src=\"http://img\\.mixi\\.jp/img/dot0\\.gif\" width=\"1\" height=\"5\"><br>\r?
+ "<img \\(alt=\"\\*\" \\)?src=\"?http://img\\.mixi\\.jp/img/dot0\\.gif\"? \\(width\\|WIDTH\\)=\"?1\"? \\(height\\|HEIGHT\\)=\"?5\"?><br>\r?
\\(.*\\)¤µ¤ó([0-9]+)")
(defconst mixi-friend-name-regexp
"<td BGCOLOR=#F2DDB7 WIDTH=80 NOWRAP><font COLOR=#996600>̾\\( \\| \\)Á°</font></td>
"Realize a FRIEND."
;; FIXME: Check a expiration of cache?
(unless (mixi-object-realized-p friend)
- (let (buf)
- (with-mixi-retrieve (mixi-friend-page friend)
- (setq buf buffer))
- (if (string-match mixi-friend-nick-regexp buf)
- (mixi-friend-set-nick friend (match-string 1 buf))
+ (with-mixi-retrieve (mixi-friend-page friend)
+ (if (re-search-forward mixi-friend-nick-regexp nil t)
+ (mixi-friend-set-nick friend (match-string 4))
(mixi-realization-error 'cannot-find-nick friend))
- ;; For getting my profile.
- (unless (string-match mixi-friend-name-regexp buf)
- (with-mixi-retrieve (concat "/show_profile.pl?id="
- (mixi-friend-id friend))
- (setq buf buffer)))
- (if (string-match mixi-friend-name-regexp buf)
- (mixi-friend-set-name friend (match-string 2 buf))
- (mixi-realization-error 'cannot-find-name friend))
- (if (string-match mixi-friend-sex-regexp buf)
- (mixi-friend-set-sex friend
- (if (string= (match-string 3 buf) "ÃË")
- 'male 'female))
- (mixi-realization-error 'cannot-find-sex friend))
- (when (string-match mixi-friend-address-regexp buf)
- (mixi-friend-set-address friend (match-string 1 buf)))
- (when (string-match mixi-friend-age-regexp buf)
- (mixi-friend-set-age
- friend (string-to-number (match-string 2 buf))))
- (when (string-match mixi-friend-birthday-regexp buf)
- (mixi-friend-set-birthday
- friend (list (string-to-number (match-string 1 buf))
- (string-to-number (match-string 2 buf)))))
- (when (string-match mixi-friend-blood-type-regexp buf)
- (mixi-friend-set-blood-type friend (intern (match-string 1 buf))))
- (when (string-match mixi-friend-birthplace-regexp buf)
- (mixi-friend-set-birthplace friend (match-string 1 buf)))
- (when (string-match mixi-friend-hobby-regexp buf)
- (mixi-friend-set-hobby
- friend (split-string (match-string 2 buf) ", ")))
- (when (string-match mixi-friend-job-regexp buf)
- (mixi-friend-set-job friend (match-string 2 buf)))
- (when (string-match mixi-friend-organization-regexp buf)
- (mixi-friend-set-organization friend (match-string 2 buf)))
- (when (string-match mixi-friend-profile-regexp buf)
- (mixi-friend-set-profile friend (match-string 1 buf))))
+ (when (re-search-forward mixi-friend-name-regexp nil t)
+ (mixi-friend-set-name friend (match-string 2)))
+ (when (re-search-forward mixi-friend-sex-regexp nil t)
+ (mixi-friend-set-sex friend (if (string= (match-string 3) "ÃË")
+ 'male 'female)))
+ (when (re-search-forward mixi-friend-address-regexp nil t)
+ (mixi-friend-set-address friend (match-string 1)))
+ (when (re-search-forward mixi-friend-age-regexp nil t)
+ (mixi-friend-set-age friend (string-to-number (match-string 2))))
+ (when (re-search-forward mixi-friend-birthday-regexp nil t)
+ (mixi-friend-set-birthday friend
+ (list (string-to-number (match-string 1))
+ (string-to-number (match-string 2)))))
+ (when (re-search-forward mixi-friend-blood-type-regexp nil t)
+ (mixi-friend-set-blood-type friend (intern (match-string 1))))
+ (when (re-search-forward mixi-friend-birthplace-regexp nil t)
+ (mixi-friend-set-birthplace friend (match-string 1)))
+ (when (re-search-forward mixi-friend-hobby-regexp nil t)
+ (mixi-friend-set-hobby friend (split-string (match-string 2) ", ")))
+ (when (re-search-forward mixi-friend-job-regexp nil t)
+ (mixi-friend-set-job friend (match-string 2)))
+ (when (re-search-forward mixi-friend-organization-regexp nil t)
+ (mixi-friend-set-organization friend (match-string 2)))
+ (when (re-search-forward mixi-friend-profile-regexp nil t)
+ (mixi-friend-set-profile friend (match-string 1))))
(mixi-object-touch friend)))
(defun mixi-friend-id (friend)
;; FIXME: Check a expiration of cache?
(unless (mixi-object-realized-p diary)
(with-mixi-retrieve (mixi-diary-page diary)
- (unless (string-match mixi-diary-closed-regexp buffer)
- (if (string-match mixi-diary-owner-nick-regexp buffer)
- (mixi-friend-set-nick (mixi-diary-owner diary)
- (match-string 1 buffer))
+ (unless (re-search-forward mixi-diary-closed-regexp nil t)
+ (if (re-search-forward mixi-diary-owner-nick-regexp nil t)
+ (mixi-friend-set-nick (mixi-diary-owner diary) (match-string 1))
(mixi-realization-error 'cannot-find-owner-nick diary))
- (if (string-match mixi-diary-time-regexp buffer)
+ (if (re-search-forward mixi-diary-time-regexp nil t)
(mixi-diary-set-time
- diary (encode-time 0 (string-to-number (match-string 10 buffer))
- (string-to-number (match-string 9 buffer))
- (string-to-number (match-string 7 buffer))
- (string-to-number (match-string 6 buffer))
- (string-to-number (match-string 5 buffer))))
+ diary (encode-time 0 (string-to-number (match-string 10))
+ (string-to-number (match-string 9))
+ (string-to-number (match-string 7))
+ (string-to-number (match-string 6))
+ (string-to-number (match-string 5))))
(mixi-realization-error 'cannot-find-time diary))
- (if (string-match mixi-diary-title-regexp buffer)
- (mixi-diary-set-title diary (match-string 2 buffer))
+ (if (re-search-forward mixi-diary-title-regexp nil t)
+ (mixi-diary-set-title diary (match-string 2))
(mixi-realization-error 'cannot-find-title diary))
- (if (string-match mixi-diary-content-regexp buffer)
- (mixi-diary-set-content diary (match-string 2 buffer))
+ (if (re-search-forward mixi-diary-content-regexp nil t)
+ (mixi-diary-set-content diary (match-string 2))
(mixi-realization-error 'cannot-find-content diary))))
(mixi-object-touch diary)))
"Return the time of DIARY."
(unless (mixi-diary-p diary)
(signal 'wrong-type-argument (list 'mixi-diary-p diary)))
- (mixi-realize-diary diary)
+ (unless (aref (cdr diary) 3)
+ (mixi-realize-diary diary))
(aref (cdr diary) 3))
(defun mixi-diary-title (diary)
"Return the title of DIARY."
(unless (mixi-diary-p diary)
(signal 'wrong-type-argument (list 'mixi-diary-p diary)))
- (mixi-realize-diary diary)
+ (unless (aref (cdr diary) 4)
+ (mixi-realize-diary diary))
(aref (cdr diary) 4))
(defun mixi-diary-content (diary)
(when ,friend (concat "&id=" (mixi-friend-id ,friend)))))
(defconst mixi-diary-list-regexp
- "<a href=\"view_diary\\.pl\\?id=\\([0-9]+\\)&owner_id=[0-9]+\">")
+ "<tr VALIGN=top>
+<td ALIGN=center ROWSPAN=3 NOWRAP bgcolor=#F2DDB7><font COLOR=#996600>\\([0-9]+\\)·î\\([0-9]+\\)Æü<br>\\([0-9]+\\):\\([0-9]+\\)</font>\\(<br><input type=\"checkbox\" name=\"diary_id\" value=\"[0-9]+\">\\|\\)</td>
+<td bgcolor=\"#FFF4E0\"> <a href=\"view_diary\\.pl\\?id=\\([0-9]+\\)&owner_id=[0-9]+\">\\(.*\\)</a></td>")
(defun mixi-get-diaries (&rest friend-or-range)
"Get diaries of FRIEND."
(signal 'wrong-type-argument (list 'mixi-friend-p friend)))
(let ((items (mixi-get-matched-items (mixi-diary-list-page friend)
mixi-diary-list-regexp
- range)))
+ range))
+ (year (nth 5 (decode-time (current-time))))
+ (month (nth 4 (decode-time (current-time)))))
(mapcar (lambda (item)
- (mixi-make-diary friend (nth 0 item)))
+ (let ((month-of-item (string-to-number (nth 0 item))))
+ (when (> month-of-item month)
+ (decf year))
+ (setq month month-of-item)
+ (mixi-make-diary friend (nth 5 item)
+ (encode-time
+ 0 (string-to-number (nth 3 item))
+ (string-to-number (nth 2 item))
+ (string-to-number (nth 1 item))
+ month year)
+ (nth 6 item))))
items))))
(defmacro mixi-new-diary-list-page ()
`(concat "/new_friend_diary.pl?page=%d"))
(defconst mixi-new-diary-list-regexp
- "<a class=\"new_link\" href=view_diary\\.pl\\?id=\\([0-9]+\\)&owner_id=\\([0-9]+\\)>")
+ "<td WIDTH=180><img src=http://img\\.mixi\\.jp/img/pen\\.gif ALIGN=left WIDTH=14 HEIGHT=16>\\([0-9]+\\)ǯ\\([0-9]+\\)·î\\([0-9]+\\)Æü \\([0-9]+\\):\\([0-9]+\\)</td>
+<td WIDTH=450><a class=\"new_link\" href=view_diary\\.pl\\?id=\\([0-9]+\\)&owner_id=\\([0-9]+\\)>\\(.+\\)</a> (\\(.*\\)) ")
(defun mixi-get-new-diaries (&optional range)
"Get new diaries."
mixi-new-diary-list-regexp
range)))
(mapcar (lambda (item)
- (mixi-make-diary (mixi-make-friend (nth 1 item)) (nth 0 item)))
+ (mixi-make-diary (mixi-make-friend (nth 6 item) (nth 8 item))
+ (nth 5 item)
+ (encode-time
+ 0 (string-to-number (nth 4 item))
+ (string-to-number (nth 3 item))
+ (string-to-number (nth 2 item))
+ (string-to-number (nth 1 item))
+ (string-to-number (nth 0 item)))
+ (nth 7 item)))
items)))
(defmacro mixi-search-diary-list-page (keyword)
`(concat "/search_diary.pl?page=%d&submit=search&keyword="
- (mixi-url-encode-and-quote-percent-string keyword)))
+ (mixi-url-encode-and-quote-percent-string ,keyword)))
(defconst mixi-search-diary-list-regexp
- "<a href=\"view_diary\\.pl\\?id=\\([0-9]+\\)&owner_id=\\([0-9]+\\)\">")
+ "<td BGCOLOR=#FDF9F2><font COLOR=#996600>̾ Á°</font></td>
+<td COLSPAN=2 BGCOLOR=#FFFFFF>\\(.*\\)
+
+</td></tr>
+
+<tr>
+<td BGCOLOR=#FDF9F2><font COLOR=#996600>¥¿¥¤¥È¥ë</font></td>
+<td COLSPAN=2 BGCOLOR=#FFFFFF>\\(.+\\)</td></tr>
+
+<tr>
+<td BGCOLOR=#FDF9F2><font COLOR=#996600>ËÜ Ê¸</font></td>
+<td COLSPAN=2 BGCOLOR=#FFFFFF>\\(.*\\)</td></tr>
+
+
+<tr>
+<td NOWRAP BGCOLOR=#FDF9F2 WIDTH=80><font COLOR=#996600>ºîÀ®Æü»þ</font></td>
+<td BGCOLOR=#FFFFFF WIDTH=220>\\([0-9]+\\)·î\\([0-9]+\\)Æü \\([0-9]+\\):\\([0-9]+\\)</td>
+<td ALIGN=center BGCOLOR=#FDF9F2 width=250><a href=\"view_diary\\.pl\\?id=\\([0-9]+\\)&owner_id=\\([0-9]+\\)\"><img src=http://img\\.mixi\\.jp/img/shbtn\\.gif ALT=¾ÜºÙ¤ò¸«¤ë BORDER=0 WIDTH=104 HEIGHT=19></a></td></tr>
+</table>
+</td></tr></table>")
(defun mixi-search-diaries (keyword &optional range)
(let ((items (mixi-get-matched-items (mixi-search-diary-list-page keyword)
mixi-search-diary-list-regexp
- range)))
+ range))
+ (year (nth 5 (decode-time (current-time))))
+ (month (nth 4 (decode-time (current-time)))))
(mapcar (lambda (item)
- (mixi-make-diary (mixi-make-friend (nth 1 item)) (nth 0 item)))
+ (let ((month-of-item (string-to-number (nth 3 item))))
+ (when (> month-of-item month)
+ (decf year))
+ (setq month month-of-item)
+ (mixi-make-diary (mixi-make-friend (nth 8 item) (nth 0 item))
+ (nth 7 item)
+ (encode-time
+ 0 (string-to-number (nth 6 item))
+ (string-to-number (nth 5 item))
+ (string-to-number (nth 4 item))
+ month year)
+ (nth 1 item)
+ (nth 2 item))))
items)))
(defmacro mixi-post-diary-page ()
("submit" . "main")))
post-key)
(with-mixi-post-form (mixi-post-diary-page) fields
- (if (string-match mixi-post-key-regexp buffer)
- (setq post-key (match-string 1 buffer))
+ (if (re-search-forward mixi-post-key-regexp nil t)
+ (setq post-key (match-string 1))
(mixi-post-error 'cannot-find-key)))
(setq fields `(("post_key" . ,post-key)
("id" . ,(mixi-friend-id (mixi-make-me)))
("diary_body" . ,content)
("submit" . "confirm")))
(with-mixi-post-form (mixi-post-diary-page) fields
- (unless (string-match mixi-post-succeed-regexp buffer)
+ (unless (re-search-forward mixi-post-succeed-regexp nil t)
(mixi-post-error 'cannot-find-succeed)))))
;; Community object.
;; FIXME: Check a expiration of cache?
(unless (mixi-object-realized-p community)
(with-mixi-retrieve (mixi-community-page community)
- (if (string-match mixi-community-nodata-regexp buffer)
+ (if (re-search-forward mixi-community-nodata-regexp nil t)
;; FIXME: Set all members?
(mixi-community-set-name community "¥Ç¡¼¥¿¤¬¤¢¤ê¤Þ¤»¤ó")
- (if (string-match mixi-community-name-regexp buffer)
- (mixi-community-set-name community (match-string 1 buffer))
+ (if (re-search-forward mixi-community-name-regexp nil t)
+ (mixi-community-set-name community (match-string 1))
(mixi-realization-error 'cannot-find-name community))
- (if (string-match mixi-community-birthday-regexp buffer)
+ (if (re-search-forward mixi-community-birthday-regexp nil t)
(mixi-community-set-birthday
- community
- (encode-time 0 0 0 (string-to-number (match-string 3 buffer))
- (string-to-number (match-string 2 buffer))
- (string-to-number (match-string 1 buffer))))
+ community (encode-time 0 0 0 (string-to-number (match-string 3))
+ (string-to-number (match-string 2))
+ (string-to-number (match-string 1))))
(mixi-realization-error 'cannot-find-birthday community))
- (if (string-match mixi-community-owner-regexp buffer)
- (if (string= (match-string 1 buffer) "home.pl")
+ (if (re-search-forward mixi-community-owner-regexp nil t)
+ (if (string= (match-string 1) "home.pl")
(mixi-community-set-owner community (mixi-make-me))
- (mixi-community-set-owner
- community (mixi-make-friend (match-string 2 buffer)
- (match-string 3 buffer))))
+ (mixi-community-set-owner community
+ (mixi-make-friend (match-string 2)
+ (match-string 3))))
(mixi-realization-error 'cannot-find-owner community))
- (if (string-match mixi-community-category-regexp buffer)
- (mixi-community-set-category community (match-string 1 buffer))
+ (if (re-search-forward mixi-community-category-regexp nil t)
+ (mixi-community-set-category community (match-string 1))
(mixi-realization-error 'cannot-find-category community))
- (if (string-match mixi-community-members-regexp buffer)
- (mixi-community-set-members
- community (string-to-number (match-string 1 buffer)))
+ (if (re-search-forward mixi-community-members-regexp nil t)
+ (mixi-community-set-members community
+ (string-to-number (match-string 1)))
(mixi-realization-error 'cannot-find-members community))
- (if (string-match mixi-community-open-level-regexp buffer)
- (mixi-community-set-open-level community (match-string 1 buffer))
+ (if (re-search-forward mixi-community-open-level-regexp nil t)
+ (mixi-community-set-open-level community (match-string 1))
(mixi-realization-error 'cannot-find-open-level community))
- (if (string-match mixi-community-authority-regexp buffer)
- (mixi-community-set-authority community (match-string 1 buffer))
+ (if (re-search-forward mixi-community-authority-regexp nil t)
+ (mixi-community-set-authority community (match-string 1))
(mixi-realization-error 'cannot-find-authority community))
- (if (string-match mixi-community-description-regexp buffer)
- (mixi-community-set-description community (match-string 1 buffer))
+ (if (re-search-forward mixi-community-description-regexp nil t)
+ (mixi-community-set-description community (match-string 1))
(mixi-realization-error 'cannot-find-description community))))
(mixi-object-touch community)))
(defmacro mixi-search-community-list-page (keyword)
`(concat "/search_community.pl?page=%d&&sort=date&type=com&submit=main"
- "&keyword=" (mixi-url-encode-and-quote-percent-string keyword)
+ "&keyword=" (mixi-url-encode-and-quote-percent-string ,keyword)
"&category_id=0"))
(defconst mixi-search-community-list-regexp
;; FIXME: Check a expiration of cache?
(unless (mixi-object-realized-p topic)
(with-mixi-retrieve (mixi-topic-page topic)
- (if (string-match mixi-topic-community-regexp buffer)
+ (if (re-search-forward mixi-topic-community-regexp nil t)
(mixi-community-set-name (mixi-topic-community topic)
- (match-string 1 buffer))
+ (match-string 1))
(mixi-realization-error 'cannot-find-community topic))
- (if (string-match mixi-topic-time-regexp buffer)
+ (if (re-search-forward mixi-topic-time-regexp nil t)
(mixi-topic-set-time
- topic (encode-time 0 (string-to-number (match-string 5 buffer))
- (string-to-number (match-string 4 buffer))
- (string-to-number (match-string 3 buffer))
- (string-to-number (match-string 2 buffer))
- (string-to-number (match-string 1 buffer))))
+ topic (encode-time 0 (string-to-number (match-string 5))
+ (string-to-number (match-string 4))
+ (string-to-number (match-string 3))
+ (string-to-number (match-string 2))
+ (string-to-number (match-string 1))))
(mixi-realization-error 'cannot-find-time topic))
- (if (string-match mixi-topic-title-regexp buffer)
- (mixi-topic-set-title topic (match-string 1 buffer))
+ (if (re-search-forward mixi-topic-title-regexp nil t)
+ (mixi-topic-set-title topic (match-string 1))
(mixi-realization-error 'cannot-find-title topic))
- (if (string-match mixi-topic-owner-regexp buffer)
- (mixi-topic-set-owner topic
- (mixi-make-friend (match-string 1 buffer)
- (match-string 2 buffer)))
+ (if (re-search-forward mixi-topic-owner-regexp nil t)
+ (mixi-topic-set-owner topic (mixi-make-friend (match-string 1)
+ (match-string 2)))
(mixi-realization-error 'cannot-find-owner topic))
- (if (string-match mixi-topic-content-regexp buffer)
- (mixi-topic-set-content topic (match-string 2 buffer))
+ (if (re-search-forward mixi-topic-content-regexp nil t)
+ (mixi-topic-set-content topic (match-string 2))
(mixi-realization-error 'cannot-find-content topic)))
(mixi-object-touch topic)))
("submit" . "main")))
post-key)
(with-mixi-post-form (mixi-post-topic-page community) fields
- (if (string-match mixi-post-key-regexp buffer)
- (setq post-key (match-string 1 buffer))
+ (if (re-search-forward mixi-post-key-regexp nil t)
+ (setq post-key (match-string 1))
(mixi-post-error 'cannot-find-key community)))
(setq fields `(("post_key" . ,post-key)
("bbs_title" . ,title)
("bbs_body" . ,content)
("submit" . "confirm")))
(with-mixi-post-form (mixi-post-topic-page community) fields
- (unless (string-match mixi-post-succeed-regexp buffer)
+ (unless (re-search-forward mixi-post-succeed-regexp nil t)
(mixi-post-error 'cannot-find-succeed community)))))
;; Event object.
;; FIXME: Check a expiration of cache?
(unless (mixi-object-realized-p event)
(with-mixi-retrieve (mixi-event-page event)
- (if (string-match mixi-event-community-regexp buffer)
+ (if (re-search-forward mixi-event-community-regexp nil t)
(mixi-community-set-name (mixi-event-community event)
- (match-string 1 buffer))
+ (match-string 1))
(mixi-realization-error 'cannot-find-community event))
- (if (string-match mixi-event-time-regexp buffer)
+ (if (re-search-forward mixi-event-time-regexp nil t)
(mixi-event-set-time
- event (encode-time 0 (string-to-number (match-string 8 buffer))
- (string-to-number (match-string 7 buffer))
- (string-to-number (match-string 6 buffer))
- (string-to-number (match-string 5 buffer))
- (string-to-number (match-string 4 buffer))))
+ event (encode-time 0 (string-to-number (match-string 8))
+ (string-to-number (match-string 7))
+ (string-to-number (match-string 6))
+ (string-to-number (match-string 5))
+ (string-to-number (match-string 4))))
(mixi-realization-error 'cannot-find-time event))
- (if (string-match mixi-event-title-regexp buffer)
- (mixi-event-set-title event (match-string 2 buffer))
+ (if (re-search-forward mixi-event-title-regexp nil t)
+ (mixi-event-set-title event (match-string 2))
(mixi-realization-error 'cannot-find-title event))
- (if (string-match mixi-event-owner-regexp buffer)
- (mixi-event-set-owner event
- (mixi-make-friend (match-string 2 buffer)
- (match-string 3 buffer)))
- (if (string-match mixi-event-owner-seceded-regexp buffer)
+ (if (re-search-forward mixi-event-owner-regexp nil t)
+ (mixi-event-set-owner event (mixi-make-friend (match-string 2)
+ (match-string 3)))
+ (if (re-search-forward mixi-event-owner-seceded-regexp nil t)
(mixi-event-set-owner event
- (mixi-make-friend nil
- (match-string 2 buffer)))
+ (mixi-make-friend nil (match-string 2)))
(mixi-realization-error 'cannot-find-owner event)))
- (if (string-match mixi-event-date-regexp buffer)
- (mixi-event-set-date event (match-string 6 buffer))
+ (if (re-search-forward mixi-event-date-regexp nil t)
+ (mixi-event-set-date event (match-string 6))
(mixi-realization-error 'cannot-find-date event))
- (if (string-match mixi-event-place-regexp buffer)
- (mixi-event-set-place event (match-string 6 buffer))
+ (if (re-search-forward mixi-event-place-regexp nil t)
+ (mixi-event-set-place event (match-string 6))
(mixi-realization-error 'cannot-find-place event))
- (if (string-match mixi-event-detail-regexp buffer)
- (mixi-event-set-detail event (match-string 6 buffer))
+ (if (re-search-forward mixi-event-detail-regexp nil t)
+ (mixi-event-set-detail event (match-string 6))
(mixi-realization-error 'cannot-find-detail event))
- (when (string-match mixi-event-limit-regexp buffer)
+ (when (re-search-forward mixi-event-limit-regexp nil t)
(mixi-event-set-limit
- event (encode-time 0 0 0 (string-to-number (match-string 8 buffer))
- (string-to-number (match-string 7 buffer))
- (string-to-number (match-string 6 buffer)))))
- (if (string-match mixi-event-members-regexp buffer)
- (mixi-event-set-members event (match-string 6 buffer))
+ event (encode-time 0 0 0 (string-to-number (match-string 8))
+ (string-to-number (match-string 7))
+ (string-to-number (match-string 6)))))
+ (if (re-search-forward mixi-event-members-regexp nil t)
+ (mixi-event-set-members event (match-string 6))
(mixi-realization-error 'cannot-find-members event)))
(mixi-object-touch event)))
(defconst mixi-bbs-list '(mixi-topic mixi-event))
(defmacro mixi-bbs-p (object)
- `(when (memq (mixi-object-class ,object) mixi-bbs-list)
- t))
+ `(memq (mixi-object-class ,object) mixi-bbs-list))
(defun mixi-bbs-community (object)
"Return the community of OBJECT."
(defmacro mixi-search-bbs-list-page (keyword)
`(concat "/search_topic.pl?page=%d&type=top&submit=search"
- "&keyword=" (mixi-url-encode-and-quote-percent-string keyword)
+ "&keyword=" (mixi-url-encode-and-quote-percent-string ,keyword)
"&community_id=0&category_id=0"))
(defconst mixi-search-bbs-list-regexp
(regexp (eval (intern (concat mixi-object-prefix name
"-comment-list-regexp")))))
(let ((items (mixi-get-matched-items
- (funcall list-page parent) regexp)))
- (let (list)
- (catch 'stop
- (mapc (lambda (item)
- (when (and (numberp range)
- (>= (length list) range))
- (throw 'stop nil))
- (setq list (cons item list)))
- (reverse items)))
- (setq items (reverse list)))
+ (funcall list-page parent) regexp range t)))
(mapcar (lambda (item)
(mixi-make-comment parent (mixi-make-friend
(nth 7 item) (nth 8 item))
("comment_body" . ,content)))
(setq fields `(("comment" . ,content))))
(with-mixi-post-form (funcall page parent) fields
- (if (string-match mixi-post-key-regexp buffer)
- (setq post-key (match-string 1 buffer))
+ (if (re-search-forward mixi-post-key-regexp nil t)
+ (setq post-key (match-string 1))
(mixi-post-error 'cannot-find-key parent)))
(if (mixi-diary-p parent)
(setq fields
("comment" . ,content)
("submit" . "confirm"))))
(with-mixi-post-form (funcall page parent) fields
- (unless (string-match mixi-post-succeed-regexp buffer)
+ (unless (re-search-forward mixi-post-succeed-regexp nil t)
(mixi-post-error 'cannot-find-succeed parent)))))
;; Message object.
(defconst mixi-message-box-list '(inbox outbox savebox thrash)) ; thrash?
(defmacro mixi-message-box-p (box)
- `(when (memq ,box mixi-message-box-list)
- t))
+ `(memq ,box mixi-message-box-list))
(defun mixi-message-box-name (box)
"Return the name of BOX."
(defconst mixi-message-owner-regexp
"<font COLOR=#996600>\\(º¹½Ð¿Í\\|°¸ Àè\\)</font> : <a HREF=\"show_friend\\.pl\\?id=\\([0-9]+\\)\">\\(.*\\)\\(</a>\\|</td>\\)")
-(defconst mixi-message-title-regexp
-"<font COLOR=#996600>·ï\\(¡¡\\| \\)̾</font> : \\(.+\\)\n?</td>")
(defconst mixi-message-time-regexp
"<font COLOR=#996600>Æü\\(¡¡\\| \\)ÉÕ</font> : \\([0-9]+\\)ǯ\\([0-9]+\\)·î\\([0-9]+\\)Æü \\([0-9]+\\)»þ\\([0-9]+\\)ʬ ")
+(defconst mixi-message-title-regexp
+"<font COLOR=#996600>·ï\\(¡¡\\| \\)̾</font> : \\(.+\\)\n?</td>")
(defconst mixi-message-content-regexp
"<tr><td CLASS=h120>\\(.+\\)</td></tr>")
"Realize a MESSAGE."
(unless (mixi-object-realized-p message)
(with-mixi-retrieve (mixi-message-page message)
- (if (string-match mixi-message-owner-regexp buffer)
+ (if (re-search-forward mixi-message-owner-regexp nil t)
(mixi-message-set-owner message
- (mixi-make-friend (match-string 2 buffer)
- (match-string 3 buffer)))
+ (mixi-make-friend (match-string 2)
+ (match-string 3)))
(mixi-realization-error 'cannot-find-owner message))
- (if (string-match mixi-message-title-regexp buffer)
- (mixi-message-set-title message (match-string 2 buffer))
- (mixi-realization-error 'cannot-find-title message))
- (if (string-match mixi-message-time-regexp buffer)
+ (if (re-search-forward mixi-message-time-regexp nil t)
(mixi-message-set-time
- message (encode-time 0 (string-to-number (match-string 6 buffer))
- (string-to-number (match-string 5 buffer))
- (string-to-number (match-string 4 buffer))
- (string-to-number (match-string 3 buffer))
- (string-to-number (match-string 2 buffer))))
+ message (encode-time 0 (string-to-number (match-string 6))
+ (string-to-number (match-string 5))
+ (string-to-number (match-string 4))
+ (string-to-number (match-string 3))
+ (string-to-number (match-string 2))))
(mixi-realization-error 'cannot-find-time message))
- (if (string-match mixi-message-content-regexp buffer)
- (mixi-message-set-content message (match-string 1 buffer))
+ (if (re-search-forward mixi-message-title-regexp nil t)
+ (mixi-message-set-title message (match-string 2))
+ (mixi-realization-error 'cannot-find-title message))
+ (if (re-search-forward mixi-message-content-regexp nil t)
+ (mixi-message-set-content message (match-string 1))
(mixi-realization-error 'cannot-find-content message)))
(mixi-object-touch message)))
("submit" . "main")))
post-key)
(with-mixi-post-form (mixi-post-message-page friend) fields
- (if (string-match mixi-post-message-key-regexp buffer)
- (setq post-key (match-string 1 buffer))
+ (if (re-search-forward mixi-post-message-key-regexp nil t)
+ (setq post-key (match-string 1))
(mixi-post-error 'cannot-find-key friend)))
(setq fields `(("post_key" . ,post-key)
("subject" . ,title)
("yes" . "¡¡Á÷¡¡¿®¡¡")
("submit" . "confirm")))
(with-mixi-post-form (mixi-post-message-page friend) fields
- (unless (string-match mixi-post-message-succeed-regexp buffer)
+ (unless (re-search-forward mixi-post-message-succeed-regexp nil t)
(mixi-post-error 'cannot-find-succeed friend)))))
;; Introduction object.
(nth 2 item)))
items))))
+;; News object.
+(defvar mixi-news-cache (make-hash-table :test 'equal))
+(defun mixi-make-news (media-id id &optional media time title content)
+ "Return a news object."
+ (mixi-make-cache (list media-id id)
+ (cons 'mixi-news (vector nil media-id id media time title
+ content))
+ mixi-news-cache))
+
+(defconst mixi-news-url-regexp
+ "/view_news\\.pl\\?id=\\([0-9]+\\)&media_id=\\([0-9]+\\)")
+
+(defun mixi-make-news-from-url (url)
+ "Return a news object from URL."
+ (when (string-match mixi-news-url-regexp url)
+ (let ((id (match-string 1 url))
+ (media-id (match-string 2 url)))
+ (mixi-make-news media-id id))))
+
+(defmacro mixi-news-p (news)
+ `(eq (mixi-object-class ,news) 'mixi-news))
+
+(defmacro mixi-news-page (news)
+ `(concat "http://news.mixi.jp/view_news.pl?id=" (mixi-news-id ,news)
+ "&media_id=" (mixi-news-media-id ,news)))
+
+(defconst mixi-news-title-regexp
+ "<td HEIGHT=\"46\" STYLE=\"font-weight: bold;font-size: 14px;\" CLASS=\"h130\">\\(.+\\)</td>")
+(defconst mixi-news-media-time-regexp
+ "<td COLSPAN=\"2\" ALIGN=\"right\">(\\(.+\\) - \\([0-9]+\\)·î\\([0-9]+\\)Æü \\([0-9]+\\):\\([0-9]+\\))</td></tr>")
+(defconst mixi-news-content-regexp
+ "<td CLASS=\"h150\">
+
+\\(.+\\)
+
+?
+
+\\(</td>\\|<br>\\)")
+
+(defun mixi-realize-news (news)
+ "Realize a NEWS."
+ ;; FIXME: Check a expiration of cache?
+ (unless (mixi-object-realized-p news)
+ (with-mixi-retrieve (mixi-news-page news)
+ (if (re-search-forward mixi-news-title-regexp nil t)
+ (mixi-news-set-title news (match-string 1))
+ (mixi-realization-error 'cannot-find-title news))
+ (if (re-search-forward mixi-news-media-time-regexp nil t)
+ (progn
+ (mixi-news-set-media news (match-string 1))
+ (let ((year (nth 5 (decode-time (current-time))))
+ (month (nth 4 (decode-time (current-time))))
+ (month-of-item (string-to-number (match-string 2))))
+ (when (> month-of-item month)
+ (decf year))
+ (mixi-news-set-time
+ news (encode-time 0 (string-to-number (match-string 5))
+ (string-to-number (match-string 4))
+ (string-to-number (match-string 3))
+ month year))))
+ (mixi-realization-error 'cannot-find-media-time news))
+ (if (re-search-forward mixi-news-content-regexp nil t)
+ (mixi-news-set-content news (match-string 1))
+ (mixi-realization-error 'cannot-find-content news)))
+ (mixi-object-touch news)))
+
+(defun mixi-news-media-id (news)
+ "Return the media-id of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (aref (cdr news) 1))
+
+(defun mixi-news-id (news)
+ "Return the id of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (aref (cdr news) 2))
+
+(defun mixi-news-media (news)
+ "Return the media of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (unless (aref (cdr news) 3)
+ (mixi-realize-news news))
+ (aref (cdr news) 3))
+
+(defun mixi-news-time (news)
+ "Return the time of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (unless (aref (cdr news) 4)
+ (mixi-realize-news news))
+ (aref (cdr news) 4))
+
+(defun mixi-news-title (news)
+ "Return the title of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (unless (aref (cdr news) 5)
+ (mixi-realize-news news))
+ (aref (cdr news) 5))
+
+(defun mixi-news-content (news)
+ "Return the content of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (mixi-realize-news news)
+ (aref (cdr news) 6))
+
+(defun mixi-news-set-media (news media)
+ "Set the media of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (aset (cdr news) 3 media))
+
+(defun mixi-news-set-time (news time)
+ "Set the time of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (aset (cdr news) 4 time))
+
+(defun mixi-news-set-title (news title)
+ "Set the title of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (aset (cdr news) 5 title))
+
+(defun mixi-news-set-content (news content)
+ "Set the content of NEWS."
+ (unless (mixi-news-p news)
+ (signal 'wrong-type-argument (list 'mixi-news-p news)))
+ (aset (cdr news) 6 content))
+
+(defconst mixi-news-category-list '(domestic politics economy area abroad
+ sports entertainment IT))
+
+(defmacro mixi-news-category-p (category)
+ `(memq ,category mixi-news-category-list))
+
+(defun mixi-news-category-id (category)
+ "Return the id of CATEGORY."
+ (unless (mixi-news-category-p category)
+ (signal 'wrong-type-argument (list 'mixi-news-category-p category)))
+ (number-to-string
+ (1+ (- (length mixi-news-category-list)
+ (length (memq category mixi-news-category-list))))))
+
+(defconst mixi-news-sort-list '(newest pickup))
+
+(defmacro mixi-news-sort-p (sort)
+ `(memq ,sort mixi-news-sort-list))
+
+(defun mixi-news-sort-id (sort)
+ "Return the id of SORT."
+ (unless (mixi-news-sort-p sort)
+ (signal 'wrong-type-argument (list 'mixi-news-sort-p sort)))
+ (number-to-string
+ (- (length mixi-news-sort-list)
+ (length (memq sort mixi-news-sort-list)))))
+
+(defmacro mixi-news-list-page (category sort)
+ `(concat "http://news.mixi.jp/list_news_category.pl?page=%d"
+ "&sort=" (mixi-news-sort-id ,sort)
+ "&id=" (mixi-news-category-id ,category)
+ "&type=bn"))
+
+(defconst mixi-news-list-regexp
+ "<tr bgcolor=\"\\(#FCF5EB\\|#FFFFFF\\)\">
+<td WIDTH=\"1%\" valign=top CLASS=\"h120\">¡¦</td>
+<td WIDTH=\"97%\" CLASS=\"h120\"><A HREF=\"view_news\\.pl\\?id=\\([0-9]+\\)&media_id=\\([0-9]+\\)\"class=\"new_link\">\\(.+\\)</A>
+\\(<IMG SRC=\"http://img\\.mixi\\.jp/img/news_camera3\\.gif\" WIDTH=\"11\" HEIGHT=\"12\">\\|\\)
+
+</td>
+<td WIDTH=\"1%\" nowrap CLASS=\"f08\"><A HREF=\"list_news_media\\.pl\\?id=[0-9]+\">\\(.+\\)</A></td>
+<td WIDTH=\"1%\" nowrap CLASS=\"f08\">\\([0-9]+\\)·î\\([0-9]+\\)Æü \\([0-9]+\\):\\([0-9]+\\)</td></tr>")
+
+(defun mixi-get-news (category sort &optional range)
+ "Get news of CATEGORY and SORT."
+ (unless (mixi-news-category-p category)
+ (signal 'wrong-type-argument (list 'mixi-news-category-p category)))
+ (unless (mixi-news-sort-p sort)
+ (signal 'wrong-type-argument (list 'mixi-news-sort-p sort)))
+ (let ((items (mixi-get-matched-items (mixi-news-list-page category sort)
+ mixi-news-list-regexp
+ range))
+ (year (nth 5 (decode-time (current-time))))
+ (month (nth 4 (decode-time (current-time)))))
+ (mapcar (lambda (item)
+ (let ((month-of-item (string-to-number (nth 6 item))))
+ (when (> month-of-item month)
+ (decf year))
+ (setq month month-of-item)
+ (mixi-make-news (nth 2 item) (nth 1 item) (nth 5 item)
+ (encode-time
+ 0 (string-to-number (nth 9 item))
+ (string-to-number (nth 8 item))
+ (string-to-number (nth 7 item))
+ month year)
+ (nth 3 item))))
+ items)))
+
(provide 'mixi)
;;; mixi.el ends here