Skip to content

Instantly share code, notes, and snippets.

@nfunato
Last active August 29, 2015 14:23
Show Gist options
  • Select an option

  • Save nfunato/9ee602523937477008e5 to your computer and use it in GitHub Desktop.

Select an option

Save nfunato/9ee602523937477008e5 to your computer and use it in GitHub Desktop.
;;; CAUTION: this code is not fully tested!
(ql:quickload
;; FIXME: use lquery rather than plump if preferable
'(
:drakma ; a full-featured common lisp http client
:plump ; a parser for HTML/XML like document
:clss ; a DOM traversal engine based on CSS selectors
:cl-redis ; a client library for Redis database, an advanced K/V store
;; :chirp ; a twitter client library for common lisp
)
:silent t)
;;; environmental I/F
(defun get-slack-user-token ()
(asdf::getenv "SLACK_TOKEN"))
;;; drakma I/F
(defvar *hbm-get-url* "http://b.hatena.ne.jp/nisemono_san/bookmark")
(defvar *slack-post-url* "https://slack.com/api/chat.postMessage")
(defmacro with-http-error-trap ((msg) &body body)
(let ((ans (gensym)) (stat (gensym)) (hdr (gensym)))
`(multiple-value-bind (,ans ,stat ,hdr) (progn ,@body)
(declare (ignorable ,hdr))
(unless (<= 200 ,stat 299) (error ,msg))
,ans)))
(defun hbm-get ()
(with-http-error-trap ("hatena-bookmark-get")
(drakma:http-request *hbm-get-url*)))
(defun slack-post (channel token text)
(with-http-error-trap ("slack-post")
(drakma:http-request *slack-post-url*
:method :post
:parameters `(("token" . ,token)
("channel" . ,channel)
("text" . ,text)
("as_user" . "true")))))
;;; (get-latest-hatena-bookmark) -- using plump and clss
(defun get-bookmark-block ()
(clss:select ".entry-block" (plump:parse (hbm-get))))
(defun bookmark-elem-p (elem)
(some (lambda (tag) (string= "@" (plump:text tag)))
(clss:select "a.user-tag" elem)))
(defun bookmark-link (elem)
(plump:attribute (elt (clss:select ".entry-title a.entry-link" elem) 0)
"href"))
(defun get-latest-hatena-bookmark ()
(let ((bme (find-if #'bookmark-elem-p (get-bookmark-block))))
(if bme
(bookmark-link bme))))
;;; (hatena->slack) -- working with redis
(defun hatena->slack (&aux (tok (get-slack-user-token)))
(redis:with-connection () ; use default connection "127.0.0.1"
(format t "SLACK TOKEN Settings: ~A ~%" tok)
(let ((lu (red:get :latest-url-redis))
(hb (get-latest-hatena-bookmark)))
(when hb
(format t "Previous URL: ~A ~%" lu)
(format t "Get URL: ~A ~%" hb)
(when (string/= lu hb)
(slack-post "#random" tok hb)
(red:set :latest-url-redis hb))))))
(defun main ()
(format t "Start.~%")
(hatena->slack)
(format t "Done.~%"))
#+:script-top-level ; don't know whether or not such feature exists!
(main)
#|
;;; the original -- http://bugrammer.hateblo.jp/entry/2015/06/20/103000
(let ((*standard-output* (make-broadcast-stream)))
(ql:quickload :cl-redis)
(ql:quickload :drakma)
(ql:quickload :plump)
(ql:quickload :clss)
(ql:quickload :chirp))
(redis:connect :host "127.0.0.1")
(defvar *user-token* (ccl::getenv "SLACK_TOKEN"))
(defvar *latest-url-redis* :latest-bookmark-post)
(defun post-message (channel text token)
(drakma:http-request "https://slack.com/api/chat.postMessage"
:method :post
:parameters `(("token" . ,token)
("channel" . ,channel)
("text" . ,text)
("as_user" . "true"))))
(defun random-> (text)
(post-message "#random" text *user-token*))
(defun hatena-request ()
(plump:parse
(drakma:http-request "http://b.hatena.ne.jp/nisemono_san/bookmark")))
(defun hatena-bookmark-block ()
(clss:select ".entry-block" (hatena-request)))
(defun post-bookmark-p (element)
(let ((tags (concatenate 'list (clss:select "a.user-tag" element))))
(and tags
(remove-if-not
(lambda (x) (string= "@" x))
(mapcar #'plump:text tags)))))
(defun get-bookmark-link (elem)
(plump:attribute (aref (clss:select ".entry-title a.entry-link" elem) 0)
"href"))
(defun latest-hatena-bookmark ()
(let ((bookmark-list
(remove-if-not #'post-bookmark-p
(concatenate 'list (hatena-bookmark-block)))))
(when bookmark-list
(get-bookmark-link bookmark-list))))
(defun hatena->slack ()
(let ((hatena-bookmark (latest-hatena-bookmark)))
(format t "Get URL: ~A ~%" hatena-bookmark)
(format t "Previous URL: ~A ~%" (red:get *latest-url-redis*))
(when (string/= (red:get *latest-url-redis*) hatena-bookmark)
(progn
(random-> hatena-bookmark)
(red:set *latest-url-redis* hatena-bookmark)))))
(format t "Start.~%")
(format t "SLACK TOKEN Settings: ~A ~%" *user-token*)
(hatena->slack)
(format t "Done.~%")
|#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment