2
2
import argparse
3
3
import logging
4
4
import sys
5
+ from enum import Enum
5
6
from pathlib import Path
6
7
from typing import List , Dict , Any , Optional
7
8
17
18
from tapen .common .domain import PrintJob
18
19
from tapen .library import TemplateLibrary
19
20
from tapen .printer import get_print_factory , PrinterFactory , TapenPrinter
21
+ from tapen .printer .common import PrintingMode , TapeInfo
20
22
from tapen .renderer import get_default_renderer , Renderer
21
23
22
24
LOGGER = logging .getLogger ("cli" )
23
25
24
26
27
+ class EnumAction (argparse .Action ):
28
+ """
29
+ Argparse action for handling Enums
30
+ """
31
+
32
+ def __init__ (self , ** kwargs ):
33
+ # Pop off the type value
34
+ enum_type = kwargs .pop ("type" , None )
35
+
36
+ # Ensure an Enum subclass is provided
37
+ if enum_type is None :
38
+ raise ValueError ("type must be assigned an Enum when using EnumAction" )
39
+ if not issubclass (enum_type , Enum ):
40
+ raise TypeError ("type must be an Enum when using EnumAction" )
41
+
42
+ # Generate choices from the Enum
43
+ kwargs .setdefault ("choices" , tuple (e .value for e in enum_type ))
44
+
45
+ super (EnumAction , self ).__init__ (** kwargs )
46
+
47
+ self ._enum = enum_type
48
+
49
+ def __call__ (self , parser , namespace , values , option_string = None ):
50
+ # Convert value back into an Enum
51
+ value = self ._enum (values )
52
+ setattr (namespace , self .dest , value )
53
+
54
+
25
55
class GlobalConfigFile (GlobalArgsExtension ):
26
56
27
57
@classmethod
@@ -87,6 +117,9 @@ def get_printer(self) -> TapenPrinter:
87
117
assert self .__printer_factory is not None , "Class is not initialized. Forgot self.init()?"
88
118
return self .__printer_factory .get_first_printer ()
89
119
120
+ def get_cached_tape_info (self , printer_id : Optional [str ]= None ) -> Optional [TapeInfo ]:
121
+ return self .__printer_factory .get_cached_tape_info (printer_id )
122
+
90
123
91
124
class ImportLibExtension (BaseCliExtension ):
92
125
COMMAND_NAME = "import-lib"
@@ -114,8 +147,18 @@ class PrintExtension(BaseCliExtension):
114
147
115
148
@classmethod
116
149
def setup_parser (cls , parser : argparse .ArgumentParser ):
117
- parser .add_argument ("template" , action = "store" , help = "Template to use" )
118
- parser .add_argument ("data" , nargs = "*" , action = "store" , help = "Data to be printed (will be passed into template)" )
150
+ parser .add_argument ("-m" , "--mode" , action = EnumAction , type = PrintingMode ,
151
+ choices = [x .value for x in PrintingMode ], default = PrintingMode .HALF_CUT ,
152
+ help = "Print mode (applicable for for more than one labels only)" )
153
+ parser .add_argument ("-c" , "--copies" , action = "store" , type = int , default = 1 ,
154
+ help = "Print mode (applicable for for more than one labels only)" )
155
+ parser .add_argument ("-f" , "--force-tape-detection" , action = "store_true" , default = False ,
156
+ help = "Forces tape detection even though there is a cached data" )
157
+ parser .add_argument ("-s" , "--skip-printing" , action = "store_true" , default = False ,
158
+ help = "Renders data and skips printing on the real device" )
159
+ parser .add_argument ("template" , action = "store" , type = str , help = "Template to use" )
160
+ parser .add_argument ("data" , nargs = "*" , action = "store" , type = str ,
161
+ help = "Data to be printed (will be passed into template)" )
119
162
120
163
def __is_template_name (self , name : str ) -> bool :
121
164
return ":" in name
@@ -130,18 +173,39 @@ def handle(self, args: argparse.Namespace):
130
173
template = self .template_library .load_template (template_name )
131
174
# Load printer data
132
175
printer = self .get_printer ()
133
- if printer is None :
176
+ if printer is None and not args . skip_printing :
134
177
CLI .print_error ("Printer is not connected." )
135
178
exit (1 )
136
179
else :
137
180
CLI .print_info ("Detected printer: {}" .format (printer ))
138
- printer .init ()
139
- printer_status = printer .get_status ()
140
- CLI .print_info ("\t Tape: {}" .format (printer_status .tape_info ))
141
- for x in data :
142
- print_job = PrintJob (template , dict (default = x ), cut_tape = False )
143
- bitmap = self .renderer .render_bitmap (print_job , printer_status .tape_info )
144
- printer .print_image (bitmap , print_job .cut_tape )
181
+ printer .init ()
182
+ tape_info = self .get_cached_tape_info ()
183
+ if tape_info is None or args .force_tape_detection :
184
+ if not args .skip_printing or args .force_tape_detection :
185
+ printer_status = printer .get_status ()
186
+ CLI .print_info ("\t Tape: {}" .format (printer_status .tape_info ))
187
+ tape_info = printer_status .tape_info
188
+ else :
189
+ if args .skip_printing :
190
+ CLI .print_error ("Tape information is not available in cache. Skip printing mode is not available" )
191
+ exit (2 )
192
+ else :
193
+ CLI .print_info ("Assuming tape: {}" .format (tape_info ))
194
+ label_num = 0
195
+ total_labels = len (data ) * args .copies
196
+ for i , x in enumerate (data ):
197
+ print_job = PrintJob (template , dict (default = x ))
198
+ bitmap = self .renderer .render_bitmap (print_job , tape_info )
199
+ if not args .skip_printing :
200
+ for c in range (args .copies ):
201
+ label_num += 1
202
+ if args .mode == PrintingMode .HALF_CUT :
203
+ cut_tape = label_num == total_labels # Cut the last label
204
+ else :
205
+ cut_tape = True
206
+ printer .print_image (bitmap , cut_tape )
207
+ else :
208
+ CLI .print_warn ("Printing skipped as per user request." )
145
209
146
210
147
211
def main (argv : List [str ]):
0 commit comments