Bonjour à tous !

J'ai besoin d'un peu d'aide de la part d'une personne calée en python, je pense que ce forum est le bon endroit pour essayer de résoudre mon problème.

Un ami m'avait écrit un petit programme qui a pour fonction l'impression d'un ticket sur imprimante thermique (style ticket de caisse pour magasin). Ce programme est exécuté sur Ubuntu 11.10.

Mon problème est que depuis que je suis passé sur Ubuntu 13.04, son programme me pose un petit problème. En fait, lorsque le ticket a fini d'être imprimé, l'imprimante coupe le papier physiquement et automatiquement. Cela fonctionnait très bien sur Ubuntu 11.10 mais ce qui n'est plus le cas sur Ubuntu 13.04. Le ticket est correctement imprimé, mais il n'est pas coupé par l'imprimante.

J'ai donc essayé d'imprimer un document avec des logiciels comme LibreOffice ou Gedit et cela fonctionne très bien, le papier est coupé par l'imprimante.

Le problème vient donc bien du programme en Python qui avait été écrit par un ami (je précise qu'il a déménagé à l'étranger, je n'ai plus la possibilité de le contacter).

Si quelqu'un a une idée pour résoudre mon problème, ce serait vraiment génial. Je ne connais rien au langage Python mais je me demandais si le problème ne venait pas d'une sorte d'instruction à rajouter en fin d'impression qui indique à l'imprimante qu'il s'agit de la fin du document à imprimer et qu'elle peut donc le couper physiquement.

Précision, sur Ubuntu 13.04 la version de Python est 2.7.4.

Merci d'avance pour votre aide...


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
from gtk import PrintOperation, PrintSettings, PRINT_OPERATION_ACTION_PRINT_DIALOG, PRINT_OPERATION_ACTION_PRINT, PRINT_OPERATION_RESULT_CANCEL, PRINT_OPERATION_RESULT_APPLY
from sys import argv, exit
from os import environ, mkdir
from os.path import isfile, isdir
from getopt import gnu_getopt, GetoptError
from pango import FontDescription, ALIGN_CENTER, SCALE
from pprint import pprint
from cairo import ImageSurface, Context
from gtk.gdk import pixbuf_new_from_file
from time import strftime
import re
import xml.sax.saxutils
 
# config values
cfgpath = environ['HOME'] + '/.vprinter/'
cfgfile = 'config.cfg'
decimalSeparator = ','
 
def main():
	global pageContent
	global currentLine
	global EOF
	global debug
 
	EOF = False
 
	# default values
	productList = ""
	tax = 0.0
	discount = 0.0
	vendor = ""
	date = strftime("%d/%m/%Y")
	time = strftime("%H:%M")
	checksum = ""
	comment = ""
	debug = False
	displayWebInfos = False
 
	try:
		opts, args = gnu_getopt(argv, "Cp:T:D:v:d:t:x:c:hVw", ["configuration", "product-list=", "tax=", "discount=", "vendor=", "date=", "time=", "checksum=", "comment=", "help", "debug", "webinforamtions"])
	except GetoptError, err:
		# print help information and exit:
		print str(err) # will print something like "option -a not recognized"
		usage()
		exit(2)
	configMode = False
	if len(opts) == 0:
		configMode = True
	else:
		# argument parsing
		for o, a in opts:
			if o == "-C" or o == "--configuration":
				configMode = True
			elif o in ("-p", "--product-list"):
				productList = a
			elif o in ("-T", "--tax"):
				tax = float(a)
			elif o in ("-D", "--discount"):
				discount = float(a)
			elif o in ("-v", "--vendor"):
				vendor = a
			elif o in ("-d", "--date"):
				date = a
			elif o in ("-t", "--time"):
				time = a
			elif o in ("-x", "--checksum"):
				checksum = a
			elif o in ("-c", "--comment"):
				comment = a
			elif o in ("-V", "--debug"):
				debug = True
			elif o in ("-w", "--webinforamtions"):
				displayWebInfos = True
			elif o in ("-h", "--help"):
				usage()
				return
			else:
				assert False, "unhandled option"
		currentLine = 0
 
		ticketWidth = 37 # In number of monospace characters
 
		#process product list here;
		result = re.findall("\{.*?\,.*?\}", productList)
		productArray = []
		total = 0.0
 
		for i in range(len(result)):
			result[i] = result[i].strip("{}")
			productArray.append((result[i].split(",")))
			productArray[-1][0] = productArray[-1][0].strip("'")
			productArray[-1][1] = float(productArray[-1][1])
 
		pageContent = ''
		pageContent += '<span font="Bangle 67">VIRTUAL DREAMS</span>\n'
		pageContent += '\n'
		pageContent += '<span font="25">ANNECY – 3 RUE DE LA PAIX</span>\n'
		pageContent += '<span font="25">TEL : 04-50-51-44-98</span>\n'
		pageContent += '\n'
		pageContent += '<span font="40">FACTURE</span>'
		pageContent += '\n'
		pageContent += '\n'
		pageContent += '\n'
		for i in range(len(productArray)):
			pageContent += padTo("Left", productArray[i][0], ticketWidth, '<span font="monospace 25">', '</span>\n')
			pageContent += padTo("Right", replaceDecimalSeparator("%.2f €" % productArray[i][1]), ticketWidth, '<span font="monospace 25">', '</span>\n')
			total += productArray[i][1]
		if discount != 0.0:
			pageContent += padTo("Left", "REDUCTION CARTE 1UP", ticketWidth, '<span font="monospace 25">', '</span>\n')
			pageContent += padTo("Right", replaceDecimalSeparator("-%.2f €" % discount), ticketWidth, '<span font="monospace 25">', '</span>\n')
			total -= discount
		pageContent += '<span font="monospace 25">'
		for i in range(ticketWidth):
			pageContent += '-'
		pageContent += '</span>\n'
		pageContent += '<span font="monospace 25">'
		pageContent += spread("TOTAL T.T.C.", replaceDecimalSeparator("%.2f €" % total), ticketWidth)
		pageContent += '</span>\n'
		pageContent += '<span font="monospace 25">'
		for i in range(ticketWidth):
			pageContent += '-'
		pageContent += '</span>\n'
 		pageContent += '\n'
		pageContent += '<span font="monospace 25">'
		pageContent += spreadAndCenter("TAUX TVA", "MONTANT H.T.", "TVA", ticketWidth)
		pageContent += '</span>\n'
		pageContent += '<span font="monospace 25">'
		pageContent += spreadAndCenter("%.2f %%" % tax, replaceDecimalSeparator("%.2f €" % (total/((tax/100)+1))), replaceDecimalSeparator("%.2f €" % (total - (total/((tax/100)+1)))), ticketWidth)
		pageContent += '</span>\n'
 		pageContent += '\n'
 		pageContent += '\n'
 		if discount != 0:
	 		pageContent += '<span font="Bangle 30">Votre carte 1UP vous a fait économiser ' + replaceDecimalSeparator("%.2f" % discount) + ' € sur votre achat.</span>\n'
	 		pageContent += '\n'
	 		pageContent += '\n'
		pageContent += 'Ce ticket de caisse est unique. Aucun duplicata ne sera délivré en cas de perte. Garantie : Consoles neuves : 1 an\nJeux neufs et d\'occasion : 1 an - Consoles d\'occasion :\n6 mois - Accessoires neufs et d\'occasion : 3 mois'
		pageContent += '\n'
		pageContent += '\n'
		pageContent += 'Vous avez été servi par ' + vendor + ',\n'
		pageContent += 'Le ' + date + ' à ' + time + '\n[' + checksum + ']\n'
		pageContent += '\n'
		pageContent += 'Nous vous remercions de votre visite et à bientôt.\n'
		if displayWebInfos:
			pageContent += '\n'
			pageContent += '<span font="Bangle Bold">Retrouvez toutes nos infos sur internet :</span>\n'
			pageContent += '<span font="Bangle Bold">Site Web : http://www.virtualdreams.fr</span>/\n'
			pageContent += '<span font="Bangle Bold">Facebook : Virtual Dreams Annecy</span>\n'
			pageContent += '<span font="Bangle Bold">Twitter : http://twitter.com/VDAnnecy</span>\n'
		pageContent += '\n'
		pageContent += '<span font="Bangle Bold">' + comment + '</span>\n'
		pageContent += '\n'
		pageContent += '\n'
		pageContent += '\n'
		pageContent += '\n'
		pageContent += '.'
 
	if configMode:
		# Popup configuration dialog here.
		printConfig()
	else:
		# Print here.
		if(configExists()):
			beginPrint()
		else:
			printConfig()
			beginPrint()
 
def replaceDecimalSeparator(floatInString):
	return floatInString.replace('.', decimalSeparator)
 
def padLineTo(direction, string, maxLenght):
	retStr = ''
	if direction.lower() == "left":
		retStr += string
		for i in range(maxLenght - (len(xml.sax.saxutils.unescape(string).decode("utf-8")) % maxLenght)):
			retStr += ' '
	elif direction.lower() == "right":
		for i in range(maxLenght - (len(xml.sax.saxutils.unescape(string).decode("utf-8")) % maxLenght)):
			retStr += ' '	
		retStr += string
	return retStr
 
 
def padTo(direction, string, maxLenght, lineStart = '', lineEnd = ''):
	returnString = lineStart
	stringArray = string.split(' ')
	recompStr = stringArray[0].decode("utf-8")
	for i in range(1, len(stringArray)):
		if len(recompStr + ' ' + xml.sax.saxutils.unescape(stringArray[i]).decode("utf-8")) < maxLenght:
			recompStr += ' ' + stringArray[i].decode("utf-8")
		else:
			returnString += padLineTo(direction, recompStr, maxLenght) + lineEnd + lineStart
			recompStr = stringArray[i].decode("utf-8")
	returnString += padLineTo(direction, recompStr, maxLenght) + lineEnd
	return returnString
 
def spread(str1, str2, maxLenght):
	if len(xml.sax.saxutils.unescape(str1).decode("utf-8")) + len(xml.sax.saxutils.unescape(str2).decode("utf-8")) >= maxLenght:
		return "Content too large"
	retStr = ''
	retStr += str1
	for i in range(maxLenght - len(xml.sax.saxutils.unescape(str1).decode("utf-8")) - len(xml.sax.saxutils.unescape(str2).decode("utf-8"))):
		retStr += ' '
	retStr += str2
	return retStr
 
def spreadAndCenter(str1, str2, str3, maxLenght):
	if len(xml.sax.saxutils.unescape(str1).decode("utf-8")) + len(xml.sax.saxutils.unescape(str2).decode("utf-8")) + len(xml.sax.saxutils.unescape(str3).decode("utf-8")) >= maxLenght:
		return "Content too large"
	retStr = ''
	paddingTotal = maxLenght - len(xml.sax.saxutils.unescape(str2).decode("utf-8"))
	if paddingTotal%2 == 0:
		paddingLeft = int(paddingTotal/2) - len(str1.decode("utf-8"))
		paddingRight = int(paddingTotal/2) - len(str3.decode("utf-8"))
	else:
		paddingLeft = int(paddingTotal/2) + 1 - len(str1.decode("utf-8"))
		paddingRight = int(paddingTotal/2) - len(str3.decode("utf-8"))
	retStr += str1
	for i in range(paddingLeft):
		retStr += ' '
	retStr += str2
	for i in range(paddingRight):
		retStr += ' '
	retStr += str3
	return retStr
 
def drawPage(operation, context, page_nr):
	global pageContent
	global currentLine
	global EOF
	global debug
 
	# Load config
	settings = PrintSettings()
 
	#settings.load_file(cfgpath + cfgfile)
	if settings != None:
		operation.set_print_settings(settings)
 
	# Get cairo context, its width and fill it.
	cairoContext = context.get_cairo_context()		# gtk.gdk.cairoContext.
 
	width = context.get_width()
	cairoContext.fill()
 
	# Create pango layout, set width, alignment and default font; and add text.
	layout = context.create_pango_layout()
	layout.set_width(int(width * SCALE))
	layout.set_alignment(ALIGN_CENTER)
	layout.set_font_description(FontDescription("Bangle 20"))
 
	i = currentLine
	k = currentLine
	array = pageContent.split("\n")
 
	while layout.get_size()[1] < 755 * SCALE and i <= len(array):
		myStr = ''
		for j in range(k, i):
			myStr += array[j] + '\n'
		layout.set_markup(myStr)
		i += 1
 
	currentLine = i - 1
 
	if i == len(array):
		if not EOF:
			EOF = True
			#print "Fin de document page " + str(page_nr + 1)
 
	rectXleft	= 0
	rectXright	= width
	rectYtop	= 0
	rectYbottom	= 86
 
 
	cairoContext.set_line_width(3.0)
	cairoContext.set_source_rgb(0, 0, 0);
	cairoContext.move_to(rectXleft, rectYtop)
 
	cairoContext.show_layout(layout)
 
	if page_nr == 0:
		cairoContext.line_to(rectXright, rectYtop)
		cairoContext.line_to(rectXright, rectYbottom)
		cairoContext.line_to(rectXleft, rectYbottom)
		cairoContext.line_to(rectXleft, rectYtop)
		cairoContext.stroke()
 
 
def beginPrint():
	#print
	print_op = PrintOperation()
	print_op.connect("draw_page", drawPage)
	print_op.set_n_pages(5)				# MUST be high enough to ensure complete printing.
	if debug:
		res = print_op.run(PRINT_OPERATION_ACTION_PRINT_DIALOG)
	else:
		res = print_op.run(PRINT_OPERATION_ACTION_PRINT)
 
def configExists():
	# Check if config file exists
	return isfile(cfgpath + cfgfile)
 
def usage():
	# Print out usage
	usage = "Si invoque sans argument, configuration. Si invoque pour la premiere fois, configuration.\n"
	usage += "aide:\n"
	usage += "-h\n"
	usage += "--help\n"
	usage += "configuration:\n"
	usage += "\t-C\n"
	usage += "\t--configuration\n"
	usage += "Liste de produits:\n"
	usage += "\t-p {{\"produit\", prix}, (\"produit\": prix), [\"produit\": prix], (\"produit\", prix), [\"produit\"; prix], {\"produit\": prix}}\n"
	usage += "\t--product-list {{\"produit\", prix}, (\"produit\": prix), [\"produit\": prix], (\"produit\", prix), [\"produit\"; prix], {\"produit\": prix}}\n"
	usage += "TVA (percentage):\n"
	usage += "\t-T\n"
	usage += "\t--tax\n"
	usage += "Discount:\n"
	usage += "\t-D\n"
	usage += "\t--discount\n"
	usage += "Vendeur:\n"
	usage += "\t-v\n"
	usage += "\t--vendor\n"
	usage += "Date:\n"
	usage += "\t-d\n"
	usage += "\t--date\n"
	usage += "Heure:\n"
	usage += "\t-t\n"
	usage += "\t--time\n"
	usage += "Numero de controle\n"
	usage += "-x\n"
	usage += "--checksum\n"
	usage += "Commentaire\n"
	usage += "-c\n"
	usage += "--comment\n"
	print usage
 
def printConfig():
	print "Fonction de configuration non disponible pour le moment."
 
if __name__ == "__main__":
	# Call main function if not started as module
	main()