git.fiddlerwoaroof.com
Raw Blame History
(cl:in-package :hhgbot-augmented-assistant)

;; Special Variables
(defparameter *zxcv* *standard-output*)
(defvar *client*)
(defvar *queue-pair* nil)
;; Macros

(defun start-in-repl (&optional (start-bot t) (team-id :atomampd))
  (ubiquitous:restore :hhgbot-augmented-assistant)
  (setf slacker::*api-token* (ubiquitous:value :api-token :atomampd))
  (if start-bot
      (start-with-apitoken team-id)
      slacker::*api-token*))

(defun start-with-apitoken (&optional (team-id :atomampd))
  (unless *queue-pair*
    (setf *queue-pair* (make-instance 'slacker::queue-pair)))

  (ubiquitous:restore :hhgbot-augmented-assistant)
  (let ((slacker::*api-token* (ubiquitous:value :api-token team-id)))
    (unless slacker::*api-token*
      (format *terminal-io* "~&API Token? ")
      (finish-output *terminal-io*)
      (setf slacker::*api-token* (read-line)))
    (values (slacker:coordinate-threads *queue-pair*)
	    slacker::*api-token*)))

(defmacro if-let* ((&rest bindings) &body (then-form &optional else-form))
  "Like if-let, but sets bindings sequentially.  Doesn't short-circuit."
  `(let* ,bindings
     (if (and ,@(mapcar #'car bindings))
       ,then-form
       ,else-form)))
;; Utility functions

(define-command "myip" (event-pump ts channel)
  (in-wq (event-pump)
    (blackbird:alet ((ip (carrier:request "http://api.ipify.org/" :return-body t)))
      (format *zxcv* "~&IP: ~a~%TS: ~a~%CHANNEL: ~a~%CLIENT: ~A~%" (babel:octets-to-string ip) ts channel event-pump)
      (edit-message ts channel
		    (concat "My ip is: "
			    (babel:octets-to-string ip))))))

(define-command "jira" (event-pump ts channel project &optional issue-number &rest rest)
  (let ((drakma:*drakma-default-external-format* :utf-8))
    (apply #'edit-message ts channel
	   (fw.lu:ensure-list
	    (cond (rest
		   "I don't understand . . .")
		  (issue-number
		   (format nil "https://atomampd.atlassian.net/browse/~A-~A"
			   project issue-number))
		  (t
		   (format nil "https://atomampd.atlassian.net/browse/ATOMOS-~a"
			   project)))))))

(define-command "pr" (event-pump ts channel num)
  (let ((num (parse-integer num)))
    (edit-message ts channel (format nil "https://bitbucket.org/atomampd/atomos/pull-requests/~d?w=1" num))))

(define-command "js>" (event-pump ts channel &rest args)
  (declare (ignorable ts))
  (let ((*js-executor* (gethash :js-executor (modules event-pump))))
    (blackbird:alet ((result (submit-js *js-executor*
					(string-join args " "))))
      (let ((result (cl-js:to-string result)))
	(queue-message event-pump channel
		       (subseq result 0
			       (min 1000
				    (length result)))
		       :quote t)))))

(define-command "my-rsa-key" (event-pump ts channel &optional (cipher "rsa"))
  (with-output-to-message (s event-pump  channel :quote t)
    (with-open-file (f (truename (concat "~/.ssh/id_" cipher ".pub"))) 
      (let ((seq (make-string (file-length f))))
	(read-sequence seq f)
	(format s seq)))))

(define-command "paste" (event-pump ts channel)
  (with-simple-restart (abort "Stop command")
    (ubiquitous:restore :atomampd-slack)
    (format t "foo")
    (let ((drakma:*drakma-default-external-format* :utf-8))
      (edit-message ts channel
		    (format nil "```~%~a~%```"
			    (pop (ubiquitous:value :clip)))))))

(define-command "id" (event-pump ts channel &optional (for "channel"))
  (edit-message ts channel
		(string-case for
		  ("channel" channel)
		  (t (concat "don't know the id for " for)))))
    
(defmacro with ((var val) &body body)
  `(let ((,var ,val))
     ,@body))

(ql:quickload '(:vecto :ironclad))

(defun hash-of-vector (vec)
  (ironclad:byte-array-to-hex-string (ironclad:digest-sequence :sha256 vec)))

(defpackage #:vecto-example
  (:use :cl :alexandria :serapeum :slacker :vecto)
  (:shadowing-import-from :alexandria :rotate))

(defparameter *zxcv* *standard-output*)

(define-command "lss" (event-pump ts channel)
  (fw.lu:let-each (:be *)
    #p"~/public_html/Screenshots/"
    (uiop:directory-files *)
    (sort * #'> :key #'file-write-date)
    (car *)
    (uiop/common-lisp:enough-namestring * #p"~/public_html/")
    (concat "https://srv2.elangley.org/~edwlan/" *)
    (slacker.api:chat.post-message channel * :as_user t :icon_emoji "camera_with_flash")))

(in-package :vecto-example)
(defmacro with ((var val) &body body)
  `(let ((,var ,val))
     ,@body))


(defun octets-to-36string (octets)
  (string-join (map 'list (lambda (it)
			    (format nil "~2,1,0,'0@a"
				    (with (*print-base* 36)
				      (write-to-string it ))))
		    octets)))

(defmacro with-digested-output ((stream (data-sym digest-sym)) data-form &body body)
  (with-gensyms (digest-stream data-stream)
    `(let* ((,digest-stream (ironclad:make-digesting-stream :sha256))
	    (,data-stream (ironclad:make-octet-output-stream))
	    (,stream (make-broadcast-stream ,data-stream ,digest-stream)))
       ,data-form
       (let ((,data-sym (ironclad:get-output-stream-octets ,data-stream))
	     (,digest-sym (ironclad:produce-digest ,digest-stream)))
	 ,@body))))

(define-command "ring-word" (event-pump ts channel &optional (content #(#x3BB)))
  (bt:make-thread
   (lambda ()
     (declare (optimize (debug 3)))
     (let ((*default-pathname-defaults* #p"/home/edwlan/github_repos/hhgbot/"))
       (with-canvas (:width 90 :height 90)
	 (let ((font (get-font "times.ttf"))
	       (step (/ pi 7)))
	   (set-font font 40)
	   (translate 45 45)
	   (format hhgbot-augmented-assistant::*zxcv* "~&content: ~s~%" content)
	   (draw-centered-string 0 -10 (map 'vector #'char-code content))
	   (set-rgb-stroke 1 0 0)
	   (centered-circle-path 0 0 35)
	   (stroke)
	   (set-rgba-stroke 0 0 1.0 0.5)
	   (set-line-width 4)
	   (dotimes (i 14)
	     (with-graphics-state
	       (vecto:rotate (* i step))
	       (move-to 30 0)
	       (line-to 40 0)
	       (stroke))))
	 (let* ((image-directory (ensure-directories-exist "/home/edwlan/public_html/slack_images/"))
		(image-basename (concat channel "-" ts ".png"))
		(image-filename (merge-pathnames image-basename image-directory))
		(payload
		 (concat "token=" *api-token*
			 "&channel=" channel
			 "&text=..." 
			 "&as_user=true"
			 "&attachments="
			 (quri:url-encode
			  (concat
			   "[{\"fallback\": \"foo\", \"ts\":" ts ",\"image_url\": \"https://srv2.elangley.org/~edwlan/slack_images/"
			   image-basename "\"}]")))))
	   (vecto:save-png image-filename)
	   (babel:octets-to-string
	    (drakma:http-request "https://slack.com/api/chat.postMessage"
				 :method :post
				 :content payload))))))
     :name "Image Maker"))