;;; web.lisp (in-package :seanut) (eval-when (:compile-toplevel) (declaim (inline json-request format-url generate-authorization download-media format-hostname))) (defun format-hostname () (if (uiop:string-suffix-p (uiop:hostname) ".local") (subseq (uiop:hostname) 0 (- (length (uiop:hostname)) 6)) (uiop:hostname))) (defun generate-authorization (&optional token) "generates a properly formatted authorization header" (apply #'format `(nil ,*authorization-format* ,@(mapcar #'url-encode (list (concatenate 'string "Seanut " (seanut-version)) (format-hostname) (string-downcase (md5-string (format-hostname))) (seanut-version) (or token "")))))) (defun format-url (domain slug &rest args) "formats DOMAIN into a url, ensures we include the url scheme SLUG is a format-coded string that represents the path for the query ARGS are the arguments for the SLUG format string" (format nil "~:[https://~;~]~A/~A" (uiop:string-prefix-p "https://" domain) domain (apply #'format `(nil ,slug ,@args)))) (defun json-request (url &key auth (method :get) extra-headers content) "makes a request to URL, using AUTH as the X-Emby-Authorization header and METHOD as the http method (defaults to get) and parses the returned value with jzon:parse if EXTRA-HEADERS is non-nil, includes them in the headers alongside the X-Emby-Authorization one if CONTENT is non-nil, passes that along to the request" (parse (dex:request url :method method :content content :headers `(,(when auth `("Authorization" . ,auth)) ,@extra-headers)))) (defun run-search-query (domain auth type name) "runs the search query to get the initial list of items can probably be removed and the request can be made in-line" (gethash "Items" (json-request (format-url domain "Items?fields=Path&includeItemTypes=~A&recursive=true&searchTerm=~A" type name) :auth auth))) (defun download-media (path url auth) "downloads the media at URL, using HEADER as the authorization header. if DESTINATION is non-nil, dumps media into that directory, otherwise it uses CWD" (dex:fetch url path :if-exists nil :headers `(("Authorization" . ,auth))))