Yu-Gi-Oh! Deck Building and Card Inventory Management web interface written in Common Lisp, utilizing HTMX.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

137 lines
5.6KB

  1. #|
  2. Conceptually, The Label Maker is very similar to the DRAW component of The Deck Builder.
  3. We currently support Avery 5160 and ULINE S-20246 labels.
  4. |#
  5. (in-package #:cl-user)
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7. ;; This package doesn't touch the DB ... yet
  8. (defpackage #:cl-deck-builder2.models.label-maker
  9. (:use :cl)
  10. (:import-from #:cl-deck-builder2.toolkit
  11. #:latex-escape)
  12. (:export #:latex-label
  13. #:latex-label-page
  14. #:latex-label-uline-s-20247
  15. #:latex-label-avery-5160
  16. #:render-page))
  17. (in-package #:cl-deck-builder2.models.label-maker)
  18. (defclass latex-label ()
  19. ((barcode :accessor latex-label-barcode
  20. :initform nil
  21. :initarg :barcode)
  22. (description :accessor latex-label-description
  23. :initform nil
  24. :initarg :description)
  25. (price :accessor latex-label-price
  26. :initform nil
  27. :initarg :price))
  28. (:documentation "An individual LaTeX label. Encapsulate metadata for a particular label."))
  29. (defclass latex-label-page ()
  30. ((;; List of LATEX-LABEL content
  31. labels :accessor latex-label-page-labels
  32. :initarg :page-labels
  33. :initform '())
  34. (;; Number of Labels this page thinks it has
  35. labels-length :accessor latex-label-page-labels-length
  36. :initarg :labels-length
  37. :initform 0)
  38. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  39. ;; Templates
  40. (;; Template for this page
  41. label-template :accessor latex-label-label-template
  42. :initform nil
  43. :initarg :label-template)
  44. (;; Header template for this page
  45. header-template :accessor latex-label-header-template
  46. :initform #P"latex/header.tex"
  47. :initarg :header-template))
  48. (:documentation "Class for a LaTeX Label Page, which encapsulates label information and additional output templating information."))
  49. (defclass latex-label-uline-s-20247 (latex-label-page)
  50. ((labels-length :initform 32)
  51. (label-template :initform #P"latex/ULINE-S-20247.tpl.tex")))
  52. (defclass latex-label-avery-5160 (latex-label-page)
  53. ((labels-length :initform 30)
  54. (label-template :initform #P"latex/Avery-5160.tpl.tex")))
  55. (defmethod initialize-instance :after ((page latex-label-page) &rest initargs &key csv &allow-other-keys)
  56. (declare (ignore initargs))
  57. (when csv
  58. (initialize-with-csv page csv)))
  59. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  60. (defmethod add-label ((page latex-label-page) (label latex-label))
  61. "Add a LABEL to PAGE."
  62. (push label (latex-label-page-labels page)))
  63. (defmethod initialize-with-csv ((page latex-label-page) pathspec)
  64. "Create LATEX-LABEL information for this LATEX-LABEL-PAGE by reading CSV information from PATHSPEC."
  65. (let ((csv (cl-csv:read-csv pathspec)))
  66. (loop for i from 1 upto (latex-label-page-labels-length page) do
  67. (destructuring-bind (label-no description price barcode)
  68. (elt csv i)
  69. (declare (ignore label-no))
  70. (when (> (length description) 0)
  71. (barcode-png barcode)
  72. (let ((label (ignore-errors
  73. (make-instance 'latex-label
  74. :barcode barcode
  75. :description (latex-escape description)
  76. :price (cl-ppcre:regex-replace "\\$" price "\\\\$")))))
  77. (add-label page label)))))))
  78. (defmethod render-page ((page latex-label-page))
  79. "Use Djula to render the LATEX-LABEL-LABEL-TEMPLATE."
  80. (cl-deck-builder2.view:render (latex-label-label-template page)
  81. (list :labels (latex-label-page-labels page))))
  82. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  83. (defun label-info (&optional t-or-nil)
  84. (let ((arg (if t-or-nil "true" "false")))
  85. (format nil "\LabelGrid~a\LabelInfo~a%%~%" arg arg)))
  86. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  87. ;; TODO (defclass barcode () ())
  88. (defun barcode-png (barcode &optional (directory #P"/tmp/labels/") (size "1x30"))
  89. (ensure-directories-exist directory)
  90. (let* ((barcode (etypecase barcode
  91. (string barcode)
  92. (integer (princ-to-string barcode))))
  93. (output (merge-pathnames
  94. (make-pathname :name barcode :type "png")
  95. (probe-file directory))))
  96. (unless (probe-file output)
  97. (and
  98. (> (length barcode) 0)
  99. (multiple-value-bind (stdout stderr rc)
  100. (inferior-shell:run
  101. `("ZXingWriter" -size ,size
  102. ,(case (length barcode)
  103. ;; 12 and 11 digit barcodes for products in store on the shelves usually - UPC-A
  104. ((12 11) 'UPC-A)
  105. ;; 10 digit barcodes for "fake" Amazon ASIN "X0037THWV7"
  106. (10 'Code128)
  107. ;; Not sure why we have UPC-E in here
  108. ;; but presumbly we have encountered
  109. ;; products with a 6 digit barcode...
  110. (6 'UPC-E)
  111. ;; Treat everything else as 13 digit
  112. ;; international EAN-13 barcodes like
  113. ;; stuff from Pokemon Stores:
  114. ;; 8206508090648
  115. (t 'EAN-13))
  116. ,barcode
  117. ,output))
  118. (declare (ignore stdout stderr))
  119. (eq rc 0))
  120. (probe-file output)))))