<commit_before>;;;; cl-dropbox.lisp

(in-package #:cl-dropbox)

;;; "cl-dropbox" goes here. Hacks and glory await!

(defparameter *api-root* "https://api.dropbox.com/1")
(defparameter *consumer-token* nil)

(defparameter *get-request-token-endpoint* (concatenate 'string *api-root* "/oauth/request_token"))
(defparameter *auth-request-token-endpoint* "https://www.dropbox.com/1/oauth/authorize")
(defparameter *get-access-token-endpoint* (concatenate 'string *api-root* "/oauth/access_token"))

;; /files api calls and /thumbnails call go to the api-content server.
(defparameter *api-content* "https://api-content.dropbox.com/1/files")

(defparameter *account-info-uri* (concatenate 'string *api-root* "/account/info"))
(defparameter *metadata-uri* (concatenate 'string *api-root* "/metadata"))
(defparameter *revisions-uri* (concatenate 'string *api-root* "/revisions"))
(defparameter *restore-uri* (concatenate 'string *api-root* "/restore"))
(defparameter *search-uri* (concatenate 'string *api-root* "/search"))
(defparameter *create-folder-uri* (concatenate 'string *api-root* "/fileops/create_folder"))
(defparameter *delete-uri* (concatenate 'string *api-root* "/fileops/delete"))

(defvar *request-token* nil)
(defvar *access-token* nil)

;; Authentication

(defun set-credentials (&key key secret)
  (setf *consumer-token* (cl-oauth:make-consumer-token :key key :secret secret)))

(defun get-request-token ()
  (setf *request-token* (cl-oauth:obtain-request-token *get-request-token-endpoint* *consumer-token*)))

(defun get-access-token ()
  (assert *request-token*)
  (setf *access-token* (cl-oauth:obtain-access-token *get-access-token-endpoint* *request-token*)))

(defun authorize-app ()
  (assert *request-token*)
  (format t "~&Visit the below url to authorize your app then return and press enter.~% ~A~%"
          (cl-oauth:make-authorization-uri *auth-request-token-endpoint* *request-token*))
  (let ((result (read-line *standard-input*)))
    (when (zerop (length result))
      (cl-oauth:authorize-request-token *request-token*))))

;; API calls

; Dropbox accounts
(defun get-account-info (&key (decode t))
  "Retrieves information about the user's account."
  (multiple-value-bind (body status)
      (cl-oauth:access-protected-resource *account-info-uri* *access-token*)
    (handle-response body status decode)))

; Files and Metadata
(defun get-file (&key path (root "/dropbox") (rev nil rev-supplied-p))
  "Downloads a file. Note that this call goes to the api-content server."
  (let ((parameter (when rev-supplied-p
                     `(("rev" . ,rev))))
        (merged-path (concatenate 'string *api-content* root "/" (encode-path path))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth :user-parameters parameter :drakma-args `(:parameters ,parameter))
      (handle-response body status nil))))

(defun get-metadata (&key (path nil path-supplied-p) (root "/dropbox") (decode t))
  "Retrieves file and folder metadata."
  (let ((merged-path (if path-supplied-p
                          (concatenate 'string *metadata-uri* root "/" (encode-path path))
                          (concatenate 'string *metadata-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token*)
      (handle-response body status decode))))

(defun get-revisions (&key (path nil path-supplied-p) (root "/dropbox") (decode t))
  "Obtains metadata for the previous revisions of a file."
  (let ((merged-path (if path-supplied-p
                         (concatenate 'string *revisions-uri* root "/" (encode-path path))
                         (concatenate 'string *revisions-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token*)
      (handle-response body status))))

(defun restore (&key (path nil path-supplied-p) rev (root "/dropbox") (decode t))
  "Restores a file path to a previous revision."
  (let ((parameter `(("rev" . ,rev)))
        (merged-path (if path-supplied-p
                         (concatenate 'string *restore-uri* root "/" (encode-path path))
                         (concatenate 'string *restore-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth :user-parameters parameter :drakma-args `(:parameters ,parameter))
      (handle-response body status))))

(defun do-search (&key (path nil path-supplied-p) query (root "/dropbox") (decode t))
  "Returns metadata for all files and folders that match the search query."
  (let ((parameter `(("query" . ,query)))
        (merged-path (if path-supplied-p
                         (concatenate 'string *search-uri* root "/" (encode-path path))
                         (concatenate 'string *search-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth :user-parameters parameter :drakma-args `(:parameters ,parameter))
      (handle-response body status))))

; File Operations
(defun create-folder (&key path (root "dropbox") (decode t))
  "Creates a folder."
  (multiple-value-bind (body status)
      (cl-oauth:access-protected-resource *create-folder-uri* *access-token*
                                          :user-parameters `(("path" . ,path)
                                                             ("root" . ,root)))
    (handle-response body status decode)))

(defun delete-content (&key path (root "dropbox") (decode t))
  "Deletes a file or folder."
  (multiple-value-bind (body status)
      (cl-oauth:access-protected-resource *delete-uri* *access-token*
                                          :user-parameters `(("path" . ,path)
                                                             ("root" . ,root)))
    (handle-response body status decode)))

; Convenience functions<commit_msg>Add /shares, /media and /thumbnails.<commit_after>;;;; cl-dropbox.lisp

(in-package #:cl-dropbox)

;;; "cl-dropbox" goes here. Hacks and glory await!

(defparameter *api-root* "https://api.dropbox.com/1")
(defparameter *api-content* "https://api-content.dropbox.com/1")
(defparameter *consumer-token* nil)

(defparameter *get-request-token-endpoint* (concatenate 'string *api-root* "/oauth/request_token"))
(defparameter *auth-request-token-endpoint* "https://www.dropbox.com/1/oauth/authorize")
(defparameter *get-access-token-endpoint* (concatenate 'string *api-root* "/oauth/access_token"))

;; /files api calls and /thumbnails call go to the api-content server.
(defparameter *files-uri* (concatenate 'string *api-content* "/files"))
(defparameter *thumbnails-uri* (concatenate 'string *api-content*"/thumbnails"))

(defparameter *account-info-uri* (concatenate 'string *api-root* "/account/info"))
(defparameter *metadata-uri* (concatenate 'string *api-root* "/metadata"))
(defparameter *revisions-uri* (concatenate 'string *api-root* "/revisions"))
(defparameter *restore-uri* (concatenate 'string *api-root* "/restore"))
(defparameter *search-uri* (concatenate 'string *api-root* "/search"))
(defparameter *shares-uri* (concatenate 'string *api-root* "/shares"))
(defparameter *media-uri* (concatenate 'string *api-root* "/media"))
(defparameter *create-folder-uri* (concatenate 'string *api-root* "/fileops/create_folder"))
(defparameter *delete-uri* (concatenate 'string *api-root* "/fileops/delete"))

(defvar *request-token* nil)
(defvar *access-token* nil)

;; Authentication

(defun set-credentials (&key key secret)
  (setf *consumer-token* (cl-oauth:make-consumer-token :key key :secret secret)))

(defun get-request-token ()
  (setf *request-token* (cl-oauth:obtain-request-token *get-request-token-endpoint* *consumer-token*)))

(defun get-access-token ()
  (assert *request-token*)
  (setf *access-token* (cl-oauth:obtain-access-token *get-access-token-endpoint* *request-token*)))

(defun authorize-app ()
  (assert *request-token*)
  (format t "~&Visit the below url to authorize your app then return and press enter.~% ~A~%"
          (cl-oauth:make-authorization-uri *auth-request-token-endpoint* *request-token*))
  (let ((result (read-line *standard-input*)))
    (when (zerop (length result))
      (cl-oauth:authorize-request-token *request-token*))))

;; API calls

; Dropbox accounts
(defun get-account-info (&key (decode t))
  "Retrieves information about the user's account."
  (multiple-value-bind (body status)
      (cl-oauth:access-protected-resource *account-info-uri* *access-token*)
    (handle-response body status decode)))

; Files and Metadata
(defun get-file (&key path (root "/dropbox") (rev nil rev-supplied-p))
  "Downloads a file. Note that this call goes to the api-content server."
  (let ((parameter (when rev-supplied-p
                     `(("rev" . ,rev))))
        (merged-path (concatenate 'string *files-uri* root "/" (encode-path path))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth :user-parameters parameter :drakma-args `(:parameters ,parameter))
      (handle-response body status nil))))

(defun get-metadata (&key (path nil path-supplied-p) (root "/dropbox") (decode t))
  "Retrieves file and folder metadata."
  (let ((merged-path (if path-supplied-p
                          (concatenate 'string *metadata-uri* root "/" (encode-path path))
                          (concatenate 'string *metadata-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token*)
      (handle-response body status decode))))

(defun get-revisions (&key (path nil path-supplied-p) (root "/dropbox") (decode t))
  "Obtains metadata for the previous revisions of a file."
  (let ((merged-path (if path-supplied-p
                         (concatenate 'string *revisions-uri* root "/" (encode-path path))
                         (concatenate 'string *revisions-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token*)
      (handle-response body status))))

(defun restore (&key (path nil path-supplied-p) rev (root "/dropbox") (decode t))
  "Restores a file path to a previous revision."
  (let ((parameter `(("rev" . ,rev)))
        (merged-path (if path-supplied-p
                         (concatenate 'string *restore-uri* root "/" (encode-path path))
                         (concatenate 'string *restore-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth :user-parameters parameter :drakma-args `(:parameters ,parameter))
      (handle-response body status))))

(defun do-search (&key (path nil path-supplied-p) query (root "/dropbox") (decode t))
  "Returns metadata for all files and folders that match the search query."
  (let ((parameter `(("query" . ,query)))
        (merged-path (if path-supplied-p
                         (concatenate 'string *search-uri* root "/" (encode-path path))
                         (concatenate 'string *search-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth :user-parameters parameter :drakma-args `(:parameters ,parameter))
      (handle-response body status))))

(defun shares (&key (path nil path-supplied-p) (root "/dropbox") (decode t))
  "Creates and returns a shareable link to files or folders."
  (let ((merged-path (if path-supplied-p
                         (concatenate 'string *shares-uri* root "/" (encode-path path))
                         (concatenate 'string *shares-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token*)
      (handle-response body status))))

(defun media (&key (path nil path-supplied-p) (root "/dropbox") (decode t))
  "Returns a link directly to a file."
  (let ((merged-path (if path-supplied-p
                         (concatenate 'string *media-uri* root "/" (encode-path path))
                         (concatenate 'string *media-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token*)
      (handle-response body status))))

(defun thumbnails (&key (path nil path-supplied-p) (root "/dropbox") (decode nil))
  "Gets a thumbnail for an image. Note that this call goes to the api-content server."
  (let ((merged-path (if path-supplied-p
                         (concatenate 'string *thumbnails-uri* root "/" (encode-path path))
                         (concatenate 'string *thumbnails-uri* root))))
    (multiple-value-bind (body status)
        (cl-oauth:access-protected-resource merged-path *access-token* :request-method :auth)
      (handle-response body status decode))))

; File Operations
(defun create-folder (&key path (root "dropbox") (decode t))
  "Creates a folder."
  (multiple-value-bind (body status)
      (cl-oauth:access-protected-resource *create-folder-uri* *access-token*
                                          :user-parameters `(("path" . ,path)
                                                             ("root" . ,root)))
    (handle-response body status decode)))

(defun delete-content (&key path (root "dropbox") (decode t))
  "Deletes a file or folder."
  (multiple-value-bind (body status)
      (cl-oauth:access-protected-resource *delete-uri* *access-token*
                                          :user-parameters `(("path" . ,path)
                                                             ("root" . ,root)))
    (handle-response body status decode)))

; Convenience functions
{'fraction_non_alphanumeric': 0.15176308739410616, 'fraction_numerical': 0.00043443631887625804, 'mean_word_length': 3.1539849624060152, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '713482', 'n_tokens_mistral': 4202, 'n_tokens_neox': 4129, 'n_words': 1124}