;;; Copyright © 2018 swedebugia ;;; ;;; 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 . (use-modules (ice-9 format) (json) (guix import json) (srfi srfi-1) (web uri) ) ;; Inspired by PYPI wikidata_suggest (define (wbsearch-uri name) "Build URI for the Wikidata wbsearchintities API." (let ((url "https://www.wikidata.org/w/api.php") (& "&") (= "=") (search name) (action "wbsearchentities") (format "json") ;; Hardcoded en for now (language "en") (type "item") (continue "0") (limit "10")) (string->uri (string-append url "?" "search" = search & "action" = action & "format" = format & "language" = language & "type" = type & "continue" = continue & "limit" = limit )))) ;; Inspired by ;; https://opendata.stackexchange.com/questions/5248/how-to-get-the-name-of-a-wikidata-item (define (wbget-uri qid) "Build URI for the Wikidata wbsearchintities API." (let ((url "https://www.wikidata.org/w/api.php") (& "&") (= "=") (ids qid) (action "wbgetentities") (format "json") ;; Hardcoded en for now (language "en")) (string->uri (string-append url "?" "ids" = ids & "action" = action & "format" = format & "language" = language & )))) (define (wdquery uri) "Fetch the data, return an alist" (json-fetch-alist uri)) (define (extract-qid alist) "Accept unnested alist and output Q-ID." (if (list? alist) (assoc-ref alist "id") (error "extract-qid: Not a proper list" alist))) (define (extract-label alist) "Accept unnested ALIST and output label." (if (list? alist) (assoc-ref alist "label") (begin (error "extract-label: Not a proper list" ) (display alist)))) (define (extract-desc alist) "Accept unnested ALIST and output label." (if (list? alist) ;; TODO add error handling when no descriptions (assoc-ref alist "description") (begin (error "extract-desc: Not a proper list" ) (display alist)))) (define (extract-all alist) (if (list? alist) `(("label" . ,(extract-label alist)) ("description" . ,(extract-desc alist)) ("id" . ,(extract-qid alist))) (begin (error "extract-all: Not a proper list" ) (display alist)))) (define (extract-result name) "Returns list with each element being an alist of label, desc, qid" (map extract-all (assoc-ref (wdquery (wbsearch-uri name)) "search"))) ;; BROKEN for some reason ;; (define (output-field qid) ;; "Generate output field with Q-ID for the package record." ;; (if (string? qid) ;; `(wikidata ,qid) ;; ;;(error "Not a string") ;; ;; Parse as pair ;; (if (pair? qid) ;; (let ((qid (cdr qid))) ;; `(wikidata ,qid)) ;; ;;Not a pair? ;; ;; debug ;; (format #t "debug qid: ~a ~%" qid) ;; ))) (define (extract-first-result alist) "Extract first result from nested alist" ;; TODO add error if no results (if (equal? (first (first alist)) "success") (first (assoc-ref alist "search")) (error "success not found")) ) ;; Broken for some reason :-/ ;; (define (parse-results query num) ;; (let lp ;; ;;Variable ;; ((num)) ;; ;;Bindings? ;; (if (> num 0) ;; ;;Body ;; (let (; Reverse list first so they end up in the right order. ;; (result (take (reverse (extract-result query)) num))) ;; (format #t "~a: ~a: ~a ~%" (number->string num) (extract-label result) (extract-desc result))) ;; ;; Subtract ;; (lp (- num 1)) ;; ;; Tail ;; num))) ;;test ;; (parse-results "emacs" 2) (define (show-first-result query) ;; First result which is often the right one :) (let ((result (first (extract-result query)))) (format #t "1.: ~a: ~a: ~a ~%" (extract-qid result) (extract-label result) (extract-desc result)) )) ;;testing :) ;;(display "first result:") (newline) (show-first-result "openssh") ;; (newline) ;; (show-first-result "xorg") ;; (newline) ;; (display "extract-label") (newline) ;; (display (extract-label (first (assoc-ref (wdquery (wbsearch-uri "xorg")) "search")))) ;; (newline) ;; (output-field (extract-qid (first (assoc-ref (wdquery (wbsearch-uri "xorg")) "search")))) ;; (format #t "parse-results: ~%") ;; (parse-results "gnome3" 1) ;; (newline) ;; (format #t "take: ~%") ;; (take (extract-result "gnome") 1) ;; (define (show-3 package-name) ;; "Correlate PACKAGE-NAME with Wikidata Q-IDs and add field to package record for all matches." ;; (let* ((q1 (take (assoc-ref (wdquery (wbsearch-uri package-name)) "search")) 2) ;; (num 2)) ;; (while ((>= num 0)) ;; (let (((take q1 num) ;; (l (extract-label q1)) ;; (d (extract-desc q1)) ;; (id (extract-qid q1)))) ;; ;; descriptions are sometimes missing ;; (if (d) ;; (format #t "~a : ~a : ~a ~%" l d id) ;; (format #t "~a : ~a ~%" l id)) ;; ;;debug ;; (display "debug: ") ;; (display q1) (newline) ;; ;;(format #t "~a ~%"(string-append t ":" d)) ;; ;;(format #t "~a ~%"(string-append t ":" id)) ;; ) ;; (- num 1)))) ;; (format #t "Show-3: ~%") ;; (show-3 "gnome3") ;;(assoc-ref (assoc-ref query "search") "label") ;; def _wikipedia(name, lang='en'): ;; url = "https://%s.wikipedia.org/w/api.php" % lang ;; params = { ;; "action": "query", ;; "list": "search", ;; "format": "json", ;; "srnamespace": "0", ;; "srsearch": name ;; } ;; sug = None ;; results = requests.get(url, params=params).json() ;; if len(results['query']['search']) > 0: ;; sug = results['query']['search'][0]['title'] ;; elif 'suggestion' in results['query']['searchinfo'] and \ ;; name != results['query']['searchinfo']['suggestion']: ;; sug = _wikipedia(results['query']['searchinfo']['suggestion'], lang) ;; return sug