summaryrefslogtreecommitdiff
path: root/wikidata/sparql.scm
diff options
context:
space:
mode:
Diffstat (limited to 'wikidata/sparql.scm')
-rw-r--r--wikidata/sparql.scm111
1 files changed, 111 insertions, 0 deletions
diff --git a/wikidata/sparql.scm b/wikidata/sparql.scm
new file mode 100644
index 0000000..5b71152
--- /dev/null
+++ b/wikidata/sparql.scm
@@ -0,0 +1,111 @@
+;;; Copyright © 2018 swedebugia <swedebugia@riseup.net>
+;;;
+;;; This file is part of guile-wikidata.
+;;;
+;;; guile-wikidata is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; guile-wikidata is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with guile-wikidata. If not, see <http://www.gnu.org/licenses/>.
+
+;; See the example-sparql.scm for how to use this library.
+
+(define-module (wikidata sparql)
+ #:use-module (ice-9 format)
+ #:use-module (ice-9 rdelim)
+ #:use-module (ice-9 receive)
+ #:use-module (guix http-client)
+;; #:use-module (guix import utils) ; useful stuff there
+;; #:use-module (sparql driver) ; does not support blazegraph
+;; #:use-module (sparql lang) ; did not work ??
+ #:use-module (sparql util)
+ #:use-module (srfi srfi-1)
+ #:use-module (srfi srfi-34)
+ #:use-module (web uri)
+ #:export (show-sparql))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Low-level proc.
+;; URI-decorators and fetching
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; TODO flesh out http-code from giux into a new guile-http library to
+;; avoid pulling in all of guix in this library.
+(define* (xml-fetch url
+ ;; Note: many websites returns 403 if we omit a
+ ;; 'User-Agent' header.
+ #:key (headers `((user-agent . "GNU Guile")
+ (Accept . "application/json"))))
+ "Return a representation of the JSON resource URL (a list or hash table), or
+#f if URL returns 403 or 404. HEADERS is a list of HTTP headers to pass in
+the query. Returns RESULT from port."
+ (guard (c ((and (http-get-error? c)
+ (let ((error (http-get-error-code c)))
+ (or (= 403 error)
+ (= 404 error))))
+ #f))
+ (let* ((port (http-fetch url #:headers headers))
+ ;; Return result without any modification.
+ (result port))
+;; (close-port port)
+ result)))
+
+(define (wdquery-xml uri)
+ "Fetch the data, return PORT"
+ (xml-fetch uri))
+
+
+;; Inspired by http://r.duckduckgo.com/l/?kh=-1&uddg=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F29886388%2Fddg%2335118127
+;;;
+;;; Wikidata-specific SPARQL-QUERY using a GET request (it also accept POST)
+;;; ---------------------------------------------------------------------------
+(define* (wdsparql-uri query
+ #:key
+ (uri #f)
+ (type "json"))
+ "Build URI for the Wikidata HTTP GET SPARQL API."
+ (let* ((get-uri "http://query.wikidata.org/sparql")
+ (get-url (if uri
+ uri
+ get-uri)))
+ (string->uri
+ (string-append get-url "?" (uri-encode query))
+ )
+ ))
+
+
+;;;
+;;; Medium-level proc.
+;;; ---------------------------------------------------------------------------
+
+;; TODO add rationale for why this is copied from (sparql util)
+(define (display-query-results port)
+ "Format the output from the port and close it"
+ (begin
+ (let ((line (read-line port)))
+ (if (eof-object? line)
+ #t
+ ;; The default output format is comma-separated values (CSV).
+ (let ((tokens (string-split line #\,)))
+ (format #t "~{~a~/~}~%" tokens)
+ (display-query-results port))))
+ (close-port port)))
+
+;;;
+;;; High-level proc.
+;;; ---------------------------------------------------------------------------
+
+;; See example-sparql.scm for how to enter the query
+(define (show-sparql query)
+ "Run the query on the Wikidata Blazegraph server. Show the result on current-output-port."
+ (display-query-results
+ (xml-fetch
+ (wdsparql-uri
+ query))))