Coverage for pyilper/pilcore.py: 86%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/python3
2# -*- coding: utf-8 -*-
3#
4# pyILPER
5#
6# Python platform dependent classes and constants
7# Copyright (c) 2016 J. Siebold
8#
9# This program is free software; you can redistribute it and/or
10# modify it under the terms of the GNU General Public License
11# as published by the Free Software Foundation; either version 2
12# of the License, or (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22#
23# pyILPER support and constants ---------------------------------------------------
24#
25# Changelog
26# 08.07.16 - jsi:
27# - initial release
28# 25.07.2016 - jsi
29# - set version to "production"
30# 21.08.2016 - jsi
31# - set version to 1.3.5 development
32# 13.10.2016 - jsi
33# - device tab constants and dictionary added
34# 18.10.2016 - jsi
35# - set version number to 1.4.0 development
36# 23.10.2016 - jsi
37# - EMU7470_VERSION added
38# 25.10.2016 - jsi
39# - decode_version moved from lifexec.py
40# 26.10.2016 - jsi
41# - version 1.4.0 beta1
42# 04.11.2016 - jsi
43# - version 1.4.0 beta2
44# 01.01.2016 - jsi
45# - version 1.4.0
46# 07.01.2016 - jsi
47# - add encode version function
48# 03.01.2016 - jsi
49# - version - 1.5.0beta1 development
50# 16.03.2017 - jsi
51# - version - 1.5.0 production
52# 01.08.2017 - jsi
53# - device HP82162A added
54# 10.08.2017 jsi
55# - version 1.6.0 development
56# 11.08.2017 jsi
57# - catch error in decode_version if no version information exists
58# 18.08.2017 jsi
59# - Tab name plotter renamed to HP7470A
60# 21.08.2017 jsi
61# - PDF and barcode constants added
62# 31.08.2017 jsi
63# - parameter TERMINAL_MINIMUM_ROWS added
64# 03.09.2017 jsi
65# - communication mode constants moved from pyilpermain.py
66# 06.09.2017 jsi
67# - restructured, assemble_frame and disassemble_frame added
68# 07.09.2017 jsi
69# - timeout constants for TCP, socket and pipe communication added
70# 01.10.2017 jsi
71# - 1.6.0 beta1
72# 12.11.2017 jsi
73# - 1.6.0 beta3
74# 13.11.2017 jsi
75# - make USE8BITS change depending on data returned by the PIL-Box
76# 27.11.2017 jsi
77# - version 1.6.0 production
78# 04.12.2017 jsi
79# - version 1.6.1 development
80# 28.12.2017 jsi
81# - AUTOSCROLL_RATE parameter introduced
82# 16.01.2018 jsi
83# - added config type parameters for cls_config_tool_button
84# 17.01.2018 jsi
85# - added color scheme constants
86# - changed version to 1.7.0 because of major enhancements of the GUI
87# 21.01.2018 jsi
88# - moved cls_config_tool_button and color scheme constants to pilwidget.py
89# 22.02.2018 jsi
90# - 1.7.1 production
91# 18.03.2018 jsi
92# - 1.7.2 development, added Python minimum version requirements
93# 04.08.2018 jsi
94# - 1.7.2 beta1
95# 11.08.2018 jsi
96# - 1.7.2 beta2
97# 20.08.2018 jsi
98# - 1.7.2 production
99# 12.12.2018 jsi
100# - added HP2225B_LINEBUFFERSIZE
101# - 1.8.0 development
102# 18.12.2018 jsi
103# - added HP2225B
104# 10.01.2019 jsi
105# - renamed Printer tab to Generic Printer
106# - prepare Beta1
107# 14.01.2019 jsi
108# - added constants for keyboard type configuration
109# - prepare Beta2
110# 27.01.2019 jsi
111# - introduced KEYBOARD_DELAY configuration parameter
112# 09.01.2019 jsi
113# - prepare release
114# 31.05.2019 jsi
115# - 1.8.1 development
116# 05.06.2019
117# - 1.8.1 production
118# 06.11.2019 jsi
119# - 1.8.2 development
120# 03.02.2020 jsi
121# - prepare release
122# 29.04.2020 jsi
123# - 1.8.3 development
124# 10.01.2021 jsi
125# - 1.8.3 release
126# 01.03.2021 jsi
127# - 1.8.4 development
128# 16.11.2021 jsi
129# - TAB_RAWDRIVE added
130# 28.11.2021 jsi
131# - prepare 1.8.5 beta 1
132# 12.12.2021 jsi
133# - function buildconfigfilename added
134# 17.02.2022 jsi
135# - 1.8.5 release
136# - function to decode the pyILPER release number rewritten
137# 18.04.22 jsi
138# - 1.8.6 beta1
139# - used raw string in re.compile to avoid DEPRECATED warning
140#
141import platform
142import os
143import re
144#
145# Program constants --------------------------------------------------
146#
147# General constants:
148#
149PRODUCTION= False # Production/Development Version
150VERSION="1.8.7b2" # pyILPR version number
151CONFIG_VERSION="2" # Version number of pyILPER config file, must be string
152#
153# Python minimum version
154#
155PYTHON_REQUIRED_MAJOR=3
156PYTHON_REQUIRED_MINOR=5
157#
158# Communication modes and classes
159#
160MODE_PILBOX=0 # connect to PIL-Box
161MODE_TCPIP=1 # connect to virtual HP-IL over TCP/IP
162MODE_SOCKET=2 # conect via Unix domain socket
164#
165# PIL-Box communication
166#
167USE8BITS= True # use 8 bit data transfer to PIL-Box
168TMOUTCMD=1 # time out for PIL-Box commands
169TMOUTFRM=0.05 # time out for HP-IL frames
171#
172# TCP/IP, socket and pipe communication
173#
174COMTMOUTREAD=0.1 # time out for read
175COMTMOUTACK=1 # time out for receiving an acknowledge
176COMTMOUTWRITE=1 # tine out for write
178#
179# Drive tab - directory listing
180#
181REFRESH_RATE=1000 # period to check whether a drive was altered and is idle
182NOT_TALKER_SPAN=3 # time (s) a drive must be inactive to be concidered as idle
183#
184# Terminal tab
185#
186UPDATE_TIMER=25 # Poll timer (ms) for terminal output queue
187CURSOR_BLINK=500 # 500 ms cursor blink rate
188CURSOR_BLINK_INTERVAL= CURSOR_BLINK / UPDATE_TIMER
189AUTOSCROLL_RATE=100 # 500 ms cursor blink rate
190TERMINAL_MINIMUM_ROWS=24 # can't get beyond that
191KEYBOARD_DELAY=500 # autorepeat delay to prevent too fast kbd input
193#
194# predefined baudrates
195# the list controlles the baudrates that are supported by the application:
196# - the first list element sets the text in the combobox
197# - the second list element is the baud rate, a value of 0 means auto baud detection
198# the baudrates must be defined in ascending order
199BAUDRATES= [ ["Auto", 0], ["9600", 9600 ] , [ "115200", 115200 ], ["230400", 230400]]
201#
202# plotter tab, required version of emu7470
203#
204EMU7470_VERSION=900
206#
207# thermal printer tab
208#
209HP82162A_LINEBUFFERSIZE=2000
211#
212# if Development Version append string to VERSION and "d" to config file name
213#
214if not PRODUCTION:
215 VERSION=VERSION+" (Development)"
216#
217# Tab types
218#
219TAB_SCOPE=0
220TAB_PRINTER=1
221TAB_DRIVE=2
222TAB_TERMINAL=3
223TAB_PLOTTER=4
224TAB_HP82162A=5
225TAB_HP2225B=6
226TAB_RAWDRIVE=7
227#
228TAB_NAMES={TAB_SCOPE:'Scope',TAB_PRINTER:'Generic Printer',TAB_DRIVE:'Drive',TAB_TERMINAL:'Terminal',TAB_PLOTTER:'HP7470A',TAB_HP82162A:'HP82162A', TAB_HP2225B: 'HP2225B', TAB_RAWDRIVE: 'Raw Drive'}
229#
230# PDF Constants in 1/10 mm
231#
232PDF_MARGINS=100
233PDF_FORMAT_A4=0
234PDF_FORMAT_LETTER=1
235PDF_ORIENTATION_PORTRAIT=0
236PDF_ORIENTATION_LANDSCAPE=1
237#
238# Barcode Constants in 1/10 mm
239#
240BARCODE_HEIGHT=100
241BARCODE_NARROW_W= 5
242BARCODE_WIDE_W= 10
243BARCODE_SPACING= 5
245#
246# utility functions --------------------------------------------------------------
247#
248# get platform
249#
250def isLINUX():
251 return platform.system()=="Linux"
252def isWINDOWS():
253 return platform.system()=="Windows"
254def isMACOS():
255 return platform.system()=="Darwin"
256#
257# Standard FONT
258# Note: It would be more elegant to use "Andale Mono" on Macos and "Consolas" on
259# Windows. "Consolas" is not available on XP and older Windows versions.
260#
261if isLINUX():
262 FONT="Monospace"
263else:
264 FONT="Courier New"
265#
266# decode version number of lifutils or emu7470
267#
268def decode_version(version_number):
269 if version_number==0:
270 return "(unknown)"
271 version=str(version_number)
272 major=int(version[0])
273 minor=int(version[1:3])
274 subversion=int(version[3:5])
275 return "{:d}.{:d}.{:d}".format(major,minor,subversion)
276#
277# decode version number of pyilper as a list
278#
279def decode_pyILPERVersion(version_string):
280#
281# parse the pyILPER version string as a list:
282# major version, minor version, subversion, a/b, devel-version
283# only major version, minor version and subersion are returned as a
284# single integer. Returns 0 if no valid release information was found.
285#
286# Fixed DEPRECATED escape sequence \. using raw string
287 reg=re.compile(r'^([0-9]+)\.([0-9]+)\.([0-9]+)(?:(b)([0-9]+)?)?.*$')
288 ret=reg.findall(version_string)
289 try:
290 major=int(ret[0][0])
291 minor=int(ret[0][1])
292 subversion=int(ret[0][2])
293 return major*10000+minor*100+subversion
294 except ValueError:
295 return 0
296 except IndexError:
297 return 0
298#
299# assemble frame from low and high byte according to 7- oder 8-bit format
300#
301def assemble_frame(hbyt,lbyt):
302 global USE8BITS
303 if( lbyt & 0x80 ):
304 USE8BITS= True
305 return ((hbyt & 0x1E) << 6) + (lbyt & 0x7F)
306 else:
307 USE8BITS= False
308 return ((hbyt & 0x1F) << 6) + (lbyt & 0x3F)
309#
310# disassemble frame from low and high byte according to 7- oder 8-bit format
311#
313def disassemble_frame(frame):
314 if not USE8BITS :
315 hbyt = ((frame >> 6) & 0x1F) | 0x20
316 lbyt = (frame & 0x3F) | 0x40
317 else:
318 hbyt = ((frame >> 6) & 0x1E) | 0x20
319 lbyt = (frame & 0x7F) | 0x80
320 return(hbyt,lbyt)
321#
322# assemble file name of config file
323#
324def buildconfigfilename(progname,filename,configversion,instance,production):
325#
326# determine config file name
327#
328 fname=filename+instance+configversion
329 if not production:
330 fname+= "d"
331#
332# determine path (os dependend)
333#
334 userhome=os.path.expanduser("~")
336 if platform.system()=="Linux":
337#
338# LINUX
339#
340 configpath=os.path.join(userhome,".config",progname)
341 elif platform.system()=="Windows":
342#
343# Windows
344#
345 configpath=os.path.join(os.environ['APPDATA'],progname)
346 elif platform.system()=="Darwin":
347#
348# Mac OS X
349#
350 configpath=os.path.join(userhome,"Library","Application Support",progname)
351#
352 else:
353#
354# Fallback
355#
356 configpath=os.path.join(userhome,progname)
357 configfilename=os.path.join(configpath,fname)
359 return configfilename,configpath