[Pycodeocr-main] SF.net SVN: pycodeocr:[27]
Status: Beta
Brought to you by:
drtrigon
|
From: <la...@us...> - 2010-10-25 18:39:38
|
Revision: 27
http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=27&view=rev
Author: laserb
Date: 2010-10-25 18:39:31 +0000 (Mon, 25 Oct 2010)
Log Message:
-----------
Initial support for Doxygen / added blacklist for devices / added checksum test for 42 digit OCR codes , calculates the last digit before the ">" which is a checksum for the amount before, returns an error if this failes / some minor fixes / !! AND support for bigger image view !!
Modified Paths:
--------------
PyCodeOCR.glade
PyCodeOCR.py
Added Paths:
-----------
__init__.py
blacklist
checksum.py
Modified: PyCodeOCR.glade
===================================================================
--- PyCodeOCR.glade 2010-09-12 19:05:23 UTC (rev 26)
+++ PyCodeOCR.glade 2010-10-25 18:39:31 UTC (rev 27)
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy toplevel-contextual -->
@@ -31,7 +31,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
- <property name="invisible_char">●</property>
+ <property name="invisible_char">●</property>
</widget>
<packing>
<property name="x">16</property>
@@ -39,17 +39,6 @@
</packing>
</child>
<child>
- <widget class="GtkImage" id="image1">
- <property name="width_request">504</property>
- <property name="height_request">84</property>
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="x">16</property>
- <property name="y">75</property>
- </packing>
- </child>
- <child>
<widget class="GtkLabel" id="label5">
<property name="width_request">90</property>
<property name="height_request">21</property>
@@ -266,7 +255,7 @@
<property name="use_underline">True</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_radiobutton2_toggled"/>
+ <signal name="toggled" handler="on_combobox2_changed"/>
</widget>
<packing>
<property name="x">534</property>
@@ -283,7 +272,7 @@
<property name="use_underline">True</property>
<property name="draw_indicator">True</property>
<property name="group">radiobutton2</property>
- <signal name="toggled" handler="on_radiobutton1_toggled"/>
+ <signal name="toggled" handler="on_combobox2_changed"/>
</widget>
<packing>
<property name="x">318</property>
@@ -317,6 +306,25 @@
<property name="y">20</property>
</packing>
</child>
+ <child>
+ <widget class="GtkEventBox" id="eventbox2">
+ <property name="width_request">505</property>
+ <property name="height_request">84</property>
+ <property name="visible">True</property>
+ <signal name="button_press_event" handler="on_eventbox2_button_press_event"/>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="width_request">505</property>
+ <property name="height_request">84</property>
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="x">16</property>
+ <property name="y">75</property>
+ </packing>
+ </child>
</widget>
</child>
</widget>
@@ -371,4 +379,30 @@
</widget>
</child>
</widget>
+ <widget class="GtkWindow" id="window3">
+ <property name="type">popup</property>
+ <property name="window_position">mouse</property>
+ <property name="destroy_with_parent">True</property>
+ <child>
+ <widget class="GtkFixed" id="fixed1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkEventBox" id="eventbox1">
+ <property name="width_request">600</property>
+ <property name="height_request">600</property>
+ <property name="visible">True</property>
+ <property name="events">GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_KEY_PRESS_MASK | GDK_STRUCTURE_MASK</property>
+ <child>
+ <widget class="GtkImage" id="image2">
+ <property name="width_request">600</property>
+ <property name="height_request">600</property>
+ <property name="visible">True</property>
+ <signal name="button_press_event" handler="on_eventbox2_button_press_event"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
</glade-interface>
Modified: PyCodeOCR.py
===================================================================
--- PyCodeOCR.py 2010-09-12 19:05:23 UTC (rev 26)
+++ PyCodeOCR.py 2010-10-25 18:39:31 UTC (rev 27)
@@ -1,9 +1,13 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+## @file PyCodeOCR.py
+# Turn your scanner into a free document
+# reader for invoices
+# (e.g. for e-banking) with the help of tesseract-ocr available
+# for many unix (and also windows) platforms.
-
# python standard modules
-import os, re, sys, subprocess, time, gobject
+import os, re, sys, subprocess, time, gobject, string, struct
# GTK, PyGTK, GLADE (GNOME) modules
@@ -12,13 +16,15 @@
import gtk, gtk.glade
import gobject
+from checksum import modulo10
+
# PIL image library and it's SANE bindings
import Image, ImageDraw
#from PIL import Image
import sane # f12: 'python-imaging-sane'
#(fedora 12 has no libWand, so it's not working at the moment...)
-## ImageMagick's MagickWand API
+# ImageMagick's MagickWand API
#from pythonmagickwand.image import Image
# search optional pakages
@@ -26,6 +32,7 @@
os.environ["LD_LIBRARY_PATH"] = "/usr/local/lib" #
os.system('python %s' % sys.argv[0]) #
sys.exit() #
+## list of available pakages
pakages = []
# gocr
if os.path.exists("gocr"):
@@ -44,9 +51,13 @@
# global variables and constants
+## path from which this program is currently executed
local_path = os.path.realpath(os.path.dirname(sys.argv[0]))
+## path of program without extension local_path/PyCodeOCR
raw_path = os.path.join(local_path, os.path.splitext(sys.argv[0])[0])
+## users home path /home/user
home_path = os.path.expanduser('~')
+## default scanning coordinates
std_scan_koords = { "0 deg": (( 82, 60, 20, 155 ), 0), # or with higher res. ( 820, 600, 200, 1559 ),
"90 deg": (( 1, 82, 150, 20 ), 90),
"180 deg": (( 3, 1, 20, 150 ), 180),
@@ -54,7 +65,7 @@
"A4": (( 0, 0, 296, 215 ), 0), } # scan whole range (A4: http://www.cl.cam.ac.uk/~mgk25/iso-paper.html)
#"A4": (( 0, 0, 290, 210 ), 0), } # (more secure; with small border)
-# MainWindow
+## MainWindow
# The GUI was created/designed using GLADE
#
class MainWindowGTK:
@@ -87,34 +98,64 @@
# (constants)
MDE = { 'invoices': 0, 'barcode': 1, 'DataMatrix': 2, 'PDF417': 3 }
+ ## Initialize
def __init__(self):
- """ ... """
# retrieve widgets
# window1 - main window
+ ## gladefile raw_path.glade
self.gladefile = raw_path + ".glade"
+ ## get xml from gladefile
self.xml = gtk.glade.XML(self.gladefile)
+ ## main window
self.window1 = self.xml.get_widget('window1')
+ ## image window
+ self.window3 = self.xml.get_widget('window3')
+ ## scan button
self.togglebutton1 = self.xml.get_widget('togglebutton1')
+ ## restart button
self.button1 = self.xml.get_widget('button1')
+ ## exit button
self.button2 = self.xml.get_widget('button2')
+ ## placement frame
self.frame1 = self.xml.get_widget('frame1')
+ ## image
self.image1 = self.xml.get_widget('image1')
+ ## image
+ self.image2 = self.xml.get_widget('image2')
+ ## output line
self.entry1 = self.xml.get_widget('entry1')
+ ## progressbar
self.progressbar1 = self.xml.get_widget('progressbar1')
+ ## Orientation label
self.label5 = self.xml.get_widget('label5')
+ ## Orientation combobox
self.combobox1 = self.xml.get_widget('combobox1')
+ ## mode combobox
self.combobox2 = self.xml.get_widget('combobox2')
+ ## x-position
self.spinbutton1 = self.xml.get_widget('spinbutton1')
+ ## y-position
self.spinbutton2 = self.xml.get_widget('spinbutton2')
+ ## x-size
self.spinbutton3 = self.xml.get_widget('spinbutton3')
+ ## y-size
self.spinbutton4 = self.xml.get_widget('spinbutton4')
+ ## file input
self.radiobutton1 = self.xml.get_widget('radiobutton1')
+ ## sane input
self.radiobutton2 = self.xml.get_widget('radiobutton2')
+ ## choose file
self.filechooserbutton1 = self.xml.get_widget('filechooserbutton1')
- # window2 - sane
+ ## device select window
self.window2 = self.xml.get_widget('window2')
+ ## device list
self.treeview1 = self.xml.get_widget('treeview1')
+ ## OK button
self.button3 = self.xml.get_widget('button3')
+ ## event box for image
+ self.eventbox2 = self.xml.get_widget('eventbox2')
+ ## event box for image window
+ self.eventbox1 = self.xml.get_widget('eventbox1')
# initiate orientation and position
self.combobox1.set_active(0)
@@ -138,7 +179,14 @@
# connect signal handlers
self.xml.signal_autoconnect( self )
+ # connect eventbox to close image window
+ self.eventbox1.connect('button_press_event', self.on_eventbox2_button_press_event)
+ # set tooltips
+ self.button1.set_tooltip_text("Restart PyCodeOCR to search for a SANE device.")
+ self.image1.set_tooltip_text("Click for bigger image")
+ self.image2.set_tooltip_text("Click to close")
+
# take some time to init sane
#self.init_sane()
@@ -151,6 +199,7 @@
return
+ ## initialize sane
def init_sane(self, source=None):
# lock window
self.window1.set_sensitive(False)
@@ -171,22 +220,49 @@
return False
+ ## Run gtk mainloop and with it THIS APP.
def run(self):
- """ Run gtk mainloop and with it THIS APP. """
gtk.main()
- # signals / glade callbacks
+ ## signals / glade callbacks
#
+ def on_eventbox2_button_press_event(self, source=None, event=None):
+ if self.window3.get_visible():
+ # clean-up
+ os.remove( self.image_file_big )
+ # hide window
+ self.window3.hide()
+ else:
+ # load original image
+ im1 = Image.open(self.imageFile)
+ # adjust width and height to your needs and keep ratio
+ (im_width, im_height) = im1.size #get image size
+ (width, height) = self.image2.get_size_request() #get needed size
+ ratio = min(float(width)/im_width,float(height)/im_height) #calculate resizing ratio
+ new_width = int(im_width*ratio)
+ new_height = int(im_height*ratio)
+ print self.image2.get_size_request()
+ # resize to fit popup window
+ im = im1.resize((new_width, new_height), Image.BILINEAR)
+ # save
+ self.image_file_big = self.temp+"06.jpg"
+ im.save( self.image_file_big )
+ # set image
+ self.image2.set_from_file( self.image_file_big )
+ # show window
+ self.window3.show()
+
def on_button3_clicked(self, source=None):
# get selection from treeview
devnr = self.treeview1.get_cursor()[0][0]
# hide window
- self.window2.destroy()
+ self.window2.hide()
# init scanner
self.run_sane.init_scanner(self.progress, self.window2, self.treeview1, devnr)
# set sensitivity
self.init_sensitivity()
+ ## set sensitivity of buttons the first time
def init_sensitivity(self):
# set sensitivity
if self.run_sane.found_scanner:
@@ -195,7 +271,7 @@
else:
self.radiobutton1.set_active(True)
self.radiobutton2.set_sensitive(False)
- self.on_radiobutton1_toggled()
+ #self.on_radiobutton1_toggled()
self.progress(0.,"No SANE device found. Use file input instead.")
self.button1.set_visible(True)
@@ -205,14 +281,14 @@
# Try to set orientation and placement sensitive. Will fail if no device is found
self.toggle_orientation_sensitive(True)
self.toggle_placement_sensitive(True)
-
+
+ ## one of the placement coordinates changed
def on_spinbutton_value_changed(self, source=None, event=None):
- """ Spinbutton value changed signal handler. """
self.scan_koords = (self.spinbutton1.get_value(),self.spinbutton2.get_value(),
self.spinbutton3.get_value(),self.spinbutton4.get_value())
+ ## Orientation changed
def on_combobox1_changed(self, source=None, event=None):
- """ Combobox changed signal handler. """
orient = self.combobox1.get_model()[self.combobox1.get_active()][0]
self.spinbutton1.set_value(std_scan_koords[orient][0][0])
@@ -222,8 +298,9 @@
self.mode = std_scan_koords[orient][1]
+ ## mode changed
def on_combobox2_changed(self, source=None):
- op_mode = self.combobox2.get_active()
+ op_mode = self.combobox2.get_active()
if (op_mode == self.MDE['invoices']):
self.toggle_placement_sensitive(True)
self.toggle_orientation_sensitive(True)
@@ -237,8 +314,8 @@
self.toggle_placement_sensitive(True)
self.toggle_orientation_sensitive(True)
+ ## ToggleButton: 'scan'/'stop'.
def on_togglebutton1_toggled(self, source=None, event=None, *a):
- """ ToggleButton: 'scan'/'stop'. """
if self.togglebutton1.get_active(): # scan !
self.togglebutton1.set_label("stop")
self.__stop = False
@@ -266,48 +343,49 @@
self.refresh()
return
-
+ ## exit and restart
def on_button1_clicked(self, source=None, event=None):
- """ Button: 'exit'. """
os.execv(sys.argv[0],sys.argv)
self.on_window1_destroy()
-
+
+ ## exit
def on_button2_clicked(self, source=None, event=None):
- """ Button: 'exit'. """
self.on_window1_destroy()
-
+
+ ## press x-button on window
def on_window1_destroy(self, source=None, event=None):
- """ Window closed signal handler. """
+ try:
+ os.remove( self.temp+"04.jpg" ) # clean-up
+ os.remove( self.image_file_small )
+ except:
+ pass
+ # exit
gtk.main_quit()
-
+
+ ## press x-button on device select window
def on_window2_destroy(self, source=None):
# when windows is closed by pressing the x-button
# choose first device
- if source != None:
- devnr = 0
- # init scanner
- self.run_sane.init_scanner(self.progress, self.window2, self.treeview1, devnr)
- # set sensitivity
- self.init_sensitivity()
+ devnr = 0
+ # init scanner
+ self.run_sane.init_scanner(self.progress, self.window2, self.treeview1, devnr)
+ # set sensitivity
+ self.init_sensitivity()
- def on_radiobutton1_toggled(self, source=None, event=None):
- #self.filechooserbutton1.set_sensitive( self.radiobutton1.get_active() )
- self.on_combobox2_changed()
-
- def on_radiobutton2_toggled(self, source=None, event=None):
- self.on_combobox2_changed()
-
+ ## file selected
def on_filechooserbutton1_file_set(self, source=None):
self.radiobutton1.set_active(True)
self.inp_file = self.filechooserbutton1.get_filename()
if not os.path.exists(self.inp_file):
self.progress(0., "File not found!")
return None
-
+
+ ## toggle orientation sensitivity
def toggle_orientation_sensitive(self, value):
self.label5.set_sensitive(value)
self.combobox1.set_sensitive(value)
-
+
+ ## toggle placement sensitivity
def toggle_placement_sensitive(self, value):
if self.radiobutton2.get_active():
self.frame1.set_sensitive(value)
@@ -315,9 +393,9 @@
self.frame1.set_sensitive(False)
# helpers
- #
+ #
+ ## Main scanning and number recognition procedure.
def scancode(self):
- """ Main scanning and number recognition procedure. """
# Initialization of scanning process
# (0/7)
self.progress(0., "")
@@ -386,7 +464,7 @@
self.run_sane.post_init(self.scan_koords, self.inp_file) # RunSANE().post_init(...) 2nd part of __init__(...)
self.run_sane.resolution = opt["resolution"]
if self.run_sane():
- self.progress(0., self.run_sane.stderr[:-1])
+ self.progress(0., self.run_sane.stderr)
return None
#del self.run_sane
else: # direct file input
@@ -487,6 +565,15 @@
if (op_mode == self.MDE['invoices']): # 0: invoices
check = (not "?" in data) # any unrecognized char in code?
check = check and ( len(data) in opt['valid_code_len'] ) # correct code len?
+ if len(data) == 42:
+ # extract details
+ (tmp, betrag, tmp, referenz, tmp, konto, tmp) = struct.unpack("2s11ss16s2s9ss",data)
+ print "Betrag: "+str(int(betrag[:-1])/100.)
+ print "Konto: "+konto[:2]+"-"+konto[3:-2]+"-"+konto[-2:]
+ print "Referenznr: "+referenz
+ # modulo10 checksum for betrag
+ checknr = modulo10().run(int(betrag[:-1]))
+ check = check and checknr == int(betrag[-1])
elif (op_mode == self.MDE['barcode']): # 1: barcode
check = not (data['type'] == "unknown")
if check:
@@ -555,31 +642,37 @@
# (7/7)
return check
+ ## Refresh window during running processes.
def refresh(self):
- """ Refresh window during running processes. """
self.window1.queue_draw()
time.sleep(0.1) # give also some time to the user... :)
while gtk.events_pending():
gtk.main_iteration()
- def setimage(self, imageFile):
- """ Resize and set PIL image to gtk/gnome window. """
- # http://www.daniweb.com/code/snippet216637.html
- # resize an image using the PIL image library
- # free from: http://www.pythonware.com/products/pil/index.htm
- # tested with Python24 vegaseat 11oct2005
- # open an image file (.bmp,.jpg,.png,.gif) you have in the working folder
+ ## Resize and set PIL image to gtk/gnome window.
+ # resize an image using the PIL image library
+ # tested with Python24 vegaseat 11oct2005
+ # open an image file (.bmp,.jpg,.png,.gif) you have in the working folder
+ # @see http://www.daniweb.com/code/snippet216637.html
+ # @see http://www.pythonware.com/products/pil/index.htm
+ def setimage(self, imageFile):
print imageFile[-3:]
if imageFile[-3:] in ["bmp","jpg","png","gif"]:
#already in right format
- im1 = Image.open(imageFile)
+ # original file name
+ self.imageFile = imageFile
+ # load file
+ im1 = Image.open(self.imageFile)
else:
#convert Image
self.run_convert = RunExternal(self.cmd_convert % (imageFile, 0, self.temp+"04.jpg"), error_msg=[ "convert: unable to open image" ])
if self.run_convert():
self.progress(0., self.run_convert.stderr[:-1])
- return None
- im1 = Image.open(self.temp+"04.jpg")
+ return None
+ # original filename
+ self.imageFile = self.temp+"04.jpg"
+ # load file
+ im1 = Image.open(self.imageFile)
# adjust width and height to your needs and keep ratio
(im_width, im_height) = im1.size #get image size
@@ -596,19 +689,19 @@
#im = im1.resize((new_width, new_height), Image.ANTIALIAS) # best down-sizing filter
#ext = ".jpg"
- image_file = self.temp+"04.jpg"
- im.save( image_file )
- self.image1.set_from_file( image_file )
- os.remove( image_file ) # clean-up
+ # set image preview
+ self.image_file_small = self.temp+"05.jpg"
+ im.save( self.image_file_small )
+ self.image1.set_from_file( self.image_file_small )
+ ## Set progress and refresh view.
def progress(self, fract, text):
- """ Set progress and refresh view. """
self.progressbar1.set_fraction(fract)
self.progressbar1.set_text(text)
self.refresh()
+ ## Character correction after recogition (on basis that there should be numbers and few special chars).
def char_correction(self, data):
- """ Character correction after recogition (on basis that there should be numbers and few special chars). """
data = re.sub("\n", "", data)
print data
corrections = [
@@ -662,22 +755,23 @@
return data
-
+## Run external shell command/application.
class RunExternal:
- """ Run external shell command/application. """
error_msg = [ "/bin/sh: " ]
+ ## initialize
def __init__(self, cmd, error_msg):
self.cmd = cmd
self.error_msg += error_msg
+ ## call
def __call__(self):
(self.error, self.stdout, self.stderr) = self._run()
return self.error
+ ## Execute external shell command.
def _run(self, piped=True):
- """ Execute external shell command. """
if piped:
run = subprocess.Popen( self.cmd,
stdin =subprocess.PIPE,
@@ -773,16 +867,16 @@
#
# return (False, "ok", "")
+## sSANE/PIL interface python wrapper/bindings.
class RunSANE:
- """ SANE/PIL interface python wrapper/bindings. """
# "scanimage --format=tif --resolution 300 --mode Gray > %s.tif"
# "scanimage --format=tif --resolution 600 --mode Gray -t 82 -y 20 -l 60 -x 155.9 > %s.tif"
#cmd_scan = "scanimage --format=tif --resolution 600 --mode Gray -t %d -l %d -y %d -x %d > %s.tif"
resolution = 600
+ ## Init of sane interface -> device.
def __init__(self, progress, window2, treeview):
- """ Init of sane and scanner. """
print "init sane python interface ...",
sys.stdout.flush()
@@ -794,6 +888,9 @@
treeview.set_model(list_store)
col = gtk.TreeViewColumn("Devices", gtk.CellRendererText(),text=0)
treeview.append_column(col)
+
+ # get blacklist
+ self.read_blacklist()
# init SANE
self.n=4.
@@ -801,15 +898,28 @@
try:
self.version = sane.init()
progress(1./self.n,"init sane python interface ... search devices")
- self.devices = sane.get_devices()
+ # get sane devices
+ self.devices1 = sane.get_devices()
+ # init filtered list
+ self.devices = []
+
print "\n"
# add found devices to treeview
- for i in range(len(self.devices)):
- print str(i)+": "+self.devices[i][1]+" "+self.devices[i][2]
- list_store.append([self.devices[i][1]+" "+self.devices[i][2]])
+ for i in range(len(self.devices1)):
+ # filter devices: remove blacklisted devices
+ if not self.devices1[i][1]+" "+self.devices1[i][2] in self.blacklist:
+ self.devices.append(self.devices1[i])
+ print str(i)+": "+self.devices1[i][1]+" "+self.devices1[i][2]
+ list_store.append([self.devices1[i][1]+" "+self.devices1[i][2]])
+ else:
+ print str(i)+": "+self.devices1[i][1]+" "+self.devices1[i][2]+" BLOCKED"
+ # self.devices is now filtered
# check how many devices we found
- if len(self.devices) > 1:
+ if len(self.devices) == 0:
+ progress(0./self.n,"No device found.")
+ self.found_scanner = False
+ elif len(list_store) > 1:
# more than one device, choose one.
progress(2./self.n,"More than one device found.")
if sys.argv[1:]:
@@ -832,12 +942,14 @@
# No device found at all
self.found_scanner = False
print "No sane device found. Restart to try it again."
-
+
+ ## iInit of sane interface -> scanner
def init_scanner(self, progress, window2, treeview, devnr):
-
+ print "Use device number: "+str(devnr)
try:
# finish init device
- self.dev = sane.get_devices()[devnr][0] # choose first device
+ self.dev = self.devices[devnr][0] # choose first device
+ print self.dev
progress(3./self.n,"Device initialized. Open scanner...")
# open scanner device
@@ -847,7 +959,7 @@
self.found_scanner = True
- progress(4./self.n,"Ready.")
+ progress(4./self.n,"Ready: %s" % self.devices[devnr][1]+" "+self.devices[devnr][2])
print "done."
except:
@@ -856,20 +968,21 @@
print "Loading sane device failed. Restart to try it again."
+ ## Not init of sane and scanner, but of scan operation.
def post_init(self, coords, out_filename):
- """ Not init of sane and scanner, but of scan operation. """
self.coords = coords
self.out_filename = out_filename
self.info()
+ ## call
def __call__(self):
(self.error, self.stdout, self.stderr) = self._run()
return self.error
- # thanks to: http://mail.python.org/pipermail/image-sig/1997-June/000307.html
- # (may be look also at: http://sane-pygtk.sourceforge.net/)
+ ## Scan and save the PIL image object to file.
+ # @see http://mail.python.org/pipermail/image-sig/1997-June/000307.html
+ # @see http://sane-pygtk.sourceforge.net/)
def _run(self):
- """ Scan and save the PIL image object to file. """
try:
# Set scan parameters (also with higher resolution!)
(t, l, y, x) = self.coords
@@ -885,7 +998,7 @@
# Get an Image object containing the scanned image
im = self.scanner.snap()
-
+
# Write the image out as a TIFF file (or whatever)
im.save(self.out_filename)
@@ -895,8 +1008,8 @@
return (False, "ok", "")
+ ## Show some info about the scanner and SANE.
def info(self):
- """ Show some info about the scanner and SANE. """
print 'SANE version:', self.version
print 'Available devices=', self.devices
print 'Selected device=', self.dev #, "\n"
@@ -905,10 +1018,24 @@
print 'Device parameters:', self.params
#print 'Device options:', "\n",self.opts
+ ## get blacklisted devices
+ def read_blacklist(self):
+ bl = open('%s/blacklist' % local_path, 'r' )
+ temp = bl.readlines()
+ bl.close
+ self.blacklist = []
+ for line in temp:
+ self.blacklist.append(line.strip())
+ ## write blacklisted devices
+ # @todo add UI way to blacklist device
+ def write_blacklist(self, blacklist):
+ bl = open('%s/blacklist' % local_path, 'w' )
+ bl.write(blacklist)
+ bl.close()
if __name__ == '__main__':
- # run main application
+ ## run main application
main = MainWindowGTK()
main.run()
Added: __init__.py
===================================================================
Added: blacklist
===================================================================
--- blacklist (rev 0)
+++ blacklist 2010-10-25 18:39:31 UTC (rev 27)
@@ -0,0 +1 @@
+Printer Name
Added: checksum.py
===================================================================
--- checksum.py (rev 0)
+++ checksum.py 2010-10-25 18:39:31 UTC (rev 27)
@@ -0,0 +1,19 @@
+## @file checksum.py
+# Checksum for 13 digit e-banking codes
+class modulo10:
+ # thanks to http://www.hosang.ch/modulo10.aspx
+ # much more details http://www.sic.ch/de/dl_tkicch_dta.pdf ( page 51 )
+ def __init__(self):
+ self.tabelle = [0,9,4,6,8,2,7,1,3,5]
+ self.uebertrag = 0
+
+ def run(self,number):
+ # make string
+ nr = str(number)
+ # iterate over each character
+ for i in range(len(nr)):
+ self.uebertrag = self.tabelle[(self.uebertrag + int(nr[i]))%10]
+
+ return self.uebertrag
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|