Advertisement
Shinmera

Colleen/modules/dramatica.lisp

Nov 28th, 2013
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 9.54 KB | None | 0 0
  1. #|
  2.   This file is a part of Colleen
  3.   (c) 2013 TymoonNET/NexT http://tymoon.eu (shinmera@tymoon.eu)
  4.   Author: Nicolas Hafner <shinmera@tymoon.eu>
  5. |#
  6.  
  7. (in-package :org.tymoonnext.colleen)
  8. (defpackage org.tymoonnext.colleen.mod.dramatica
  9.   (:use :cl :colleen)
  10.   (:shadowing-import-from :colleen :restart))
  11. (in-package :org.tymoonnext.colleen.mod.dramatica)
  12.  
  13. (ql:quickload :cl-wiki)
  14. (ql:quickload :xencl)
  15.  
  16. (define-module dramatica ()
  17.     ((%log-running :initarg :log-running :initform NIL :accessor log-running)
  18.      (%log-loop :initarg :log-loop :initform NIL :accessor log-loop))
  19.   (:documentation "Module related to Encyclopedia Dramatica activities."))
  20.  
  21. (define-group ed :documentation "Interact or change ED settings.")
  22.  
  23. (defmethod start ((dramatica dramatica))
  24.   (setf wiki:*wiki-api* (config-tree :dramatica :wiki :api))
  25.   (when (> (length (config-tree :dramatica :wiki :pass)) 0)
  26.     (wiki:login (config-tree :dramatica :wiki :user)
  27.                 (config-tree :dramatica :wiki :pass)))
  28.   (when (> (length (config-tree :dramatica :forum :pass)) 0)
  29.     (xencl:initiate (config-tree :dramatica :forum :url)
  30.                     (config-tree :dramatica :forum :user)
  31.                     (config-tree :dramatica :forum :pass))))
  32.  
  33. (defmethod stop ((dramatica dramatica))
  34.   (setf (config-tree :dramatica :wiki :api) wiki:*wiki-api*)
  35.   (setf (config-tree :dramatica :forum :url) xencl:*index*))
  36.  
  37. ;;;;;;;;;;;; RECENT CHANGES
  38.  
  39. (define-command (ed recent-changes) (&optional start-or-stop) (:authorization T :documentation "Start or stop the recent-changes polling.")
  40.   (cond
  41.     ((string-equal start-or-stop "start")
  42.      (if (log-loop dramatica)
  43.          (respond event "Polling is already activated!")
  44.          (progn
  45.            (start-log-loop dramatica)
  46.            (respond event "Recent-changes polling activated."))))
  47.  
  48.     ((string-equal start-or-stop "stop")
  49.      (if (log-loop dramatica)
  50.          (progn
  51.            (stop-log-loop dramatica)
  52.            (respond event "Recent-changes polling deactivated."))
  53.          (respond event "Polling is already deactivated!")))
  54.    
  55.     (T (respond event "Recent changes polling is ~:[deactivated~;activated~]" (log-loop dramatica)))))
  56.  
  57. (defun start-log-loop (dramatica)
  58.   (v:info :dramatica.recentchanges "Starting log-loop.")
  59.   (setf (log-running dramatica) T
  60.         (log-loop dramatica) (bordeaux-threads:make-thread #'(lambda () (wiki-log-loop dramatica)))))
  61.  
  62. (defun stop-log-loop (dramatica)
  63.   (v:info :dramatica.recentchanges "Stopping log-loop.")
  64.   (setf (log-running dramatica) NIL)
  65.   ;; Wait for timeout or terminate.
  66.   (loop for i from 0 to 10
  67.      while (and (log-loop dramatica)
  68.                 (bordeaux-threads:thread-alive-p (log-loop dramatica)))
  69.      do (sleep 1)
  70.      finally (progn
  71.                (when (and (>= i 10) (log-loop dramatica) (bordeaux-threads:thread-alive-p (log-loop dramatica)))
  72.                  (bordeaux-threads:destroy-thread (log-loop dramatica)))
  73.                (setf (log-loop dramatica) NIL))))
  74.  
  75. (defun wiki-log-loop (dramatica)
  76.   (let ((latest-timestamp
  77.          (multiple-value-bind (query timestamp) (wiki:recent-changes :limit 1 :type :log)
  78.            (declare (ignore query)) timestamp))
  79.         (last-id 0))
  80.     (loop while (log-running dramatica)
  81.        do (sleep 10)
  82.          (v:debug :dramatica.recentchanges "Querying log.")
  83.          (handler-case
  84.              (let ((query (wiki:recent-changes :end latest-timestamp :limit 1000 :type :log :properties '(user comment loginfo timestamp title))))
  85.                (setf latest-timestamp (cdr (assoc :timestamp (first query))))
  86.                (v:trace :dramatica.recentchanges "Log return: ~a" query)
  87.                (dolist (log query)
  88.                  (when (> (cdr (assoc :logid log)) last-id)
  89.                    (setf last-id (cdr (assoc :logid log)))
  90.                    (v:info :dramatica.recentchanges "New log entry: ~a" log)
  91.                    
  92.                    (handle-log (cdr (assoc :logtype log))
  93.                                (cdr (assoc :title log))
  94.                                (cdr (assoc :comment log)))))))))
  95.   (setf (log-loop dramatica) NIL))
  96.  
  97. (defun handle-log (logtype title comment)
  98.   (cond
  99.     ((string= logtype "block")
  100.      (let* ((page title)
  101.             (page-content (wiki:page-get page)))
  102.        (if (search "{{banned}}" page-content)
  103.            (v:warn :dramatica.handle-log "<~a> Ban message already set!" page)
  104.            (handler-case
  105.                (progn
  106.                  (if (search "spam" comment :test #'char-equal)
  107.                      (wiki:page-edit page "{{banned}}")
  108.                      (wiki:page-prepend page "{{banned}}"))
  109.                  (v:info :dramatica.handle-log "<~a> Ban page created." page))))))
  110.    
  111.     ((string= logtype "newusers")
  112.      (let* ((page (format NIL "User_Talk:~a" (subseq title 5)))
  113.             (page-content (wiki:page-get page)))
  114.        (if (search "{{welcome}}" page-content)
  115.            (v:warn :dramatica.handle-log "<~a> Welcome message already set!" page)
  116.            (progn
  117.              (wiki:page-append page "{{welcome}} ~~~~")
  118.              (v:info :dramatica.handle-log "<~a> Welcome page created." page)))))))
  119.  
  120. ;;;;;;;;;;;; WIKI COMMANDS
  121.  
  122. (define-group wiki :documentation "Commands for the Encyclopedia Dramatica Wiki.")
  123.  
  124. (define-command (wiki api-page) (&optional new-url) (:authorization T :documentation "Change or view the used MediaWiki API URL.")
  125.   (when new-url
  126.     (setf wiki:*wiki-api* new-url))
  127.   (respond event "Used API: ~a" wiki:*wiki-api*))
  128.  
  129. (define-command (wiki login) (&optional username password) (:authorization T :documentation "Log in to the wiki.")
  130.   (handler-case
  131.       (progn
  132.         (wiki:login (or username (config-tree :dramatica :wiki :user))
  133.                     (or password (config-tree :dramatica :wiki :pass)))
  134.         (respond event "Login successful."))
  135.     (error (err)
  136.       (respond event "Error: ~a" err))))
  137.  
  138. (defmacro define-wiki-command (name (&rest args) (&rest options) &body body)
  139.   `(define-command (wiki ,name) ,args ,options
  140.      (handler-case
  141.          (progn ,@body)
  142.        (wiki:wiki-error (err)
  143.          (respond event "Wiki error: ~a (E~a)" (wiki:info err) (wiki:code err))))))
  144.  
  145. (define-wiki-command token () (:authorization T :documentation "Retrieve the edit-token.")
  146.   (respond event "Token: ~a" (wiki:token)))
  147.  
  148. (define-command page (page) (:documentation "Retrieve the contents of a page.")
  149.   (respond event (wiki:page-get page)))
  150.  
  151. (define-command prepend (page &rest content) (:authorization T :documentation "Prepend content to a page.")
  152.   (wiki:page-prepend page (format NIL "~{~a~^ ~}" content))
  153.   (respond event "Page edited."))
  154.  
  155. (define-command append (page &rest content) (:authorization T :documentation "Append content to a page.")
  156.   (wiki:page-append page (format NIL "~{~a~^ ~}" content))
  157.   (respond event "Page edited."))
  158.  
  159. (define-command create (page &rest content) (:authorization T :documentation "Create a new page.")
  160.   (wiki:page-create page (format NIL "~{~a~^ ~}" content))
  161.   (respond event "Page created."))
  162.  
  163. (define-command edit (page &rest content) (:authorization T :documentation "Edit the content of a page.")
  164.   (wiki:page-edit page (format NIL "~{~a~^ ~}" content))
  165.   (respond event "Page edited."))
  166.  
  167. (define-command delete (page) (:authorization T :documentation "Delete a page.")
  168.   (wiki:page-delete page)
  169.   (respond event "Page deleted."))
  170.  
  171. (define-command protect (page &optional (expiry "never") cascade &rest reason) (:authorization T :documentation "Protect a page from edits.")
  172.   (setf cascade (string-equal cascade "yes")
  173.         reason (format NIL "~{~a~^ ~}" reason))
  174.   (wiki:page-protect page :expiry expiry :cascade cascade :reason reason)
  175.   (respond event "Page protected until ~a (~a)~@[~* cascading the protect~]." expiry reason cascade))
  176.  
  177. (define-command rollback (page &rest edit-summary) (:authorization T :documentation "Roll a page back to the previous change.")
  178.   (wiki:page-rollback page :summary (format NIL "~{~a~^ ~}" edit-summary))
  179.   (respond event "Page rollback performed."))
  180.  
  181. (define-command block (user &optional (expiry "never") &rest reason) (:authorization T :documentation "Block a user from the wiki.")
  182.   (setf reason (format NIL "~{~a~^ ~}" reason))
  183.   (wiki:user-block user :expiry expiry :reason reason)
  184.   (respond event "User blocked until ~a (~a)." expiry reason))
  185.  
  186. ;;;;;;;;;;;; FORUM COMMANDS
  187.  
  188. (define-group edf :documentation "Commands for the Encyclopedia Dramatica Forums.")
  189.  
  190. (define-command (edf url) (&optional url) (:authorization T :documentation "View or set the forum URL.")
  191.   (when url
  192.     (setf xencl:*index* url))
  193.   (respond event "Used URL: ~a" xencl:*index*))
  194.  
  195. (defmacro define-edf-command (name (&rest args) (&rest options) &body body)
  196.   `(define-command (edf ,name) ,args ,options
  197.      (handler-case
  198.          (progn ,@body)
  199.        (xencl:forum-error (err)
  200.          (respond event "Forum error: ~a (E~a) ~@[on page ~a~]" (xencl:info err) (xencl:code err) (xencl:page err))))))
  201.  
  202. (define-edf-command login (&optional username password) (:authorization T :documentation "Log in to the forum.")
  203.   (xencl:login (make-instance 'xencl:user
  204.                               :title (or username (config-tree :dramatica :forum :user))
  205.                               :pass (or password (config-tree :dramatica :forum :pass))))
  206.   (respond event "Login successful."))
  207.  
  208. (define-edf-command shoutbox-post (&rest message) (:authorization T :documentation "Posted a message to the shoutbox.")
  209.   (xencl:post (make-instance 'xencl:shoutbox) (format NIL "~{~a~^ ~}" message))
  210.   (respond event "Message posted."))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement