git.fiddlerwoaroof.com
Browse code

Initial working commit

fiddlerwoaroof authored on 24/03/2016 04:11:23
Showing 5 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,33 @@
1
+Simple command line utility to query the Index Thomisticus hosted on Corpus Thomisticum
2
+and display the results.
3
+
4
+# Installation:
5
+
6
+To install from source:
7
+
8
+- Get sbcl: [http://www.sbcl.org](http://www.sbcl.org)
9
+- Get quicklisp: [https://www.quicklisp.org/beta/](https://www.quicklisp.org/beta/)
10
+- Get buildapp: `sbcl --eval '(ql:quickload :buildapp)' --eval '(buildapp:build-buildapp)' --exit`
11
+- Build this project: `./buildapp  --load ~/quicklisp/setup.lisp --eval '(push (truename #p".")
12
+  asdf:*central-registry*)' --load-system `basename $PWD` --entry indexthomisticus-client::main --output
13
+  it-lookup --compress-core`
14
+
15
+# Usage:
16
+
17
+```
18
+./it-lookup '=ordo' '=dicit'
19
+```
20
+
21
+This form displays the results for the query '=ordo =dicit' and prompts for further commands or queries.
22
+Note that, if you use any of the search operators supported by corpus thomisticum, you probably should 
23
+quote the query: i.e. not `./it-lookup =ordo =dicit` but either `./it-lookup '=ordo' '=dicit'` or
24
+`./it-lookup '=ordo =dicit'`
25
+
26
+```
27
+./it-lookup
28
+```
29
+
30
+This just prompts for commands or queries.
31
+
32
+When at the `Query?` prompt, `next` will bring up the next page of results. `prev` brings up the previous
33
+page of results. `quit` exits. and anything else is submitted as a query to Corpus Thomisticum.
0 34
new file mode 100644
... ...
@@ -0,0 +1,15 @@
1
+;;;; indexthomisticus-client.asd
2
+
3
+(asdf:defsystem #:indexthomisticus-client
4
+  :description "Describe indexthomisticus-client here"
5
+  :author "Your Name <your.name@example.com>"
6
+  :license "Specify license here"
7
+  :depends-on (:alexandria
8
+                :serapeum
9
+                :fwoar.lisputils
10
+                :drakma
11
+                :lquery)
12
+  :serial t
13
+  :components ((:file "package")
14
+               (:file "indexthomisticus-client")))
15
+
0 16
new file mode 100644
... ...
@@ -0,0 +1,102 @@
1
+;;;; indexthomisticus-client.lisp
2
+
3
+(in-package #:indexthomisticus-client)
4
+
5
+;;; "indexthomisticus-client" goes here. Hacks and glory await!
6
+
7
+(defparameter *post-url*  "http://www.corpusthomisticum.org/it/index.age")
8
+
9
+(defparameter *cookie-jar* (make-instance 'drakma:cookie-jar))
10
+
11
+(defun run-query (query &optional (page 1))
12
+  (drakma:http-request *post-url*
13
+                       :method :POST
14
+                       :parameters `(("text" . ,query)
15
+                                     ("Form.option.concordances" . "concordances")
16
+                                     ("results.currentPage" . ,(prin1-to-string page)))
17
+                       :cookie-jar *cookie-jar*))
18
+
19
+(defclass it-case ()
20
+  ((reference :initarg :reference :accessor case-reference)
21
+   (text :initarg :text :accessor case-text)))
22
+
23
+(defmethod initialize-instance :after ((object it-case) &key)
24
+  (with-slots (reference text) object
25
+    (when (arrayp reference)
26
+      (setf reference (elt reference 0)))
27
+    (when (plump:element-p reference)
28
+      (setf reference (plump-dom:text reference)))
29
+    (setf text (subseq text (+ (search reference text) (length reference))))
30
+    (setf reference (string-right-trim '(#\space) reference))
31
+    ))
32
+
33
+(defmacro make-constructor (class &rest initargs)
34
+  (let ((initarg-syms (mapcar #'(lambda (x) x (gensym)) initargs)))
35
+    `(defun ,(intern (concatenate 'string (string 'make-) (string class))) ,initarg-syms
36
+       (make-instance ',class ,@(loop for initarg in initargs
37
+                                     for sym in initarg-syms
38
+                                     nconc (list initarg sym))))))
39
+
40
+(make-constructor it-case :reference :text)
41
+
42
+(defun parse-results (query-result)
43
+  (lquery:$ (initialize query-result) "p[title]" (:combine ".ref" (text)) (map-apply #'make-it-case)))
44
+
45
+(defun format-result (parsed-result &optional (stream t))
46
+  (with-slots (reference text) parsed-result
47
+    (pprint-logical-block (stream nil)
48
+      (princ reference stream)
49
+      (pprint-indent :block 4 stream)
50
+      (pprint-newline :mandatory stream)
51
+      (pprint-logical-block (stream (split-sequence #\space text))
52
+        (loop
53
+              (princ (pprint-pop) stream)
54
+              (pprint-exit-if-list-exhausted)
55
+              (princ #\space stream)
56
+              (pprint-newline :fill stream))))))
57
+
58
+(defun format-results (parsed-results &optional (stream t))
59
+  (fresh-line stream)
60
+  (loop :for parsed-results :across parsed-results
61
+        :do (format-result parsed-results stream)
62
+        :do (terpri stream)))
63
+
64
+(defmacro compose-funcs ((&rest funcs) &rest args)
65
+  `(funcall (compose ,@funcs) ,@args))
66
+
67
+(defun main (args)
68
+  (handler-case
69
+    (let ((current-page 1)
70
+          current-query)
71
+      (flet ((next-page () (incf current-page))
72
+             (prev-page ()
73
+               (when (> current-page 0)
74
+                 (decf current-page)))
75
+             (get-results (current-query current-page)
76
+               (compose-funcs (#'format-results #'parse-results #'run-query)
77
+                              current-query current-page)))
78
+
79
+        (format *terminal-io* "~&Index Thomisticus Query Utility v0.1~%")
80
+
81
+        (when (cadr args)
82
+          (setf current-query (string-join (cdr args) #\space))
83
+          (format *terminal-io* "~&Query: ~a~%" current-query)
84
+          (get-results current-query current-page))
85
+        (loop
86
+          (format *terminal-io* "~&Query? ")
87
+          (finish-output *terminal-io*)
88
+          (let ((action (read-line *terminal-io*)))
89
+            (string-case action
90
+              ("quit" (return-from main))
91
+              ("prev"
92
+               (prev-page)
93
+               (format *terminal-io* "~&Query: ~a, Page: ~3d~%" current-query current-page)
94
+               (get-results current-query current-page))      
95
+              ("next"
96
+               (next-page)
97
+               (format *terminal-io* "~&Query: ~a, Page: ~3d~%" current-query current-page)
98
+               (get-results current-query current-page))      
99
+              (t (setf current-query action)
100
+                 (get-results current-query current-page)))))))
101
+    (end-of-file (c) (declare (ignore c)))
102
+    (sb-sys:interactive-interrupt (c) (declare (ignore c)))))
0 103
new file mode 100755
1 104
Binary files /dev/null and b/it-lookup.lx differ
2 105
new file mode 100644
... ...
@@ -0,0 +1,5 @@
1
+;;;; package.lisp
2
+
3
+(defpackage #:indexthomisticus-client
4
+  (:use #:cl #:alexandria #:serapeum #:fwoar.lisputils))
5
+