diff options
Diffstat (limited to 'wikidata/sparql.scm')
| -rw-r--r-- | wikidata/sparql.scm | 111 |
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)))) |
