use cooper theme -- end of git, I am trying livemesh
[srid.dotfiles.git] / emacs / external / ljupdate / lj-edit.el
blobf1399415582f529ba0adb4d4ce847731b619d269
1 ;;; lj-edit.el --- post editing for ljupdate
2 ;; Copyright (C) 2002, 2003, 2004, 2005 Edward O'Connor <ted@oconnor.cx>
3 ;; Copyright (C) 2006 Paul Huff <paul.huff@gmail.com>
5 ;; Author: Edward O'Connor <ted@oconnor.cx>
6 ;; Author: Paul Huff <paul.huff@gmail.com>
7 ;; Keywords: convenience
9 ;; This file is an addition to ljupdate, a LiveJournal client for Emacs.
11 ;; ljupdate is free software; you can redistribute it and/or
12 ;; modify it under the terms of the GNU General Public License as
13 ;; published by the Free Software Foundation; either version 2, or
14 ;; {at your option} any later version.
16 ;; ljupdate is distributed in the hope that it will be useful, but
17 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ;; General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING, or type `C-h C-c'. If
23 ;; not, write to the Free Software Foundation at this address:
25 ;; Free Software Foundation
26 ;; 51 Franklin Street, Fifth Floor
27 ;; Boston, MA 02110-1301
28 ;; USA
30 ;;; Commentary:
33 ;;; History:
36 ;;; Code:
37 (require 'cl)
38 (require 'message)
39 (require 'sendmail)
41 (require 'lj-compose)
42 (require 'lj-custom)
43 (require 'lj-acct)
44 (require 'lj-fill)
45 (require 'lj-pcomplete)
46 (require 'lj-protocol)
47 (require 'lj-login)
48 (require 'lj-util)
50 (defun lj-edit-post (&optional edit-itemid)
51 (interactive)
52 (message (if edit-itemid
53 (concat "Editing id: " edit-itemid)
54 "Editing last post."))
55 (let* ((edit-server (or lj-last-server lj-default-server
56 "www.livejournal.com"))
57 (edit-username (or lj-last-username lj-default-username ""))
58 (edit-request (list '("mode" . "getevents")
59 '("auth_method" . "challenge")
60 '("ver" . "1")
61 '("selecttype" . "one")
62 (cons "itemid" (if edit-itemid
63 edit-itemid
64 "-1"))
66 (edit-challenge (lj-getchallenge edit-server)))
67 (when (string= edit-username "")
68 (setq edit-username (read-from-minibuffer (format "Username @%s: " edit-server))))
69 (add-to-list 'edit-request (cons "user" edit-username))
70 (add-to-list 'edit-request (cons "auth_challenge" edit-challenge))
71 (add-to-list 'edit-request
72 (cons "auth_response"
73 (lj-md5 (concat edit-challenge (lj-password edit-server edit-username)))))
74 (let ((edit-response (lj-protocol-send-request edit-server edit-request)))
75 (with-output-to-temp-buffer "lj-list"
76 (set-buffer "lj-list")
77 ;; (lj-list-props response)
78 (if (not (eq (get-buffer "*LiveJournal*") nil))
79 (kill-buffer (get-buffer "*LiveJournal*")))
80 (lj-compose)
81 (goto-char (- 1 (lj-compose-find-separator)))
82 (lj-add-props edit-response edit-server edit-username)
83 (goto-char (+ 1 (lj-compose-find-separator)))
84 (insert (replace-regexp-in-string "\r" "" (decode-coding-string (string-make-unibyte (lj-html-decode-string (gethash "events_1_event" edit-response))) lj-coding-system)))
85 )))(delete-windows-on "lj-list"))
87 (defun lj-add-prop (prop value)
88 (let ((found-field (message-position-on-field prop)))
89 (beginning-of-line)
90 (re-search-forward (concat "^" (regexp-quote prop) ":") nil t)
91 (kill-region (point) (line-end-position))
92 (insert (concat " " value))))
94 (defun lj-add-props-helper (response n)
95 (if (> n 0)
96 (progn
97 (let ((prop_name (gethash (concat "prop_" (number-to-string n) "_name") response))
98 (prop_value (gethash (concat "prop_" (number-to-string n) "_value") response)))
99 (cond ((string= prop_name "current_mood") (lj-add-prop "Mood" prop_value))
100 ((string= prop_name "current_music") (lj-add-prop "Music" prop_value))
101 ((string= prop_name "taglist") (lj-add-prop "Tags" prop_value))
102 ((string= prop_name "picture_keyword") (lj-add-prop "Picture" prop_value))
103 ((and (string= prop_name "opt_nocomments") (string= prop_value "1"))
104 (lj-add-prop "Allow-Comments" "no"))
105 ((and (string= prop_name "opt_noemail") (string= prop_value "1"))
106 (lj-add-prop "Receive-Mail-Notification" "no"))
108 (lj-add-props-helper response (- n 1)))))
110 (defun lj-add-props (response edit-server edit-username)
111 (let ((subject (gethash "events_1_subject" response)))
112 (when subject
113 (lj-add-prop "Subject" subject)))
114 (let ((time (gethash "events_1_eventtime" response)))
115 (when time
116 (lj-add-prop "Time" time)))
117 (let ((itemid (gethash "events_1_itemid" response)))
118 (when itemid
119 (lj-add-prop "Itemid" itemid)))
121 (let* ((access (gethash "events_1_security" response))
122 (allowmask (gethash "events_1_allowmask" response)))
123 (if (stringp access)
124 (cond ((string-match "public" access)
125 (lj-add-prop "Access" "public"))
126 ((string-match "private" access)
127 (lj-add-prop "Access" "private"))
128 ((string-match "usemask" access)
129 (if (eq (truncate (log (string-to-number allowmask) 2)) 0)
130 (lj-add-prop "Access" "friends")
131 (lj-add-prop "Access" (car (rassoc (truncate (log (string-to-number allowmask) 2)) (lj-user-get edit-server edit-username :friends-groups)))))))))
132 (lj-add-props-helper response (string-to-number (gethash "prop_count" response))))
133 ;;;###autoload
134 ;; (defun lj-edit-submit ()
135 ;; "Submit this entry to the server."
136 ;; (interactive)
137 ;; (let* ((buf (current-buffer))
138 ;; ;; The text of the entry.
139 ;; (event (lj-compose-prepare-body))
141 ;; ;; Some convenience variables for oft-used headers
142 ;; (server (lj-compose-fetch-field "Server"))
143 ;; (user (lj-compose-fetch-field "User"))
144 ;; (itemid (lj-compose-fetch-field "Itemid"))
145 ;; ;; The current time -- or use the specified time if it exists
146 ;; (time (lj-compose-fetch-field "Time"))
147 ;; (timestamp (if (eq nil time)
148 ;; ()
149 ;; (date-to-time (concat time " " (cadr (current-time-zone))))))
151 ;; (time (split-string (format-time-string "%Y:%m:%d:%H:%M" timestamp) "[:]"))
152 ;; (year (pop time))
153 ;; (month (pop time))
154 ;; (day (pop time))
155 ;; (hour (pop time))
156 ;; (minute (pop time))
158 ;; ;; LJ Authentication information
159 ;; challenge
161 ;; ;; The actual request packet, and the response we receive from
162 ;; ;; the server.
163 ;; (request (list '("mode" . "editevent")
164 ;; '("auth_method" . "challenge")
165 ;; '("ver" . "1")
166 ;; (cons "itemid" itemid)
167 ;; (cons "year" year)
168 ;; (cons "mon" month)
169 ;; (cons "day" day)
170 ;; (cons "hour" hour)
171 ;; (cons "min" minute)
172 ;; (cons "event" event))))
174 ;; ;; Build up the request packet.
175 ;; (add-to-list 'request (cons "user" user))
177 ;; (let ((subject (lj-compose-fetch-field "Subject")))
178 ;; (when subject
179 ;; (add-to-list 'request (cons "subject" subject))))
180 ;; ;; FIXME: use moodid if available
181 ;; (let ((mood (lj-compose-fetch-field "Mood")))
182 ;; (when mood
183 ;; (add-to-list 'request (cons "prop_current_mood" mood))))
185 ;; (let ((tags (lj-compose-fetch-field "Tags")))
186 ;; (when tags
187 ;; (add-to-list 'request (cons "prop_taglist" tags))))
189 ;; (let ((music (lj-compose-fetch-field "Music")))
190 ;; (when music
191 ;; (add-to-list 'request (cons "prop_current_music" music))))
193 ;; (let ((community (lj-compose-fetch-field "Community")))
194 ;; (when community
195 ;; (add-to-list 'request (cons "usejournal" community))))
197 ;; (let ((picture (lj-compose-fetch-field "Picture")))
198 ;; (when picture
199 ;; (add-to-list 'request (cons "prop_picture_keyword" picture))))
201 ;; (let ((comments (lj-compose-fetch-field "Allow-Comments")))
202 ;; (when (and comments (string-match "[Nn][Oo]" comments))
203 ;; (add-to-list 'request '("prop_opt_nocomments" . "1"))))
205 ;; (let ((email (lj-compose-fetch-field "Receive-Mail-Notification")))
206 ;; (when (and email (string-match "[Nn][Oo]" email))
207 ;; (add-to-list 'request '("prop_opt_noemail" . "1"))))
209 ;; (let* ((access (lj-compose-fetch-field "Access"))
210 ;; (friends-group-number
211 ;; (cdr (assoc access (lj-user-get server user :friends-groups)))))
212 ;; (if (stringp access)
213 ;; (cond ((string-match "public" access)
214 ;; (add-to-list 'request '("security" . "public")))
215 ;; ((string-match "private" access)
216 ;; (add-to-list 'request '("security" . "private")))
217 ;; ((string-match "friends" access)
218 ;; (add-to-list 'request '("allowmask" . "1"))
219 ;; (add-to-list 'request '("security" . "usemask")))
220 ;; (friends-group-number
221 ;; (add-to-list 'request (cons "allowmask"
222 ;; (lj-exp2 friends-group-number)))
223 ;; (add-to-list 'request '("security" . "usemask")))
224 ;; (t
225 ;; (warn "Unable to understand Access: %s; presuming private.")
226 ;; (add-to-list 'request '("security" . "private"))))
227 ;; (add-to-list 'request '("security" . "public"))))
229 ;; ;; Actually talk to the LJ server.
230 ;; (message "Connecting to `%s' as `%s'. Please wait." server user)
231 ;; (setq challenge (lj-getchallenge server))
233 ;; (add-to-list 'request (cons "auth_challenge" challenge))
234 ;; (add-to-list 'request
235 ;; (cons "auth_response"
236 ;; (lj-md5 (concat challenge (lj-password server user)))))
238 ;; (message "Submitting to `%s' as `%s'. Please wait." server user)
240 ;; (let ((response (lj-protocol-send-request server request)))
241 ;; (set-buffer buf) ; return to the *LiveJournal* buffer
242 ;; (if (and (hash-table-p response)
243 ;; (string= (gethash "success" response) "OK"))
244 ;; (progn
245 ;; (set-buffer-modified-p nil)
246 ;; (message "Successfully posted as %s." (gethash "url" response))
247 ;; t)
248 ;; (let ((errmsg (gethash "errmsg" response)))
249 ;; (if errmsg
250 ;; (message "Posting to %s failed: %s" server errmsg)
251 ;; (message "Posting to %s failed!" server)))
252 ;; nil))))
254 (defun lj-html-decode-string (string)
255 (interactive)
256 (let ((string (replace-regexp-in-string "%\\([0-9A-F]\\{2\\}\\)" (lambda (match) (char-to-string (string-to-number (substring match 1) 16))) string)))
257 (replace-regexp-in-string "+" " " string)))
259 (defun lj-list-props (response n)
260 (interactive)
261 (if (> n 0)
262 (progn
263 (insert (gethash (concat "prop_" (number-to-string n) "_name") response))
264 (insert "\t")
265 (insert (gethash (concat "prop_" (number-to-string n) "_value") response))
266 (insert "\n")
267 (lj-list-props response (- n 1)))))
269 (defun lj-insert-entry-into-entry-list (hash n)
270 (lexical-let* ((event_string (concat "events_" (number-to-string n)))
271 (event_subject (concat event_string "_subject"))
272 (event_time (concat event_string "_eventtime"))
273 (event_itemid_string (concat event_string "_itemid"))
274 (event_itemid (gethash event_itemid_string hash))
275 (button_start -1)
276 (button_end -1)
277 (which_event n))
278 (if (<= n (string-to-number (gethash "events_count" hash)))
279 (progn
280 (insert-button (concat (gethash event_time hash) " - "
281 (if (gethash event_subject hash)
282 (gethash event_subject hash)
283 "(no subject)")) 'action (lambda (event) (lj-edit-post event_itemid)))
284 (insert "\n")
285 (lj-insert-entry-into-entry-list hash (+ n 1))))))
287 (defun lj-get-last-n (n)
288 (let* ((server (or lj-last-server lj-default-server
289 "www.livejournal.com"))
290 (username (or lj-last-username lj-default-username ""))
291 (request (list '("mode" . "getevents")
292 '("auth_method" . "challenge")
293 '("ver" . "1")
294 '("selecttype" . "lastn")
295 (cons "howmany" (number-to-string n))))
296 (challenge (lj-getchallenge server)))
297 (when (string= username "")
298 (setq username (read-from-minibuffer (format "Username @%s: " server))))
299 (add-to-list 'request (cons "user" username))
300 (add-to-list 'request (cons "auth_challenge" challenge))
301 (add-to-list 'request
302 (cons "auth_response"
303 (lj-md5 (concat challenge (lj-password server username)))))
304 (let ((response (lj-protocol-send-request server request)))
305 (with-output-to-temp-buffer "lj-list"
306 (set-buffer "lj-list")
307 (lj-insert-entry-into-entry-list response 1)
308 (print-help-return-message)))))
310 ;;;###autoload
311 (defun lj-browse-entries ()
312 (interactive)
313 (lj-get-last-n 10))
315 ;;;###autoload
316 (defalias 'lj-edit-last 'lj-edit-post)
318 (provide 'lj-edit)
320 (provide 'lj-edit)
322 ;;; lj-edit.el ends here