Yu-Gi-Oh! Deck Building and Card Inventory Management web interface written in Common Lisp, utilizing HTMX.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
5.6KB

  1. #|
  2. src/models/ygoprodeck-cardinfo.lisp
  3. Version 2 JSON Downloader
  4. The idea behind this code is you'll be able to one click button download and update the db:
  5. (cardinfo-update-and-cleanup t)
  6. TODO Use INFERIOR-SHELL
  7. |#
  8. (in-package #:cl-deck-builder2.models.ygoprodeck.cardinfo)
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10. ;; Constants
  11. (defparameter +ygoprodeck-api-uri+ "https://db.ygoprodeck.com/api/v7/cardinfo.php")
  12. (defparameter +ygoprodeck-api-uri-misc+ :|misc|)
  13. (defparameter +ygoprodeck-api-uri-tcgplayer-data+ :|tcgplayer_data|)
  14. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  15. ;; Specials
  16. (defparameter *cardinfo* nil
  17. "The current CARDINFO object.")
  18. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  19. ;; Class Definitions
  20. (defclass cardinfo ()
  21. ((input :initarg :input)
  22. (output :initarg :output)))
  23. (defclass cardinfo-php (cardinfo)
  24. ()
  25. (:default-initargs
  26. :input +ygoprodeck-api-uri+
  27. :output #P"/tmp/cardinfo.php"
  28. :tcgplayer-data "yes"
  29. :misc "yes"))
  30. (defclass cardinfo-json (cardinfo)
  31. ()
  32. (:default-initargs
  33. :input #P"/tmp/cardinfo.php"
  34. :output #P"/tmp/cardinfo.json"))
  35. ;; Extract the card_images image_url from the cardinfo.json
  36. ;;
  37. ;; jq '.[].card_images[].image_url' < /tmp/cardinfo.json
  38. (defclass cardinfo-list (cardinfo)
  39. ()
  40. (:default-initargs
  41. :input #P"/tmp/cardinfo.json"
  42. :output #P"/tmp/cardinfo.list"))
  43. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  44. ;; Generics
  45. (defgeneric cardinfo-cleanup (obj))
  46. (defgeneric cardinfo-convert (from to &optional force))
  47. (defgeneric cardinfo-download (obj &optional force))
  48. (defgeneric cardinfo-input (obj)
  49. (:method ((obj cardinfo))
  50. (let ((slot-value (slot-value obj 'input)))
  51. (typecase slot-value
  52. (pathname (namestring slot-value))
  53. (t slot-value)))))
  54. (defgeneric cardinfo-output (obj)
  55. (:method ((obj cardinfo))
  56. (let ((slot-value (slot-value obj 'output)))
  57. (typecase slot-value
  58. (pathname (namestring slot-value))
  59. (t slot-value)))))
  60. (defgeneric (setf cardinfo-input) (new-value obj)
  61. (:method (new-value (obj cardinfo))
  62. (setf (slot-value obj 'input) new-value)))
  63. (defgeneric (setf cardinfo-output) (new-value obj)
  64. (:method (new-value (obj cardinfo))
  65. (setf (slot-value obj 'output) new-value)))
  66. (defgeneric cardinfo-input-exists-p (obj)
  67. (:method ((obj cardinfo))
  68. (probe-file (cardinfo-output obj))))
  69. (defgeneric cardinfo-output-exists-p (obj)
  70. (:method ((obj cardinfo))
  71. (probe-file (cardinfo-output obj))))
  72. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  73. ;; Methods
  74. (defmethod initialize-instance :after ((obj cardinfo-php) &rest initargs &key misc tcgplayer-data &allow-other-keys)
  75. (declare (ignore initargs))
  76. (let ((params '()))
  77. (when misc (setf (getf params +ygoprodeck-api-uri-misc+) misc))
  78. (when tcgplayer-data (setf (getf params +ygoprodeck-api-uri-tcgplayer-data+) tcgplayer-data))
  79. (when params
  80. (setf (cardinfo-input obj)
  81. (caveman2.helper::add-query-parameters
  82. (cardinfo-input obj) params))))
  83. obj)
  84. (defmethod cardinfo-cleanup ((obj cardinfo))
  85. (v:info :ygoprodeck.json "CARDINFO-CLEANUP: ~a" obj)
  86. (uiop:delete-file-if-exists (cardinfo-output obj)))
  87. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  88. ;; TODO This could probably be replaced with CL-JSON processor.
  89. (defun cardinfo-run-program (command from to &optional force)
  90. (let* ((from-output (cardinfo-output from))
  91. (from-output-exists-p (probe-file from-output))
  92. ;; TO-INPUT is the same as FROM-OUTPUT
  93. (to-input (cardinfo-input to))
  94. (to-output (cardinfo-output to))
  95. (to-output-exists-p (probe-file to-output)))
  96. (if (and (string= from-output to-input)
  97. from-output-exists-p
  98. (or force
  99. (not to-output-exists-p)))
  100. (let ((command (format nil command from-output to-output)))
  101. (v:info :ygoprodeck.cardinfo "Running command: \"~a\"" command)
  102. (if (uiop:run-program command :output '(:string :stripped t))
  103. (cardinfo-output-exists-p to)))
  104. (v:info :ygoprodeck.cardinfo "Detected existing file: \"~a\"" to-output))))
  105. (defmethod cardinfo-convert ((from cardinfo-php) (to cardinfo-json) &optional force)
  106. (cardinfo-run-program "jq '.data' < \"~a\" > \"~a\"" from to force))
  107. (defmethod cardinfo-convert ((from cardinfo-json) (to cardinfo-list) &optional force)
  108. (cardinfo-run-program "jq '.[].card_images[].image_url' < \"~a\" > \"~a\"" from to force))
  109. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  110. (defmethod cardinfo-download ((obj cardinfo) &optional force)
  111. (v:info :ygoprodeck.json "CARDINFO-DOWNLOAD: ~a"
  112. (cardinfo-input obj))
  113. (let* ((input (cardinfo-input obj))
  114. (output (cardinfo-output obj))
  115. (output-exists-p (probe-file output)))
  116. (if (or force
  117. (not output-exists-p))
  118. (trivial-download:download input output)
  119. (cardinfo-output-exists-p obj))))
  120. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  121. (defun cardinfo-update-and-cleanup (&optional cleanup)
  122. (let ((cardinfo-php (make-instance 'cardinfo-php))
  123. (cardinfo-json (make-instance 'cardinfo-json))
  124. (cardinfo-list (make-instance 'cardinfo-list)))
  125. (cardinfo-download cardinfo-php)
  126. (cardinfo-convert cardinfo-php cardinfo-json)
  127. (cardinfo-convert cardinfo-json cardinfo-list)
  128. (when cleanup
  129. (mapcar #'cardinfo-cleanup (list cardinfo-php cardinfo-json cardinfo-list)))))