1
0
Переглянути джерело

Initial version, load latest akb tweets

Innocenty Enikeew 10 роки тому
коміт
3555330ba9
6 змінених файлів з 87 додано та 0 видалено
  1. 1 0
      .gitignore
  2. 16 0
      chatikbot.asd
  3. 21 0
      chatikbot.lisp
  4. 5 0
      package.lisp
  5. 28 0
      twitter.lisp
  6. 16 0
      utils.lisp

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+config.lisp

+ 16 - 0
chatikbot.asd

@@ -0,0 +1,16 @@
+;;;; chatikbot.asd
+(asdf:defsystem #:chatikbot
+  :description "Chatik Telegram bot"
+  :author "Innokentiy Enikeev <me@enikesha.net>"
+  :license "MIT"
+  :depends-on (#:alexandria
+               #:flexi-streams
+               #:yason
+               #:cl-oauth
+               #:trivial-utf-8)
+  :serial t
+  :components ((:file "package")
+               (:file "utils")
+               (:file "twitter")
+               (:file "chatikbot")
+               ))

+ 21 - 0
chatikbot.lisp

@@ -0,0 +1,21 @@
+(in-package #:chatikbot)
+
+;; Load config file
+(alexandria:when-let (file (probe-file
+                            (merge-pathnames "config.lisp"
+                                             (asdf:component-pathname
+                                              (asdf:find-system '#:chatikbot)))))
+  (load file))
+
+
+
+(defparameter +akb-user-id+ "3021296351" "Twitter user id of 'B-category anecdotes'")
+(defvar *akb-max-count* 5 "Max number of tweets to return per run")
+(defvar *akb-last-id* nil "id of last AKB tweet")
+
+(defun fetch-latest-akb ()
+  (loop for (id . text) in (get-tweets +akb-user-id+
+                                       :since-id *akb-last-id*
+                                       :count *akb-max-count*)
+     do (setf *akb-last-id* (max (or *akb-last-id* 0) id))
+     collect text))

+ 5 - 0
package.lisp

@@ -0,0 +1,5 @@
+(defpackage #:chatikbot
+  (:use #:cl)
+  (:export #:*twitter-access-token*))
+
+(in-package #:chatikbot)

+ 28 - 0
twitter.lisp

@@ -0,0 +1,28 @@
+(in-package #:chatikbot)
+
+(defvar *twitter-access-token* nil "OAuth access token")
+
+(defparameter *timeline-url* "https://api.twitter.com/1.1/statuses/user_timeline.json")
+
+(defun get-tweets (user-id &key since-id (count 5))
+  (loop for status in
+       (yason:parse
+                 (flexi-streams:octets-to-string
+                  (cl-oauth:access-protected-resource
+                   (format nil "~A?~A"
+                           *timeline-url*
+                           (cl-oauth::alist->query-string
+                            (remove-if
+                             (complement #'cdr)
+                             (list
+                              (cons "user_id" user-id)
+                              (cons "count" count)
+                              (cons "since_id" since-id)
+                              (cons "trim_user" 1)
+                              (cons "exclude_replies" 1)))
+                            :include-leading-ampersand nil))
+                   *twitter-access-token*))
+                 :object-as :alist)
+     collect (cons
+              (cdr (assoc "id" status :test #'equal))
+              (cdr (assoc "text" status :test #'equal)))))

+ 16 - 0
utils.lisp

@@ -0,0 +1,16 @@
+(in-package #:chatikbot)
+
+(defun replace-all (string part replacement &key (test #'char=))
+"Returns a new string in which all the occurences of the part
+is replaced with replacement."
+    (with-output-to-string (out)
+      (loop with part-length = (length part)
+            for old-pos = 0 then (+ pos part-length)
+            for pos = (search part string
+                              :start2 old-pos
+                              :test test)
+            do (write-string string out
+                             :start old-pos
+                             :end (or pos (length string)))
+            when pos do (write-string replacement out)
+            while pos)))