;; functions for interacting with purl.org ;; e.g. (create-new-purl "/NET/sandbox/1" "http://foo.com/" "alanruttenberg" "xxxxxx" '(melanie cmungall)) ;; add optional last argument t to make it partial. In which case purl must end in a "/" ;; returns t if successful (defun create-new-purl (purl url user password maintainers &optional (partial nil)) (let* ((answer (get-url "http://purl.oclc.org/maint/new.pl.cgi" :force-refetch t :dont-cache t :persist nil :post `(("confirm" "true") ("id" ,user) ("password" ,password) ("purl" ,purl) ("url" ,url) ("inst" ,(format nil "~a ~{~a~^ ~}" user maintainers)) ,@(if partial (list (list "partial" "on"))) )))) (#"matches" answer "(?s).*Added:.*"))) (defun split-into-sized-lists (list count) (let ((counter -1) (accum nil) (all nil)) (loop while list do (loop while list while (< (incf counter) count) do (push (pop list) accum)) (push accum all) (setq counter -1 accum nil)) all)) ;http://pir.georgetown.edu/cgi-bin/pro/entry_pro?id=PRO:000000009 (defun create-new-purls (purls user password maintainers) (let ((batches (split-into-sized-lists purls 90))) (loop for batch in batches for count from 1 do (with-output-to-string (s) (write-string "" s) (loop for (purl url) in batch do (format s "~a~a~{~a~}User_Batch_Add" purl url maintainers)) (write-string "" s) (let* ((answer (get-url "http://purl.oclc.org/maint/batch.pl.cgi" :force-refetch t :dont-cache t :persist nil :post `(("id" ,user) ("password" ,password) ("list" ,(get-output-stream-string s)) )))) (format t "Batch ~a ~a~%" count (#"matches" (print answer) "(?s).*Added:.*"))))))) ;; (update-purl "/NET/sandbox/1" "http://bar.com/" "alanruttenberg" "xxxxxx" '(melanie cmungall) "made a mistake") ;; returns (list purl url), if successful (defun update-purl (purl url user password maintainers comment) (let* ((answer (get-url "http://purl.oclc.org/maint/modify.pl.cgi" :force-refetch t :dont-cache t :persist nil :post `(("confirm" "true") ("id" ,user) ("password" ,password) ("purl" ,purl) ("url" ,url) ("inst" ,(format nil "~a ~{~a~^ ~}" user maintainers)) ("public" ,comment) )))) (car (all-matches answer "(?s).*Replaced:\\s*(.*?)\\s*=> (.*?)\\s+" 1 3)))) ;; returns (list purl url partial? . maintainers ) ;; (get-purl "/obo/obi.owl") -> ;; ("http://purl.oclc.org/obo/obi.owl" ;; "http://obi.svn.sourceforge.net/svnroot/obi/tags/releases/2008-05-30/merged/OBI.owl" nil ;; "MELANIE" "CMUNGALL" "ALANRUTTENBERG") (defun get-purl (purl) (let* ((answer (get-url (format nil "http://purl.org/maint/display.pl.cgi?purlreg=~a&url=&maint=&inst=&noedit=on&id=nobody" purl) :force-refetch t :dont-cache t :referer "http://purl.org/maint/display.html" :persist nil))) (let ((did (all-matches answer "(?s)PURL\\s*.*?\\s*URL\\s*(.*?).*?Maintainers\\s+(.*?)\\n" 1 2 3))) (and (car did) (list* (first (car did)) (second (car did)) (#"matches" answer "(?s).*Partial Redirection\\s*Enabled.*") (split-at-regex (third (car did)) ",\\s*")))))) (defun purls-matching (string &key start (refetch nil)) (let* ((answer (get-url (format nil "http://purl.org/maint/display.pl.cgi?purlreg=~a&url=&maint=&inst=&noedit=on&id=nobody&start=~a" string (or start "")) :force-refetch refetch :referer "http://purl.org/maint/display.html" :persist nil))) (let ((did (all-matches answer (format nil "(?s)(?i)cookie=\">(.*?~a.*?).*?<\/td>(.*?)<\/td>" string) 1 2))) (if (all-matches answer "(?s)(Next records)" 1) (append did (purls-matching string :start (+ (or start 0) 25))) did)))) ;; (create-purls '(("/NET/sandbox/5" "http://example.com/3") ;; ("/NET/sandbox/8" "http://example.com/8")) ;; "alanruttenberg" "xx" nil nil) ;; => ;; (values purls-created purls-with-errors) (defun create-purls (purl-url-pairs user password maintainers &optional (partial nil)) (let* ((ids (format nil "~a~{~a~}" user maintainers)) (partial (if partial "" "")) (request (with-output-to-string (s) (write-string "" s) (loop for (purl url) in purl-url-pairs do (format s "~a~a~a~a" purl url ids partial)) (write-string "" s))) (answer (get-url "http://purl.oclc.org//maint/batch.pl.cgi" :force-refetch t :dont-cache t :persist nil :post `(("id" ,user) ("password" ,password) ("list" ,request) ("add" "add"))))) (values (mapcar 'car (all-matches answer "(?si)Added:\s*.*?>(.*?)<" 1)) (mapcar 'car (all-matches answer "Error:.*?>(.*?)<" 1))))) ;; (modify-purls '(("/NET/sandbox/5" "http://example.com/3") ;; ("/NET/sandbox/8" "http://example.com/8")) ;; "alanruttenberg" "xx" nil nil "because") ;; => ;; (values purls-created purls-with-errors) (defun modify-purls (purl-url-pairs user password maintainers &optional (partial nil) (note "")) (let* ((ids (format nil "~a~{~a~}" user maintainers)) (partial (if partial "" "")) (request (with-output-to-string (s) (write-string "" s) (loop for (purl url) in purl-url-pairs do (format s "~a~a~a~aBatch_Modified~a" purl url ids partial note)) (write-string "" s))) (answer (get-url "http://purl.oclc.org//maint/batch.pl.cgi" :force-refetch t :dont-cache t :persist nil :post `(("id" ,user) ("password" ,password) ("list" ,request) ("replace" "replace"))))) (values (mapcar 'car (all-matches answer "(?si)Replaced:\s*.*?>(.*?)<" 1)) (union (mapcar 'car (all-matches answer "Error:(?=Skip).*?>(.*?)<" 1)) (mapcar (lambda(e) (format nil "http://purl.oclc.org~a" (car e))) (all-matches answer "Error:.*?Skipping PURL \\((.*?)\\)" 1)))))) ;;(get-purl-group "obi") ;; -> values ;; ("ALANRUTTENBERG" "CMUNGALL" "MELANIE") ;; ("ALANRUTTENBERG" "CMUNGALL" "MELANIE" "JAR287") ;; "for managing the purls of the obi project http //purl.obofoundry.org/obo/obi" (defun get-purl-group (name) (let* ((answer (get-url (format nil "http://purl.org/maint/search_group.pl.cgi?groupid=~a&groupown=&groupmem=&noedit=on&id=nobody" name) :force-refetch t :dont-cache t :persist nil))) (flet ((userlist (header) (mapcar 'car (all-matches (caar (all-matches a (format nil "(?s)~a:\\s*((\\s*.*?)*)" header) 1 )) "\\s*(.*?)*" 1)))) (values (userlist "Maintainers") (userlist "Members") (caar (all-matches answer "(?s)Comment:\\s*\\s*(.*?)\\s*" 1))))))