#!/usr/bin/python
################################################################################
# This is a Pyla protocol module.
# Copyright (C) 2003 Andrea Nicolini
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Andrea Nicolini's Address is:
#
# Via G.Zoccoli n.80 Baggiovara
# Modena, ITALY
# E-Mail <andrea@teamsw.it>
#
################################################################################
import traceback
import string,os,ftplib,xmlrpclib,StringIO
from types import ListType
import time
JFMT = "%j|%o|%e|%P|%a|%D|%z|%s|%f"
pbar = None
def get_exdesc(excpt):
if type(excpt.args) == type(''):
return excpt.args
elif type(excpt.args) == type(()):
return excpt.args[-1]
else:
return str(excpt)
class Hylafax:
retrbuf = []
filepath = ""
coverpath = ""
username = "Anonymous"
password = ''
adminpass = ''
parmhash = {}
sendhash = {}
multicover = 0
cover_as_document = 0
recvfile = ''
ftpexcpt = None
filerror = None
tzone = 0
def __init__(self,host='',port=4559, debug=0, passive=1, debug_funct=None):
self.debug = debug
self._debug_funct = debug_funct
self.ftp = ftplib.FTP()
self.ftp.set_pasv(passive)
self.setfaxhost(host,port)
def setfaxhost(self,host,port):
hosterr = "Parameter 'host' must be a string."
porterr = "Parameter 'port' must be an integer."
if type(host) == type(""):
self.faxhost = host
else:
try:
self.faxhost = str(host)
except:
raise hosterr
if type(port) == type(1):
self.faxport = port
else:
raise porterr
def login(self,ftpobj,username,password,adminpass):
try:
if self.debug:
self.ftp.set_debuglevel(self.debug)
ftpobj.sendcmd('USER '+username)
if password:
ftpobj.sendcmd('PASS '+password)
if adminpass:
ftpobj.sendcmd('ADMIN '+adminpass)
except (ftplib.error_perm, ftplib.error_temp), msg:
#Hide the "already logged in" error
if not str(msg).startswith("503"):
print "Already logged", msg
except Exception, msg:
print "Error on login!", msg
msg = get_exdesc(msg)
return (1, msg)
if self.tzone == 0: tzoneCmd = 'GMT'
else: tzoneCmd = 'LOCAL'
ftpobj.sendcmd('TZONE %s' % tzoneCmd)
ftpobj.sendcmd('MODE S')
return (0, 'ok')
def getstatus(self):
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (0, msg)
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
self.retrbuf = []
self.ftp.retrlines('LIST status', self.callback)
self.ftp.quit()
return (0, self.retrbuf)
def getqueue(self,queue,jfmt=JFMT,view='priv', user_pos = 0, date_pos = 0, filter = ()):
retlist = []
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
except Exception, msg:
msg = get_exdesc(msg)
return (2, msg)
if queue == 'recvq':
fmt = 'RCVFMT'
else:
fmt = 'JOBFMT'
try:
self.ftp.sendcmd('%s "%s"' % (fmt,jfmt))
except Exception, msg:
msg = get_exdesc(msg)
return (3, msg)
self.retrbuf = []
self.ftp.retrlines('LIST '+ queue, self.callback)
self.ftp.quit()
for l in self.retrbuf:
sl = self.divide(l,'|')
if queue != 'recvq':
try:
if view == 'priv':
str_user_pos = sl[user_pos]
if str_user_pos != self.username: continue
except:
continue
if len(sl) == len(self.divide(jfmt,'|')):
retlist.append(sl)
months = ['None','Jan', 'Feb', 'Mar', 'Apr', 'May','Jun','Jul',
'Aug','Sep','Oct','Nov','Dec']
days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat','Sun']
if queue != 'recvq':
retlist.sort(self.__cmp)
else:
retlist.sort()
retlist.reverse()
if filter:
if filter[0] == 'n':
if queue != 'recvq':
return (0, self.contrlDateHour( retlist[:filter[1]], date_pos ) )
else:
return (0, retlist[:filter[1]] )
elif filter[0] == 'd':
new_retlist = list()
f_n = filter[1]
#Day of year now in seconds
doy_now = time.time()
#Filter number in seconds
f_n_sec = float(f_n * 24 * 60 * 60)
if queue != 'recvq':
doy_filter = doy_now - f_n_sec
for i in retlist:
split_day_hour = i[date_pos].split(' ')
final_time, final_struct = convert_date_hour(split_day_hour)
doy_send = time.mktime(final_struct)
if doy_filter < doy_send:
new_retlist.append(i)
return (0, self.contrlDateHour( new_retlist, date_pos ) )
else:
#Day of week
DOW_pos = time.gmtime()[6]
for i in retlist:
d = i[date_pos]
if string.find(d, ':') != -1:
new_retlist.append(i)
continue
elif f_n <= 7 and d[:3] in days:
#Number of day + 1 (today)
day_pos = days.index(d[:3]) + 1
if day_pos > DOW_pos:
day_pos = day_pos - 7
if (DOW_pos - f_n ) < day_pos:
new_retlist.append(i)
elif f_n > 7 and d[:3] in days:
new_retlist.append(i)
else:
#Add 1 to day (today)
day, month, year = int(d[:2]) +1, \
int(months.index(d[2:5])), int(d[-2:])
fax_day = time.mktime((year,month,day,
1,1,1,1,1,-1))
if (doy_now - f_n_sec) < fax_day:
new_retlist.append(i)
return (0, new_retlist)
else:
if queue != 'recvq':
return (0, self.contrlDateHour( retlist, date_pos ) )
else:
return (0, retlist)
def deletejob(self,jobid):
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
if jobid.startswith('fax'):
self.ftp.sendcmd('DELE recvq/%s' % jobid)
else:
self.ftp.sendcmd('JOB %s' % jobid)
self.ftp.sendcmd('JDELE')
self.ftp.quit()
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
return (0,'ok')
def suspendjob(self, jobid):
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
self.ftp.sendcmd('JOB %s' % jobid)
self.ftp.sendcmd('JSUSP')
self.ftp.quit()
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
return (0,'ok')
def callback(self,str):
self.retrbuf.append(str)
def snd_com(self):
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
self.ftp.quit()
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
return (0,'ok')
def jobcmd(self,cmd,job):
ret = []
joblist = []
if type(job) == type([]):
joblist = job
else:
joblist.append(job)
ftpcmd = ftplib.FTP()
ftpcmd.connect(self.faxhost,self.faxport)
self.login(ftpcmd,self.username,self.password,self.adminpass)
for j in joblist:
try:
ftpcmd.sendcmd( '%s %s' % (cmd.upper(), j.strip()) )
except ftplib.error_perm, msg:
ret.append('Job %s -> ' % j + msg[0] )
except ftplib.error_temp, msg:
ret.append('Job %s -> ' % j + msg[0] )
ret.append('Job %s -> %s OK' % (j,cmd))
ftpcmd.quit()
return ret
def divide(self, obj, sep):
tmp = []
tmp1 = []
for l in range(len(obj)):
if obj[l] == sep:
tmp.append(l)
if not tmp:
return obj.strip()
for l1 in range(len(tmp) +1):
if l1 == 0:
tmp1.append( obj[:tmp[l1]].strip() )
elif l1 == len(tmp):
tmp1.append( obj[tmp[l1 -1]+1:].strip() )
else:
tmp1.append( obj[tmp[l1 -1]+1 :tmp[l1]].strip() )
return tmp1
def del_n(self, st):
if st[-1:] == '\n':
return st[:-1]
else:
return st
def get_recvfile(self, filename, tmpfile, directory):
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
fd = open(tmpfile,'wb')
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
self.ftp.cwd(directory)
self.ftp.retrbinary('RETR ' + filename, fd.write,1024)
fd.close()
except ftplib.error_perm, msg:
fd.close()
msg = get_exdesc(msg)
return (1, msg)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
return (0, 'ok')
def alterjob(self, jobid, param):
"""
"""
try:
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
try:
self.login(self.ftp,self.username,self.password,self.adminpass)
self.suspendjob(jobid)
self.ftp.sendcmd('JOB %s' % jobid)
for jparm, jval in param.iteritems():
if not isinstance(jval, basestring):
jval = str(jval)
if not jval.strip():
continue
self.ftp.sendcmd('JPARM %s %s' % (jparm, jval))
self.ftp.sendcmd('JSUBM')
self.ftp.quit()
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
return (0, 'ok')
def sndfax(self,lst_file, param, coverpage=None):
"""
"""
self._do_debug("sndfax. Files: %s" % str(lst_file))
param = dict( ( (k.upper(), v) for k, v in param.iteritems() ) )
try:
self._do_debug("Try to connect")
self.ftp.connect(self.faxhost,self.faxport)
except Exception, msg:
msg = get_exdesc(msg)
return (1, msg)
self.login(self.ftp,self.username,self.password,self.adminpass)
if type(lst_file) is not LT:
files = []
files.append(lst_file)
else:
files = lst_file
file2snd = []
fileNotexits = filter( lambda x: not os.path.exists(x), files )
if fileNotexits:
return (1, "This files not exists: %s" % str(fileNotexits) )
#send the cover, if need
cover_name = ""
if coverpage:
self.ftp.sendcmd('FORM PS')
self._do_debug("Set form to ps into the cover")
try:
fd = SendFile(coverpage.make_cover_path())
cover_name = self.ftp.storbinary('STOT', fd)
cover_name = self._extract_filename(cover_name)
except Exception, msg:
msg = get_exdesc(msg), coverpage
print "Error send cover!", msg
return (1, msg)
for file in files:
#Send multiple documents
f = open(file)
header = f.read(4)
f.close()
if header == "%!PS":
form_type = 'FORM PS'
elif header == "%PDF":
form_type = 'FORM PS'
else:
form_type = 'FORM TIFF'
self.ftp.sendcmd(form_type)
self._do_debug("End set form type: %s" % form_type)
try:
fd = SendFile(file)
except Exception, msg:
print "Error on send file", file, msg
msg = get_exdesc(msg)
return (1, msg)
#wait for a reply avoid the "200 Type set to Image" error
time.sleep(0.5)
self._do_debug("Start to STOT")
file2snd.append(self.ftp.storbinary('STOT',fd, 10240))
for k, def_val in (("vres","196"),("pagewidth","209"),
("pagelength","296"),("pagechop","default"),
("chopthreshold","3"),):
k = k.upper()
if not k in param:
param[k] = def_val
jobl = []
try:
self._do_debug("Start to JNEW")
self.ftp.sendcmd('JNEW')
for jparm, jval in param.iteritems():
if not isinstance(jval, basestring):
jval = str(jval)
if not jval.strip():
continue
self._do_debug("Set JPARM: %s" % jparm)
self.ftp.sendcmd('JPARM %s %s' % (jparm, jval))
#send the conver name, if need
if coverpage:
self.ftp.sendcmd('JPARM %s %s' % ('COVER', cover_name))
#send the filename
for file in file2snd:
filename = self._extract_filename(file)
self._do_debug("Set DOCUMENT: %s" % filename)
self.ftp.sendcmd('JPARM %s %s' % ('DOCUMENT', filename))
self._do_debug("Set JSUBM")
self.ftp.sendcmd('JSUBM')
self.ftp.quit()
except:
msg = traceback.format_exc()
print 'Error on send fax', msg
return (1, msg)
return (0, 'ok')
def close(self,):
try:
self.ftp.close()
except Exception, ex:
print "Exception on close %s " % str(ex)
def contrlDateHour(self, data, datePos):
"""
"""
if not datePos: return data
newData = list()
for lines in data:
dte = lines.pop(datePos)
try:
newDte = convert_date_hour(dte.split(' '))[0]
lines.insert(datePos, newDte)
newData.append(lines)
except:
pass
return newData
def __cmp(self, x, y):
try:
return cmp(int(x[0]), int(y[0]))
except ValueError:
return 0
def _extract_filename(self, filename):
return filename.split()[-1][:-2]
def _do_debug(self, msg):
"""Write to the debug, if can"""
if callable(self._debug_funct):
self._debug_funct("HYLAPROTO: " + str(msg))
def convert_date_hour(date_hour):
#date_hour must be a list with ['date','hour']
import calendar as C
if len(date_hour) <= 1:
return
#print date_hour
dat = date_hour[0].split('/')
hour = date_hour[1].split('.')
#Need if hour have no seconds.
if len(hour) == 2: hour.append('00')
final_tmp = [int(i) for i in dat]
final_tmp.extend([int(h) for h in hour])
DOW = C.weekday(int(dat[0]), int(dat[1]), int(dat[2]))
NOD = 1
for d in range(1, int(dat[1])):
NOD += C.monthrange(int(dat[0]), d)[1]
NOD += int(dat[2])
final_tmp.extend([DOW,NOD,-1])
final_time = time.strftime('%d/%m/%y %H.%M', final_tmp)
return final_time, final_tmp
def getalljob(inst):
jobl = []
for l in inst.getsendq():
splitted = string.split(l)
if splitted:
jobl.append(splitted[0])
return jobl
class SendFile:
i = 0
steps = 0
filesize = 0
def __init__(self,filename):
self.filesize = os.stat(filename)[6]
self.ft = open(filename,'rb')
def read(self, readbuf):
buf = self.ft.read(readbuf)
if buf:
return buf
else:
self.ft.close()
if __name__ == '__main__': #This is a script
h = Hylafax('192.168.1.1')
h.username = "michele"
print h.getstatus()
|