Skip to content

Instantly share code, notes, and snippets.

@youz
Created December 25, 2011 06:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save youz/1518798 to your computer and use it in GitHub Desktop.
Save youz/1518798 to your computer and use it in GitHub Desktop.
read it later viewer for xyttr
;;; -*- mode:lisp; package: xyttr -*-
(eval-when (:compile-toplevel :load-toplevel :execute)
(require "xyttr"))
(in-package :xyttr)
(defvar *ril-baseurl* "https://readitlaterlist.com/v2/")
(defvar *ril-apikey* "xxxxxxxxxx") ; http://readitlaterlist.com/api/signup/ より取得して設定
(defvar *ril-user* nil) ; ReadItLater ユーザー名
(defvar *ril-pass* nil) ; パスワード
;;; Read It Later API Documentation
;;; http://readitlaterlist.com/api/docs/
(defun ril-request (command params)
(let ((url (format nil "~A~A" *ril-baseurl* command))
(q `(:apikey ,*ril-apikey* :username ,*ril-user* :password ,*ril-pass*
,@params)))
(multiple-value-bind (res status headers)
(xhr:xhr-get url :query q :since :epoch
:key #'xhr:xhr-response-values)
(if (<= 200 status 209) res
(error "~A" res)))))
(defun ril-request-async (command params &key onsuccess onfailure)
(let ((url (format nil "~A~A" *ril-baseurl* command))
(q `(:apikey ,*ril-apikey* :username ,*ril-user* :password ,*ril-pass*
,@params)))
(xhr:xhr-get-async
url :query q :key #'xhr:xhr-response-values
:since :epoch
:onsuccess (lambda (res status headers)
(when onsuccess
(funcall onsuccess res)))
:onfailure onfailure)))
(defun ril-add (url &optional title)
(ril-request-async
:add `(:url ,url :title ,(or title url))
:onsuccess (lambda (res) (message "Done: ~A" url))
:onfailure (lambda (res status headers) (message "Failed: ~A" res))))
(defun ril-mark-as-read (url)
(let ((json (format nil "{\"0\":{\"url\":~S}}" url)))
(ril-request-async
:send `(:read ,json)
:onsuccess (lambda (res) (message "Marked as read: ~A" url))
:onfailure (lambda (res status headers) (message "Failed: ~A" res)))))
(defun ril-getall (&key since (state "unread") onsuccess onfailure)
(let ((q `(:format :json :since ,since :state ,state)))
(ril-request-async
:get q
:onsuccess
(lambda (res) (funcall onsuccess (json:json-decode res)))
:onfailure
(or onfailure (lambda (res status headers) (message "Failed: ~A" res))))))
(defun utc2ut (utc)
(+ utc #.(encode-universal-time 0 0 0 1 1 1970 0)))
(defun ril-entry-to-tweet (entry)
(w/json (title url time_updated time_added state) (cdr entry)
(let ((time (format-date-string "%a %b %d %H:%M:%S %Z %Y"
(utc2ut (parse-integer time_updated)))))
`(("id" . ,time_updated)
("user" ("screen_name" . "my_readitlater"))
("text" . ,(format nil "~A~%~A" title url))
("created_at" . ,time)
("ril"
("url" . ,url)
("title" . ,title)
("time_updated" . ,time_updated)
("time_added" . ,time_added)
("state" . ,state))))))
(defun api-ril-getall-async (&key since_id max_id onsuccess onfailure)
(when max_id
(return-from api-ril-getall-async nil))
(ril-getall
:since since_id
:onsuccess
(lambda (res)
(w/json (since list) res
(when list
(let ((cnv (mapcar #'ril-entry-to-tweet list)))
(setf (json-value (car cnv) id) since)
(funcall onsuccess cnv)))))
:onfailure onfailure))
(defun ril-mark-as-read-focused-url ()
(interactive)
(whenlet url (focused-url)
(ril-mark-as-read url)))
(defun ril-list-mode ()
(let ((km (copy-keymap *xyttr-timeline-keymap*)))
(define-key km #\m 'ril-mark-as-read-focused-url)
(use-keymap km)))
(defvar *ril-list-hook* nil)
(add-hook '*ril-list-hook* #'ril-list-mode)
(define-tl-command readitlater ()
:buffer-name "*ril*"
:api-func #'api-ril-getall-async
:hook '*ril-timeline-hook*
:auto-reload 3600)
(defun ril-focused-url ()
(interactive)
(whenlet url (expand-focused-url)
(w/entry (user.screen_name text)
(ril-add url (format nil "@~A: ~A" user.screen_name text)))))
(define-key *xyttr-timeline-keymap* '(#\r #\i #\l) 'ril-focused-url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment