将UNIX python程序转换为在windows中工作
我需要做一个程序来驱动DYMO LabelManager PnP标签打印设备。DYMO为此提供了一个SDK,但经过一些绝望的尝试后,我认为SDK是无用的。然后我找到了一个程序,它正是我所需要的,由一个叫S.Bronner的人编写。但问题是,他的程序是为UNIX中的Python编写的,我需要它在Windows中使用Python。所以我在问,有没有人可以检查这段代码并将其转换为在windows中为我工作?我的Python技能不足以完成这项任务。以下是应转换的代码:将UNIX python程序转换为在windows中工作,python,windows,unix,Python,Windows,Unix,我需要做一个程序来驱动DYMO LabelManager PnP标签打印设备。DYMO为此提供了一个SDK,但经过一些绝望的尝试后,我认为SDK是无用的。然后我找到了一个程序,它正是我所需要的,由一个叫S.Bronner的人编写。但问题是,他的程序是为UNIX中的Python编写的,我需要它在Windows中使用Python。所以我在问,有没有人可以检查这段代码并将其转换为在windows中为我工作?我的Python技能不足以完成这项任务。以下是应转换的代码: #!/usr/bin/env py
#!/usr/bin/env python
DEV_CLASS = 3
DEV_VENDOR = 0x0922
DEV_PRODUCT = 0x1001
DEV_NODE = None
DEV_NAME = 'Dymo LabelManager PnP'
FONT_FILENAME = '/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf'
FONT_SIZERATIO = 7./8
import Image
import ImageDraw
import ImageFont
import array
import fcntl
import os
import re
import struct
import subprocess
import sys
import termios
import textwrap
class DymoLabeler:
"""
Create and work with a Dymo LabelManager PnP object.
This class contains both mid-level and high-level functions. In general,
the high-level functions should be used. However, special purpose usage
may require the mid-level functions. That is why they are provided.
However, they should be well understood before use. Look at the
high-level functions for help. Each function is marked in its docstring
with 'HLF' or 'MLF' in parentheses.
"""
def __init__(self, dev):
"""Initialize the LabelManager object. (HLF)"""
self.maxBytesPerLine = 8 # 64 pixels on a 12mm-tape
self.ESC = 0x1b
self.SYN = 0x16
self.cmd = []
self.rsp = False
self.bpl = None
self.dtb = 0
if not os.access(dev, os.R_OK | os.W_OK): return False
self.dev = open(dev, 'r+')
def sendCommand(self):
"""Send the already built command to the LabelManager. (MLF)"""
if len(self.cmd) == 0: return
cmdBin = array.array('B', self.cmd)
cmdBin.tofile(self.dev)
self.cmd = []
if not self.rsp: return
self.rsp = False
rspBin = self.dev.read(8)
rsp = array.array('B', rspBin).tolist()
return rsp
def resetCommand(self):
"""Remove a partially built command. (MLF)"""
self.cmd = []
self.rsp = False
def buildCommand(self, cmd):
"""Add the next instruction to the command. (MLF)"""
self.cmd += cmd
def statusRequest(self):
"""Set instruction to get the device's status. (MLF)"""
cmd = [self.ESC, ord('A')]
self.buildCommand(cmd)
self.rsp = True
def dotTab(self, value):
"""Set the bias text height, in bytes. (MLF)"""
if value < 0 or value > self.maxBytesPerLine: raise ValueError
cmd = [self.ESC, ord('B'), value]
self.buildCommand(cmd)
self.dtb = value
self.bpl = None
def tapeColor(self, value):
"""Set the tape color. (MLF)"""
if value < 0: raise ValueError
cmd = [self.ESC, ord('C'), value]
self.buildCommand(cmd)
def bytesPerLine(self, value):
"""Set the number of bytes sent in the following lines. (MLF)"""
if value < 0 or value + self.dtb > self.maxBytesPerLine: raise ValueError
if value == self.bpl: return
cmd = [self.ESC, ord('D'), value]
self.buildCommand(cmd)
self.bpl = value
def cut(self):
"""Set instruction to trigger cutting of the tape. (MLF)"""
cmd = [self.ESC, ord('E')]
self.buildCommand(cmd)
def line(self, value):
"""Set next printed line. (MLF)"""
self.bytesPerLine(len(value))
cmd = [self.SYN] + value
self.buildCommand(cmd)
def chainMark(self):
"""Set Chain Mark. (MLF)"""
self.dotTab(0)
self.bytesPerLine(self.maxBytesPerLine)
self.line([0x99] * self.maxBytesPerLine)
def skipLines(self, value):
"""Set number of lines of white to print. (MLF)"""
if value <= 0: raise ValueError
self.bytesPerLine(0)
cmd = [self.SYN] * value
self.buildCommand(cmd)
def initLabel(self):
"""Set the label initialization sequence. (MLF)"""
cmd = [0x00] * 8
self.buildCommand(cmd)
def getStatus(self):
"""Ask for and return the device's status. (HLF)"""
self.statusRequest()
rsp = self.sendCommand()
print rsp
def printLabel(self, lines, dotTab):
"""Print the label described by lines. (HLF)"""
self.initLabel
self.tapeColor(0)
self.dotTab(dotTab)
for line in lines:
self.line(line)
self.skipLines(56) # advance printed matter past cutter
self.skipLines(56) # add symmetric margin
self.statusRequest()
rsp = self.sendCommand()
print rsp
def die(message=None):
if message: print >> sys.stderr, message
sys.exit(1)
def pprint(par, fd=sys.stdout):
rows, columns = struct.unpack('HH', fcntl.ioctl(sys.stderr, termios.TIOCGWINSZ, struct.pack('HH', 0, 0)))
print >> fd, textwrap.fill(par, columns)
def getDeviceFile(classID, vendorID, productID):
# find file containing the device's major and minor numbers
searchdir = '/sys/bus/hid/devices'
pattern = '^%04d:%04X:%04X.[0-9A-F]{4}$' % (classID, vendorID, productID)
deviceCandidates = os.listdir(searchdir)
foundpath = None
for devname in deviceCandidates:
if re.match(pattern, devname):
foundpath = os.path.join(searchdir, devname)
break
if not foundpath: return
searchdir = os.path.join(foundpath, 'hidraw')
devname = os.listdir(searchdir)[0]
foundpath = os.path.join(searchdir, devname)
filepath = os.path.join(foundpath, 'dev')
# get the major and minor numbers
f = open(filepath, 'r')
devnums = [int(n) for n in f.readline().strip().split(':')]
f.close()
devnum = os.makedev(devnums[0], devnums[1])
# check if a symlink with the major and minor numbers is available
filepath = '/dev/char/%d:%d' % (devnums[0], devnums[1])
if os.path.exists(filepath):
return os.path.realpath(filepath)
# check if the relevant sysfs path component matches a file name in
# /dev, that has the proper major and minor numbers
filepath = os.path.join('/dev', devname)
if os.stat(filepath).st_rdev == devnum:
return filepath
# search for a device file with the proper major and minor numbers
for dirpath, dirnames, filenames in os.walk('/dev'):
for filename in filenames:
filepath = os.path.join(dirpath, filename)
if os.stat(filepath).st_rdev == devnum:
return filepath
def access_error(dev):
pprint('You do not have sufficient access to the device file %s:' % dev, sys.stderr)
subprocess.call(['ls', '-l', dev], stdout=sys.stderr)
print >> sys.stderr
pprint('You probably want to add a rule in /etc/udev/rules.d along the following lines:', sys.stderr)
print >> sys.stderr, ' SUBSYSTEM=="hidraw", \\'
print >> sys.stderr, ' ACTION=="add", \\'
print >> sys.stderr, ' DEVPATH=="/devices/pci[0-9]*/usb[0-9]*/0003:0922:1001.*/hidraw/hidraw0", \\'
print >> sys.stderr, ' GROUP="plugdev"'
print >> sys.stderr
pprint('Following that, turn off your device and back on again to activate the new permissions.', sys.stderr)
# get device file name
if not DEV_NODE:
dev = getDeviceFile(DEV_CLASS, DEV_VENDOR, DEV_PRODUCT)
else:
dev = DEV_NODE
if not dev: die("The device '%s' could not be found on this system." % DEV_NAME)
# create dymo labeler object
lm = DymoLabeler(dev)
if not lm: die(access_error(dev))
# check for any text specified on the command line
labeltext = [arg.decode(sys.stdin.encoding) for arg in sys.argv[1:]]
if len(labeltext) == 0: die("No label text was specified.")
# create an empty label image
labelheight = lm.maxBytesPerLine * 8
lineheight = float(labelheight) / len(labeltext)
fontsize = int(round(lineheight * FONT_SIZERATIO))
font = ImageFont.truetype(FONT_FILENAME, fontsize)
labelwidth = max(font.getsize(line)[0] for line in labeltext)
labelbitmap = Image.new('1', (labelwidth, labelheight))
# write the text into the empty image
labeldraw = ImageDraw.Draw(labelbitmap)
for i, line in enumerate(labeltext):
lineposition = int(round(i * lineheight))
labeldraw.text((0, lineposition), line, font=font, fill=255)
del labeldraw
# convert the image to the proper matrix for the dymo labeler object
labelrotated = labelbitmap.transpose(Image.ROTATE_270)
labelstream = labelrotated.tostring()
labelstreamrowlength = labelheight/8 + (1 if labelheight%8 != 0 else 0)
if len(labelstream)/labelstreamrowlength != labelwidth: die('An internal problem was encountered while processing the label bitmap!')
labelrows = [labelstream[i:i+labelstreamrowlength] for i in range(0, len(labelstream), labelstreamrowlength)]
labelmatrix = [array.array('B', labelrow).tolist() for labelrow in labelrows]
# optimize the matrix for the dymo label printer
dottab = 0
while max(line[0] for line in labelmatrix) == 0:
labelmatrix = [line[1:] for line in labelmatrix]
dottab += 1
for line in labelmatrix:
while len(line) > 0 and line[-1] == 0:
del line[-1]
# print the label
lm.printLabel(labelmatrix, dottab)
#/usr/bin/env python
DEV_CLASS=3
DEV_供应商=0x0922
DEV_PRODUCT=0x1001
DEV_节点=无
开发人员名称='Dymo LabelManager PnP'
FONT\u FILENAME='/usr/share/fonts/truetype/ttf bitstream vera/vera.ttf'
字体大小=7./8
导入图像
导入图像绘制
导入图像字体
导入数组
进口fcntl
导入操作系统
进口稀土
导入结构
导入子流程
导入系统
进口术语
导入文本包装
DymoLabeler类:
"""
创建并使用Dymo LabelManager PnP对象。
此类包含中级和高级函数。通常,
应使用高级功能。但是,特殊用途
可能需要中级功能。这就是提供这些功能的原因。
但是,在使用之前,应该充分理解它们
用于帮助的高级函数。每个函数都在其docstring中标记
括号中带有“HLF”或“MLF”。
"""
定义初始化(self,dev):
“”“初始化LabelManager对象。(HLF)”
self.maxBytesPerLine=12毫米磁带上的8#64像素
self.ESC=0x1b
self.SYN=0x16
self.cmd=[]
self.rsp=False
self.bpl=None
self.dtb=0
如果不是os.access(dev,os.R_OK | os.W_OK):返回False
self.dev=open(dev,'r+')
def sendCommand(自我):
“”“将已生成的命令发送到LabelManager。(MLF)”
如果len(self.cmd)==0:返回
cmdBin=array.array('B',self.cmd)
cmdBin.tofile(self.dev)
self.cmd=[]
如果不是self.rsp:返回
self.rsp=False
rspBin=self.dev.read(8)
rsp=array.array('B',rspBin).tolist()
返回rsp
def RESET命令(自我):
“”“删除部分生成的命令。(MLF)”
self.cmd=[]
self.rsp=False
def buildCommand(self,cmd):
“”“将下一条指令添加到命令。(MLF)”
self.cmd+=cmd
def状态请求(自我):
“”“设置获取设备状态的指令。(MLF)”
cmd=[self.ESC,ord('A')]
self.buildCommand(cmd)
self.rsp=True
def dotTab(自身,值):
“”“以字节为单位设置偏移文本高度。(MLF)”
如果值<0或值>self.maxBytesPerLine:引发值错误
cmd=[self.ESC,ord('B'),value]
self.buildCommand(cmd)
self.dtb=值
self.bpl=None
def tapeColor(自身、值):
“”“设置磁带颜色。(MLF)”
如果值<0:提升值错误
cmd=[self.ESC,ord('C'),value]
self.buildCommand(cmd)
def字节数PERLINE(自身,值):
“”“设置在以下行中发送的字节数。(MLF)”
如果值<0或值+self.dtb>self.maxBytesPerLine:引发值错误
如果值==self.bpl:返回
cmd=[self.ESC,ord('D'),value]
self.buildCommand(cmd)
self.bpl=值
def切割(自):
“”“设置指令以触发剪切磁带。(MLF)”
cmd=[self.ESC,ord('E')]
self.buildCommand(cmd)
def管路(自身、值):
“”“设置下一打印行。(MLF)”
自身字节数(len(value))
cmd=[self.SYN]+值
self.buildCommand(cmd)
def链标记(自身):
“”“设置链标记。(MLF)”
self.dotTab(0)
self.bytesPerLine(self.maxBytesPerLine)
self.line([0x99]*self.maxBytesPerLine)
def skipLines(自身、值):
“”“设置要打印的白色行数。(MLF)”
如果值>sys.stderr,则显示消息
系统出口(1)
def pprint(par,fd=sys.stdout):
行,列=struct.unpack('HH',fcntl.ioctl(sys.stderr,termios.TIOCGWINSZ,struct.pack('HH',0,0)))
打印>>fd,textwrap.fill(段落,列)
def getDeviceFile(classID、vendorID、productID):
#查找包含设备主要和次要编号的文件
searchdir='/sys/bus/hid/devices'
模式='^%04d:%04X:%04X。[0-9A-F]{4}$'%(classID、vendorID、productID)
deviceCandidates=os.listdir(searchdir)
foundpath=None
对于deviceCandidates中的devname:
如果重新匹配(模式、名称):
foundpath=os.path.join(searchdir,devname)
打破
如果未找到路径:返回
searchdir=os.path.join(foundpath'hidraw')
devname=os.listdir(searchdir)[0]
foundpath=os.path.join(searchdir,devname)
filepath=os.path.join(foundpath,'dev')
#获取主要和次要数字
f=打开(文件路径“r”)
devnums=[int(n)表示f.readline().strip().split(“:”)中的n]
f、 关闭()
devnum=os.makedev(devnums[0],devnums[1])
#检查是否有带有主要和次要编号的符号链接可用
文件路径='/dev/char/%d:%d'(devnums[0],devnums[1])
如果os.path.存在(文件路径):
返回os.path.realpath(filepath)
#检查相关的sysfs路径组件是否与中的文件名匹配
#/dev,它有正确的主次编号
filepath=os.path.join('/dev',devname)
如果os.stat(filepath).st_rdev==devnum:
返回文件路径
#搜索具有正确主数字和次数字的设备文件
对于os.walk('/dev')中的dirpath、dirname和文件名:
对于文件名中的文件名:
filepath=os.path.join(dirpath,文件名)
如果os.stat(filepath).st_rdev==devnum:
返回文件路径
def访问_错误(开发人员):
pprint('您没有足够的权限访问设备文件%s:'%dev,sys.stderr〕
子进程调用(['ls','-l',dev],stdout=sys.stderr)
打印>>sys.stderr
pprint('您可能希望在/etc/udev/rules.d中沿以下行添加规则:',sys.stderr)
打印>>sys.stderr,'SUBSYSTEM==“hidraw”,\\'
打印>>sys.stderr'ACT
FONT_FILENAME = '/usr/share/fonts/truetype/ttf-bitstream-vera/Vera.ttf'
// should be changed to path to the font on your system
searchdir = '/sys/bus/hid/devices'
// take a look at "pywinusb" library (?)
filepath = '/dev/char/%d:%d' % (devnums[0], devnums[1])