lto.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. # (c) 2008 Jerome Alet - <alet@librelogiciel.com>
  2. # Licensing terms : ReportLab's license.
  3. from reportlab.graphics.barcode.code39 import Standard39
  4. from reportlab.lib import colors
  5. from reportlab.lib.units import cm
  6. from string import digits as string_digits
  7. from reportlab.lib.utils import ascii_uppercase
  8. class BaseLTOLabel(Standard39) :
  9. """
  10. Base class for LTO labels.
  11. Specification taken from "IBM LTO Ultrium Cartridge Label Specification, Revision 3"
  12. available on May 14th 2008 from :
  13. http://www-1.ibm.com/support/docview.wss?rs=543&context=STCVQ6R&q1=ssg1*&uid=ssg1S7000429&loc=en_US&cs=utf-8&lang=en+en
  14. """
  15. LABELWIDTH = 7.9 * cm
  16. LABELHEIGHT = 1.7 * cm
  17. LABELROUND = 0.15 * cm
  18. CODERATIO = 2.75
  19. CODENOMINALWIDTH = 7.4088 * cm
  20. CODEBARHEIGHT = 1.11 * cm
  21. CODEBARWIDTH = 0.0432 * cm
  22. CODEGAP = CODEBARWIDTH
  23. CODELQUIET = 10 * CODEBARWIDTH
  24. CODERQUIET = 10 * CODEBARWIDTH
  25. def __init__(self, prefix="",
  26. number=None,
  27. subtype="1",
  28. border=None,
  29. checksum=False,
  30. availheight=None) :
  31. """
  32. Initializes an LTO label.
  33. prefix : Up to six characters from [A-Z][0-9]. Defaults to "".
  34. number : Label's number or None. Defaults to None.
  35. subtype : LTO subtype string , e.g. "1" for LTO1. Defaults to "1".
  36. border : None, or the width of the label's border. Defaults to None.
  37. checksum : Boolean indicates if checksum char has to be printed. Defaults to False.
  38. availheight : Available height on the label, or None for automatic. Defaults to None.
  39. """
  40. self.height = max(availheight, self.CODEBARHEIGHT)
  41. self.border = border
  42. if (len(subtype) != 1) \
  43. or (subtype not in ascii_uppercase + string_digits) :
  44. raise ValueError("Invalid subtype '%s'" % subtype)
  45. if ((not number) and (len(prefix) > 6)) \
  46. or not prefix.isalnum() :
  47. raise ValueError("Invalid prefix '%s'" % prefix)
  48. label = "%sL%s" % ((prefix + str(number or 0).zfill(6 - len(prefix)))[:6],
  49. subtype)
  50. if len(label) != 8 :
  51. raise ValueError("Invalid set of parameters (%s, %s, %s)" \
  52. % (prefix, number, subtype))
  53. self.label = label
  54. Standard39.__init__(self,
  55. label,
  56. ratio=self.CODERATIO,
  57. barHeight=self.height,
  58. barWidth=self.CODEBARWIDTH,
  59. gap=self.CODEGAP,
  60. lquiet=self.CODELQUIET,
  61. rquiet=self.CODERQUIET,
  62. quiet=True,
  63. checksum=checksum)
  64. def drawOn(self, canvas, x, y) :
  65. """Draws the LTO label onto the canvas."""
  66. canvas.saveState()
  67. canvas.translate(x, y)
  68. if self.border :
  69. canvas.setLineWidth(self.border)
  70. canvas.roundRect(0, 0,
  71. self.LABELWIDTH,
  72. self.LABELHEIGHT,
  73. self.LABELROUND)
  74. Standard39.drawOn(self,
  75. canvas,
  76. (self.LABELWIDTH-self.CODENOMINALWIDTH)/2.0,
  77. self.LABELHEIGHT-self.height)
  78. canvas.restoreState()
  79. class VerticalLTOLabel(BaseLTOLabel) :
  80. """
  81. A class for LTO labels with rectangular blocks around the tape identifier.
  82. """
  83. LABELFONT = ("Helvetica-Bold", 14)
  84. BLOCKWIDTH = 1*cm
  85. BLOCKHEIGHT = 0.45*cm
  86. LINEWIDTH = 0.0125
  87. NBBLOCKS = 7
  88. COLORSCHEME = ("red",
  89. "yellow",
  90. "lightgreen",
  91. "lightblue",
  92. "grey",
  93. "orangered",
  94. "pink",
  95. "darkgreen",
  96. "orange",
  97. "purple")
  98. def __init__(self, *args, **kwargs) :
  99. """
  100. Initializes the label.
  101. colored : boolean to determine if blocks have to be colorized.
  102. """
  103. if "colored" in kwargs:
  104. self.colored = kwargs["colored"]
  105. del kwargs["colored"]
  106. else :
  107. self.colored = False
  108. kwargs["availheight"] = self.LABELHEIGHT-self.BLOCKHEIGHT
  109. BaseLTOLabel.__init__(self, *args, **kwargs)
  110. def drawOn(self, canvas, x, y) :
  111. """Draws some blocks around the identifier's characters."""
  112. BaseLTOLabel.drawOn(self,
  113. canvas,
  114. x,
  115. y)
  116. canvas.saveState()
  117. canvas.setLineWidth(self.LINEWIDTH)
  118. canvas.setStrokeColorRGB(0, 0, 0)
  119. canvas.translate(x, y)
  120. xblocks = (self.LABELWIDTH-(self.NBBLOCKS*self.BLOCKWIDTH))/2.0
  121. for i in range(self.NBBLOCKS) :
  122. (font, size) = self.LABELFONT
  123. newfont = self.LABELFONT
  124. if i == (self.NBBLOCKS - 1) :
  125. part = self.label[i:]
  126. (font, size) = newfont
  127. size /= 2.0
  128. newfont = (font, size)
  129. else :
  130. part = self.label[i]
  131. canvas.saveState()
  132. canvas.translate(xblocks+(i*self.BLOCKWIDTH), 0)
  133. if self.colored and part.isdigit() :
  134. canvas.setFillColorRGB(*getattr(colors,
  135. self.COLORSCHEME[int(part)],
  136. colors.Color(1, 1, 1)).rgb())
  137. else:
  138. canvas.setFillColorRGB(1, 1, 1)
  139. canvas.rect(0, 0, self.BLOCKWIDTH, self.BLOCKHEIGHT, fill=True)
  140. canvas.translate((self.BLOCKWIDTH+canvas.stringWidth(part, *newfont))/2.0,
  141. (self.BLOCKHEIGHT/2.0))
  142. canvas.rotate(90.0)
  143. canvas.setFont(*newfont)
  144. canvas.setFillColorRGB(0, 0, 0)
  145. canvas.drawCentredString(0, 0, part)
  146. canvas.restoreState()
  147. canvas.restoreState()
  148. def test() :
  149. """Test this."""
  150. from reportlab.pdfgen.canvas import Canvas
  151. from reportlab.lib import pagesizes
  152. canvas = Canvas("labels.pdf", pagesize=pagesizes.A4)
  153. canvas.setFont("Helvetica", 30)
  154. (width, height) = pagesizes.A4
  155. canvas.drawCentredString(width/2.0, height-4*cm, "Sample LTO labels")
  156. xpos = xorig = 2 * cm
  157. ypos = yorig = 2 * cm
  158. colwidth = 10 * cm
  159. lineheight = 3.9 * cm
  160. count = 1234
  161. BaseLTOLabel("RL", count, "3").drawOn(canvas, xpos, ypos)
  162. ypos += lineheight
  163. count += 1
  164. BaseLTOLabel("RL", count, "3",
  165. border=0.0125).drawOn(canvas, xpos, ypos)
  166. ypos += lineheight
  167. count += 1
  168. VerticalLTOLabel("RL", count, "3").drawOn(canvas, xpos, ypos)
  169. ypos += lineheight
  170. count += 1
  171. VerticalLTOLabel("RL", count, "3",
  172. border=0.0125).drawOn(canvas, xpos, ypos)
  173. ypos += lineheight
  174. count += 1
  175. VerticalLTOLabel("RL", count, "3",
  176. colored=True).drawOn(canvas, xpos, ypos)
  177. ypos += lineheight
  178. count += 1
  179. VerticalLTOLabel("RL", count, "3",
  180. border=0.0125, colored=True).drawOn(canvas, xpos, ypos)
  181. canvas.showPage()
  182. canvas.save()
  183. if __name__ == "__main__" :
  184. test()