Thread: [Pycodeocr-main] SF.net SVN: pycodeocr:[47] trunk
Status: Beta
Brought to you by:
drtrigon
From: <drt...@us...> - 2011-04-27 14:58:51
|
Revision: 47 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=47&view=rev Author: drtrigon Date: 2011-04-27 14:58:45 +0000 (Wed, 27 Apr 2011) Log Message: ----------- followup to r24 and r43: default action/button does work now Modified Paths: -------------- trunk/PyCodeOCR.glade trunk/PyCodeOCR.py Added Paths: ----------- README Added: README =================================================================== --- README (rev 0) +++ README 2011-04-27 14:58:45 UTC (rev 47) @@ -0,0 +1,17 @@ +The 'trunk' is the main line of development in a SVN repository. + +A 'branch' is a side-line of development created to make larger, experimental or +disrupting work without annoying users of the trunk version. Also, branches can +be used to create development lines for multiple versions of the same product, +like having a place to backport bugfixes into a stable release. + +Finally, 'tags' are markers to highlight notable revisions in the history of the +repository, usually things like "this was released as 1.0". + +See the HTML version of "Version Control with Subversion", especially Chapter 4: +Branching and Merging or buy it in paper (e.g. from amazon) for an in-depth +discussion of the technical details. +http://svnbook.red-bean.com/ +http://svnbook.red-bean.com/en/1.5/svn.branchmerge.html + +http://stackoverflow.com/questions/698313/what-is-trunk-branch-and-tag-in-subversion Modified: trunk/PyCodeOCR.glade =================================================================== --- trunk/PyCodeOCR.glade 2011-04-27 14:31:11 UTC (rev 46) +++ trunk/PyCodeOCR.glade 2011-04-27 14:58:45 UTC (rev 47) @@ -351,6 +351,7 @@ <property name="visible">True</property> <property name="can_focus">True</property> <property name="enable_grid_lines">horizontal</property> + <signal name="row_activated" handler="on_treeview1_row_activated"/> </widget> <packing> <property name="x">15</property> Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-04-27 14:31:11 UTC (rev 46) +++ trunk/PyCodeOCR.py 2011-04-27 14:58:45 UTC (rev 47) @@ -14,6 +14,8 @@ # @mainpage PyCodeOCR # @anchor mainpage # +# http://pycodeocr.sourceforge.net/ +# # @section Description # # Turn your scanner into a free document @@ -316,6 +318,10 @@ self.run_sane.init_scanner(self.progress, self.window2, self.treeview1, devnr) # set sensitivity self.init_sensitivity() + + # http://www.pygtk.org/pygtk2tutorial/sec-TreeViewSignals.html + def on_treeview1_row_activated(self, *args, **kwargs): + self.on_button3_clicked() ## set sensitivity of buttons the first time def init_sensitivity(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <drt...@us...> - 2011-04-27 19:02:00
|
Revision: 49 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=49&view=rev Author: drtrigon Date: 2011-04-27 19:01:54 +0000 (Wed, 27 Apr 2011) Log Message: ----------- some followup to r47, main-window improved, checksum class and char_correction updated Modified Paths: -------------- trunk/CHANGES trunk/PyCodeOCR.glade trunk/PyCodeOCR.py trunk/checksum.py trunk/requirements.py Modified: trunk/CHANGES =================================================================== --- trunk/CHANGES 2011-04-27 15:51:57 UTC (rev 48) +++ trunk/CHANGES 2011-04-27 19:01:54 UTC (rev 49) @@ -25,6 +25,7 @@ # CHANGES: # # * (Version 1.1): +# - [ r18 - HEAD ] # - Added support for barcodes with gocr (somehow preliminary). Can find and # recognize the code automatic, therefore the whole page is scanned. [expermental # or beta] Modified: trunk/PyCodeOCR.glade =================================================================== --- trunk/PyCodeOCR.glade 2011-04-27 15:51:57 UTC (rev 48) +++ trunk/PyCodeOCR.glade 2011-04-27 19:01:54 UTC (rev 49) @@ -340,7 +340,6 @@ <property name="urgency_hint">True</property> <property name="deletable">False</property> <property name="transient_for">window1</property> - <signal name="destroy" handler="on_window2_destroy"/> <child> <widget class="GtkFixed" id="fixed1"> <property name="visible">True</property> Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-04-27 15:51:57 UTC (rev 48) +++ trunk/PyCodeOCR.py 2011-04-27 19:01:54 UTC (rev 49) @@ -9,6 +9,9 @@ # # $Id$ # +# @todo This module/script has become large (more than 1000 lines) +# and should be splitted into seperate files. +# # For further information please consult the @ref mainpage also. # # @mainpage PyCodeOCR @@ -278,11 +281,12 @@ self.on_eventbox2_button_press_event() def on_pointer_motion(self, source=None, event=None): - (x,y,state) = self.window1.window.get_pointer() - (wxim, wyim ) = self.image1.get_size_request() - if x > 16+(wxim-self.new_width)/2 and x < 16+(wxim+self.new_width)/2 and y > 75+(wyim-self.new_height)/2 and y < 75+(wyim+self.new_height)/2: - if not self.window3.get_visible(): - self.on_eventbox2_button_press_event() + pass +# (x,y,state) = self.window1.window.get_pointer() +# (wxim, wyim ) = self.image1.get_size_request() +# if x > 16+(wxim-self.new_width)/2 and x < 16+(wxim+self.new_width)/2 and y > 75+(wyim-self.new_height)/2 and y < 75+(wyim+self.new_height)/2: +# if not self.window3.get_visible(): +# self.on_eventbox2_button_press_event() def on_eventbox2_button_press_event(self, source=None, event=None): if self.window3.get_visible(): @@ -422,16 +426,6 @@ 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 - devnr = 0 - # init scanner - self.run_sane.init_scanner(self.progress, self.window2, self.treeview1, devnr) - # set sensitivity - self.init_sensitivity() ## file selected def on_filechooserbutton1_file_set(self, source=None): @@ -450,8 +444,10 @@ def toggle_placement_sensitive(self, value): if self.radiobutton2.get_active(): self.frame1.set_sensitive(value) + self.filechooserbutton1.set_sensitive(False) else: self.frame1.set_sensitive(False) + self.filechooserbutton1.set_sensitive(True) # helpers # @@ -494,7 +490,7 @@ #dmtxread recognition opt = { 'tmp_file': "02.jpg", # some issues with recogition 'recog_class': RunExternal, # . - 'recog_cmd': "%s %s02.jpg"%(paths["dmtxread"],self.temp), # of different file formats + 'recog_cmd': "%s -v -D %s02.jpg"%(paths["dmtxread"],self.temp), # of different file formats 'recog_error_msg': [ "error" ], # . #opt = { 'tmp_file': "02.bmp", # and drawing/marking the @@ -633,16 +629,13 @@ reference = tmp[0] account = tmp[1] # initialize modulo10 checksum - m10 = modulo10() + m10 = modulo10(amount, account, reference) # check amount, account number and reference number - checksum_b = (int(amount[-1]) == m10.run(amount[:-1]) ) - checksum_k = (int(account[-1]) == m10.run(account[:-1]) ) - checksum_r = (int(reference[-1]) == m10.run(reference[:-1]) ) - print "Amount: "+str(int(amount[2:-1])/100.),checksum_b - print "Account number: "+account,checksum_k - print "Reference number: "+reference,checksum_r + print "Amount:", m10.amount, m10.checksum_b + print "Account number:", m10.account, m10.checksum_k + print "Reference number:", m10.reference, m10.checksum_r - checksum = checksum_b and checksum_k and checksum_r + checksum = m10.checksum # if len(data) == 42: # # extract details @@ -688,11 +681,10 @@ # Data final output # (6/?) self.progress(6./max_steps, "Final data output...") + self.entry1.set_text(data) if check: os.remove(self.temp+opt['tmp_file']) # clean-up - self.entry1.set_text(data) - # get the clipboard clipboard = gtk.clipboard_get() # set the clipboard text data @@ -795,7 +787,7 @@ print data corrections = [ # Zero - ("O", "0"), ("D", "0"), ("U", "0"), ("Q", "0"), ("\(\)", "0"), ("G", "0"), + ("O", "0"), ("D", "0"), ("U", "0"), ("Q", "0"), ("\(\)", "0"), ("G", "0"), ("o", "0"), # Two ("Z", "2"), # Three @@ -833,6 +825,7 @@ ("\x98", ""), ("\x5f", ""), ("\x60", ""), + ("'", ""), #('\xbb', 187)('\x99', 153)('\x98', 152) ("\+", "+ "), ("\x92", "1"), # post correction Modified: trunk/checksum.py =================================================================== --- trunk/checksum.py 2011-04-27 15:51:57 UTC (rev 48) +++ trunk/checksum.py 2011-04-27 19:01:54 UTC (rev 49) @@ -19,13 +19,29 @@ # much more details http://www.sic.ch/de/dl_tkicch_dta.pdf ( page 51 ) # @see http://www.bundesbank.de/download/zahlungsverkehr/zv_pz201012.pdf # @see http://www.bundesbank.de/zahlungsverkehr/zahlungsverkehr_pruefziffernberechnung.php - def __init__(self): + def __init__(self, amount, account, reference): self.tabelle = [0,9,4,6,8,2,7,1,3,5] + + self.account = account + self.reference = reference - def run(self,nr): + self.checksum_b = self._checksum(amount) + self.checksum_k = self._checksum(account) + self.checksum_r = self._checksum(reference) + self.checksum = self.checksum_b and self.checksum_k and self.checksum_r + + try: + self.amount = str(int(amount[2:-1])/100.) + except ValueError: + self.amount = amount + " (error)" + + def _run(self, nr): self.uebertrag = 0 # iterate over each character for i in range(len(nr)): self.uebertrag = self.tabelle[(self.uebertrag + int(nr[i]) )%10] return (10-self.uebertrag)%10 + + def _checksum(self, value): + return (int(value[-1]) == self._run(value[:-1]) ) Modified: trunk/requirements.py =================================================================== --- trunk/requirements.py 2011-04-27 15:51:57 UTC (rev 48) +++ trunk/requirements.py 2011-04-27 19:01:54 UTC (rev 49) @@ -218,6 +218,7 @@ #require_python_module('pydmtx') require_executable("dmtxread") except MissingRequirement: + #r = installbundle.install({'linux-fedora': ['python-libdmtx']}) r = installbundle.install({'linux-fedora': ['libdmtx-utils'], 'linux-ubuntu': ['libdmtx-utils']}) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <drt...@us...> - 2011-04-27 19:43:48
|
Revision: 50 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=50&view=rev Author: drtrigon Date: 2011-04-27 19:43:41 +0000 (Wed, 27 Apr 2011) Log Message: ----------- group the various modules into one single package 'utils' Modified Paths: -------------- trunk/PyCodeOCR.py Added Paths: ----------- trunk/utils/ trunk/utils/__init__.py trunk/utils/checksum.py trunk/utils/installbundle.py trunk/utils/ocr.py trunk/utils/requirements.py Removed Paths: ------------- trunk/checksum.py trunk/installbundle.py trunk/requirements.py Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-04-27 19:01:54 UTC (rev 49) +++ trunk/PyCodeOCR.py 2011-04-27 19:43:41 UTC (rev 50) @@ -41,12 +41,14 @@ # python standard modules import os, re, sys, subprocess, time, gobject, string, struct +# PyCodeOCR python standard utils (modules) +import utils + # check and install requirements #print "To check and install requirements run: 'python %s --install-deps'" % sys.argv[0] -import requirements if "--install-deps" in sys.argv: - requirements.check_all_pycodeocr_requirements() + utils.requirements.check_all_pycodeocr_requirements() sys.exit() @@ -56,7 +58,7 @@ import gtk, gtk.glade import gobject -from checksum import modulo10 +from utils.checksum import modulo10 # PIL image library and it's SANE bindings import Image, ImageDraw @@ -76,9 +78,9 @@ print "To check and install requirements run: 'python %s --install-deps'" % sys.argv[0] pakages = [] # gocr -paths = { "gocr": requirements.which("gocr"), - "dmtxread": requirements.which("dmtxread"), - "pdf417decode.exe": requirements.which("pdf417decode.exe"), } +paths = { "gocr": utils.requirements.which("gocr"), + "dmtxread": utils.requirements.which("dmtxread"), + "pdf417decode.exe": utils.requirements.which("pdf417decode.exe"), } if os.path.exists(paths["gocr"]): pakages.append( "gocr" ) print "gocr found." @@ -612,7 +614,7 @@ if (op_mode == self.MDE['invoices']): # 0: invoices self.progress(4./max_steps, "Character correction...") print "*** " * 10 - data = self.char_correction(data) + data = utils.ocr.char_correction(data) self.refresh() if self.__stop: return @@ -775,68 +777,6 @@ self.progressbar1.set_text(text) self.refresh() - ## Character correction after recogition (on basis that there should be numbers and few special chars). - # - # @test Add unittest to check correct operation of this important module/function. - # - # @todo May be this important function should be placed into a separate module, - # similar to @ref checksum. - # - def char_correction(self, data): - data = re.sub("\n", "", data) - print data - corrections = [ - # Zero - ("O", "0"), ("D", "0"), ("U", "0"), ("Q", "0"), ("\(\)", "0"), ("G", "0"), ("o", "0"), - # Two - ("Z", "2"), - # Three - ("\?>", "3"), - # Four - ("l\.", "4"), ("A", "4"), ("l»", "4"), ("h", "4"), ("i»", "4"), ("l\xe2\x80\xa2", "4"), ("&", "4"), - # Five - ("S", "5"), - # Six - ("c>", "6"), - # Seven - #("\?", "7"), - # One (critical, therefore done as last; has also Overlapps e.g. with Four) - (chr(226)+chr(128)+chr(153)+"I", "1"), - (chr(226)+chr(128)+chr(153)+"\|", "1"), - (chr(226)+chr(128)+chr(152)+"\|", "1"), - (chr(226)+chr(128)+chr(152)+"I", "1"), - (chr(39)+"I", "1"), - ("I", "1"), - (chr(153)+"l", "1"), - (chr(39)+"l", "1"), - ("l", "1"), - (chr(39)+"!", "1"), - (chr(39)+"\|", "1"), - ("\|", "1"), - ("'\]", "1"), - ("'\}", "1"), - (r'\\', "1"), - # non-numbers - (" ", ""), - ("\xe2", ""), - ("\x80", ""), - ("\xbb", ""), - ("\x99", ""), - ("\x98", ""), - ("\x5f", ""), - ("\x60", ""), - ("'", ""), - #('\xbb', 187)('\x99', 153)('\x98', 152) - ("\+", "+ "), - ("\x92", "1"), # post correction - ] - for item in corrections: - olddata = data - data = re.sub(item[0], item[1], data) - if not (data == olddata): print 'subst: "%s" => "%s"' % (item[0], item[1]) - - return data - ## Run external shell command/application. class RunExternal: Deleted: trunk/checksum.py =================================================================== --- trunk/checksum.py 2011-04-27 19:01:54 UTC (rev 49) +++ trunk/checksum.py 2011-04-27 19:43:41 UTC (rev 50) @@ -1,47 +0,0 @@ -## -# @file checksum.py -# @package checksum -# @authors laserb, drtrigon -# @version 1.1 -# @brief Modulo 10 checksum for e-banking codes. -# -# @test Add unittest to check correct operation of this important module. -# -# $Id$ -# -# @section Description -# -# Modulo 10 checksum for 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 ) - # @see http://www.bundesbank.de/download/zahlungsverkehr/zv_pz201012.pdf - # @see http://www.bundesbank.de/zahlungsverkehr/zahlungsverkehr_pruefziffernberechnung.php - def __init__(self, amount, account, reference): - self.tabelle = [0,9,4,6,8,2,7,1,3,5] - - self.account = account - self.reference = reference - - self.checksum_b = self._checksum(amount) - self.checksum_k = self._checksum(account) - self.checksum_r = self._checksum(reference) - self.checksum = self.checksum_b and self.checksum_k and self.checksum_r - - try: - self.amount = str(int(amount[2:-1])/100.) - except ValueError: - self.amount = amount + " (error)" - - def _run(self, nr): - self.uebertrag = 0 - # iterate over each character - for i in range(len(nr)): - self.uebertrag = self.tabelle[(self.uebertrag + int(nr[i]) )%10] - - return (10-self.uebertrag)%10 - - def _checksum(self, value): - return (int(value[-1]) == self._run(value[:-1]) ) Deleted: trunk/installbundle.py =================================================================== --- trunk/installbundle.py 2011-04-27 19:01:54 UTC (rev 49) +++ trunk/installbundle.py 2011-04-27 19:43:41 UTC (rev 50) @@ -1,196 +0,0 @@ -## -# @file installbundle.py -# @package installbundle -# @authors University of Utah (VisTrails), drtrigon -# @version 1.1 -# @brief Module with utilities to try and install a bundle if possible. -# -# $Id$ -# -# @section Description -# -# Module with utilities to try and install a bundle if possible. -# -############################################################################ -## -## Copyright (C) 2006-2010 University of Utah. All rights reserved. -## -## This file is part of VisTrails. -## -## This file may be used under the terms of the GNU General Public -## License version 2.0 as published by the Free Software Foundation -## and appearing in the file LICENSE.GPL included in the packaging of -## this file. Please review the following to ensure GNU General Public -## Licensing requirements will be met: -## http://www.opensource.org/licenses/gpl-license.php -## -## If you are unsure which license is appropriate for your use (for -## instance, you are interested in developing a commercial derivative -## of VisTrails), please contact us at vis...@sc.... -## -## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -## -## Changed 2011 by drtrigon. Source from 'core.bundles.installbundle' -## http://downloads.sourceforge.net/project/vistrails/vistrails/nightly/vistrails-src-nightly.tar.gz -## -## This file was modified to be used as part of PyCodeOCR. -## -############################################################################ -# - -"""Module with utilities to try and install a bundle if possible.""" - -import os - -############################################################################## - -def linux_ubuntu_install(package_name): - qt = has_qt() - hide_splash_if_necessary() - - if qt: - cmd = core.system.vistrails_root_directory() - cmd += '/core/bundles/linux_ubuntu_install.py' - else: - cmd = 'apt-get install -y' - - if type(package_name) == str: - cmd += ' ' + package_name - elif type(package_name) == list: - for package in package_name: - if type(package) != str: - raise TypeError("Expected string or list of strings") - cmd += ' ' + package - - if qt: - sucmd = guess_graphical_sudo() + " '" + cmd + "'" - else: - debug.warning("PyCodeOCR wants to install package(s) '%s'" % - package_name) - sucmd = "sudo " + cmd - - result = os.system(sucmd) - - return (result == 0) # 0 indicates success - -def linux_fedora_install(package_name): - qt = has_qt() - hide_splash_if_necessary() - if qt: - cmd = core.system.vistrails_root_directory() - cmd += '/core/bundles/linux_fedora_install.py' - else: - cmd = 'yum -y install' - - if type(package_name) == str: - cmd += ' ' + package_name - elif type(package_name) == list: - for package in package_name: - if type(package) != str: - raise TypeError("Expected string or list of strings") - cmd += ' ' + package - - if qt: - sucmd = guess_graphical_sudo() + " " + cmd - else: - debug.warning(("PyCodeOCR wants to install package(s) '%s' through " - "_sudo_. Make sure you are a sudoer.") % package_name) - sucmd = "sudo " + cmd - - debug.warning("EXECUTING: sucmd") - result = os.system(sucmd) - debug.warning("RETURN VALUE: %s" % result) - return (result == 0) - -def show_question(which_files): - qt = has_qt() - if qt: - import gui.utils - if type(which_files) == str: - which_files = [which_files] - v = gui.utils.show_question("Required packages missing", - "One or more required packages are missing: " + - " ".join(which_files) + - ". PyCodeOCR can " + - "automaticallly install them. " + - "If you click OK, PyCodeOCR will need "+ - "administrator privileges, and you " + - "might be asked for the administrator password.", - buttons=[gui.utils.OK_BUTTON, - gui.utils.CANCEL_BUTTON], - default=gui.utils.OK_BUTTON) - return v == gui.utils.OK_BUTTON - else: - print "Required package missing" - print ("A required package is missing, but PyCodeOCR can " + - "automatically install it. " + - "If you say Yes, PyCodeOCR will need "+ - "administrator privileges, and you" + - "might be asked for the administrator password.") - print "Give PyCodeOCR permission to try to install package? (y/N)" - v = raw_input().upper() - return v == 'Y' or v == 'YES' - - -def install(dependency_dictionary): - """Tries to import a python module. If unsuccessful, tries to install -the appropriate bundle and then reimport. py_import tries to be smart -about which system it runs on.""" - - # Ugly fix to avoid circular import - distro = guess_system() - if not dependency_dictionary.has_key(distro): - return False - else: - files = dependency_dictionary[distro] - if show_question(files): - callable_ = getattr(installbundle, - distro.replace('-', '_') + '_install') - return callable_(files) - else: - return False - -############################################################################## - -## Guesses the operation system. -# -# Replaces original VisTrails 'core.bundles.utils.guess_system'. -# -# @since (added for PyCodeOCR) -# -def guess_system(): - import platform - #print os.name, platform.platform() - return ("%s-%s" % (platform.system(), platform.dist()[0])).lower() - -## Dummy function, returns False. -# -# Replaces original VisTrails 'has_qt'. -# -# @since (added for PyCodeOCR) -# -def has_qt(): - return False - -import installbundle - -## Dummy function, just passes. -# -# Replaces original VisTrails 'hide_splash_if_necessary'. -# -# @since (added for PyCodeOCR) -# -def hide_splash_if_necessary(): - pass - -## Debug warning output handler. -# -# Replaces original VisTrails 'core.debug.warning'. -# -# @since (added for PyCodeOCR) -# -class dbg(): - def warning(self, *args): - print "".join(args) -debug = dbg() Deleted: trunk/requirements.py =================================================================== --- trunk/requirements.py 2011-04-27 19:01:54 UTC (rev 49) +++ trunk/requirements.py 2011-04-27 19:43:41 UTC (rev 50) @@ -1,241 +0,0 @@ -## -# @file requirements.py -# @package requirements -# @authors University of Utah (VisTrails), drtrigon -# @version 1.1 -# @brief Online test presence of runtime components. -# -# $Id$ -# -# @section Description -# -# module that allows online inspection of environment to test presence of -# runtime components such as binaries, libraries, other python modules, etc. -# -############################################################################ -## -## Copyright (C) 2006-2010 University of Utah. All rights reserved. -## -## This file is part of VisTrails. -## -## This file may be used under the terms of the GNU General Public -## License version 2.0 as published by the Free Software Foundation -## and appearing in the file LICENSE.GPL included in the packaging of -## this file. Please review the following to ensure GNU General Public -## Licensing requirements will be met: -## http://www.opensource.org/licenses/gpl-license.php -## -## If you are unsure which license is appropriate for your use (for -## instance, you are interested in developing a commercial derivative -## of VisTrails), please contact us at vis...@sc.... -## -## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -## -## Changed 2011 by drtrigon. Source from 'core.requirements' -## http://downloads.sourceforge.net/project/vistrails/vistrails/nightly/vistrails-src-nightly.tar.gz -## -## This file was modified to be used as part of PyCodeOCR. -## -############################################################################ -# - -"""module that allows online inspection of environment to test presence of -runtime components such as binaries, libraries, other python modules, etc.""" - -import sys - -############################################################################## - -def python_module_exists(module_name): - """python_module_exists(module_name): Boolean. -Returns if python module of given name can be safely imported.""" - - try: - sys.modules[module_name] - return True - except KeyError: - pass - try: - __import__(module_name) - return True - except ImportError: - return False - - -def executable_file_exists(filename): - """executable_file_exists(filename): Boolean. -Returns if certain file is in current path and is executable.""" - result = executable_is_in_path(filename) - if result == "": - result = executable_is_in_pythonpath(filename) - return result != "" - -# FIXME: Add documentation. - -def require_python_module(module_name): - if not python_module_exists(module_name): - raise MissingRequirement(module_name) - -def require_executable(filename): - if not executable_file_exists(filename): - raise MissingRequirement(filename) - -def check_pyqt4(): - # checks for the presence of pyqt4, which is more important than the rest, - # since using pyqt requires a qapplication. - try: - require_python_module('PyQt4.QtGui') - require_python_module('PyQt4.QtOpenGL') - except MissingRequirement: - r = core.bundles.installbundle.install({'linux-ubuntu': ['python-qt4', - 'python-qt4-gl', - 'python-qt4-sql']}) - if not r: - raise - - -def check_all_vistrails_requirements(): - pass - - # check scipy -# try: -# require_python_module('scipy') -# except MissingRequirement: -# r = core.bundles.installbundle.install({'linux-ubuntu': 'python-scipy'}) -# if not r: -# raise - - -############################################################################## - -class MissingRequirement(Exception): - """Raise this exception in packages when necessary items are missing.""" - def __init__(self, req): - self.requirement = req - def __str__(self): - return "Missing Requirement: %s" % self.requirement - -############################################################################## - -import installbundle -import os - - -## Shows the full path of (shell) commands. -# -# According to shell command 'which', look also at: -# @see http://unixhelp.ed.ac.uk/CGI/man-cgi?which -# @see http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python -# -# @since (added for PyCodeOCR) -# -def which(program, search_path=None): - is_exe = lambda fpath: os.path.exists(fpath) and os.access(fpath, os.X_OK) - #is_exe = lambda fpath: os.path.exists(fpath) - - fpath, fname = os.path.split(program) - if fpath: - if is_exe(program): - return program - else: - if not search_path: - search_path = os.environ["PATH"].split(os.pathsep) - search_path += [ '.' ] # add local path - for path in search_path: - exe_file = os.path.join(path, program) - if is_exe(exe_file): - return exe_file - return "" - -## Checks if executable is in system PATH. -# -# Replaces original VisTrails 'core.system.executable_is_in_path'. -# -# @since (added for PyCodeOCR) -# -def executable_is_in_path(filename): - #print os.system(filename) - return which(filename) - -## Checks if executable is in system PYTHONPATH. -# -# Replaces original VisTrails 'core.system.executable_is_in_pythonpath'. -# -# @since (added for PyCodeOCR) -# -def executable_is_in_pythonpath(filename): - return which(filename, search_path=os.environ.get("PYTHONPATH", None)) - - -## Checks if pygtk libraries are installed. -# -# @since (added for PyCodeOCR) -# -# @todo Check if further dependencies/packages are needed...? -# -def check_pygtk(): - # checks for the presence of pygtk, which is more important than the rest. - try: - require_python_module('pygtk') - #pygtk.require('2.0') - require_python_module('gtk') - require_python_module('gtk.glade') - require_python_module('gobject') - except MissingRequirement: - r = core.bundles.installbundle.install({'linux-fedora': ['pygtk2']}) - # other deps? - if not r: - raise - -## Checks if sane libraries are installed. -# -# @since (added for PyCodeOCR) -# -# @todo Check if further dependencies/packages are needed...? -# -def check_sane(): - try: - require_python_module('sane') - except MissingRequirement: - r = core.bundles.installbundle.install({'linux-fedora': ['python-imaging-sane']}) - # other deps? - if not r: - raise - -## Checks if optional libraries are installed. -# -# @since (added for PyCodeOCR) -# -def check_optionals(): - try: - require_executable("gocr") - except MissingRequirement: - r = installbundle.install({'linux-fedora': ['gocr'], - 'linux-ubuntu': ['gocr']}) - - try: - #require_python_module('pydmtx') - require_executable("dmtxread") - except MissingRequirement: - #r = installbundle.install({'linux-fedora': ['python-libdmtx']}) - r = installbundle.install({'linux-fedora': ['libdmtx-utils'], - 'linux-ubuntu': ['libdmtx-utils']}) - - -## Checks if all libraries whether needed or optional are installed. -# -# @since (added for PyCodeOCR) -# -def check_all_pycodeocr_requirements(): - print "Checking all PyCodeOCR requirements:" - - # needed - print " * NEEDED 'pygtk2'" - check_pygtk() - print " * NEEDED 'sane' (scanner)" - check_sane() - - # optional - print " * OPTIONAL 'gocr', 'dmtxread'" - check_optionals() Added: trunk/utils/__init__.py =================================================================== --- trunk/utils/__init__.py (rev 0) +++ trunk/utils/__init__.py 2011-04-27 19:43:41 UTC (rev 50) @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +## +# @file __init__.py +# @namespace utils +# @authors drtrigon +# @version 1.1 +# @brief This is the utils package with important functions. +# +# $Id: checksum.py -1 $ +# +# @section Description +# +# This is the utils package with important functions. +# + +import utils.checksum +import utils.requirements +import utils.ocr Property changes on: trunk/utils/__init__.py ___________________________________________________________________ Added: svn:eol-style + native Copied: trunk/utils/checksum.py (from rev 49, trunk/checksum.py) =================================================================== --- trunk/utils/checksum.py (rev 0) +++ trunk/utils/checksum.py 2011-04-27 19:43:41 UTC (rev 50) @@ -0,0 +1,47 @@ +## +# @file utils/checksum.py +# @namespace utils::checksum +# @authors laserb, drtrigon +# @version 1.1 +# @brief Modulo 10 checksum for e-banking codes. +# +# @test Add unittest to check correct operation of this important module. +# +# $Id$ +# +# @section Description +# +# Modulo 10 checksum for 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 ) + # @see http://www.bundesbank.de/download/zahlungsverkehr/zv_pz201012.pdf + # @see http://www.bundesbank.de/zahlungsverkehr/zahlungsverkehr_pruefziffernberechnung.php + def __init__(self, amount, account, reference): + self.tabelle = [0,9,4,6,8,2,7,1,3,5] + + self.account = account + self.reference = reference + + self.checksum_b = self._checksum(amount) + self.checksum_k = self._checksum(account) + self.checksum_r = self._checksum(reference) + self.checksum = self.checksum_b and self.checksum_k and self.checksum_r + + try: + self.amount = str(int(amount[2:-1])/100.) + except ValueError: + self.amount = amount + " (error)" + + def _run(self, nr): + self.uebertrag = 0 + # iterate over each character + for i in range(len(nr)): + self.uebertrag = self.tabelle[(self.uebertrag + int(nr[i]) )%10] + + return (10-self.uebertrag)%10 + + def _checksum(self, value): + return (int(value[-1]) == self._run(value[:-1]) ) Copied: trunk/utils/installbundle.py (from rev 46, trunk/installbundle.py) =================================================================== --- trunk/utils/installbundle.py (rev 0) +++ trunk/utils/installbundle.py 2011-04-27 19:43:41 UTC (rev 50) @@ -0,0 +1,196 @@ +## +# @file utils/installbundle.py +# @namespace utils::installbundle +# @authors University of Utah (VisTrails), drtrigon +# @version 1.1 +# @brief Module with utilities to try and install a bundle if possible. +# +# $Id$ +# +# @section Description +# +# Module with utilities to try and install a bundle if possible. +# +############################################################################ +## +## Copyright (C) 2006-2010 University of Utah. All rights reserved. +## +## This file is part of VisTrails. +## +## This file may be used under the terms of the GNU General Public +## License version 2.0 as published by the Free Software Foundation +## and appearing in the file LICENSE.GPL included in the packaging of +## this file. Please review the following to ensure GNU General Public +## Licensing requirements will be met: +## http://www.opensource.org/licenses/gpl-license.php +## +## If you are unsure which license is appropriate for your use (for +## instance, you are interested in developing a commercial derivative +## of VisTrails), please contact us at vis...@sc.... +## +## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +## +## Changed 2011 by drtrigon. Source from 'core.bundles.installbundle' +## http://downloads.sourceforge.net/project/vistrails/vistrails/nightly/vistrails-src-nightly.tar.gz +## +## This file was modified to be used as part of PyCodeOCR. +## +############################################################################ +# + +"""Module with utilities to try and install a bundle if possible.""" + +import os + +############################################################################## + +def linux_ubuntu_install(package_name): + qt = has_qt() + hide_splash_if_necessary() + + if qt: + cmd = core.system.vistrails_root_directory() + cmd += '/core/bundles/linux_ubuntu_install.py' + else: + cmd = 'apt-get install -y' + + if type(package_name) == str: + cmd += ' ' + package_name + elif type(package_name) == list: + for package in package_name: + if type(package) != str: + raise TypeError("Expected string or list of strings") + cmd += ' ' + package + + if qt: + sucmd = guess_graphical_sudo() + " '" + cmd + "'" + else: + debug.warning("PyCodeOCR wants to install package(s) '%s'" % + package_name) + sucmd = "sudo " + cmd + + result = os.system(sucmd) + + return (result == 0) # 0 indicates success + +def linux_fedora_install(package_name): + qt = has_qt() + hide_splash_if_necessary() + if qt: + cmd = core.system.vistrails_root_directory() + cmd += '/core/bundles/linux_fedora_install.py' + else: + cmd = 'yum -y install' + + if type(package_name) == str: + cmd += ' ' + package_name + elif type(package_name) == list: + for package in package_name: + if type(package) != str: + raise TypeError("Expected string or list of strings") + cmd += ' ' + package + + if qt: + sucmd = guess_graphical_sudo() + " " + cmd + else: + debug.warning(("PyCodeOCR wants to install package(s) '%s' through " + "_sudo_. Make sure you are a sudoer.") % package_name) + sucmd = "sudo " + cmd + + debug.warning("EXECUTING: sucmd") + result = os.system(sucmd) + debug.warning("RETURN VALUE: %s" % result) + return (result == 0) + +def show_question(which_files): + qt = has_qt() + if qt: + import gui.utils + if type(which_files) == str: + which_files = [which_files] + v = gui.utils.show_question("Required packages missing", + "One or more required packages are missing: " + + " ".join(which_files) + + ". PyCodeOCR can " + + "automaticallly install them. " + + "If you click OK, PyCodeOCR will need "+ + "administrator privileges, and you " + + "might be asked for the administrator password.", + buttons=[gui.utils.OK_BUTTON, + gui.utils.CANCEL_BUTTON], + default=gui.utils.OK_BUTTON) + return v == gui.utils.OK_BUTTON + else: + print "Required package missing" + print ("A required package is missing, but PyCodeOCR can " + + "automatically install it. " + + "If you say Yes, PyCodeOCR will need "+ + "administrator privileges, and you" + + "might be asked for the administrator password.") + print "Give PyCodeOCR permission to try to install package? (y/N)" + v = raw_input().upper() + return v == 'Y' or v == 'YES' + + +def install(dependency_dictionary): + """Tries to import a python module. If unsuccessful, tries to install +the appropriate bundle and then reimport. py_import tries to be smart +about which system it runs on.""" + + # Ugly fix to avoid circular import + distro = guess_system() + if not dependency_dictionary.has_key(distro): + return False + else: + files = dependency_dictionary[distro] + if show_question(files): + callable_ = getattr(installbundle, + distro.replace('-', '_') + '_install') + return callable_(files) + else: + return False + +############################################################################## + +## Guesses the operation system. +# +# Replaces original VisTrails 'core.bundles.utils.guess_system'. +# +# @since (added for PyCodeOCR) +# +def guess_system(): + import platform + #print os.name, platform.platform() + return ("%s-%s" % (platform.system(), platform.dist()[0])).lower() + +## Dummy function, returns False. +# +# Replaces original VisTrails 'has_qt'. +# +# @since (added for PyCodeOCR) +# +def has_qt(): + return False + +import installbundle + +## Dummy function, just passes. +# +# Replaces original VisTrails 'hide_splash_if_necessary'. +# +# @since (added for PyCodeOCR) +# +def hide_splash_if_necessary(): + pass + +## Debug warning output handler. +# +# Replaces original VisTrails 'core.debug.warning'. +# +# @since (added for PyCodeOCR) +# +class dbg(): + def warning(self, *args): + print "".join(args) +debug = dbg() Added: trunk/utils/ocr.py =================================================================== --- trunk/utils/ocr.py (rev 0) +++ trunk/utils/ocr.py 2011-04-27 19:43:41 UTC (rev 50) @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- +## +# @file utils/ocr.py +# @namespace utils::ocr +# @authors drtrigon +# @version 1.1 +# @brief Character recogition (OCR) functions. +# +# $Id$ +# +# @section Description +# +# Character recogition (OCR) functions. +# + +# python standard modules +import re + +## Character correction after recogition (on basis that there should be numbers and few special chars). +# +# @test Add unittest to check correct operation of this important module/function. +# +def char_correction(data): + data = re.sub("\n", "", data) + print data + corrections = [ + # Zero + ("O", "0"), ("D", "0"), ("U", "0"), ("Q", "0"), ("\(\)", "0"), ("G", "0"), ("o", "0"), + # Two + ("Z", "2"), + # Three + ("\?>", "3"), + # Four + ("l\.", "4"), ("A", "4"), ("l»", "4"), ("h", "4"), ("i»", "4"), ("l\xe2\x80\xa2", "4"), ("&", "4"), + # Five + ("S", "5"), + # Six + ("c>", "6"), + # Seven + #("\?", "7"), + # One (critical, therefore done as last; has also Overlapps e.g. with Four) + (chr(226)+chr(128)+chr(153)+"I", "1"), + (chr(226)+chr(128)+chr(153)+"\|", "1"), + (chr(226)+chr(128)+chr(152)+"\|", "1"), + (chr(226)+chr(128)+chr(152)+"I", "1"), + (chr(39)+"I", "1"), + ("I", "1"), + (chr(153)+"l", "1"), + (chr(39)+"l", "1"), + ("l", "1"), + (chr(39)+"!", "1"), + (chr(39)+"\|", "1"), + ("\|", "1"), + ("'\]", "1"), + ("'\}", "1"), + (r'\\', "1"), + # non-numbers + (" ", ""), + ("\xe2", ""), + ("\x80", ""), + ("\xbb", ""), + ("\x99", ""), + ("\x98", ""), + ("\x5f", ""), + ("\x60", ""), + ("'", ""), + #('\xbb', 187)('\x99', 153)('\x98', 152) + ("\+", "+ "), + ("\x92", "1"), # post correction + ] + for item in corrections: + olddata = data + data = re.sub(item[0], item[1], data) + if not (data == olddata): print 'subst: "%s" => "%s"' % (item[0], item[1]) + + return data Property changes on: trunk/utils/ocr.py ___________________________________________________________________ Added: svn:keywords + Id Added: svn:eol-style + native Copied: trunk/utils/requirements.py (from rev 49, trunk/requirements.py) =================================================================== --- trunk/utils/requirements.py (rev 0) +++ trunk/utils/requirements.py 2011-04-27 19:43:41 UTC (rev 50) @@ -0,0 +1,241 @@ +## +# @file utils/requirements.py +# @namespace utils::requirements +# @authors University of Utah (VisTrails), drtrigon +# @version 1.1 +# @brief Online test presence of runtime components. +# +# $Id$ +# +# @section Description +# +# module that allows online inspection of environment to test presence of +# runtime components such as binaries, libraries, other python modules, etc. +# +############################################################################ +## +## Copyright (C) 2006-2010 University of Utah. All rights reserved. +## +## This file is part of VisTrails. +## +## This file may be used under the terms of the GNU General Public +## License version 2.0 as published by the Free Software Foundation +## and appearing in the file LICENSE.GPL included in the packaging of +## this file. Please review the following to ensure GNU General Public +## Licensing requirements will be met: +## http://www.opensource.org/licenses/gpl-license.php +## +## If you are unsure which license is appropriate for your use (for +## instance, you are interested in developing a commercial derivative +## of VisTrails), please contact us at vis...@sc.... +## +## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +## +## Changed 2011 by drtrigon. Source from 'core.requirements' +## http://downloads.sourceforge.net/project/vistrails/vistrails/nightly/vistrails-src-nightly.tar.gz +## +## This file was modified to be used as part of PyCodeOCR. +## +############################################################################ +# + +"""module that allows online inspection of environment to test presence of +runtime components such as binaries, libraries, other python modules, etc.""" + +import sys + +############################################################################## + +def python_module_exists(module_name): + """python_module_exists(module_name): Boolean. +Returns if python module of given name can be safely imported.""" + + try: + sys.modules[module_name] + return True + except KeyError: + pass + try: + __import__(module_name) + return True + except ImportError: + return False + + +def executable_file_exists(filename): + """executable_file_exists(filename): Boolean. +Returns if certain file is in current path and is executable.""" + result = executable_is_in_path(filename) + if result == "": + result = executable_is_in_pythonpath(filename) + return result != "" + +# FIXME: Add documentation. + +def require_python_module(module_name): + if not python_module_exists(module_name): + raise MissingRequirement(module_name) + +def require_executable(filename): + if not executable_file_exists(filename): + raise MissingRequirement(filename) + +def check_pyqt4(): + # checks for the presence of pyqt4, which is more important than the rest, + # since using pyqt requires a qapplication. + try: + require_python_module('PyQt4.QtGui') + require_python_module('PyQt4.QtOpenGL') + except MissingRequirement: + r = core.bundles.installbundle.install({'linux-ubuntu': ['python-qt4', + 'python-qt4-gl', + 'python-qt4-sql']}) + if not r: + raise + + +def check_all_vistrails_requirements(): + pass + + # check scipy +# try: +# require_python_module('scipy') +# except MissingRequirement: +# r = core.bundles.installbundle.install({'linux-ubuntu': 'python-scipy'}) +# if not r: +# raise + + +############################################################################## + +class MissingRequirement(Exception): + """Raise this exception in packages when necessary items are missing.""" + def __init__(self, req): + self.requirement = req + def __str__(self): + return "Missing Requirement: %s" % self.requirement + +############################################################################## + +import installbundle +import os + + +## Shows the full path of (shell) commands. +# +# According to shell command 'which', look also at: +# @see http://unixhelp.ed.ac.uk/CGI/man-cgi?which +# @see http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python +# +# @since (added for PyCodeOCR) +# +def which(program, search_path=None): + is_exe = lambda fpath: os.path.exists(fpath) and os.access(fpath, os.X_OK) + #is_exe = lambda fpath: os.path.exists(fpath) + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + if not search_path: + search_path = os.environ["PATH"].split(os.pathsep) + search_path += [ '.' ] # add local path + for path in search_path: + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + return "" + +## Checks if executable is in system PATH. +# +# Replaces original VisTrails 'core.system.executable_is_in_path'. +# +# @since (added for PyCodeOCR) +# +def executable_is_in_path(filename): + #print os.system(filename) + return which(filename) + +## Checks if executable is in system PYTHONPATH. +# +# Replaces original VisTrails 'core.system.executable_is_in_pythonpath'. +# +# @since (added for PyCodeOCR) +# +def executable_is_in_pythonpath(filename): + return which(filename, search_path=os.environ.get("PYTHONPATH", None)) + + +## Checks if pygtk libraries are installed. +# +# @since (added for PyCodeOCR) +# +# @todo Check if further dependencies/packages are needed...? +# +def check_pygtk(): + # checks for the presence of pygtk, which is more important than the rest. + try: + require_python_module('pygtk') + #pygtk.require('2.0') + require_python_module('gtk') + require_python_module('gtk.glade') + require_python_module('gobject') + except MissingRequirement: + r = core.bundles.installbundle.install({'linux-fedora': ['pygtk2']}) + # other deps? + if not r: + raise + +## Checks if sane libraries are installed. +# +# @since (added for PyCodeOCR) +# +# @todo Check if further dependencies/packages are needed...? +# +def check_sane(): + try: + require_python_module('sane') + except MissingRequirement: + r = core.bundles.installbundle.install({'linux-fedora': ['python-imaging-sane']}) + # other deps? + if not r: + raise + +## Checks if optional libraries are installed. +# +# @since (added for PyCodeOCR) +# +def check_optionals(): + try: + require_executable("gocr") + except MissingRequirement: + r = installbundle.install({'linux-fedora': ['gocr'], + 'linux-ubuntu': ['gocr']}) + + try: + #require_python_module('pydmtx') + require_executable("dmtxread") + except MissingRequirement: + #r = installbundle.install({'linux-fedora': ['python-libdmtx']}) + r = installbundle.install({'linux-fedora': ['libdmtx-utils'], + 'linux-ubuntu': ['libdmtx-utils']}) + + +## Checks if all libraries whether needed or optional are installed. +# +# @since (added for PyCodeOCR) +# +def check_all_pycodeocr_requirements(): + print "Checking all PyCodeOCR requirements:" + + # needed + print " * NEEDED 'pygtk2'" + check_pygtk() + print " * NEEDED 'sane' (scanner)" + check_sane() + + # optional + print " * OPTIONAL 'gocr', 'dmtxread'" + check_optionals() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <drt...@us...> - 2011-04-27 20:26:27
|
Revision: 51 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=51&view=rev Author: drtrigon Date: 2011-04-27 20:26:18 +0000 (Wed, 27 Apr 2011) Log Message: ----------- more OCR code moved to utils, now main code below 1000 lines ;) Modified Paths: -------------- trunk/PyCodeOCR.py trunk/utils/__init__.py trunk/utils/checksum.py trunk/utils/ocr.py Property Changed: ---------------- trunk/utils/__init__.py Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-04-27 19:43:41 UTC (rev 50) +++ trunk/PyCodeOCR.py 2011-04-27 20:26:18 UTC (rev 51) @@ -9,9 +9,6 @@ # # $Id$ # -# @todo This module/script has become large (more than 1000 lines) -# and should be splitted into seperate files. -# # For further information please consult the @ref mainpage also. # # @mainpage PyCodeOCR @@ -39,7 +36,7 @@ # # python standard modules -import os, re, sys, subprocess, time, gobject, string, struct +import os, re, sys, time # PyCodeOCR python standard utils (modules) import utils @@ -63,7 +60,6 @@ # 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 @@ -102,6 +98,7 @@ # global variables and constants ## path from which this program is currently executed local_path = os.path.realpath(os.path.dirname(sys.argv[0])) +utils.ocr.local_path = local_path # (ugly patch) ## 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 @@ -256,7 +253,7 @@ # lock window self.window1.set_sensitive(False) # init sane - self.run_sane = RunSANE(self.progress, self.window2, self.treeview1) + self.run_sane = utils.ocr.RunSANE(self.progress, self.window2, self.treeview1) # try to set sensitivity, fails if no scanner is initialized yet try: @@ -465,7 +462,7 @@ self.on_spinbutton_value_changed() # scan selected range self.on_combobox1_changed() # orientation mode opt = { 'tmp_file': "02.tif", - 'recog_class': RunExternal, + 'recog_class': utils.ocr.RunExternal, 'recog_cmd': self.cmd_tesser % (self.temp+"02", self.temp+"03"), 'recog_error_msg': [ "Unable" ], 'valid_code_len': self.valid_code_len, @@ -475,7 +472,7 @@ self.scan_koords = std_scan_koords["A4"][0] #self.mode = std_scan_koords["A4"][1] opt = { 'tmp_file': "02.pnm", - 'recog_class': RunExternal, + 'recog_class': utils.ocr.RunExternal, 'recog_cmd': self.cmd_gocr % (self.temp+"02",), 'recog_error_msg': [ "\nERROR pnm.c" ], 'valid_code_len': [ 13, 10, 9 ], @@ -486,25 +483,25 @@ self.mode = std_scan_koords["A4"][1] #pydmtx recognition # opt = { 'tmp_file': "02.jpg", # some issues with recogition -# 'recog_class': RunLibdmtx, # . +# 'recog_class': utils.ocr.RunLibdmtx, # . # 'recog_cmd': self.temp+"02.jpg", # of different file formats # 'recog_error_msg': [ None ], # . #dmtxread recognition opt = { 'tmp_file': "02.jpg", # some issues with recogition - 'recog_class': RunExternal, # . + 'recog_class': utils.ocr.RunExternal, # . 'recog_cmd': "%s -v -D %s02.jpg"%(paths["dmtxread"],self.temp), # of different file formats 'recog_error_msg': [ "error" ], # . #opt = { 'tmp_file': "02.bmp", # and drawing/marking the - # 'recog_cmd': (self.temp+"02.bmp", [ None ], RunLibdmtx), } # processed region(s)... + # 'recog_cmd': (self.temp+"02.bmp", [ None ], utils.ocr.RunLibdmtx), } # processed region(s)... #opt = { 'tmp_file': "02.png", # (but this should work for 'tif') - # 'recog_cmd': (self.temp+"02.png", [ None ], RunLibdmtx), } # + # 'recog_cmd': (self.temp+"02.png", [ None ], utils.ocr.RunLibdmtx), } # 'resolution': 150, } elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) self.on_spinbutton_value_changed() # scan selected range self.on_combobox1_changed() # orientation mode opt = { 'tmp_file': "02.png", - 'recog_class': RunExternal, + 'recog_class': utils.ocr.RunExternal, 'recog_cmd': self.cmd_pdf417dec % (self.temp+"02",), 'recog_error_msg': [ "wine: cannot find", "pdf417decode.exe imagefile|string.txt|-i", "Decoding failed." ], 'resolution': 300, } @@ -519,8 +516,8 @@ if source_mode: # SANE scanning interface self.progress(1./max_steps, "Scanning data...") self.inp_file = self.temp+"01.tif" - #self.run_sane = RunExternal(self.cmd_scan % ( self.scan_koords + (inp_file,) ), [ "no SANE devices found" ]) - self.run_sane.post_init(self.scan_koords, self.inp_file) # RunSANE().post_init(...) 2nd part of __init__(...) + #self.run_sane = utils.ocr.RunExternal(self.cmd_scan % ( self.scan_koords + (inp_file,) ), [ "no SANE devices found" ]) + self.run_sane.post_init(self.scan_koords, self.inp_file) # utils.ocr.RunSANE().post_init(...) 2nd part of __init__(...) self.run_sane.resolution = opt["resolution"] if self.run_sane(): self.progress(0., self.run_sane.stderr) @@ -545,8 +542,8 @@ print "No input file. Please select input file or SANE Interface." #self.progress(0., "No input file. Please select input file or SANE Interface.") return None - self.run_convert = RunExternal(self.cmd_convert % (self.inp_file, mode, self.temp+opt['tmp_file']), error_msg=[ "convert: unable to open image" ]) -# self.run_convert = RunMagickWand(inp_file, mode*90, self.temp+opt['tmp_file']) + self.run_convert = utils.ocr.RunExternal(self.cmd_convert % (self.inp_file, mode, self.temp+opt['tmp_file']), error_msg=[ "convert: unable to open image" ]) +# self.run_convert = utils.ocr.RunMagickWand(inp_file, mode*90, self.temp+opt['tmp_file']) # improve quality by using imagemagicks filter and conversion capabilities... if self.run_convert(): self.progress(0., self.run_convert.stderr[:-1]) @@ -742,7 +739,7 @@ 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" ]) + self.run_convert = utils.ocr.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 @@ -777,285 +774,6 @@ self.progressbar1.set_text(text) self.refresh() -## Run external shell command/application. -class RunExternal: - - 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): - if piped: - run = subprocess.Popen( self.cmd, - stdin =subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True ) - (stdoutdata, stderrdata) = run.communicate() - return ((max(map(stderrdata.find, self.error_msg)) != -1), stdoutdata, stderrdata) - else: - os.system( self.cmd ) - return (False, "", "") - -#class RunLibdmtx: -# """ Use libdmtx python wrapper/bindings (pydmtx). """ - -# def __init__(self, cmd, error_msg): -# #self.cmd = cmd -# #self.error_msg += error_msg -# self.filename = cmd - -# def __call__(self): -# (self.error, self.stdout, self.stderr) = self._run() -# return self.error - -# # thanks to: http://www.pastequestion.com/blog/python/how-to-use-python-imaging-library.html -# def _run(self): -# """ Read a Data Matrix barcode. """ -# dm_read = DataMatrix() -# #print self.filename -# img = Image.open(self.filename) -# try: -# self.decode = dm_read.decode(img.size[0], img.size[1], buffer(img.tostring())) -# self.count = dm_read.count() -# self.message = [ dm_read.message(i+1) for i in range(self.count) ] -# self.stats = [ dm_read.stats(i+1) for i in range(self.count) ] -# except: -# return (True, "error", sys.exc_info()[1]) - -# print "Detected %i DataMatrix barcodes" % self.count -# for i in range(self.count): -# print "Code # %i:" % (i+1) -# print self.message[i] -# stats = self.stats[i] -# print stats - -# # mark the recognized region and save back to file -# points = list(stats[1]) -# points.append(points[0]) -# draw = ImageDraw.Draw(img) -# old = points[0] -# for i, xy in enumerate(points[1:]): -# #draw.line(old+xy, fill=(0, 255, 0), width=2) -# #draw.line(old+xy, fill=(0, 255, 0)) -# draw.line(old+xy, fill="rgb(0, 255, 0)") -# old = xy -# img.save(self.filename) - -# #return (False, self.message, "") -# #print self.stats, (self.count == 0) -# return ((self.count == 0), self.message, "") - -#class RunMagickWand: -# """ Use Python bindings to ImageMagick's MagickWand API. """ -# # "convert %s.tif -crop 1600x250+800+960 -depth 8 %s.tif" -# # "convert %s.tif -crop 1700x250+750+960 -depth 8 %s.tif" -# # "convert %s.tif -crop 3400x500+1500+1900 -depth 8 %s.tif" -# # "convert %s.tif -depth 8 %s.tif" -# # "convert %s.tif -depth 8 -rotate %d %s.tif" -# # "convert %s.tif -depth 8 -rotate %d %s" -# #cmd_convert = "convert %s -depth 8 -rotate %d %s" -# -# def __init__(self, inp_filename, rotate, out_filename): -# self.inp_filename = inp_filename -# self.out_filename = out_filename -# self.angle = rotate -# self.depth = 8 -# -# def __call__(self): -# (self.error, self.stdout, self.stderr) = self._run() -# return self.error -# -# # thanks to: http://www.assembla.com/wiki/show/pythonmagickwand -# def _run(self): -# """ This rotates, changes depth, format and writes a new file. """ -# try: -# i = Image(self.inp_filename) -# i.rotate(self.angle) -# i.depth(self.depth) -# i.format = self.out_filename[-3:].upper() -# i.save(self.out_filename) -# except: -# return (True, "error", sys.exc_info()[1]) -# -# return (False, "ok", "") - -## sSANE/PIL interface python wrapper/bindings. -class RunSANE: - # "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): - print "init sane python interface ...", - sys.stdout.flush() - - # Get the path set up properly - #sys.path.append('.') - - # create treeview things - list_store = gtk.ListStore(gobject.TYPE_STRING) - 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. - progress(0.,"init sane python interface ...") - try: - self.version = sane.init() - progress(1./self.n,"init sane python interface ... search 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.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) == 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:]: - # choose one by command line - devnr = raw_input("Choose device: ") - progress(2./self.n,"More than one device found. Choose device number %i" % devnr) - # continue to init scanner - self.init_scanner(progress, window2, treeview, devnr) - else: - # simply continue and select device in GUI ( look in init_sane ) - progress(2./self.n,"More than one device found.") - - else: - # only one device found - progress(2./self.n,"Device: %s" % self.devices[0][1]+" "+self.devices[0][2]) - # continue to init scanner - self.init_scanner(progress, window2, treeview, 0) - - except: - # 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 = self.devices[devnr][0] # choose first device - print self.dev - progress(3./self.n,"Device initialized. Open scanner...") - - # open scanner device - self.scanner = sane.open(self.dev) - self.params = self.scanner.get_parameters() - self.opts = self.scanner.get_options() - - self.found_scanner = True - - progress(4./self.n,"Ready: %s" % self.devices[devnr][1]+" "+self.devices[devnr][2]) - print "done." - - except: - # init scanner failed. maybe device has no scanner - self.found_scanner = False - 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): - 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 - - ## 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): - try: - # Set scan parameters (also with higher resolution!) - (t, l, y, x) = self.coords - self.scanner.tl_y = float(t) - self.scanner.tl_x = float(l) - self.scanner.br_y = (float(y) + self.scanner.tl_y) - self.scanner.br_x = (float(x) + self.scanner.tl_x) - self.scanner.resolution = self.resolution - self.scanner.mode = "Gray" - - # Initiate the scan - self.scanner.start() - - # 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) - - #self.scanner.close() - except: - return (True, "error", sys.exc_info()[1]) - - return (False, "ok", "") - - ## Show some info about the scanner and SANE. - def info(self): - print 'SANE version:', self.version - print 'Available devices=', self.devices - print 'Selected device=', self.dev #, "\n" - - print 'SaneDev object=', self.scanner - 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 main = MainWindowGTK() Modified: trunk/utils/__init__.py =================================================================== --- trunk/utils/__init__.py 2011-04-27 19:43:41 UTC (rev 50) +++ trunk/utils/__init__.py 2011-04-27 20:26:18 UTC (rev 51) @@ -6,7 +6,7 @@ # @version 1.1 # @brief This is the utils package with important functions. # -# $Id: checksum.py -1 $ +# $Id$ # # @section Description # Property changes on: trunk/utils/__init__.py ___________________________________________________________________ Added: svn:keywords + Id Modified: trunk/utils/checksum.py =================================================================== --- trunk/utils/checksum.py 2011-04-27 19:43:41 UTC (rev 50) +++ trunk/utils/checksum.py 2011-04-27 20:26:18 UTC (rev 51) @@ -33,7 +33,7 @@ try: self.amount = str(int(amount[2:-1])/100.) except ValueError: - self.amount = amount + " (error)" + self.amount = amount + " [ERROR!]" def _run(self, nr): self.uebertrag = 0 Modified: trunk/utils/ocr.py =================================================================== --- trunk/utils/ocr.py 2011-04-27 19:43:41 UTC (rev 50) +++ trunk/utils/ocr.py 2011-04-27 20:26:18 UTC (rev 51) @@ -4,7 +4,7 @@ # @namespace utils::ocr # @authors drtrigon # @version 1.1 -# @brief Character recogition (OCR) functions. +# @brief Character recogition (OCR) functions and classes. # # $Id$ # @@ -14,8 +14,12 @@ # # python standard modules -import re +import os, re, sys, subprocess, gobject +# PIL image library and it's SANE bindings +import sane # f12: 'python-imaging-sane' + + ## Character correction after recogition (on basis that there should be numbers and few special chars). # # @test Add unittest to check correct operation of this important module/function. @@ -74,3 +78,284 @@ if not (data == olddata): print 'subst: "%s" => "%s"' % (item[0], item[1]) return data + + +## Run external shell command/application. +class RunExternal: + + 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): + if piped: + run = subprocess.Popen( self.cmd, + stdin =subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True ) + (stdoutdata, stderrdata) = run.communicate() + return ((max(map(stderrdata.find, self.error_msg)) != -1), stdoutdata, stderrdata) + else: + os.system( self.cmd ) + return (False, "", "") + +#class RunLibdmtx: +# """ Use libdmtx python wrapper/bindings (pydmtx). """ + +# def __init__(self, cmd, error_msg): +# #self.cmd = cmd +# #self.error_msg += error_msg +# self.filename = cmd + +# def __call__(self): +# (self.error, self.stdout, self.stderr) = self._run() +# return self.error + +# # thanks to: http://www.pastequestion.com/blog/python/how-to-use-python-imaging-library.html +# def _run(self): +# """ Read a Data Matrix barcode. """ +# dm_read = DataMatrix() +# #print self.filename +# img = Image.open(self.filename) +# try: +# self.decode = dm_read.decode(img.size[0], img.size[1], buffer(img.tostring())) +# self.count = dm_read.count() +# self.message = [ dm_read.message(i+1) for i in range(self.count) ] +# self.stats = [ dm_read.stats(i+1) for i in range(self.count) ] +# except: +# return (True, "error", sys.exc_info()[1]) + +# print "Detected %i DataMatrix barcodes" % self.count +# for i in range(self.count): +# print "Code # %i:" % (i+1) +# print self.message[i] +# stats = self.stats[i] +# print stats + +# # mark the recognized region and save back to file +# points = list(stats[1]) +# points.append(points[0]) +# draw = ImageDraw.Draw(img) +# old = points[0] +# for i, xy in enumerate(points[1:]): +# #draw.line(old+xy, fill=(0, 255, 0), width=2) +# #draw.line(old+xy, fill=(0, 255, 0)) +# draw.line(old+xy, fill="rgb(0, 255, 0)") +# old = xy +# img.save(self.filename) + +# #return (False, self.message, "") +# #print self.stats, (self.count == 0) +# return ((self.count == 0), self.message, "") + +#class RunMagickWand: +# """ Use Python bindings to ImageMagick's MagickWand API. """ +# # "convert %s.tif -crop 1600x250+800+960 -depth 8 %s.tif" +# # "convert %s.tif -crop 1700x250+750+960 -depth 8 %s.tif" +# # "convert %s.tif -crop 3400x500+1500+1900 -depth 8 %s.tif" +# # "convert %s.tif -depth 8 %s.tif" +# # "convert %s.tif -depth 8 -rotate %d %s.tif" +# # "convert %s.tif -depth 8 -rotate %d %s" +# #cmd_convert = "convert %s -depth 8 -rotate %d %s" +# +# def __init__(self, inp_filename, rotate, out_filename): +# self.inp_filename = inp_filename +# self.out_filename = out_filename +# self.angle = rotate +# self.depth = 8 +# +# def __call__(self): +# (self.error, self.stdout, self.stderr) = self._run() +# return self.error +# +# # thanks to: http://www.assembla.com/wiki/show/pythonmagickwand +# def _run(self): +# """ This rotates, changes depth, format and writes a new file. """ +# try: +# i = Image(self.inp_filename) +# i.rotate(self.angle) +# i.depth(self.depth) +# i.format = self.out_filename[-3:].upper() +# i.save(self.out_filename) +# except: +# return (True, "error", sys.exc_info()[1]) +# +# return (False, "ok", "") + +## SANE/PIL interface python wrapper/bindings. +class RunSANE: + # "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): + print "init sane python interface ...", + sys.stdout.flush() + + # Get the path set up properly + #sys.path.append('.') + + # create treeview things + import gtk # (ugly patch) + list_store = gtk.ListStore(gobject.TYPE_STRING) + 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. + progress(0.,"init sane python interface ...") + try: + self.version = sane.init() + progress(1./self.n,"init sane python interface ... search 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.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) == 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:]: + # choose one by command line + devnr = raw_input("Choose device: ") + progress(2./self.n,"More than one device found. Choose device number %i" % devnr) + # continue to init scanner + self.init_scanner(progress, window2, treeview, devnr) + else: + # simply continue and select device in GUI ( look in init_sane ) + progress(2./self.n,"More than one device found.") + + else: + # only one device found + progress(2./self.n,"Device: %s" % self.devices[0][1]+" "+self.devices[0][2]) + # continue to init scanner + self.init_scanner(progress, window2, treeview, 0) + + except: + # 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 = self.devices[devnr][0] # choose first device + print self.dev + progress(3./self.n,"Device initialized. Open scanner...") + + # open scanner device + self.scanner = sane.open(self.dev) + self.params = self.scanner.get_parameters() + self.opts = self.scanner.get_options() + + self.found_scanner = True + + progress(4./self.n,"Ready: %s" % self.devices[devnr][1]+" "+self.devices[devnr][2]) + print "done." + + except: + # init scanner failed. maybe device has no scanner + self.found_scanner = False + 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): + 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 + + ## 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): + try: + # Set scan parameters (also with higher resolution!) + (t, l, y, x) = self.coords + self.scanner.tl_y = float(t) + self.scanner.tl_x = float(l) + self.scanner.br_y = (float(y) + self.scanner.tl_y) + self.scanner.br_x = (float(x) + self.scanner.tl_x) + self.scanner.resolution = self.resolution + self.scanner.mode = "Gray" + + # Initiate the scan + self.scanner.start() + + # 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) + + #self.scanner.close() + except: + return (True, "error", sys.exc_info()[1]) + + return (False, "ok", "") + + ## Show some info about the scanner and SANE. + def info(self): + print 'SANE version:', self.version + print 'Available devices=', self.devices + print 'Selected device=', self.dev #, "\n" + + print 'SaneDev object=', self.scanner + 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() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <drt...@us...> - 2011-04-28 07:42:00
|
Revision: 53 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=53&view=rev Author: drtrigon Date: 2011-04-28 07:41:54 +0000 (Thu, 28 Apr 2011) Log Message: ----------- README and CHANGES into doxygen docu, more deps auto install (for tesseract and convert) Modified Paths: -------------- trunk/CHANGES trunk/Doxyfile trunk/PyCodeOCR.py trunk/README trunk/utils/ocr.py trunk/utils/requirements.py Modified: trunk/CHANGES =================================================================== --- trunk/CHANGES 2011-04-27 21:22:33 UTC (rev 52) +++ trunk/CHANGES 2011-04-28 07:41:54 UTC (rev 53) @@ -60,4 +60,3 @@ # - Some docu written for orientation and use, look at README. # # - Modified: trunk/Doxyfile =================================================================== --- trunk/Doxyfile 2011-04-27 21:22:33 UTC (rev 52) +++ trunk/Doxyfile 2011-04-28 07:41:54 UTC (rev 53) @@ -656,7 +656,7 @@ # directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = . # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-04-27 21:22:33 UTC (rev 52) +++ trunk/PyCodeOCR.py 2011-04-28 07:41:54 UTC (rev 53) @@ -34,6 +34,14 @@ # # (not implemented yet). # +# @section readme Readme +# +# @include "./README" +# +# @section changes Changes +# +# @include "./CHANGES" +# # python standard modules import os, re, sys, time @@ -451,6 +459,9 @@ # helpers # ## Main scanning and number recognition procedure. + # + # @todo Put this function (may be as class with functions for each step) into utils::ocr + # def scancode(self): # Initialization of scanning process # (0/7) Modified: trunk/README =================================================================== --- trunk/README 2011-04-27 21:22:33 UTC (rev 52) +++ trunk/README 2011-04-28 07:41:54 UTC (rev 53) @@ -145,5 +145,3 @@ # # If there is is any question or suggestion please contact me at sf.net, thanks! # - - Modified: trunk/utils/ocr.py =================================================================== --- trunk/utils/ocr.py 2011-04-27 21:22:33 UTC (rev 52) +++ trunk/utils/ocr.py 2011-04-28 07:41:54 UTC (rev 53) @@ -2,7 +2,7 @@ ## # @file utils/ocr.py # @namespace utils::ocr -# @authors drtrigon +# @authors laserb, drtrigon # @version 1.1 # @brief Character recogition (OCR) functions and classes. # Modified: trunk/utils/requirements.py =================================================================== --- trunk/utils/requirements.py 2011-04-27 21:22:33 UTC (rev 52) +++ trunk/utils/requirements.py 2011-04-28 07:41:54 UTC (rev 53) @@ -7,6 +7,8 @@ # # $Id$ # +# @todo Check if further dependencies/packages are needed...? +# # @section Description # # module that allows online inspection of environment to test presence of @@ -172,8 +174,6 @@ # # @since (added for PyCodeOCR) # -# @todo Check if further dependencies/packages are needed...? -# def check_pygtk(): # checks for the presence of pygtk, which is more important than the rest. try: @@ -192,8 +192,6 @@ # # @since (added for PyCodeOCR) # -# @todo Check if further dependencies/packages are needed...? -# def check_sane(): try: require_python_module('sane') @@ -203,6 +201,27 @@ if not r: raise +## Checks if external programs (tesseract and convert) are installed. +# +# @since (added for PyCodeOCR) +# +def check_binaries(): + try: + require_executable('tesseract') + except MissingRequirement: + r = core.bundles.installbundle.install({'linux-fedora': ['tesseract']}) + # other deps? + if not r: + raise + + try: + require_executable('convert') + except MissingRequirement: + r = core.bundles.installbundle.install({'linux-fedora': ['imagemagick']}) + # other deps? + if not r: + raise + ## Checks if optional libraries are installed. # # @since (added for PyCodeOCR) @@ -235,6 +254,8 @@ check_pygtk() print " * NEEDED 'sane' (scanner)" check_sane() + print " * NEEDED 'tesseract' and 'convert' (binaries)" + check_binaries() # optional print " * OPTIONAL 'gocr', 'dmtxread'" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <la...@us...> - 2011-07-27 07:33:38
|
Revision: 55 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=55&view=rev Author: laserb Date: 2011-07-27 07:33:30 +0000 (Wed, 27 Jul 2011) Log Message: ----------- Merge with branche from laserb: + outsource RunExternal, RunLibdmtx and RunMagickWand from ocr.py + add blacklist_manager + clean up scanner initialization code, no longer jumping back and forth in code, retry connecting to scanner possible + renamed some gtk elements to have a meaningful name + make main window resizable + added tabstyle, todo: show information in different tabs + changed glade format to GTKBuilder instead of libglade, as libglade is depriciated ( no longer supported as of glade 3.10 ) Modified Paths: -------------- trunk/PyCodeOCR.glade trunk/PyCodeOCR.py trunk/README trunk/utils/__init__.py trunk/utils/ocr.py Added Paths: ----------- trunk/utils/RunExternal.py trunk/utils/RunLibdmtx.py trunk/utils/RunMagickWand.py trunk/utils/blacklist_manager.py Modified: trunk/PyCodeOCR.glade =================================================================== --- trunk/PyCodeOCR.glade 2011-04-28 10:21:55 UTC (rev 54) +++ trunk/PyCodeOCR.glade 2011-07-27 07:33:30 UTC (rev 55) @@ -1,417 +1,865 @@ -<?xml version="1.0"?> -<glade-interface> - <!-- interface-requires gtk+ 2.16 --> - <!-- interface-naming-policy toplevel-contextual --> - <widget class="GtkWindow" id="window1"> - <property name="width_request">798</property> - <property name="height_request">246</property> - <property name="visible">True</property> - <property name="title" translatable="yes">PyCodeOCR</property> - <property name="resizable">False</property> - <signal name="destroy" handler="on_window1_destroy"/> +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="2.24"/> + <object class="GtkAdjustment" id="adjustment1"> + <property name="upper">300</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment2"> + <property name="upper">300</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment3"> + <property name="upper">300</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkAdjustment" id="adjustment4"> + <property name="upper">300</property> + <property name="step_increment">1</property> + <property name="page_increment">10</property> + </object> + <object class="GtkWindow" id="img_popup"> + <property name="can_focus">False</property> + <property name="type">popup</property> + <property name="window_position">mouse</property> + <property name="destroy_with_parent">True</property> + <signal name="leave-notify-event" handler="on_main_image_eventbox_button_press_event" swapped="no"/> <child> - <widget class="GtkFixed" id="fixed1"> + <object class="GtkVBox" id="vbox1"> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkProgressBar" id="progressbar1"> - <property name="width_request">504</property> - <property name="height_request">20</property> + <object class="GtkEventBox" id="popup_image_eventbox"> <property name="visible">True</property> - <property name="pulse_step">0.10000000149</property> - </widget> + <property name="can_focus">False</property> + <property name="events">GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK | GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK | GDK_VISIBILITY_NOTIFY_MASK | GDK_PROXIMITY_IN_MASK | GDK_PROXIMITY_OUT_MASK | GDK_SUBSTRUCTURE_MASK | GDK_SCROLL_MASK</property> + <property name="visible_window">False</property> + <child> + <object class="GtkImage" id="popup_image"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + </object> <packing> - <property name="x">16</property> - <property name="y">208</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> </packing> </child> + </object> + </child> + </object> + <object class="GtkWindow" id="main_window"> + <property name="width_request">786</property> + <property name="height_request">242</property> + <property name="can_focus">False</property> + <signal name="destroy" handler="on_main_window_destroy" swapped="no"/> + <signal name="motion-notify-event" handler="on_pointer_motion" swapped="no"/> + <child> + <object class="GtkNotebook" id="notebook"> + <property name="width_request">786</property> + <property name="height_request">242</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="tab_pos">left</property> <child> - <widget class="GtkEntry" id="entry1"> - <property name="width_request">504</property> - <property name="height_request">27</property> + <object class="GtkHBox" id="hbox1"> + <property name="width_request">1284</property> + <property name="height_request">443</property> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="editable">False</property> - <property name="invisible_char">●</property> - </widget> - <packing> - <property name="x">16</property> - <property name="y">168</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label5"> - <property name="width_request">90</property> - <property name="height_request">21</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Orientation:</property> - </widget> - <packing> - <property name="x">569</property> - <property name="y">160</property> - </packing> - </child> - <child> - <widget class="GtkComboBox" id="combobox1"> - <property name="width_request">90</property> - <property name="height_request">29</property> - <property name="visible">True</property> - <property name="items" translatable="yes">0 deg -90 deg -180 deg -270 deg</property> - <signal name="changed" handler="on_combobox1_changed"/> - </widget> - <packing> - <property name="x">691</property> - <property name="y">155</property> - </packing> - </child> - <child> - <widget class="GtkFrame" id="frame1"> - <property name="width_request">224</property> - <property name="height_request">91</property> - <property name="visible">True</property> - <property name="label_xalign">0</property> + <property name="can_focus">False</property> <child> - <widget class="GtkAlignment" id="alignment1"> + <object class="GtkVBox" id="vbox4"> <property name="visible">True</property> - <property name="left_padding">12</property> + <property name="can_focus">False</property> <child> - <widget class="GtkFixed" id="fixed2"> + <object class="GtkHBox" id="hbox2"> + <property name="height_request">32</property> <property name="visible">True</property> + <property name="can_focus">False</property> <child> - <widget class="GtkLabel" id="label2"> - <property name="width_request">72</property> - <property name="height_request">17</property> + <object class="GtkHBox" id="hbox6"> + <property name="height_request">30</property> <property name="visible">True</property> - <property name="label" translatable="yes">Position:</property> - </widget> + <property name="can_focus">False</property> + <property name="spacing">11</property> + <child> + <object class="GtkRadioButton" id="file_input_button"> + <property name="width_request">21</property> + <property name="height_request">21</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + <property name="group">sane_input_button</property> + <signal name="toggled" handler="on_mode_changed" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFileChooserButton" id="filechooserbutton"> + <property name="width_request">168</property> + <property name="height_request">29</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="do_overwrite_confirmation">True</property> + <signal name="file-set" handler="on_filechooserbutton_file_set" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">1</property> + </packing> + </child> + </object> <packing> - <property name="y">8</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="pack_type">end</property> + <property name="position">0</property> </packing> </child> <child> - <widget class="GtkSpinButton" id="spinbutton1"> - <property name="width_request">56</property> - <property name="height_request">27</property> + <object class="GtkComboBox" id="mode_combobox"> + <property name="width_request">200</property> + <property name="height_request">29</property> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="adjustment">1 0 200 1 10 0</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - <signal name="value_changed" handler="on_spinbutton_value_changed"/> - </widget> + <property name="can_focus">False</property> + <property name="model">mode_list</property> + <property name="active">0</property> + <property name="has_entry">True</property> + <property name="entry_text_column">0</property> + <signal name="changed" handler="on_mode_changed" swapped="no"/> + <child internal-child="entry"> + <object class="GtkEntry" id="combobox-entry2"> + <property name="can_focus">False</property> + <property name="editable">False</property> + <property name="shadow_type">none</property> + <property name="caps_lock_warning">False</property> + </object> + </child> + </object> <packing> - <property name="x">80</property> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> </packing> </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="scanned_code_label"> + <property name="width_request">102</property> + <property name="height_request">17</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">Scanned code:</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkEventBox" id="main_image_eventbox"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <signal name="button-press-event" handler="on_main_image_eventbox_button_press_event" swapped="no"/> <child> - <widget class="GtkSpinButton" id="spinbutton2"> - <property name="width_request">56</property> - <property name="height_request">27</property> + <object class="GtkImage" id="main_image"> <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="padding">4</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="output"> + <property name="width_request">504</property> + <property name="height_request">27</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="invisible_char">•</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkProgressBar" id="progressbar"> + <property name="width_request">504</property> + <property name="height_request">20</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="pulse_step">0.10000000149</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">4</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox5"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkHBox" id="hbox3"> + <property name="height_request">30</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkRadioButton" id="sane_input_button"> + <property name="label" translatable="yes">Standard SANE Interface</property> + <property name="width_request">224</property> + <property name="height_request">21</property> + <property name="visible">True</property> <property name="can_focus">True</property> - <property name="adjustment">1 0 200 1 10 0</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - <signal name="value_changed" handler="on_spinbutton_value_changed"/> - </widget> + <property name="receives_default">False</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <property name="active">True</property> + <property name="draw_indicator">True</property> + <signal name="toggled" handler="on_mode_changed" swapped="no"/> + </object> <packing> - <property name="x">144</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">0</property> </packing> </child> <child> - <widget class="GtkSpinButton" id="spinbutton3"> - <property name="width_request">56</property> - <property name="height_request">27</property> - <property name="visible">True</property> + <object class="GtkButton" id="retry_button"> + <property name="label" translatable="yes">Retry</property> + <property name="width_request">60</property> + <property name="height_request">29</property> <property name="can_focus">True</property> - <property name="adjustment">1 0 200 1 10 0</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - <signal name="value_changed" handler="on_spinbutton_value_changed"/> - </widget> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <signal name="clicked" handler="on_retry_button_clicked" swapped="no"/> + </object> <packing> - <property name="x">80</property> - <property name="y">40</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">1</property> </packing> </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="placement_frame"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> <child> - <widget class="GtkSpinButton" id="spinbutton4"> - <property name="width_request">56</property> - <property name="height_request">27</property> + <object class="GtkAlignment" id="alignment1"> <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="left_padding">12</property> + <child> + <object class="GtkFixed" id="fixed2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="position_label"> + <property name="width_request">72</property> + <property name="height_request">17</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Position:</property> + </object> + <packing> + <property name="y">8</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="position_x"> + <property name="width_request">56</property> + <property name="height_request">27</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="adjustment">adjustment1</property> + <property name="climb_rate">1</property> + <property name="numeric">True</property> + <signal name="value-changed" handler="on_placement_value_changed" swapped="no"/> + </object> + <packing> + <property name="x">80</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="position_y"> + <property name="width_request">56</property> + <property name="height_request">27</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="adjustment">adjustment2</property> + <property name="climb_rate">1</property> + <property name="numeric">True</property> + <signal name="value-changed" handler="on_placement_value_changed" swapped="no"/> + </object> + <packing> + <property name="x">144</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="size_x"> + <property name="width_request">56</property> + <property name="height_request">27</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="adjustment">adjustment3</property> + <property name="climb_rate">1</property> + <property name="numeric">True</property> + <signal name="value-changed" handler="on_placement_value_changed" swapped="no"/> + </object> + <packing> + <property name="x">80</property> + <property name="y">40</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="size_y"> + <property name="width_request">56</property> + <property name="height_request">27</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="primary_icon_activatable">False</property> + <property name="secondary_icon_activatable">False</property> + <property name="adjustment">adjustment4</property> + <property name="climb_rate">1</property> + <property name="numeric">True</property> + <signal name="value-changed" handler="on_placement_value_changed" swapped="no"/> + </object> + <packing> + <property name="x">144</property> + <property name="y">40</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="size_label"> + <property name="width_request">72</property> + <property name="height_request">17</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Size:</property> + </object> + <packing> + <property name="y">48</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="placement_label"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Placement</property> + <property name="use_markup">True</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox4"> + <property name="width_request">1</property> + <property name="height_request">30</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="orientation_label"> + <property name="width_request">92</property> + <property name="height_request">21</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Orientation:</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="orientation"> + <property name="width_request">90</property> + <property name="height_request">29</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="model">orientation_list</property> + <property name="has_entry">True</property> + <property name="entry_text_column">0</property> + <signal name="changed" handler="on_orientation_changed" swapped="no"/> + <child internal-child="entry"> + <object class="GtkEntry" id="combobox-entry4"> + <property name="can_focus">False</property> + <property name="editable">False</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label8"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + <child> + <object class="GtkHBox" id="hbox5"> + <property name="height_request">31</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkToggleButton" id="scan_button"> + <property name="label" translatable="yes">scan</property> + <property name="width_request">90</property> + <property name="height_request">29</property> + <property name="visible">True</property> <property name="can_focus">True</property> - <property name="adjustment">1 0 200 1 10 0</property> - <property name="climb_rate">1</property> - <property name="numeric">True</property> - <signal name="value_changed" handler="on_spinbutton_value_changed"/> - </widget> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <signal name="toggled" handler="on_scan_button_clicked" swapped="no"/> + </object> <packing> - <property name="x">144</property> - <property name="y">40</property> + <property name="expand">True</property> + <property name="fill">False</property> + <property name="position">0</property> </packing> </child> <child> - <widget class="GtkLabel" id="label3"> - <property name="width_request">72</property> - <property name="height_request">17</property> + <object class="GtkButton" id="exit_button"> + <property name="label" translatable="yes">exit</property> + <property name="width_request">90</property> + <property name="height_request">19</property> <property name="visible">True</property> - <property name="label" translatable="yes">Size:</property> - </widget> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="use_underline">True</property> + <signal name="clicked" handler="on_exit_button_clicked" swapped="no"/> + </object> <packing> - <property name="y">48</property> + <property name="expand">True</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> - </widget> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">4</property> + </packing> </child> - </widget> - </child> - <child> - <widget class="GtkLabel" id="label1"> - <property name="visible">True</property> - <property name="label" translatable="yes">Placement</property> - <property name="use_markup">True</property> - </widget> + </object> <packing> - <property name="type">label_item</property> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> </packing> </child> - </widget> - <packing> - <property name="x">558</property> - <property name="y">56</property> - </packing> + </object> </child> - <child> - <widget class="GtkLabel" id="label4"> - <property name="width_request">102</property> - <property name="height_request">17</property> + <child type="tab"> + <object class="GtkLabel" id="scan_label"> <property name="visible">True</property> - <property name="label" translatable="yes">Scanned code:</property> - </widget> + <property name="can_focus">False</property> + <property name="label" translatable="yes">SCAN</property> + </object> <packing> - <property name="x">16</property> - <property name="y">55</property> + <property name="tab_fill">False</property> </packing> </child> <child> - <widget class="GtkButton" id="button2"> - <property name="label" translatable="yes">exit</property> - <property name="width_request">90</property> - <property name="height_request">29</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <signal name="clicked" handler="on_button2_clicked"/> - </widget> - <packing> - <property name="x">692</property> - <property name="y">200</property> - </packing> + <placeholder/> </child> <child> - <widget class="GtkToggleButton" id="togglebutton1"> - <property name="label" translatable="yes">scan</property> - <property name="width_request">90</property> - <property name="height_request">29</property> + <object class="GtkVBox" id="vbox3"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <signal name="toggled" handler="on_togglebutton1_toggled"/> - </widget> + <property name="can_focus">False</property> + <property name="resize_mode">immediate</property> + <child> + <object class="GtkScrolledWindow" id="device_info_scrolled"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="window_placement_set">True</property> + <child> + <object class="GtkTextView" id="device_info_text"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="wrap_mode">word</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> <packing> - <property name="x">568</property> - <property name="y">200</property> + <property name="position">1</property> </packing> </child> - <child> - <widget class="GtkComboBox" id="combobox2"> - <property name="width_request">256</property> - <property name="height_request">31</property> + <child type="tab"> + <object class="GtkLabel" id="device_info_label"> <property name="visible">True</property> - <property name="items" translatable="yes">E-Banking invoice OCR -Barcode optical recogn. (beta) -DataMatrix optical recogn. (beta) -PDF417 bc. optical recogn. (beta) -</property> - <signal name="changed" handler="on_combobox2_changed"/> - </widget> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Device Info</property> + </object> <packing> - <property name="x">16</property> - <property name="y">16</property> + <property name="position">1</property> + <property name="tab_fill">False</property> </packing> </child> <child> - <widget class="GtkRadioButton" id="radiobutton2"> - <property name="label" translatable="yes">Standard SANE Interface</property> - <property name="width_request">224</property> - <property name="height_request">21</property> + <object class="GtkHBox" id="hbox10"> + <property name="width_request">100</property> + <property name="height_request">80</property> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="active">True</property> - <property name="draw_indicator">True</property> - <signal name="toggled" handler="on_combobox2_changed"/> - </widget> + <property name="can_focus">False</property> + <child> + <object class="GtkVBox" id="vbox9"> + <property name="width_request">100</property> + <property name="height_request">80</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkScrolledWindow" id="device_list_scrolled"> + <property name="width_request">740</property> + <property name="height_request">140</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkTreeView" id="device_treeview"> + <property name="width_request">740</property> + <property name="height_request">140</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="enable_grid_lines">horizontal</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection1"/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="device_chooser_button"> + <property name="label" translatable="yes">OK</property> + <property name="width_request">90</property> + <property name="height_request">29</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <signal name="clicked" handler="on_device_chooser_button_clicked" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox8"> + <property name="width_request">75</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkLabel" id="label12"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="blacklist_add_button"> + <property name="label" translatable="yes">--></property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <signal name="clicked" handler="blacklist_add" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="blacklist_remove_button"> + <property name="label" translatable="yes"><--</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_action_appearance">False</property> + <property name="image_position">right</property> + <signal name="clicked" handler="blacklist_remove" swapped="no"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label13"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">3</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox7"> + <property name="width_request">100</property> + <property name="height_request">80</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <child> + <object class="GtkScrolledWindow" id="blacklist_scrolled"> + <property name="width_request">740</property> + <property name="height_request">140</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkTreeView" id="blacklist_treeview"> + <property name="width_request">740</property> + <property name="height_request">140</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="enable_grid_lines">horizontal</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection2"/> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> <packing> - <property name="x">534</property> - <property name="y">24</property> + <property name="position">3</property> </packing> </child> - <child> - <widget class="GtkRadioButton" id="radiobutton1"> - <property name="width_request">21</property> - <property name="height_request">21</property> + <child type="tab"> + <object class="GtkLabel" id="blacklist_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="draw_indicator">True</property> - <property name="group">radiobutton2</property> - <signal name="toggled" handler="on_combobox2_changed"/> - </widget> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Blacklist</property> + </object> <packing> - <property name="x">318</property> - <property name="y">24</property> + <property name="position">2</property> + <property name="tab_fill">False</property> </packing> </child> <child> - <widget class="GtkFileChooserButton" id="filechooserbutton1"> - <property name="width_request">168</property> - <property name="height_request">31</property> + <object class="GtkVBox" id="vbox6"> <property name="visible">True</property> - <property name="do_overwrite_confirmation">True</property> - <signal name="file_set" handler="on_filechooserbutton1_file_set"/> - </widget> - <packing> - <property name="x">342</property> - <property name="y">16</property> - </packing> - </child> - <child> - <widget class="GtkButton" id="button1"> - <property name="label" translatable="yes">Restart</property> - <property name="width_request">60</property> - <property name="height_request">29</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <signal name="clicked" handler="on_button1_clicked"/> - </widget> - <packing> - <property name="x">721</property> - <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"/> + <property name="can_focus">False</property> + <property name="resize_mode">immediate</property> <child> - <widget class="GtkImage" id="image1"> - <property name="width_request">505</property> - <property name="height_request">84</property> + <object class="GtkScrolledWindow" id="log_scrolled"> <property name="visible">True</property> - </widget> + <property name="can_focus">True</property> + <property name="window_placement_set">True</property> + <child> + <object class="GtkTextView" id="log_text"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="wrap_mode">word</property> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> </child> - </widget> + </object> <packing> - <property name="x">16</property> - <property name="y">75</property> + <property name="position">3</property> </packing> </child> - </widget> - </child> - </widget> - <widget class="GtkWindow" id="window2"> - <property name="width_request">470</property> - <property name="height_request">190</property> - <property name="title" translatable="yes">Device selection</property> - <property name="resizable">False</property> - <property name="modal">True</property> - <property name="window_position">center</property> - <property name="destroy_with_parent">True</property> - <property name="type_hint">dialog</property> - <property name="urgency_hint">True</property> - <property name="deletable">False</property> - <property name="transient_for">window1</property> - <child> - <widget class="GtkFixed" id="fixed1"> - <property name="visible">True</property> - <child> - <widget class="GtkTreeView" id="treeview1"> - <property name="width_request">440</property> - <property name="height_request">84</property> + <child type="tab"> + <object class="GtkLabel" id="log_label"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="enable_grid_lines">horizontal</property> - <signal name="row_activated" handler="on_treeview1_row_activated"/> - </widget> + <property name="can_focus">False</property> + <property name="label" translatable="yes">Log</property> + </object> <packing> - <property name="x">15</property> - <property name="y">52</property> + <property name="position">3</property> + <property name="tab_fill">False</property> </packing> </child> - <child> - <widget class="GtkButton" id="button3"> - <property name="label" translatable="yes">OK</property> - <property name="width_request">90</property> - <property name="height_request">29</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <signal name="clicked" handler="on_button3_clicked"/> - </widget> - <packing> - <property name="x">365</property> - <property name="y">149</property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label1"> - <property name="width_request">416</property> - <property name="height_request">30</property> - <property name="visible">True</property> - <property name="label" translatable="yes">Select device to use.</property> - </widget> - <packing> - <property name="x">23</property> - <property name="y">12</property> - </packing> - </child> - </widget> + </object> </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="eventbox... [truncated message content] |
From: <la...@us...> - 2011-07-27 13:51:41
|
Revision: 57 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=57&view=rev Author: laserb Date: 2011-07-27 13:51:33 +0000 (Wed, 27 Jul 2011) Log Message: ----------- + Display infos about devices in corresponding tab + Display log in tab instead of terminal + Added program icon, needs to be improved, feel free to change it if you have a better idea Modified Paths: -------------- trunk/PyCodeOCR.py trunk/utils/__init__.py trunk/utils/ocr.py Added Paths: ----------- trunk/PyCodeOCR.png trunk/PyCodeOCR.svg trunk/utils/logging.py Added: trunk/PyCodeOCR.png =================================================================== (Binary files differ) Property changes on: trunk/PyCodeOCR.png ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-07-27 07:36:33 UTC (rev 56) +++ trunk/PyCodeOCR.py 2011-07-27 13:51:33 UTC (rev 57) @@ -122,15 +122,6 @@ "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) -## redirect print to textbuffer instead of shell -class logging: - def __init__(self, textbuffer): - self.textbuffer = textbuffer - - def write(self, text): - enditer = self.textbuffer.get_end_iter() - self.textbuffer.insert(enditer,"%s" % text ) - ## MainWindow # The GUI was created/designed using GLADE # @@ -181,6 +172,7 @@ # get objects from glade/GTKBuilder ## main window self.main_window = self.builder.get_object('main_window') + self.main_window.set_icon_from_file(raw_path+".png") ## notebok self.notebook = self.builder.get_object('notebook') ## image window @@ -201,7 +193,7 @@ self.output = self.builder.get_object('output') self.log_text = self.builder.get_object('log_text') self.textbuffer = self.log_text.get_buffer() - self.entry3 = self.builder.get_object('device_info_text') + self.device_info_text = self.builder.get_object('device_info_text') ## progressbar self.progressbar = self.builder.get_object('progressbar') ## Orientation label @@ -269,9 +261,9 @@ # redirect print - self.logging = logging(self.textbuffer) -# sys.stdout = self.logging -# sys.stderr = self.logging + self.logging = utils.logging(self.textbuffer) + sys.stdout = self.logging + sys.stderr = self.logging # initialize treeviews in Blacklist Manager @@ -294,8 +286,10 @@ self.device_chooser_event = threading.Event() ## initialize sane - self.run_sane = utils.ocr.RunSANE(self.notebook, self.progress, self.device_chooser_button, BlacklistMgr,self.device_chooser_event) + self.run_sane = utils.ocr.RunSANE(self.notebook, self.progress, self.device_chooser_button, BlacklistMgr,self.device_chooser_event,self.device_info_text) self.run_sane.start() + # redirect print again to old textbuffer + sys.stdout = self.logging gtk.main() Added: trunk/PyCodeOCR.svg =================================================================== --- trunk/PyCodeOCR.svg (rev 0) +++ trunk/PyCodeOCR.svg 2011-07-27 13:51:33 UTC (rev 57) @@ -0,0 +1,739 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.0" + width="96" + height="96" + id="svg2408" + inkscape:version="0.48.2 r9819" + sodipodi:docname="pyCodeOCR.svg"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1676" + inkscape:window-height="993" + id="namedview60" + showgrid="false" + inkscape:zoom="2.4583333" + inkscape:cx="-19.728814" + inkscape:cy="48" + inkscape:window-x="0" + inkscape:window-y="26" + inkscape:window-maximized="0" + inkscape:current-layer="svg2408" /> + <defs + id="defs2410"> + <inkscape:path-effect + effect="envelope" + id="path-effect5517" + is_visible="true" + yy="true" + xx="true" + bendpath1="m -104.1387,-70.660316 92.329171,0" + bendpath2="m -11.809529,-70.660316 0,49.999931" + bendpath3="m -104.1387,-20.660385 92.329171,0" + bendpath4="m -104.1387,-70.660316 0,49.999931" /> + <linearGradient + id="linearGradient5503"> + <stop + style="stop-color:#000000;stop-opacity:0.77631581;" + offset="0" + id="stop5505" /> + <stop + id="stop5515" + offset="0.71120352" + style="stop-color:#000000;stop-opacity:0.9868421;" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop5507" /> + </linearGradient> + <inkscape:path-effect + effect="envelope" + id="path-effect5493" + is_visible="true" + yy="true" + xx="true" + bendpath1="m -102.95333,-67.077292 c 48.568167,-40.285028 53.09126,32.208086 91.045264,42.239695" + bendpath2="m -11.908066,-24.837597 0,4.254275" + bendpath3="m -103.44693,-56.118303 c 29.104665,-13.697544 33.638272,46.9089172 91.538864,35.534981" + bendpath4="m -104.9277,-73.111534 0.98718,7.606632" + bendpath1-nodetypes="cc" + bendpath3-nodetypes="cc" + bendpath4-nodetypes="cc" /> + <inkscape:path-effect + effect="envelope" + id="path-effect5491" + is_visible="true" + yy="true" + xx="false" + bendpath1="m -106.37629,-68.427295 c 33.66968,1.169568 1.67227,76.0227568 89.632807,8.045656" + bendpath2="m -11.807562,-68.427295 0,48.744647" + bendpath3="m -106.37629,-19.682648 94.568728,0" + bendpath4="m -106.37629,-68.427295 0,48.744647" + bendpath1-nodetypes="cc" /> + <inkscape:path-effect + effect="bend_path" + id="path-effect5473" + is_visible="true" + bendpath="m -105.42129,-42.824599 c 44.735743,-67.438381 45.978505,32.051229 93.513224,20.11414" + prop_scale="1" + scale_y_rel="false" + vertical="false" + bendpath-nodetypes="cc" /> + <linearGradient + inkscape:collect="always" + id="linearGradient5350"> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop5352" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop5354" /> + </linearGradient> + <linearGradient + id="linearGradient3731"> + <stop + id="stop3733" + style="stop-color:#dcdcdc;stop-opacity:1" + offset="0" /> + <stop + id="stop3757" + style="stop-color:#ebebeb;stop-opacity:1" + offset="0.30654153" /> + <stop + id="stop3737" + style="stop-color:#ffffff;stop-opacity:1" + offset="0.70706075" /> + <stop + id="stop3759" + style="stop-color:#fafafa;stop-opacity:1" + offset="0.84501493" /> + <stop + id="stop3735" + style="stop-color:#f0f0f0;stop-opacity:1" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient2881"> + <stop + id="stop2883" + style="stop-color:#e4a033;stop-opacity:0.55263156;" + offset="0" /> + <stop + id="stop2885" + style="stop-color:#f08230;stop-opacity:1;" + offset="1" /> + </linearGradient> + <linearGradient + x1="45.447727" + y1="92.539597" + x2="45.447727" + y2="7.0165396" + id="ButtonShadow" + gradientUnits="userSpaceOnUse" + gradientTransform="scale(1.0058652,0.994169)"> + <stop + id="stop3750" + style="stop-color:#000000;stop-opacity:1" + offset="0" /> + <stop + id="stop3752" + style="stop-color:#000000;stop-opacity:0.58823532" + offset="1" /> + </linearGradient> + <linearGradient + id="linearGradient3737"> + <stop + id="stop3739" + style="stop-color:#ffffff;stop-opacity:1" + offset="0" /> + <stop + id="stop3741" + style="stop-color:#ffffff;stop-opacity:0" + offset="1" /> + </linearGradient> + <filter + color-interpolation-filters="sRGB" + id="filter3174"> + <feGaussianBlur + id="feGaussianBlur3176" + stdDeviation="1.71" /> + </filter> + <linearGradient + x1="36.357143" + y1="6" + x2="36.357143" + y2="63.893143" + id="linearGradient3188" + xlink:href="#linearGradient3737" + gradientUnits="userSpaceOnUse" /> + <filter + x="-0.192" + y="-0.192" + width="1.3839999" + height="1.3839999" + color-interpolation-filters="sRGB" + id="filter3794"> + <feGaussianBlur + id="feGaussianBlur3796" + stdDeviation="5.28" /> + </filter> + <linearGradient + x1="48" + y1="20.220806" + x2="48" + y2="138.66119" + id="linearGradient3613" + xlink:href="#linearGradient3737" + gradientUnits="userSpaceOnUse" /> + <radialGradient + cx="48" + cy="90.171875" + r="42" + fx="48" + fy="90.171875" + id="radialGradient3619" + xlink:href="#linearGradient3737" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.5510206,0.19713193)" /> + <clipPath + id="clipPath3613"> + <rect + width="84" + height="84" + rx="6" + ry="6" + x="6" + y="6" + id="rect3615" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /> + </clipPath> + <linearGradient + x1="48" + y1="90" + x2="48" + y2="5.9877172" + id="linearGradient3617" + xlink:href="#linearGradient2881" + gradientUnits="userSpaceOnUse" /> + <linearGradient + x1="45.447727" + y1="92.539597" + x2="45.447727" + y2="7.0165396" + id="ButtonShadow-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0058652,0,0,0.994169,100,0)"> + <stop + id="stop3750-8" + style="stop-color:#000000;stop-opacity:1" + offset="0" /> + <stop + id="stop3752-5" + style="stop-color:#000000;stop-opacity:0.58823532" + offset="1" /> + </linearGradient> + <linearGradient + x1="32.251034" + y1="6.1317081" + x2="32.251034" + y2="90.238609" + id="linearGradient3780" + xlink:href="#ButtonShadow-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" /> + <linearGradient + x1="32.251034" + y1="6.1317081" + x2="32.251034" + y2="90.238609" + id="linearGradient3772" + xlink:href="#ButtonShadow-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" /> + <linearGradient + x1="32.251034" + y1="6.1317081" + x2="32.251034" + y2="90.238609" + id="linearGradient3725" + xlink:href="#ButtonShadow-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" /> + <linearGradient + x1="32.251034" + y1="6.1317081" + x2="32.251034" + y2="90.238609" + id="linearGradient3721" + xlink:href="#ButtonShadow-0" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(0,-97)" /> + <linearGradient + x1="32.251034" + y1="6.1317081" + x2="32.251034" + y2="90.238609" + id="linearGradient2918" + xlink:href="#ButtonShadow-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" /> + <linearGradient + x1="6.6201301" + y1="16.384687" + x2="6.6201301" + y2="1.0923122" + id="linearGradient3053" + xlink:href="#linearGradient3731" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-4.5057883,0,0,3.8842887,81.128906,14.057144)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2881" + id="linearGradient5255" + x1="6" + y1="48" + x2="90" + y2="48" + gradientUnits="userSpaceOnUse" + spreadMethod="pad" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2881" + id="linearGradient5269" + gradientUnits="userSpaceOnUse" + spreadMethod="pad" + x1="6" + y1="48" + x2="90" + y2="48" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2881" + id="linearGradient5271" + gradientUnits="userSpaceOnUse" + spreadMethod="pad" + x1="6" + y1="48" + x2="90" + y2="48" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2881" + id="linearGradient5273" + gradientUnits="userSpaceOnUse" + spreadMethod="pad" + x1="6" + y1="48" + x2="90" + y2="48" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5350" + id="linearGradient5356" + x1="6" + y1="48" + x2="90" + y2="48" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5350" + id="linearGradient5374" + gradientUnits="userSpaceOnUse" + x1="6" + y1="48" + x2="90" + y2="48" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5350" + id="linearGradient5376" + gradientUnits="userSpaceOnUse" + x1="6" + y1="48" + x2="90" + y2="48" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5350" + id="linearGradient5378" + gradientUnits="userSpaceOnUse" + x1="6" + y1="48" + x2="90" + y2="48" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient5503" + id="linearGradient5513" + x1="-11.340742" + y1="-44.44244" + x2="-105.09332" + y2="-43.771969" + gradientUnits="userSpaceOnUse" /> + </defs> + <metadata + id="metadata2413"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer2" + style="display:none"> + <rect + width="86" + height="85" + rx="6" + ry="6" + x="5" + y="7" + id="rect3745" + style="opacity:0.9;fill:url(#ButtonShadow);fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3174)" /> + </g> + <g + id="layer7" + style="display:inline" + transform="translate(0.4067798,-1.6271182)"> + <path + d="m 12,-95.03125 c -5.5110903,0 -10.03125,4.52016 -10.03125,10.03125 l 0,71 c 0,5.5110902 4.5201598,10.03125 10.03125,10.03125 l 72,0 c 5.51109,0 10.03125,-4.5201597 10.03125,-10.03125 l 0,-71 c 0,-5.51109 -4.52016,-10.03125 -10.03125,-10.03125 l -72,0 z" + transform="scale(1,-1)" + id="path3786" + style="opacity:0.07999998;fill:url(#linearGradient2918);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + inkscape:connector-curvature="0" /> + <path + d="m 12,-94.03125 c -4.971633,0 -9.03125,4.059617 -9.03125,9.03125 l 0,71 c 0,4.9716329 4.0596171,9.03125 9.03125,9.03125 l 72,0 c 4.971633,0 9.03125,-4.059617 9.03125,-9.03125 l 0,-71 c 0,-4.971633 -4.059617,-9.03125 -9.03125,-9.03125 l -72,0 z" + transform="scale(1,-1)" + id="path3778" + style="opacity:0.1;fill:url(#linearGradient3780);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + inkscape:connector-curvature="0" /> + <path + d="m 12,-93 c -4.4091333,0 -8,3.590867 -8,8 l 0,71 c 0,4.4091333 3.5908667,8 8,8 l 72,0 c 4.409133,0 8,-3.5908667 8,-8 l 0,-71 c 0,-4.409133 -3.590867,-8 -8,-8 l -72,0 z" + transform="scale(1,-1)" + id="path3770" + style="opacity:0.2;fill:url(#linearGradient3772);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + inkscape:connector-curvature="0" /> + <rect + width="86" + height="85" + rx="7" + ry="7" + x="5" + y="-92" + transform="scale(1,-1)" + id="rect3723" + style="opacity:0.3;fill:url(#linearGradient3725);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" /> + <rect + width="84" + height="84" + rx="6" + ry="6" + x="6" + y="-91" + transform="scale(1,-1)" + id="rect3716" + style="opacity:0.45;fill:url(#linearGradient3721);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" /> + </g> + <rect + style="fill:#f2f2f2;fill-opacity:0.98058256;fill-rule:nonzero;stroke:none" + id="rect5384" + width="83.389839" + height="83.796608" + x="6.9152541" + y="5.6949153" + rx="6.6329193" + ry="4.1945705" /> + <g + id="layer1" + style="fill:url(#linearGradient5255);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + transform="matrix(0.00204918,-0.66276636,0.9999979,0.00135813,0.71530508,92.720005)"> + <rect + width="84" + height="84" + rx="6" + ry="6" + x="6" + y="6" + id="rect2419" + style="fill:url(#linearGradient5269);fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <path + d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,2 0,68 0,2 c 0,0.334721 0.04135,0.6507 0.09375,0.96875 0.0487,0.295596 0.09704,0.596915 0.1875,0.875 0.00988,0.03038 0.020892,0.0636 0.03125,0.09375 0.098865,0.287771 0.2348802,0.547452 0.375,0.8125 0.1445918,0.273507 0.3156161,0.535615 0.5,0.78125 0.1843839,0.245635 0.3737765,0.473472 0.59375,0.6875 0.439947,0.428056 0.94291,0.814526 1.5,1.09375 0.278545,0.139612 0.5734731,0.246947 0.875,0.34375 -0.2562018,-0.100222 -0.4867109,-0.236272 -0.71875,-0.375 -0.00741,-0.0044 -0.023866,0.0045 -0.03125,0 -0.031933,-0.0193 -0.062293,-0.04251 -0.09375,-0.0625 -0.120395,-0.0767 -0.2310226,-0.163513 -0.34375,-0.25 -0.1061728,-0.0808 -0.2132809,-0.161112 -0.3125,-0.25 C 8.4783201,88.557317 8.3087904,88.373362 8.15625,88.1875 8.0486711,88.057245 7.9378561,87.922215 7.84375,87.78125 7.818661,87.74287 7.805304,87.69538 7.78125,87.65625 7.716487,87.553218 7.6510225,87.451733 7.59375,87.34375 7.4927417,87.149044 7.3880752,86.928049 7.3125,86.71875 7.30454,86.69694 7.288911,86.6782 7.28125,86.65625 7.2494249,86.5643 7.2454455,86.469419 7.21875,86.375 7.1884177,86.268382 7.1483606,86.171969 7.125,86.0625 7.0521214,85.720988 7,85.364295 7,85 L 7,83 7,15 7,13 C 7,10.218152 9.2181517,8 12,8 l 2,0 68,0 2,0 c 2.781848,0 5,2.218152 5,5 l 0,2 0,68 0,2 c 0,0.364295 -0.05212,0.720988 -0.125,1.0625 -0.04415,0.206893 -0.08838,0.397658 -0.15625,0.59375 -0.0077,0.02195 -0.0233,0.04069 -0.03125,0.0625 -0.06274,0.173739 -0.138383,0.367449 -0.21875,0.53125 -0.04158,0.0828 -0.07904,0.169954 -0.125,0.25 -0.0546,0.09721 -0.126774,0.18835 -0.1875,0.28125 -0.09411,0.140965 -0.204921,0.275995 -0.3125,0.40625 -0.143174,0.17445 -0.303141,0.346998 -0.46875,0.5 -0.01117,0.0102 -0.01998,0.02115 -0.03125,0.03125 -0.138386,0.125556 -0.285091,0.234436 -0.4375,0.34375 -0.102571,0.07315 -0.204318,0.153364 -0.3125,0.21875 -0.0074,0.0045 -0.02384,-0.0044 -0.03125,0 -0.232039,0.138728 -0.462548,0.274778 -0.71875,0.375 0.301527,-0.0968 0.596455,-0.204138 0.875,-0.34375 0.55709,-0.279224 1.060053,-0.665694 1.5,-1.09375 0.219973,-0.214028 0.409366,-0.441865 0.59375,-0.6875 0.184384,-0.245635 0.355408,-0.507743 0.5,-0.78125 0.14012,-0.265048 0.276135,-0.524729 0.375,-0.8125 0.01041,-0.03078 0.02133,-0.06274 0.03125,-0.09375 0.09046,-0.278085 0.1388,-0.579404 0.1875,-0.875 C 89.95865,84.6507 90,84.334721 90,84 l 0,-2 0,-68 0,-2 C 90,8.676 87.324,6 84,6 L 12,6 z" + inkscape:connector-curvature="0" + id="rect3728" + style="opacity:0.4;fill:url(#linearGradient5271);fill-opacity:1;fill-rule:nonzero;stroke:none" /> + <path + d="M 12,90 C 8.676,90 6,87.324 6,84 L 6,82 6,14 6,12 c 0,-0.334721 0.04135,-0.6507 0.09375,-0.96875 0.0487,-0.295596 0.09704,-0.596915 0.1875,-0.875 C 6.29113,10.12587 6.302142,10.09265 6.3125,10.0625 6.411365,9.774729 6.5473802,9.515048 6.6875,9.25 6.8320918,8.976493 7.0031161,8.714385 7.1875,8.46875 7.3718839,8.223115 7.5612765,7.995278 7.78125,7.78125 8.221197,7.353194 8.72416,6.966724 9.28125,6.6875 9.559795,6.547888 9.8547231,6.440553 10.15625,6.34375 9.9000482,6.443972 9.6695391,6.580022 9.4375,6.71875 c -0.00741,0.0044 -0.023866,-0.0045 -0.03125,0 -0.031933,0.0193 -0.062293,0.04251 -0.09375,0.0625 -0.120395,0.0767 -0.2310226,0.163513 -0.34375,0.25 -0.1061728,0.0808 -0.2132809,0.161112 -0.3125,0.25 C 8.4783201,7.442683 8.3087904,7.626638 8.15625,7.8125 8.0486711,7.942755 7.9378561,8.077785 7.84375,8.21875 7.818661,8.25713 7.805304,8.30462 7.78125,8.34375 7.716487,8.446782 7.6510225,8.548267 7.59375,8.65625 7.4927417,8.850956 7.3880752,9.071951 7.3125,9.28125 7.30454,9.30306 7.288911,9.3218 7.28125,9.34375 7.2494249,9.4357 7.2454455,9.530581 7.21875,9.625 7.1884177,9.731618 7.1483606,9.828031 7.125,9.9375 7.0521214,10.279012 7,10.635705 7,11 l 0,2 0,68 0,2 c 0,2.781848 2.2181517,5 5,5 l 2,0 68,0 2,0 c 2.781848,0 5,-2.218152 5,-5 l 0,-2 0,-68 0,-2 C 89,10.635705 88.94788,10.279012 88.875,9.9375 88.83085,9.730607 88.78662,9.539842 88.71875,9.34375 88.71105,9.3218 88.69545,9.30306 88.6875,9.28125 88.62476,9.107511 88.549117,8.913801 88.46875,8.75 88.42717,8.6672 88.38971,8.580046 88.34375,8.5 88.28915,8.40279 88.216976,8.31165 88.15625,8.21875 88.06214,8.077785 87.951329,7.942755 87.84375,7.8125 87.700576,7.63805 87.540609,7.465502 87.375,7.3125 87.36383,7.3023 87.35502,7.29135 87.34375,7.28125 87.205364,7.155694 87.058659,7.046814 86.90625,6.9375 86.803679,6.86435 86.701932,6.784136 86.59375,6.71875 c -0.0074,-0.0045 -0.02384,0.0044 -0.03125,0 -0.232039,-0.138728 -0.462548,-0.274778 -0.71875,-0.375 0.301527,0.0968 0.596455,0.204138 0.875,0.34375 0.55709,0.279224 1.060053,0.665694 1.5,1.09375 0.219973,0.214028 0.409366,0.441865 0.59375,0.6875 0.184384,0.245635 0.355408,0.507743 0.5,0.78125 0.14012,0.265048 0.276135,0.524729 0.375,0.8125 0.01041,0.03078 0.02133,0.06274 0.03125,0.09375 0.09046,0.278085 0.1388,0.579404 0.1875,0.875 C 89.95865,11.3493 90,11.665279 90,12 l 0,2 0,68 0,2 c 0,3.324 -2.676,6 -6,6 l -72,0 z" + inkscape:connector-curvature="0" + id="path3615" + style="opacity:0.2;fill:url(#linearGradient5273);fill-opacity:1;fill-rule:nonzero;stroke:none" /> + </g> + <path + style="fill:#666666;stroke:#666666;stroke-width:1.10000001999999997;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1.10000000000000009, 1.10000000000000009;stroke-dashoffset:0;fill-opacity:0.97734630000000000" + d="m 47.59322,32.542373 0,36.610169" + id="path5521" + inkscape:connector-curvature="0" /> + <g + id="layer5" + style="display:none"> + <rect + width="66" + height="66" + rx="12" + ry="12" + x="15" + y="15" + clip-path="url(#clipPath3613)" + id="rect3171" + style="opacity:0.1;fill:url(#linearGradient3613);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3794)" /> + </g> + <rect + style="fill:#ececec;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="rect5283" + width="69.559624" + height="19.525425" + x="20.745771" + y="69.152542" + rx="6.7946978" + ry="4.2352943" /> + <g + transform="matrix(0.00204918,-0.66276636,0.9999979,0.00135813,-0.09825424,93.533564)" + style="fill:#f9f9f9;fill-opacity:0;fill-rule:nonzero;stroke:url(#linearGradient5356);stroke-opacity:1;display:inline" + id="g5342"> + <rect + style="fill:#f9f9f9;fill-opacity:0;fill-rule:nonzero;stroke:url(#linearGradient5374);stroke-opacity:1" + id="rect5344" + y="6" + x="6" + ry="6" + rx="6" + height="84" + width="84" /> + <path + style="opacity:0.4;fill:#f9f9f9;fill-opacity:0;fill-rule:nonzero;stroke:url(#linearGradient5376);stroke-opacity:1" + id="path5346" + inkscape:connector-curvature="0" + d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,2 0,68 0,2 c 0,0.334721 0.04135,0.6507 0.09375,0.96875 0.0487,0.295596 0.09704,0.596915 0.1875,0.875 0.00988,0.03038 0.020892,0.0636 0.03125,0.09375 0.098865,0.287771 0.2348802,0.547452 0.375,0.8125 0.1445918,0.273507 0.3156161,0.535615 0.5,0.78125 0.1843839,0.245635 0.3737765,0.473472 0.59375,0.6875 0.439947,0.428056 0.94291,0.814526 1.5,1.09375 0.278545,0.139612 0.5734731,0.246947 0.875,0.34375 -0.2562018,-0.100222 -0.4867109,-0.236272 -0.71875,-0.375 -0.00741,-0.0044 -0.023866,0.0045 -0.03125,0 -0.031933,-0.0193 -0.062293,-0.04251 -0.09375,-0.0625 -0.120395,-0.0767 -0.2310226,-0.163513 -0.34375,-0.25 -0.1061728,-0.0808 -0.2132809,-0.161112 -0.3125,-0.25 C 8.4783201,88.557317 8.3087904,88.373362 8.15625,88.1875 8.0486711,88.057245 7.9378561,87.922215 7.84375,87.78125 7.818661,87.74287 7.805304,87.69538 7.78125,87.65625 7.716487,87.553218 7.6510225,87.451733 7.59375,87.34375 7.4927417,87.149044 7.3880752,86.928049 7.3125,86.71875 7.30454,86.69694 7.288911,86.6782 7.28125,86.65625 7.2494249,86.5643 7.2454455,86.469419 7.21875,86.375 7.1884177,86.268382 7.1483606,86.171969 7.125,86.0625 7.0521214,85.720988 7,85.364295 7,85 L 7,83 7,15 7,13 C 7,10.218152 9.2181517,8 12,8 l 2,0 68,0 2,0 c 2.781848,0 5,2.218152 5,5 l 0,2 0,68 0,2 c 0,0.364295 -0.05212,0.720988 -0.125,1.0625 -0.04415,0.206893 -0.08838,0.397658 -0.15625,0.59375 -0.0077,0.02195 -0.0233,0.04069 -0.03125,0.0625 -0.06274,0.173739 -0.138383,0.367449 -0.21875,0.53125 -0.04158,0.0828 -0.07904,0.169954 -0.125,0.25 -0.0546,0.09721 -0.126774,0.18835 -0.1875,0.28125 -0.09411,0.140965 -0.204921,0.275995 -0.3125,0.40625 -0.143174,0.17445 -0.303141,0.346998 -0.46875,0.5 -0.01117,0.0102 -0.01998,0.02115 -0.03125,0.03125 -0.138386,0.125556 -0.285091,0.234436 -0.4375,0.34375 -0.102571,0.07315 -0.204318,0.153364 -0.3125,0.21875 -0.0074,0.0045 -0.02384,-0.0044 -0.03125,0 -0.232039,0.138728 -0.462548,0.274778 -0.71875,0.375 0.301527,-0.0968 0.596455,-0.204138 0.875,-0.34375 0.55709,-0.279224 1.060053,-0.665694 1.5,-1.09375 0.219973,-0.214028 0.409366,-0.441865 0.59375,-0.6875 0.184384,-0.245635 0.355408,-0.507743 0.5,-0.78125 0.14012,-0.265048 0.276135,-0.524729 0.375,-0.8125 0.01041,-0.03078 0.02133,-0.06274 0.03125,-0.09375 0.09046,-0.278085 0.1388,-0.579404 0.1875,-0.875 C 89.95865,84.6507 90,84.334721 90,84 l 0,-2 0,-68 0,-2 C 90,8.676 87.324,6 84,6 L 12,6 z" /> + <path + style="opacity:0.2;fill:#f9f9f9;fill-opacity:0;fill-rule:nonzero;stroke:url(#linearGradient5378);stroke-opacity:1" + id="path5348" + inkscape:connector-curvature="0" + d="M 12,90 C 8.676,90 6,87.324 6,84 L 6,82 6,14 6,12 c 0,-0.334721 0.04135,-0.6507 0.09375,-0.96875 0.0487,-0.295596 0.09704,-0.596915 0.1875,-0.875 C 6.29113,10.12587 6.302142,10.09265 6.3125,10.0625 6.411365,9.774729 6.5473802,9.515048 6.6875,9.25 6.8320918,8.976493 7.0031161,8.714385 7.1875,8.46875 7.3718839,8.223115 7.5612765,7.995278 7.78125,7.78125 8.221197,7.353194 8.72416,6.966724 9.28125,6.6875 9.559795,6.547888 9.8547231,6.440553 10.15625,6.34375 9.9000482,6.443972 9.6695391,6.580022 9.4375,6.71875 c -0.00741,0.0044 -0.023866,-0.0045 -0.03125,0 -0.031933,0.0193 -0.062293,0.04251 -0.09375,0.0625 -0.120395,0.0767 -0.2310226,0.163513 -0.34375,0.25 -0.1061728,0.0808 -0.2132809,0.161112 -0.3125,0.25 C 8.4783201,7.442683 8.3087904,7.626638 8.15625,7.8125 8.0486711,7.942755 7.9378561,8.077785 7.84375,8.21875 7.818661,8.25713 7.805304,8.30462 7.78125,8.34375 7.716487,8.446782 7.6510225,8.548267 7.59375,8.65625 7.4927417,8.850956 7.3880752,9.071951 7.3125,9.28125 7.30454,9.30306 7.288911,9.3218 7.28125,9.34375 7.2494249,9.4357 7.2454455,9.530581 7.21875,9.625 7.1884177,9.731618 7.1483606,9.828031 7.125,9.9375 7.0521214,10.279012 7,10.635705 7,11 l 0,2 0,68 0,2 c 0,2.781848 2.2181517,5 5,5 l 2,0 68,0 2,0 c 2.781848,0 5,-2.218152 5,-5 l 0,-2 0,-68 0,-2 C 89,10.635705 88.94788,10.279012 88.875,9.9375 88.83085,9.730607 88.78662,9.539842 88.71875,9.34375 88.71105,9.3218 88.69545,9.30306 88.6875,9.28125 88.62476,9.107511 88.549117,8.913801 88.46875,8.75 88.42717,8.6672 88.38971,8.580046 88.34375,8.5 88.28915,8.40279 88.216976,8.31165 88.15625,8.21875 88.06214,8.077785 87.951329,7.942755 87.84375,7.8125 87.700576,7.63805 87.540609,7.465502 87.375,7.3125 87.36383,7.3023 87.35502,7.29135 87.34375,7.28125 87.205364,7.155694 87.058659,7.046814 86.90625,6.9375 86.803679,6.86435 86.701932,6.784136 86.59375,6.71875 c -0.0074,-0.0045 -0.02384,0.0044 -0.03125,0 -0.232039,-0.138728 -0.462548,-0.274778 -0.71875,-0.375 0.301527,0.0968 0.596455,0.204138 0.875,0.34375 0.55709,0.279224 1.060053,0.665694 1.5,1.09375 0.219973,0.214028 0.409366,0.441865 0.59375,0.6875 0.184384,0.245635 0.355408,0.507743 0.5,0.78125 0.14012,0.265048 0.276135,0.524729 0.375,0.8125 0.01041,0.03078 0.02133,0.06274 0.03125,0.09375 0.09046,0.278085 0.1388,0.579404 0.1875,0.875 C 89.95865,11.3493 90,11.665279 90,12 l 0,2 0,68 0,2 c 0,3.324 -2.676,6 -6,6 l -72,0 z" /> + </g> + <text + xml:space="preserve" + style="font-size:5.48460484px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="29.985468" + y="64.419136" + id="text5362" + sodipodi:linespacing="125%" + transform="scale(0.82412104,1.213414)"><tspan + sodipodi:role="line" + id="tspan5364" + x="29.985468" + y="64.419136">0101692>48949+120943></tspan></text> + <rect + style="fill:#ffffff;fill-opacity:0;fill-rule:nonzero;stroke:none" + id="rect5382" + width="50.440678" + height="45.559322" + x="8.9491529" + y="-70.372879" + rx="6.7946978" + ry="4.2352943" /> + <path + style="fill:#666666;stroke:#666666;stroke-width:0.85770785999999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:0.85770784000000000, 0.85770784000000000;stroke-dashoffset:0" + d="m 49.686232,45.966102 40.212073,0" + id="path5523" + inkscape:connector-curvature="0" /> + <g + transform="matrix(0.82412104,0,0,1.213414,97.627119,102.91525)" + style="font-size:5.48460484000000026px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient5513);fill-opacity:1;stroke:none;font-family:Sans" + id="text5405" + inkscape:path-effect="#path-effect5493"> + <path + d="m -102.3486,-70.065413 c -0.45372,0.01972 -0.81136,0.0063 -1.05378,0.04878 -0.24241,0.04251 -0.36738,0.152936 -0.38209,0.426998 -0.0147,0.274062 0.0799,0.716251 0.24088,1.303402 0.16097,0.587151 0.3859,1.317012 0.62334,2.032969 0.23743,0.715958 0.48674,1.410212 0.71372,1.867864 0.22698,0.457651 0.43377,0.665863 0.59007,0.509197 0.15629,-0.156666 0.25921,-0.684588 0.2753,-1.435203 0.0161,-0.750616 -0.0704,-1.698643 -0.15162,-2.551591 -0.0744,-0.544877 -0.0982,-1.107003 -0.16086,-1.505832 -0.0313,-0.199415 -0.0785,-0.36383 -0.18077,-0.480625 -0.10222,-0.116795 -0.2608,-0.18176 -0.51419,-0.215963 z m 0.25246,-0.200276 c 0.3643,-0.03372 0.61181,-0.0097 0.78331,0.135798 0.17149,0.145511 0.26769,0.401743 0.33684,0.729627 0.0692,0.327884 0.11415,0.721262 0.16434,1.184263 0.0502,0.463001 0.10628,1.002771 0.14454,1.656831 0.0383,0.654059 0.0541,1.432502 0.002,2.261356 -0.0521,0.828854 -0.17491,1.70611 -0.37233,2.374369 -0.19741,0.668259 -0.46462,1.109757 -0.78227,1.036931 -0.31764,-0.07283 -0.68325,-0.681403 -1.12517,-1.833316 -0.34724,-1.416806 -0.70833,-3.195186 -0.99211,-4.541296 -0.14189,-0.673056 -0.26104,-1.246707 -0.33804,-1.690553 -0.077,-0.443846 -0.11125,-0.758514 -0.0914,-0.962121 0.0396,-0.407213 0.30894,-0.369275 0.73086,-0.321988 0.21095,0.02364 0.45627,0.04678 0.71776,0.04231 0.26148,-0.0045 0.53846,-0.03768 0.82175,-0.07221 z" + id="path5410" + inkscape:connector-curvature="0" + inkscape:original-d="m -86.239658,-24.372847 c -2.477575,0.958443 0.730416,5.393411 0.840902,1.646989 -0.01991,-0.587284 -0.02836,-1.6044 -0.840902,-1.646989 z m 0,-0.428484 c 2.375792,0.132605 1.593431,5.411682 -0.830524,3.850002 -0.855804,-0.995242 -0.913988,-3.76136 0.830524,-3.850002 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -98.871161,-62.850536 c 0.403376,0.444676 0.663939,0.530381 0.818552,0.365481 0.154614,-0.1649 0.201563,-0.568953 0.182143,-1.040166 -0.01942,-0.471213 -0.10453,-1.004791 -0.197583,-1.497569 -0.09305,-0.492779 -0.191891,-0.948048 -0.248156,-1.336456 -0.0855,-0.308796 -0.112433,-0.682137 -0.09422,-1.060931 0.01822,-0.378795 0.08342,-0.775204 0.130195,-1.145616 0.04677,-0.370413 0.07076,-0.712358 -0.0215,-0.883565 -0.09226,-0.171208 -0.305187,-0.145669 -0.696043,0.06445 -0.33417,-0.09431 -0.437153,-0.223187 -0.389569,-0.370476 0.04758,-0.147288 0.246395,-0.321725 0.509577,-0.521299 0.263182,-0.199573 0.589928,-0.428753 0.889798,-0.590629 0.299869,-0.161876 0.57289,-0.244511 0.732565,-0.102952 -0.120107,0.865797 -0.246593,1.605792 -0.331876,2.253928 -0.08528,0.648136 -0.127819,1.206733 -0.107544,1.774224 0.04055,1.134982 0.366274,2.334348 0.678328,4.515853 0.326807,-0.21838 0.605034,-0.12005 0.816602,0.108297 0.211568,0.228347 0.355358,0.603719 0.40271,0.998989 0.04735,0.39527 -0.0035,0.813807 -0.168165,1.032345 -0.164676,0.218538 -0.439853,0.219247 -0.836616,-0.209939 -0.330307,-0.416656 -0.860114,-0.04721 -1.298736,-0.06243 -0.219311,-0.0076 -0.413889,-0.123743 -0.550036,-0.486872 -0.136146,-0.363128 -0.214278,-0.987948 -0.220396,-1.804661 -1e-5,-2e-6 -2.1e-5,-5e-6 -3.2e-5,-7e-6 z" + id="path5412" + inkscape:connector-curvature="0" + inkscape:original-d="m -83.810685,-21.185991 c 1.117055,0.363473 0.902637,-0.604528 0.88375,-1.376997 -0.148257,-0.585453 0.437231,-2.066419 -0.613687,-1.5502 -1.071243,-0.127671 0.522204,-0.847199 1.109057,-0.615837 0.094,1.10042 0.01332,2.375527 0.04024,3.543034 1.11822,-0.3247 1.113098,0.759261 0.0075,0.455265 -0.453194,-0.151724 -1.701327,0.387829 -1.426835,-0.455265 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -93.22695,-70.249588 c -0.477876,0.584656 -0.859601,1.262734 -1.133538,1.890921 -0.273937,0.628187 -0.436678,1.213239 -0.479122,1.761003 -0.04244,0.547764 0.03672,1.066137 0.204051,1.59707 0.167334,0.530933 0.420223,1.080728 0.693644,1.616983 0.273422,0.536254 0.56498,1.056463 0.82211,1.416395 0.25713,0.359932 0.481878,0.544117 0.635761,0.435983 0.153882,-0.108134 0.231938,-0.51152 0.211615,-1.113372 -0.01016,-0.300927 -0.0443,-0.64632 -0.08892,-1.031382 -0.04462,-0.385062 -0.09967,-0.804917 -0.131854,-1.321954 -0.03238,-0.32739 -0.04851,-0.725425 -0.05141,-1.195332 -0.0029,-0.469907 0.0074,-1.018744 -0.0029,-1.595708 -0.01024,-0.576963 -0.04324,-1.181182 -0.143532,-1.650744 -0.100289,-0.469563 -0.268389,-0.789172 -0.535941,-0.809863 z m 0.222831,-2.198889 c 0.39294,-0.03255 0.680356,0.463129 0.869667,1.254862 0.189311,0.791733 0.277682,1.844639 0.317921,2.826347 0.04024,0.981708 0.03909,1.881744 0.06015,2.634793 0.02106,0.753049 0.06777,1.377006 0.123407,2.000819 0.05564,0.623813 0.113629,1.266426 0.103965,1.943973 -0.0097,0.677547 -0.0919,1.385758 -0.267771,1.904888 -0.175875,0.51913 -0.438947,0.824133 -0.77428,0.697419 -0.335332,-0.126714 -0.741943,-0.698278 -1.253158,-1.601243 -0.187938,-0.48693 -0.380271,-1.012714 -0.567609,-1.523618 0,0 0,-10e-7 0,-10e-7 -0.25112,-0.684374 -0.492649,-1.337488 -0.681708,-1.926879 -0.18906,-0.58939 -0.322973,-1.119207 -0.371044,-1.63943 -0.04807,-0.520223 -0.0099,-1.036622 0.107851,-1.603898 0.117702,-0.567277 0.312795,-1.19003 0.554602,-1.847755 0.233663,-0.635435 0.50903,-1.30384 0.807972,-1.880616 0.298942,-0.576776 0.622414,-1.056517 0.970033,-1.239661 z" + id="path5414" + inkscape:connector-curvature="0" + inkscape:original-d="m -79.255356,-24.372847 c -2.477576,0.958443 0.730417,5.393412 0.840901,1.646989 -0.01991,-0.587284 -0.02836,-1.6044 -0.840901,-1.646989 z m 0,-0.428484 c 2.375791,0.132606 1.59343,5.411682 -0.830525,3.850002 -0.855804,-0.995243 -0.913988,-3.761361 0.830525,-3.850002 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -89.645193,-60.315936 c 0.422306,0.475937 0.680346,0.620072 0.825789,0.485356 0.145443,-0.134716 0.175324,-0.528727 0.135348,-0.992703 -0.03997,-0.463976 -0.149331,-0.989274 -0.260168,-1.487853 -0.110836,-0.498578 -0.219756,-0.97888 -0.273563,-1.444612 -0.08463,-0.365161 -0.100744,-0.851184 -0.05571,-1.470247 0.04503,-0.619063 0.152688,-1.397628 0.238311,-2.214331 0.08562,-0.816703 0.142406,-1.661002 0.05913,-2.081047 -0.04164,-0.210023 -0.117946,-0.309321 -0.238819,-0.258896 -0.120873,0.05043 -0.286524,0.252383 -0.502019,0.589031 -0.345531,-0.159895 -0.444327,-0.501635 -0.384779,-0.962512 0.05955,-0.460878 0.278071,-1.053063 0.564975,-1.667365 0.286905,-0.614302 0.642342,-1.2523 0.970378,-1.640275 0.328035,-0.387975 0.628907,-0.500542 0.795545,-0.06828 -0.165213,2.319152 -0.366762,4.147491 -0.519549,5.573438 -0.152788,1.425947 -0.254474,2.454808 -0.265449,3.303337 -0.01098,0.848528 0.06917,1.522434 0.213388,2.282603 0.144218,0.760169 0.350816,1.611412 0.535948,2.778938 0.08352,-0.04667 0.164221,-0.06945 0.24169,-0.07321 0.49741,-0.02373 0.862967,0.724711 0.943922,1.527785 0.04048,0.401537 0.0093,0.812775 -0.100701,1.050761 -0.109973,0.237985 -0.295801,0.288381 -0.567486,-0.01369 -0.08225,-0.09141 -0.172588,-0.214012 -0.272113,-0.36833 -0.316302,-0.555301 -0.819618,-0.299817 -1.245887,-0.443533 -0.213135,-0.07186 -0.405529,-0.249032 -0.55039,-0.640246 -0.14486,-0.391213 -0.244041,-1.00545 -0.287755,-1.76411 -1.1e-5,-4e-6 -2.2e-5,-8e-6 -3.3e-5,-1.2e-5 z" + id="path5416" + inkscape:connector-curvature="0" + inkscape:original-d="m -76.826384,-21.185991 c 1.117055,0.363473 0.902637,-0.604528 0.88375,-1.376997 -0.148257,-0.585453 0.437231,-2.066419 -0.613687,-1.5502 -1.071243,-0.127671 0.522204,-0.847199 1.109057,-0.615837 0.094,1.10042 0.01332,2.375527 0.04024,3.543034 1.11822,-0.3247 1.113098,0.759261 0.0075,0.455265 -0.453194,-0.151724 -1.701327,0.387829 -1.426835,-0.455265 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -84.370572,-63.481346 c -0.3502,0.06696 -0.603377,0.275139 -0.761582,0.549043 -0.158204,0.273905 -0.220501,0.613492 -0.202097,0.997506 0.0184,0.384013 0.117237,0.816848 0.262141,1.29586 0.144903,0.479013 0.334257,1.008602 0.529784,1.533309 0.195528,0.524706 0.396513,1.042922 0.581214,1.419915 0.184701,0.376993 0.355063,0.602626 0.496273,0.552903 0.14121,-0.04972 0.253512,-0.382698 0.304483,-0.956642 0.05097,-0.573943 0.03003,-1.359595 -0.04212,-2.260821 -0.06111,-0.695215 -0.209317,-1.411623 -0.40053,-2.016839 -0.191213,-0.605217 -0.439401,-1.08661 -0.767568,-1.114234 z m 2.795805,-10.48319 c -0.139526,1.308249 -0.278217,2.122576 -0.422598,2.693604 -0.144381,0.571027 -0.294898,0.891262 -0.454832,1.091638 -0.319867,0.40075 -0.679369,0.323512 -1.060761,0.419616 -0.190695,0.04805 -0.386319,0.137173 -0.580919,0.327719 -0.194599,0.190546 -0.388407,0.484265 -0.570897,0.905563 -0.182491,0.421299 -0.354418,0.970804 -0.493704,1.616388 -0.139287,0.645584 -0.247078,1.382102 -0.274398,2.14811 -0.03599,0.176742 0.830834,-0.145184 1.5815,0.333513 0.375334,0.239348 0.711185,0.703832 0.933629,1.424239 0.111223,0.360203 0.196347,0.777178 0.260419,1.253244 0.06407,0.476066 0.109112,1.001861 0.13578,1.677838 0.03937,0.825297 0.05727,1.62347 0.02095,2.374662 -0.03632,0.751191 -0.122674,1.438326 -0.240578,1.952151 -0.117904,0.513826 -0.26507,0.849645 -0.42224,0.96559 -0.15717,0.115944 -0.324303,0.01362 -0.498077,-0.263356 -0.347549,-0.553947 -0.732372,-1.788175 -1.161369,-3.015694 -0.214499,-0.613759 -0.438022,-1.226936 -0.652588,-1.799916 -0.214565,-0.572981 -0.419567,-1.105861 -0.587006,-1.609069 0,0 -1e-6,0 -1e-6,-10e-7 -0.21793,-0.654753 -0.370135,-1.258252 -0.399763,-1.932407 -0.02963,-0.674155 0.06421,-1.424627 0.305548,-2.414509 0.156547,-0.642632 0.374218,-1.386936 0.653483,-2.268547 0.572386,-2.504664 1.403613,-5.281584 2.153062,-6.622017 0.374725,-0.670217 0.733375,-0.979861 1.040265,-0.852562 0.306891,0.127299 0.560504,0.691855 0.735093,1.594225 10e-7,-7e-6 2e-6,-1.4e-5 3e-6,-2.2e-5 z" + id="path5418" + inkscape:connector-curvature="0" + inkscape:original-d="m -72.204104,-22.945457 c -2.118425,0.390015 0.538594,3.28804 0.790019,0.931955 0.03935,-0.452898 -0.289167,-0.968876 -0.790019,-0.931955 z m 1.07389,-1.695193 c 0.1729,0.96584 -2.112937,-0.233647 -1.927847,1.406304 -0.03364,0.09804 2.503244,-0.519848 2.187616,1.220846 -0.485936,3.030078 -4.183398,0.14924 -2.507975,-1.917468 0.380529,-0.86151 1.445501,-1.055397 2.248206,-0.70968 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -81.070614,-53.839827 c -0.01256,-0.854791 -0.0043,-1.350925 0.04041,-1.67844 0.04474,-0.327515 0.123718,-0.47881 0.228313,-0.542171 0.209192,-0.126722 0.517748,0.107311 0.820977,0.229467 0.303228,0.122157 0.604555,0.108811 0.804057,-0.416707 0.09975,-0.262759 0.172864,-0.647198 0.204252,-1.146455 0.03139,-0.499256 0.01801,-1.103301 -0.03104,-1.829976 0.01766,-0.180752 -0.732444,-0.08739 -1.479744,-0.640594 -0.37365,-0.276602 -0.756259,-0.699264 -1.013414,-1.383752 -0.128577,-0.342244 -0.224748,-0.747715 -0.249476,-1.291719 -0.02473,-0.544003 0.02082,-1.212845 0.209954,-2.269867 0.158802,-0.92138 0.368287,-1.918451 0.599128,-2.934141 0.230841,-1.01569 0.482876,-2.046357 0.735103,-3.005032 0.504455,-1.917351 1.005531,-3.506927 1.415435,-4.293305 0.409905,-0.786379 0.729775,-0.76876 0.931497,-0.05349 0.201722,0.715269 0.284894,2.100542 0.285609,3.700447 7.15e-4,1.599904 -0.07658,3.388315 -0.161258,4.989485 -0.08468,1.60117 -0.171758,3.009211 -0.234353,4.177791 -0.0626,1.168581 -0.101323,2.112767 -0.16899,3.039082 -0.06767,0.926316 -0.169675,1.857136 -0.389148,2.953677 -0.09007,0.972368 -0.255034,1.917091 -0.462844,2.677415 -0.207809,0.760324 -0.454489,1.324061 -0.700106,1.578793 -0.245617,0.254732 -0.489327,0.199395 -0.719561,-0.139504 -0.230234,-0.338899 -0.448618,-0.95642 -0.6648,-1.721018 0,5e-6 -1e-6,1e-5 -1e-6,1.4e-5 z m 0.990488,-6.806946 c 0.662678,-0.06792 0.962734,-0.783982 1.169536,-2.045477 0.103401,-0.630747 0.183585,-1.411406 0.249638,-2.307123 0.06605,-0.895718 0.117494,-1.910545 0.133887,-2.882439 0.01639,-0.971894 -0.0045,-1.893459 -0.09055,-2.49551 -0.08603,-0.602052 -0.239045,-0.867009 -0.461802,-0.613951 -0.222756,0.253058 -0.517073,1.035651 -0.835873,2.198927 -0.318799,1.163275 -0.664925,2.679754 -0.90265,4.149254 -0.178643,1.136941 -0.160038,2.075812 -0.0055,2.767225 0.154538,0.691413 0.428122,1.168612 0.743309,1.229094 z" + id="path5420" + inkscape:connector-curvature="0" + inkscape:original-d="m -69.919744,-20.813745 c -0.17305,-0.966374 2.111714,0.234823 1.927678,-1.405131 0.03784,-0.109784 -2.504841,0.519138 -2.184769,-1.222019 0.486754,-3.031102 4.179317,-0.145419 2.505295,1.919143 -0.378938,0.863284 -1.446471,1.052241 -2.248204,0.708005 z m 1.076568,-1.695195 c 2.117049,-0.391631 -0.54078,-3.285579 -0.790019,-0.931954 -0.04045,0.45476 0.287407,0.969232 0.790019,0.931954 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -76.633813,-53.083877 c 0.138379,0.43341 0.345139,0.584495 0.578247,0.631313 0.233108,0.04682 0.491163,-0.0013 0.72107,0.06256 0.229907,0.06385 0.433452,0.228586 0.544281,0.741059 0.05541,0.256237 0.08747,0.600403 0.0815,1.094246 -0.006,0.493843 -0.04909,1.134247 -0.157944,2.042394 -0.339314,0.40393 -0.677487,0.299891 -1.01513,-0.01593 -0.337644,-0.315823 -0.679491,-0.825365 -1.024092,-1.199604 -0.178754,-0.194171 -0.357689,-0.353588 -0.534212,-0.437535 -0.02539,-0.0121 -0.05073,-0.02263 -0.07601,-0.03147 0.07426,-1.200777 0.164587,-2.228593 0.272482,-3.115849 0.16988,-1.396832 0.384482,-2.442747 0.643644,-3.321779 0.25163,-0.852894 0.545845,-1.552511 0.864873,-2.30334 0.319029,-0.750829 0.663986,-1.559452 0.988051,-2.586486 0.324066,-1.027033 0.62898,-2.278604 0.816558,-3.77327 0.187579,-1.494667 0.258274,-3.236525 0.04329,-5.024995 -0.56744,1.182979 -0.949069,1.750284 -1.224635,2.021999 0,0 0,0 0,0 -0.240342,0.237069 -0.396797,0.236282 -0.487822,0.07833 -0.09102,-0.157951 -0.115702,-0.476582 -0.08152,-0.91432 0.04966,-0.635745 0.225338,-1.532571 0.502467,-2.534128 0,-10e-7 0,-10e-7 0,-10e-7 0.18644,-0.673832 0.418609,-1.393573 0.681201,-2.06767 0.262593,-0.674096 0.555654,-1.301606 0.855028,-1.752376 0,0 0,0 0,0 0.33034,-0.49736 0.667958,-0.774506 0.971028,-0.651709 0.403096,0.715067 0.56994,1.8938 0.576571,3.263415 0.0066,1.369615 -0.143492,2.920477 -0.360982,4.409005 -0.21749,1.488529 -0.500623,2.911413 -0.786413,4.151678 -0.285791,1.240265 -0.574346,2.300138 -0.840688,3.19571 -0.532684,1.791143 -0.971251,2.952093 -1.379845,4.185657 -0.204297,0.616782 -0.403829,1.25031 -0.601008,1.905485 -0.19718,0.655174 -0.39217,1.330696 -0.569994,1.947585 -2e-6,1e-5 -4e-6,2e-5 -5e-6,3e-5 z" + id="path5422" + inkscape:connector-curvature="0" + inkscape:original-d="m -65.977686,-21.185991 c 0.557154,0.197364 1.938183,-0.429146 1.888011,0.375545 -0.674697,0.18642 -1.695964,0.02627 -2.503632,0.07972 -0.193801,-1.183245 3.434684,-2.751786 1.132481,-3.61534 -1.427069,0.763271 -1.507313,-0.49268 -0.01071,-0.45527 2.843361,0.346404 0.541999,2.725021 -0.506147,3.61534 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -72.205415,-61.672395 c 0.127686,-0.747454 0.273156,-1.371647 0.407584,-1.819861 0.134428,-0.448215 0.257979,-0.719452 0.362157,-0.819555 0.208356,-0.200205 0.336868,0.290785 0.446722,0.991179 0.109855,0.700394 0.210751,1.579061 0.339881,2.267415 0.129131,0.688354 0.280547,1.206954 0.447843,1.321024 0.05063,0.601695 0.209755,1.016149 0.39384,1.39244 0.184084,0.376291 0.394872,0.709372 0.570509,1.092739 0.175638,0.383367 0.315779,0.815755 0.373139,1.370041 0.05736,0.554287 0.03553,1.211809 -0.113116,2.141566 -1.521037,1.042854 -2.963989,2.339476 -4.551548,4.78023 0.08784,-0.951925 0.160551,-1.641404 0.238144,-2.183409 0.07759,-0.542006 0.159253,-0.934002 0.250284,-1.238001 0.18206,-0.607998 0.402516,-0.87062 0.645041,-1.03557 0.485048,-0.329902 1.049566,-0.266748 1.452159,-0.947697 1.573669,-0.237195 1.164983,-1.658376 0.151049,-3.46831 -0.502191,-1.189073 -0.9805,-2.430814 -1.413688,-3.844231 0,0 0,0 0,0 z" + id="path5424" + inkscape:connector-curvature="0" + inkscape:original-d="m -62.956868,-23.43018 c -0.143214,-0.992665 1.20031,0.135448 1.765194,0.15286 0.515053,0.378573 1.810764,0.209878 1.66804,1.049575 -1.144411,0.415095 -2.288823,0.830189 -3.433234,1.245284 -0.143593,-0.889833 1.203497,-0.726403 1.769881,-1.114592 1.281043,-0.255658 0.802535,-0.512832 -0.190708,-0.770451 -0.526391,-0.187559 -1.052782,-0.375117 -1.579173,-0.562676 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -63.015168,-64.18037 c -0.744663,1.909958 -1.350571,3.432562 -1.857765,4.698968 -1.362623,3.402557 -2.014835,4.958845 -2.700959,7.209358 0.393888,0.458919 0.777087,0.870228 1.119751,0.756978 0.234908,-0.07761 0.449192,-0.399214 0.635539,-1.063489 0.09317,-0.332137 0.179075,-0.747691 0.266805,-1.27935 0.08773,-0.53166 0.175618,-1.174071 0.299613,-2.035578 0.417943,-1.930998 1.063201,-4.349616 2.237016,-8.286887 0,0 0,0 0,0 z m 1.591403,-5.903979 c 0.347811,-0.472458 0.555952,-0.610532 0.63857,-0.448168 0.08262,0.162363 0.04096,0.621509 -0.08594,1.275399 -0.253808,1.30778 -0.837176,3.359399 -1.412589,5.303503 -0.575413,1.944104 -1.136566,3.766554 -1.548589,5.208473 -0.412024,1.441918 -0.686897,2.541529 -0.825945,3.377328 -0.433749,1.162146 -0.560976,1.965221 -0.591544,2.684667 -0.03057,0.719446 0.0464,1.324365 0.121537,1.861159 0.07514,0.536793 0.150787,1.000187 0.129196,1.443196 -0.02159,0.443009 -0.139639,0.861567 -0.459827,1.371026 -0.100458,-0.176031 -0.283324,0.395205 -0.532789,1.423833 -0.124732,0.514315 -0.26795,1.149726 -0.426169,1.857383 -0.15822,0.707658 -0.331983,1.48931 -0.504274,2.240596 -0.34458,1.502573 -0.682863,2.880335 -0.747273,2.805833 -0.0322,-0.03725 0.0058,-0.443863 0.113252,-1.25787 0.107488,-0.814008 0.284421,-2.037201 0.476958,-3.494971 0.196728,-0.950207 0.322116,-1.653826 0.404338,-2.218985 0.08222,-0.565159 0.120596,-0.989407 0.130091,-1.328656 0.01899,-0.678498 -0.07629,-1.023726 -0.223333,-1.234851 -0.205308,-0.294852 -0.515344,-0.308085 -0.809943,-0.358894 -0.2946,-0.05081 -0.572596,-0.145666 -0.725339,-0.592394 0.06952,-1.163021 0.180412,-2.054633 0.344596,-2.838268 0.164183,-0.783636 0.380893,-1.457589 0.64753,-2.149382 0.533276,-1.383587 1.263323,-2.82918 2.133125,-5.263377 0.574725,-1.436133 1.2679,-3.187226 2.127433,-5.411264 0,0 0,-10e-7 0,-10e-7 0,0 0,0 0,0 1e-6,0 1e-6,-1e-6 1e-6,-1e-6 0.486099,-1.257743 1.025429,-2.666726 1.626927,-4.255314 0,0 0,0 0,0 z" + id="path5426" + inkscape:connector-curvature="0" + inkscape:original-d="m -56.869706,-24.257691 c -0.455265,0.711463 -0.91053,1.422926 -1.365795,2.134389 0.874751,0.08567 1.693957,0.115792 1.365795,-1.001453 0,-0.377645 0,-0.755291 0,-1.132936 z m -0.141936,-0.471334 c 1.102551,-0.333358 0.553252,0.985135 0.68022,1.627361 -0.556185,1.003667 1.116492,1.002682 0.320057,1.428271 -0.420389,-0.05568 -0.450813,1.807609 -0.858341,0.567122 0.253182,-1.026403 -1.152446,-0.393996 -1.752542,-0.567122 -0.263263,-0.736834 0.672268,-1.411579 0.977992,-2.09194 0.210872,-0.32123 0.421743,-0.642461 0.632614,-0.963692 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -62.125743,-51.093097 c -0.776361,0.112277 -1.201408,0.995102 -1.426368,2.341592 -0.11248,0.673245 -0.17992,1.473712 -0.222313,2.336708 -0.04239,0.862996 -0.06052,1.790221 -0.04792,2.619375 0.0126,0.829155 0.05783,1.553001 0.160963,1.950726 0.103131,0.397726 0.267885,0.455658 0.493564,0.05936 0.225679,-0.396294 0.512855,-1.250557 0.795421,-2.416081 0.282567,-1.165523 0.546666,-2.600417 0.745271,-4.137485 0.0676,-0.83054 0.02927,-1.453706 -0.06624,-1.915079 -0.09552,-0.461372 -0.251024,-0.752199 -0.432374,-0.839121 z m -0.408344,-1.48443 c -0.212178,-0.988953 -0.263065,-1.977415 -0.151629,-3.041156 0.111435,-1.063742 0.387542,-2.21046 0.798702,-3.444217 0.41116,-1.233756 0.958144,-2.55716 1.555888,-3.819457 0.597744,-1.262297 1.244055,-2.456667 1.807956,-3.307114 0.563901,-0.850446 1.040018,-1.342141 1.309223,-1.241207 0.269206,0.100934 0.325901,0.808245 0.14992,2.086881 -0.17598,1.278637 -0.583636,3.123986 -1.101529,5.142274 -0.258947,1.009143 -0.543102,2.055604 -0.83166,3.080632 -0.288559,1.025028 -0.580627,2.025713 -0.863908,2.975581 -0.639167,0.638988 -0.957693,1.376703 -1.112522,2.19847 -0.154828,0.821768 -0.145262,1.723946 -0.145568,2.764408 -3.06e-4,1.040462 -0.008,2.208924 -0.239158,3.739063 -0.231149,1.530139 -0.681669,3.403715 -1.65843,6.243865 -0.522022,1.514404 -0.992324,2.642561 -1.337616,3.16871 -0.345292,0.52615 -0.566815,0.45599 -0.677979,-0.09448 -0.111165,-0.550468 -0.116075,-1.566383 -0.0696,-2.772442 0.04647,-1.206059 0.141351,-2.59175 0.24403,-3.920848 0.102679,-1.329097 0.212811,-2.599682 0.3293,-3.708342 0.11649,-1.10866 0.241006,-2.060094 0.400697,-2.858971 0.159691,-0.798877 0.356534,-1.451528 0.61678,-1.982635 0.260245,-0.531107 0.584591,-0.943493 0.977107,-1.209016 0,0 0,0 0,0 z m 0.93267,-4.912214 c -0.201532,0.893519 -0.320502,1.558894 -0.396054,2.097326 -0.07555,0.538433 -0.106741,0.947088 -0.112516,1.271402 -0.01155,0.648627 0.076,0.964284 0.206565,1.073707 0.261137,0.218846 0.696049,-0.38262 1.198733,-1.539095 0.251342,-0.578238 0.523991,-1.30832 0.795378,-2.14769 0.271387,-0.83937 0.542907,-1.792387 0.749442,-2.708587 0.206535,-0.916199 0.345731,-1.789829 0.314533,-2.366002 -0.0312,-0.576172 -0.239563,-0.837113 -0.695851,-0.604508 -0.260267,0.234178 -0.663942,1.029706 -1.052168,1.968152 -0.388227,0.938445 -0.7555,2.004677 -1.008062,2.955295 z" + id="path5428" + inkscape:connector-curvature="0" + inkscape:original-d="m -53.706951,-22.629449 c -2.395714,0.516849 1.141994,2.824229 0.774621,0.451249 -0.113653,-0.310332 -0.462549,-0.467557 -0.774621,-0.451249 z m -0.540962,-0.230311 c -2.544898,-1.267859 2.220598,-3.288762 1.769506,-0.588495 -1.427664,0.652009 1.071909,1.314691 -0.21357,2.48454 -1.378682,1.248216 -3.677,-1.078649 -1.555936,-1.896045 z m -0.198174,-0.854291 c 0.560353,1.978126 2.622565,-0.988679 0.427145,-0.615274 -0.267629,0.06854 -0.445505,0.345482 -0.427145,0.615274 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -61.974664,-36.292864 c 0.320094,-1.635037 0.534672,-2.541018 0.725563,-3.122847 0.19089,-0.58183 0.353524,-0.822665 0.512768,-0.913461 0.318488,-0.181593 0.618864,0.252314 0.98369,0.23502 0,0 0,0 0,0 0.290483,-0.01369 0.630021,-0.345675 1.000896,-1.291031 0.370875,-0.945356 0.759522,-2.472282 1.040541,-4.332332 0.05364,-0.199018 -0.406539,-0.158059 -0.888636,-0.505859 -0.390719,-0.28158 -0.793401,-0.841149 -0.96543,-1.904835 -0.08602,-0.531842 -0.117921,-1.176668 -0.04278,-1.991717 0.03757,-0.407524 0.102447,-0.858617 0.210539,-1.383977 0.108092,-0.525359 0.258809,-1.123288 0.482549,-1.864033 0.454128,-1.532535 1.023915,-3.140741 1.612526,-4.647866 0.588612,-1.507125 1.187605,-2.886548 1.689317,-3.89374 0.501713,-1.007192 0.904076,-1.635883 1.164326,-1.809258 0.260249,-0.173374 0.379816,0.104556 0.383171,0.734193 0.0058,1.090164 -0.329114,3.212563 -0.696523,5.398422 -0.183705,1.092929 -0.375117,2.201125 -0.551323,3.247383 -0.176206,1.046258 -0.337074,2.030133 -0.480837,2.932624 -0.287527,1.80498 -0.496391,3.252592 -0.814092,4.772791 -0.317702,1.520198 -0.766756,3.184977 -1.542276,5.440706 -0.469337,1.721787 -1.028961,3.451732 -1.561484,4.823426 -0.532524,1.371693 -1.031684,2.36286 -1.409074,2.735846 -0.303503,0.299961 -0.529227,0.204375 -0.668853,-0.266012 -0.139626,-0.470387 -0.193972,-1.312512 -0.184577,-2.393467 -10e-7,8e-6 -3e-6,1.6e-5 -5e-6,2.4e-5 z m 3.566747,-11.494783 c 0.03004,-9.93e-4 0.05968,-0.0039 0.08893,-0.0086 0.412128,-0.06633 0.741399,-0.485045 1.012867,-1.11628 0.271467,-0.631235 0.488795,-1.484421 0.705581,-2.537888 0.216787,-1.053468 0.441665,-2.332178 0.650665,-3.630722 0.208999,-1.298545 0.397569,-2.606007 0.415963,-3.381895 0.01034,-0.437435 -0.03595,-0.699044 -0.159243,-0.703111 -0.123297,-0.0041 -0.324887,0.25277 -0.595342,0.775122 -0.270454,0.522351 -0.609619,1.309383 -0.968193,2.264731 -0.358573,0.955348 -0.732951,2.06753 -1.059879,3.224011 -0.350142,1.256892 -0.510106,2.42565 -0.516239,3.356389 -0.0061,0.930738 0.130048,1.640986 0.424894,1.758241 z" + id="path5430" + inkscape:connector-curvature="0" + inkscape:original-d="m -51.355642,-20.813745 c -0.17305,-0.966374 2.111714,0.234823 1.927678,-1.405131 0.03784,-0.109784 -2.504841,0.519138 -2.184769,-1.222019 0.486754,-3.031102 4.179317,-0.145419 2.505295,1.919143 -0.378938,0.863284 -1.44647,1.052241 -2.248204,0.708005 z m 1.076568,-1.695195 c 2.117049,-0.391631 -0.540779,-3.285578 -0.790019,-0.931954 -0.04045,0.45476 0.287408,0.969232 0.790019,0.931954 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -51.768778,-54.068 c -1.072093,2.579272 -1.799291,4.261061 -2.39959,5.669661 -0.600299,1.4086 -1.073364,2.544709 -1.625757,4.081768 -0.04915,0.136739 -0.09891,0.276678 -0.149449,0.42031 0.01984,0.02534 0.03968,0.05053 0.05951,0.07548 0.43661,0.549501 0.8752,0.963895 1.282662,0.531763 0.203731,-0.216065 0.396637,-0.633218 0.565806,-1.28029 0.08458,-0.323536 0.163067,-0.703522 0.23896,-1.155063 0.07589,-0.451541 0.148371,-0.972356 0.234439,-1.613738 0.360146,-1.680614 0.849176,-3.61764 1.793421,-6.729892 0,0 0,0 0,0 z m 1.306799,-4.727028 c 0.284662,-0.30607 0.451672,-0.35775 0.516322,-0.18513 0.06465,0.172621 0.02803,0.566748 -0.07556,1.103151 -0.207189,1.072805 -0.671028,2.686195 -1.119856,4.20728 -0.448829,1.521085 -0.879992,2.941631 -1.199293,4.092374 -0.319301,1.150743 -0.538158,2.064261 -0.650292,2.792068 -0.3833,0.979693 -0.52032,1.750178 -0.564624,2.456251 -0.0443,0.706074 0.01218,1.324185 0.0704,1.872754 0.05823,0.548568 0.119443,1.024578 0.07878,1.488589 -0.04067,0.464011 -0.182046,0.91115 -0.548851,1.489053 -0.100257,-0.17517 -0.323347,0.451799 -0.640249,1.589483 -0.158451,0.568843 -0.342096,1.272351 -0.543207,2.05665 -0.201111,0.784299 -0.420117,1.651118 -0.634176,2.484947 -0.428117,1.66766 -0.835634,3.199893 -0.909425,3.140299 -0.0369,-0.0298 0.01138,-0.464501 0.151046,-1.350201 0.13967,-0.885701 0.371565,-2.225377 0.643942,-3.830754 0.245632,-1.012994 0.412774,-1.770902 0.530372,-2.381558 0.117597,-0.610656 0.185109,-1.071893 0.219112,-1.441718 0.06801,-0.739651 0.0039,-1.121777 -0.122292,-1.355453 -0.252446,-0.467353 -0.764521,-0.293921 -1.158556,-0.408076 0,0 0,0 0,0 -0.200999,-0.05824 -0.369861,-0.197719 -0.458592,-0.535921 0.208596,-1.610194 0.452579,-2.755319 0.741008,-3.714425 0.288429,-0.959107 0.62042,-1.729051 0.988819,-2.527158 0,0 0,0 0,0 0.466559,-1.010876 0.988008,-2.05931 1.556548,-3.568755 0.763015,-1.776228 1.742614,-4.099313 3.128627,-7.47375 0,0 0,0 0,0 z" + id="path5432" + inkscape:connector-curvature="0" + inkscape:original-d="m -46.393254,-24.257691 c -0.455265,0.711463 -0.91053,1.422926 -1.365795,2.134389 0.874751,0.08567 1.693957,0.115792 1.365795,-1.001453 0,-0.377645 0,-0.755291 0,-1.132936 z m -0.141936,-0.471334 c 1.102551,-0.333358 0.553252,0.985135 0.68022,1.627361 -0.556185,1.003667 1.116492,1.002682 0.320057,1.428271 -0.420389,-0.05568 -0.450813,1.807609 -0.858341,0.567122 0.253182,-1.026403 -1.152446,-0.393996 -1.752542,-0.567122 -0.263263,-0.736834 0.672268,-1.411579 0.977992,-2.09194 0.210872,-0.32123 0.421743,-0.642461 0.632614,-0.963692 z" + style="stroke:none;fill-opacity:1.0;fill:url(#linearGradient5513)" /> + <path + d="m -54.27263,-30.620632 c 0.289572,-1.495111 0.499656,-2.394543 0.685864,-3.004014 0.186209,-0.609471 0.346276,-0.918575 0.501024,-1.080457 0.309497,-0.323764 0.596677,-0.05273 0.925339,0.01786 0.164332,0.0353 0.338735,0.02141 0.527172,-0.125993 0.188436,-0.147402 0.391513,-0.431061 0.603283,-0.892893 0.211771,-0.461832 0.432454,-1.10285 0.638887,-1.889439 0.206432,-0.786589 0.396251,-1.710148 0.54174,-2.707898 0.06773,-0.248655 -0.761374,-0.08468 -1.370089,-0.89007 -0.304357,-0.402696 -0.552295,-1.058386 -0.625695,-2.018408 -0.0367,-0.48001 -0.0314,-1.02955 0.04244,-1.67828 0.07384,-0.64873 0.212002,-1.384564 0.494229,-2.384584 0.240876,-0.874306 0.520445,-1.749922 0.822917,-2.607157 0.302472,-0.857234 0.626295,-1.691195 0.941896,-2.43752 0.631203,-1.49265 1.214075,-2.594167 1.592477,-2.985026 0.378403,-0.39086 0.554928,-0.07808 0.574831,0.743581 0.0199,0.821661 -0.105182,2.123537 -0.253475,3.509866 -0.148293,1.386329 -0.313041,2.838789 -0.442208,4.13041 -0.129168,1.291621 -0.224281,2.4227 -0.340867,3.470267 -0.116587,1.047568 -0.260265,2.02613 -0.534785,3.198203 -0.27452,1.172073 -0.684413,2.557386 -1.302029,4.337756 -0.422801,1.544225 -0.920923,3.117023 -1.410986,4.442017 -0.490062,1.324994 -0.969316,2.388779 -1.368461,2.979838 -0.399145,0.591059 -0.717179,0.705611 -0.926005,0.324033 -0.208825,-0.381579 -0.308929,-1.... [truncated message content] |
From: <drt...@us...> - 2011-09-17 18:41:19
|
Revision: 58 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=58&view=rev Author: drtrigon Date: 2011-09-17 18:41:11 +0000 (Sat, 17 Sep 2011) Log Message: ----------- PEP 8 Modified Paths: -------------- trunk/PyCodeOCR.py trunk/utils/RunExternal.py trunk/utils/RunLibdmtx.py trunk/utils/RunMagickWand.py trunk/utils/blacklist_manager.py trunk/utils/checksum.py trunk/utils/logging.py trunk/utils/ocr.py Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-07-27 13:51:33 UTC (rev 57) +++ trunk/PyCodeOCR.py 2011-09-17 18:41:11 UTC (rev 58) @@ -77,10 +77,10 @@ #from pythonmagickwand.image import Image # search optional pakages -if "LD_LIBRARY_PATH" not in os.environ: # patch/work-a-round for libdmtx bindings - os.environ["LD_LIBRARY_PATH"] = "/usr/local/lib" # - os.system('python %s' % sys.argv[0]) # - sys.exit() # +if "LD_LIBRARY_PATH" not in os.environ: # patch/work-a-round for libdmtx bindings + os.environ["LD_LIBRARY_PATH"] = "/usr/local/lib" # + os.system('python %s' % sys.argv[0]) # + sys.exit() # ## list of available pakages print "To check and install requirements run: 'python %s --install-deps'" % sys.argv[0] pakages = [] @@ -89,21 +89,21 @@ "dmtxread": utils.requirements.which("dmtxread"), "pdf417decode.exe": utils.requirements.which("pdf417decode.exe"), } if os.path.exists(paths["gocr"]): - pakages.append( "gocr" ) - print "gocr found." + pakages.append( "gocr" ) + print "gocr found." # libdmtx bindings #try: -# from pydmtx import DataMatrix -# pakages.append( "libdmtx" ) -# print "libdmtx and pydmtx found." -#except: pass +# from pydmtx import DataMatrix +# pakages.append( "libdmtx" ) +# print "libdmtx and pydmtx found." +#except: pass if os.path.exists(paths["dmtxread"]): - pakages.append( "libdmtx" ) - print "libdmtx and pydmtx found." + pakages.append( "libdmtx" ) + print "libdmtx and pydmtx found." # pdf417decode if os.path.exists(paths["pdf417decode.exe"]): - pakages.append( "pdf417decode" ) - print "pdf417decode.exe found." + pakages.append( "pdf417decode" ) + print "pdf417decode.exe found." # global variables and constants @@ -115,712 +115,704 @@ ## 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 ), +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), "270 deg": (( 60, 3, 150, 20 ), 270), - "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) + "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 # The GUI was created/designed using GLADE # class MainWindowGTK: - """ - PyCodeOCR main GUI window and application class. - """ + """ + PyCodeOCR main GUI window and application class. + """ - # initialization - # (variables) - max_retry = 3 # max. scan attempts - valid_code_len = [ 53, 42, 32 ] # valid code lenghts - scan_koords = std_scan_koords["0 deg"][0] # default scan pos. - mode = std_scan_koords["0 deg"][1] # default scan orient. - res_color = { True: gtk.gdk.color_parse("#00FF00"), - False: gtk.gdk.color_parse("#FF0000"), - None: gtk.gdk.color_parse("#FFFFFF"), } - temp = os.path.join(home_path, "PyCodeOCR_tmp") - debug = ( os.path.join(home_path, "PyCodeOCR_debug"), - os.path.join(home_path, "PyCodeOCR_debug.txt"), ) - regex_gocr = re.compile('<barcode(.*?)/>') + # initialization + # (variables) + max_retry = 3 # max. scan attempts + valid_code_len = [ 53, 43, 42, 32 ] # valid code lenghts + scan_koords = std_scan_koords["0 deg"][0] # default scan pos. + mode = std_scan_koords["0 deg"][1] # default scan orient. + res_color = { True: gtk.gdk.color_parse("#00FF00"), + False: gtk.gdk.color_parse("#FF0000"), + None: gtk.gdk.color_parse("#FFFFFF"), } + temp = os.path.join(home_path, "PyCodeOCR_tmp") + debug = ( os.path.join(home_path, "PyCodeOCR_debug"), + os.path.join(home_path, "PyCodeOCR_debug.txt"), ) + regex_gocr = re.compile('<barcode(.*?)/>') - #cmd_scan = "scanimage --format=tif --resolution 600 --mode Gray -t %d -l %d -y %d -x %d > %s" # SANE scan command - cmd_convert = "convert %s -depth 8 -rotate %d %s" # ImageMagick command - cmd_tesser = "tesseract %s.tif %s" # TesserAct command - cmd_gocr = paths["gocr"] + " -i %s.pnm" # GOCR command (local) - cmd_pdf417dec = "wine " + paths["pdf417decode.exe"] + " %s.png" # pdf417decode/wine command (local) + #cmd_scan = "scanimage --format=tif --resolution 600 --mode Gray -t %d -l %d -y %d -x %d > %s" # SANE scan command + cmd_convert = "convert %s -depth 8 -rotate %d %s" # ImageMagick command + cmd_tesser = "tesseract %s.tif %s" # TesserAct command + cmd_gocr = paths["gocr"] + " -i %s.pnm" # GOCR command (local) + cmd_pdf417dec = "wine " + paths["pdf417decode.exe"] + " %s.png" # pdf417decode/wine command (local) - __stop = False + __stop = False - # (constants) - MDE = { 'invoices': 0, 'barcode': 1, 'DataMatrix': 2, 'PDF417': 3 } + # (constants) + MDE = { 'invoices': 0, 'barcode': 1, 'DataMatrix': 2, 'PDF417': 3 } - ## Initialize - def __init__(self): - - -# # retrieve widgets -# # main_window - main window -# ## gladefile raw_path.glade - self.gladefile = raw_path + ".glade" - # open GTKBuilder - self.builder = gtk.Builder() - self.builder.add_from_file(self.gladefile) - # connect signal handlers - self.builder.connect_signals(self) - - # get objects from glade/GTKBuilder - ## main window - self.main_window = self.builder.get_object('main_window') - self.main_window.set_icon_from_file(raw_path+".png") - ## notebok - self.notebook = self.builder.get_object('notebook') - ## image window - self.img_popup = self.builder.get_object('img_popup') - ## scan button - self.scan_button = self.builder.get_object('scan_button') - ## restart button - self.retry_button = self.builder.get_object('retry_button') - ## exit button - self.exit_button = self.builder.get_object('exit_button') - ## placement frame - self.placement_frame = self.builder.get_object('placement_frame') - ## image - self.main_image = self.builder.get_object('main_image') - ## image - self.popup_image = self.builder.get_object('popup_image') - ## output line - self.output = self.builder.get_object('output') - self.log_text = self.builder.get_object('log_text') - self.textbuffer = self.log_text.get_buffer() - self.device_info_text = self.builder.get_object('device_info_text') - ## progressbar - self.progressbar = self.builder.get_object('progressbar') - ## Orientation label - self.placement_label = self.builder.get_object('placement_label') - ## Orientation combobox - self.orientation = self.builder.get_object('orientation') - ## mode combobox - self.mode_combobox = self.builder.get_object('mode_combobox') - ## list with possible values for modes - self.mode_list = self.builder.get_object('mode_list') - ## x-position - self.position_x = self.builder.get_object('position_x') - ## y-position - self.position_y = self.builder.get_object('position_y') - ## x-size - self.size_x = self.builder.get_object('size_x') - ## y-size - self.size_y = self.builder.get_object('size_y') - ## file input - self.file_input_button = self.builder.get_object('file_input_button') - ## sane input - self.sane_input_button = self.builder.get_object('sane_input_button') - ## choose file - self.filechooserbutton = self.builder.get_object('filechooserbutton') - ## device list - self.device_treeview = self.builder.get_object('device_treeview') - ## blacklisted device list - self.blacklist_treeview = self.builder.get_object('blacklist_treeview') - ## OK button - self.device_chooser_button = self.builder.get_object('device_chooser_button') - ## event box for image - self.main_image_eventbox = self.builder.get_object('main_image_eventbox') - ## event box for image window - self.popup_image_eventbox = self.builder.get_object('popup_image_eventbox') + ## Initialize + def __init__(self): +# # retrieve widgets +# # main_window - main window +# ## gladefile raw_path.glade + self.gladefile = raw_path + ".glade" + # open GTKBuilder + self.builder = gtk.Builder() + self.builder.add_from_file(self.gladefile) + # connect signal handlers + self.builder.connect_signals(self) + + # get objects from glade/GTKBuilder + ## main window + self.main_window = self.builder.get_object('main_window') + self.main_window.set_icon_from_file(raw_path+".png") + ## notebok + self.notebook = self.builder.get_object('notebook') + ## image window + self.img_popup = self.builder.get_object('img_popup') + ## scan button + self.scan_button = self.builder.get_object('scan_button') + ## restart button + self.retry_button = self.builder.get_object('retry_button') + ## exit button + self.exit_button = self.builder.get_object('exit_button') + ## placement frame + self.placement_frame = self.builder.get_object('placement_frame') + ## image + self.main_image = self.builder.get_object('main_image') + ## image + self.popup_image = self.builder.get_object('popup_image') + ## output line + self.output = self.builder.get_object('output') + self.log_text = self.builder.get_object('log_text') + self.textbuffer = self.log_text.get_buffer() + self.device_info_text = self.builder.get_object('device_info_text') + ## progressbar + self.progressbar = self.builder.get_object('progressbar') + ## Orientation label + self.placement_label = self.builder.get_object('placement_label') + ## Orientation combobox + self.orientation = self.builder.get_object('orientation') + ## mode combobox + self.mode_combobox = self.builder.get_object('mode_combobox') + ## list with possible values for modes + self.mode_list = self.builder.get_object('mode_list') + ## x-position + self.position_x = self.builder.get_object('position_x') + ## y-position + self.position_y = self.builder.get_object('position_y') + ## x-size + self.size_x = self.builder.get_object('size_x') + ## y-size + self.size_y = self.builder.get_object('size_y') + ## file input + self.file_input_button = self.builder.get_object('file_input_button') + ## sane input + self.sane_input_button = self.builder.get_object('sane_input_button') + ## choose file + self.filechooserbutton = self.builder.get_object('filechooserbutton') + ## device list + self.device_treeview = self.builder.get_object('device_treeview') + ## blacklisted device list + self.blacklist_treeview = self.builder.get_object('blacklist_treeview') + ## OK button + self.device_chooser_button = self.builder.get_object('device_chooser_button') + ## event box for image + self.main_image_eventbox = self.builder.get_object('main_image_eventbox') + ## event box for image window + self.popup_image_eventbox = self.builder.get_object('popup_image_eventbox') - # initiate orientation and position - self.orientation.set_active(0) - self.position_x.set_value(self.scan_koords[0]) - self.position_y.set_value(self.scan_koords[1]) - self.size_x.set_value(self.scan_koords[2]) - self.size_y.set_value(self.scan_koords[3]) - - - self.mode_combobox.set_active(0) - if "gocr" not in pakages: - self.mode_combobox.remove_text(1) - self.mode_combobox.insert_text(1, "< not installed >") - if "libdmtx" not in pakages: - self.mode_combobox.remove_text(2) - self.mode_combobox.insert_text(2, "< not installed >") - if "pdf417decode" not in pakages: - self.mode_combobox.remove_text(3) - self.mode_combobox.insert_text(3, "< not installed >") - - - # connect eventbox to close image window - (self.new_width, self.new_height ) = (0,0) - - # set tooltips - self.retry_button.set_tooltip_text("Restart PyCodeOCR to search for a SANE device.") - self.retry_button.set_visible(True) - self.main_image.set_tooltip_text("Click for bigger image") - self.popup_image.set_tooltip_text("Leave window to close") - - - # redirect print - self.logging = utils.logging(self.textbuffer) - sys.stdout = self.logging - sys.stderr = self.logging - - - # initialize treeviews in Blacklist Manager - BlacklistMgr.post_init(self.device_treeview, self.blacklist_treeview, local_path) - - print "---------",strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()),"----------" - - - - - # display window - self.main_window.show() + # initiate orientation and position + self.orientation.set_active(0) + self.position_x.set_value(self.scan_koords[0]) + self.position_y.set_value(self.scan_koords[1]) + self.size_x.set_value(self.scan_koords[2]) + self.size_y.set_value(self.scan_koords[3]) + + + self.mode_combobox.set_active(0) + if "gocr" not in pakages: + self.mode_combobox.remove_text(1) + self.mode_combobox.insert_text(1, "< not installed >") + if "libdmtx" not in pakages: + self.mode_combobox.remove_text(2) + self.mode_combobox.insert_text(2, "< not installed >") + if "pdf417decode" not in pakages: + self.mode_combobox.remove_text(3) + self.mode_combobox.insert_text(3, "< not installed >") + + + # connect eventbox to close image window + (self.new_width, self.new_height ) = (0,0) + + # set tooltips + self.retry_button.set_tooltip_text("Restart PyCodeOCR to search for a SANE device.") + self.retry_button.set_visible(True) + self.main_image.set_tooltip_text("Click for bigger image") + self.popup_image.set_tooltip_text("Leave window to close") + + + # redirect print + self.logging = utils.logging(self.textbuffer) + sys.stdout = self.logging + sys.stderr = self.logging + + + # initialize treeviews in Blacklist Manager + BlacklistMgr.post_init(self.device_treeview, self.blacklist_treeview, local_path) + + print "---------",strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()),"----------" - return - - ## Run gtk mainloop and with it THIS APP. - def run(self): - gtk.gdk.threads_init() - - self.device_chooser_event = threading.Event() - - ## initialize sane - self.run_sane = utils.ocr.RunSANE(self.notebook, self.progress, self.device_chooser_button, BlacklistMgr,self.device_chooser_event,self.device_info_text) - self.run_sane.start() - # redirect print again to old textbuffer - sys.stdout = self.logging - - gtk.main() - - - def on_device_chooser_button_clicked(self, source=None): - self.device_chooser_button.set_visible(False) - self.device_chooser_event.set() - - - - ## set sensitivity of buttons the first time - def init_sensitivity(self): - # set sensitivity - if self.run_sane.found_scanner: - self.sane_input_button.set_active(True) - self.sane_input_button.set_sensitive(True) - else: - self.file_input_button.set_active(True) - self.sane_input_button.set_sensitive(False) - - # Try to set orientation and placement sensitive - self.toggle_orientation_sensitive(True) - self.toggle_placement_sensitive(True) - - ## toggle orientation sensitivity - def toggle_orientation_sensitive(self, value): - self.placement_label.set_sensitive(value) - self.orientation.set_sensitive(value) + + # display window + self.main_window.show() - ## toggle placement sensitivity - def toggle_placement_sensitive(self, value): - if self.sane_input_button.get_active(): - self.placement_frame.set_sensitive(value) - else: - self.placement_frame.set_sensitive(False) + return + + ## Run gtk mainloop and with it THIS APP. + def run(self): + gtk.gdk.threads_init() + + self.device_chooser_event = threading.Event() + + ## initialize sane + self.run_sane = utils.ocr.RunSANE(self.notebook, self.progress, self.device_chooser_button, BlacklistMgr,self.device_chooser_event,self.device_info_text) + self.run_sane.start() + # redirect print again to old textbuffer + sys.stdout = self.logging + + gtk.main() + + + def on_device_chooser_button_clicked(self, source=None): + self.device_chooser_button.set_visible(False) + self.device_chooser_event.set() + + + ## set sensitivity of buttons the first time + def init_sensitivity(self): + # set sensitivity + if self.run_sane.found_scanner: + self.sane_input_button.set_active(True) + self.sane_input_button.set_sensitive(True) + else: + self.file_input_button.set_active(True) + self.sane_input_button.set_sensitive(False) + + # Try to set orientation and placement sensitive + self.toggle_orientation_sensitive(True) + self.toggle_placement_sensitive(True) + + ## toggle orientation sensitivity + def toggle_orientation_sensitive(self, value): + self.placement_label.set_sensitive(value) + self.orientation.set_sensitive(value) + ## toggle placement sensitivity + def toggle_placement_sensitive(self, value): + if self.sane_input_button.get_active(): + self.placement_frame.set_sensitive(value) + else: + self.placement_frame.set_sensitive(False) + ## signals / glade callbacks + # + def on_pointer_motion(self, source=None, event=None): + pass +# (x,y,state) = self.main_window.window.get_pointer() +# (wxim, wyim ) = self.main_image.get_size_request() +# if x > 16+(wxim-self.new_width)/2 and x < 16+(wxim+self.new_width)/2 and y > 75+(wyim-self.new_height)/2 and y < 75+(wyim+self.new_height)/2: +# if not self.img_popup.get_visible(): +# self.on_main_image_eventbox_button_press_event() + + def on_main_image_eventbox_button_press_event(self, source=None, event=None): + if self.img_popup.get_visible(): + # clean-up + os.remove( self.image_file_big ) + # hide window + self.img_popup.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 + # get size of shown image + width = self.main_image.allocation.width + height = self.main_image.allocation.height + + # make it bigger in window + # size should be at least 600 + if max(width,height) < 300: + ratio = min(600/float(width),600/float(height)) + width = ratio*width + height = ratio*height + # or 2x bigger + else: + width = 2*width + height = 2*height + + 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) + # 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.popup_image.set_from_file( self.image_file_big ) + # show window + self.img_popup.show() - ## signals / glade callbacks - # - def on_pointer_motion(self, source=None, event=None): - pass -# (x,y,state) = self.main_window.window.get_pointer() -# (wxim, wyim ) = self.main_image.get_size_request() -# if x > 16+(wxim-self.new_width)/2 and x < 16+(wxim+self.new_width)/2 and y > 75+(wyim-self.new_height)/2 and y < 75+(wyim+self.new_height)/2: -# if not self.img_popup.get_visible(): -# self.on_main_image_eventbox_button_press_event() - - def on_main_image_eventbox_button_press_event(self, source=None, event=None): - if self.img_popup.get_visible(): - # clean-up - os.remove( self.image_file_big ) - # hide window - self.img_popup.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 - # get size of shown image - width = self.main_image.allocation.width - height = self.main_image.allocation.height - - # make it bigger in window - # size should be at least 600 - if max(width,height) < 300: - ratio = min(600/float(width),600/float(height)) - width = ratio*width - height = ratio*height - # or 2x bigger - else: - width = 2*width - height = 2*height - - 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) - # 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.popup_image.set_from_file( self.image_file_big ) - # show window - self.img_popup.show() + + ## add device to blacklist + def blacklist_add(self, widget=None): + BlacklistMgr.blacklist_add() + + ## remove device from blacklist + def blacklist_remove(self, widget=None): + BlacklistMgr.blacklist_remove() + + ## one of the placement coordinates changed + def on_placement_value_changed(self, source=None, event=None): + self.scan_koords = (self.position_x.get_value(),self.position_y.get_value(), + self.size_x.get_value(),self.size_y.get_value()) - - ## add device to blacklist - def blacklist_add(self, widget=None): - BlacklistMgr.blacklist_add() - - ## remove device from blacklist - def blacklist_remove(self, widget=None): - BlacklistMgr.blacklist_remove() - - ## one of the placement coordinates changed - def on_placement_value_changed(self, source=None, event=None): - self.scan_koords = (self.position_x.get_value(),self.position_y.get_value(), - self.size_x.get_value(),self.size_y.get_value()) + ## Orientation changed + def on_orientation_changed(self, source=None, event=None): + orient = self.orientation.get_model()[self.orientation.get_active()][0] - ## Orientation changed - def on_orientation_changed(self, source=None, event=None): - orient = self.orientation.get_model()[self.orientation.get_active()][0] + self.position_x.set_value(std_scan_koords[orient][0][0]) + self.position_y.set_value(std_scan_koords[orient][0][1]) + self.size_x.set_value(std_scan_koords[orient][0][2]) + self.size_y.set_value(std_scan_koords[orient][0][3]) - self.position_x.set_value(std_scan_koords[orient][0][0]) - self.position_y.set_value(std_scan_koords[orient][0][1]) - self.size_x.set_value(std_scan_koords[orient][0][2]) - self.size_y.set_value(std_scan_koords[orient][0][3]) + self.mode = std_scan_koords[orient][1] + + ## mode changed + def on_mode_changed(self, source=None): + op_mode = self.mode_combobox.get_active() + if (op_mode == self.MDE['invoices']): + self.toggle_placement_sensitive(True) + self.toggle_orientation_sensitive(True) + elif (op_mode == self.MDE['barcode']): + self.toggle_placement_sensitive(False) + self.toggle_orientation_sensitive(True) + elif (op_mode == self.MDE['DataMatrix']): + self.toggle_placement_sensitive(False) + self.toggle_orientation_sensitive(False) + elif (op_mode == self.MDE['PDF417']): + self.toggle_placement_sensitive(True) + self.toggle_orientation_sensitive(True) - self.mode = std_scan_koords[orient][1] - - ## mode changed - def on_mode_changed(self, source=None): - op_mode = self.mode_combobox.get_active() - if (op_mode == self.MDE['invoices']): - self.toggle_placement_sensitive(True) - self.toggle_orientation_sensitive(True) - elif (op_mode == self.MDE['barcode']): - self.toggle_placement_sensitive(False) - self.toggle_orientation_sensitive(True) - elif (op_mode == self.MDE['DataMatrix']): - self.toggle_placement_sensitive(False) - self.toggle_orientation_sensitive(False) - elif (op_mode == self.MDE['PDF417']): - self.toggle_placement_sensitive(True) - self.toggle_orientation_sensitive(True) + ## ToggleButton: 'scan'/'stop'. + def on_scan_button_clicked(self, source=None, event=None, *a): + if self.scan_button.get_active(): # scan ! + # test if we ask for a scanner, but there is none connected + if not self.run_sane.found_scanner and self.sane_input_button.get_active(): + self.__stop = True + self.scan_button.set_active(False) + return + + self.scan_button.set_label("stop") + self.__stop = False - ## ToggleButton: 'scan'/'stop'. - def on_scan_button_clicked(self, source=None, event=None, *a): - if self.scan_button.get_active(): # scan ! - # test if we ask for a scanner, but there is none connected - if not self.run_sane.found_scanner and self.sane_input_button.get_active(): - self.__stop = True - self.scan_button.set_active(False) - return - - self.scan_button.set_label("stop") - self.__stop = False + self.output.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF")) # widget color + self.refresh() - self.output.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF")) # widget color - self.refresh() + for i in range(self.max_retry): + check = self.scancode() + if check or (check == None) or self.__stop: break + if self.__stop: return - for i in range(self.max_retry): - check = self.scancode() - if check or (check == None) or self.__stop: break - if self.__stop: return + self.output.modify_base(gtk.STATE_NORMAL, self.res_color[check]) # widget color + self.refresh() - self.output.modify_base(gtk.STATE_NORMAL, self.res_color[check]) # widget color - self.refresh() + self.__stop = True # other way around; to be able to decide if it was stopped or ended correctly + self.scan_button.set_active(False) # (since this triggers THIS function again) + else: # stop/abort ! + self.scan_button.set_label("scan") + if self.__stop: return + self.__stop = True - self.__stop = True # other way around; to be able to decide if it was stopped or ended correctly - self.scan_button.set_active(False) # (since this triggers THIS function again) - else: # stop/abort ! - self.scan_button.set_label("scan") - if self.__stop: return - self.__stop = True + self.output.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF")) # widget color + self.progressbar.set_text("Stopped by user!") + self.refresh() + return - self.output.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse("#FFFFFF")) # widget color - self.progressbar.set_text("Stopped by user!") - self.refresh() - return + ## exit and restart + def on_retry_button_clicked(self, source=None, event=None): + self.device_chooser_event.clear() + self.run_sane.retry() - ## exit and restart - def on_retry_button_clicked(self, source=None, event=None): - self.device_chooser_event.clear() - self.run_sane.retry() + ## exit + def on_exit_button_clicked(self, source=None, event=None): + self.on_main_window_destroy() - ## exit - def on_exit_button_clicked(self, source=None, event=None): - self.on_main_window_destroy() + ## press x-button on window + def on_main_window_destroy(self, source=None, event=None): + 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 window - def on_main_window_destroy(self, source=None, event=None): - try: - os.remove( self.temp+"04.jpg" ) # clean-up - os.remove( self.image_file_small ) - except: - pass - # exit - gtk.main_quit() + ## file selected + def on_filechooserbutton_file_set(self, source=None): + self.file_input_button.set_active(True) + self.inp_file = self.filechooserbutton.get_filename() + if not os.path.exists(self.inp_file): + self.progress(0., "File not found!") + return None + self.setimage(self.inp_file) - ## file selected - def on_filechooserbutton_file_set(self, source=None): - self.file_input_button.set_active(True) - self.inp_file = self.filechooserbutton.get_filename() - if not os.path.exists(self.inp_file): - self.progress(0., "File not found!") - return None - self.setimage(self.inp_file) + # helpers + # + ## Main scanning and number recognition procedure. + # + # @todo Put this function (may be as class with functions for each step) into utils::ocr + # + def scancode(self): + # Initialization of scanning process + # (0/7) + self.progress(0., "") + max_steps = 7 + op_mode = self.mode_combobox.get_active() + source_mode = self.sane_input_button.get_active() + if (op_mode == self.MDE['invoices']): # 0: invoices (tesser) + self.on_placement_value_changed() # scan selected range + self.on_orientation_changed() # orientation mode + opt = { 'tmp_file': "02.tif", + 'recog_class': utils.RunExternal, + 'recog_cmd': self.cmd_tesser % (self.temp+"02", self.temp+"03"), + 'recog_error_msg': [ "Unable" ], + 'valid_code_len': self.valid_code_len, + 'resolution': 600, } + elif (op_mode == self.MDE['barcode']): # 1: barcode (gocr) + self.on_orientation_changed() # orientation mode + self.scan_koords = std_scan_koords["A4"][0] + #self.mode = std_scan_koords["A4"][1] + opt = { 'tmp_file': "02.pnm", + 'recog_class': utils.RunExternal, + 'recog_cmd': self.cmd_gocr % (self.temp+"02",), + 'recog_error_msg': [ "\nERROR pnm.c" ], + 'valid_code_len': [ 13, 10, 9 ], + 'resolution': 300, } + elif (op_mode == self.MDE['DataMatrix']): # 2: DataMatrix (libdmtx) + #self.on_orientation_changed() # orientation mode + self.scan_koords = std_scan_koords["A4"][0] + self.mode = std_scan_koords["A4"][1] + #pydmtx recognition +# opt = { 'tmp_file': "02.jpg", # some issues with recogition +# 'recog_class': utils.RunLibdmtx, # . +# 'recog_cmd': self.temp+"02.jpg", # of different file formats +# 'recog_error_msg': [ None ], # . + #dmtxread recognition + opt = { 'tmp_file': "02.jpg", # some issues with recogition + 'recog_class': utils.RunExternal, # . + 'recog_cmd': "%s -v -D %s02.jpg"%(paths["dmtxread"],self.temp), # of different file formats + 'recog_error_msg': [ "error" ], # . + #opt = { 'tmp_file': "02.bmp", # and drawing/marking the + # 'recog_cmd': (self.temp+"02.bmp", [ None ], utils.ocr.RunLibdmtx), } # processed region(s)... + #opt = { 'tmp_file': "02.png", # (but this should work for 'tif') + # 'recog_cmd': (self.temp+"02.png", [ None ], utils.ocr.RunLibdmtx), } # + 'resolution': 150, } + elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) + self.on_placement_value_changed() # scan selected range + self.on_orientation_changed() # orientation mode + opt = { 'tmp_file': "02.png", + 'recog_class': utils.RunExternal, + 'recog_cmd': self.cmd_pdf417dec % (self.temp+"02",), + 'recog_error_msg': [ "wine: cannot find", "pdf417decode.exe imagefile|string.txt|-i", "Decoding failed." ], + 'resolution': 300, } - # helpers - # - ## Main scanning and number recognition procedure. - # - # @todo Put this function (may be as class with functions for each step) into utils::ocr - # - def scancode(self): - # Initialization of scanning process - # (0/7) - self.progress(0., "") - max_steps = 7 - op_mode = self.mode_combobox.get_active() - source_mode = self.sane_input_button.get_active() - if (op_mode == self.MDE['invoices']): # 0: invoices (tesser) - self.on_placement_value_changed() # scan selected range - self.on_orientation_changed() # orientation mode - opt = { 'tmp_file': "02.tif", - 'recog_class': utils.RunExternal, - 'recog_cmd': self.cmd_tesser % (self.temp+"02", self.temp+"03"), - 'recog_error_msg': [ "Unable" ], - 'valid_code_len': self.valid_code_len, - 'resolution': 600, } - elif (op_mode == self.MDE['barcode']): # 1: barcode (gocr) - self.on_orientation_changed() # orientation mode - self.scan_koords = std_scan_koords["A4"][0] - #self.mode = std_scan_koords["A4"][1] - opt = { 'tmp_file': "02.pnm", - 'recog_class': utils.RunExternal, - 'recog_cmd': self.cmd_gocr % (self.temp+"02",), - 'recog_error_msg': [ "\nERROR pnm.c" ], - 'valid_code_len': [ 13, 10, 9 ], - 'resolution': 300, } - elif (op_mode == self.MDE['DataMatrix']): # 2: DataMatrix (libdmtx) - #self.on_orientation_changed() # orientation mode - self.scan_koords = std_scan_koords["A4"][0] - self.mode = std_scan_koords["A4"][1] - #pydmtx recognition -# opt = { 'tmp_file': "02.jpg", # some issues with recogition -# 'recog_class': utils.RunLibdmtx, # . -# 'recog_cmd': self.temp+"02.jpg", # of different file formats -# 'recog_error_msg': [ None ], # . - #dmtxread recognition - opt = { 'tmp_file': "02.jpg", # some issues with recogition - 'recog_class': utils.RunExternal, # . - 'recog_cmd': "%s -v -D %s02.jpg"%(paths["dmtxread"],self.temp), # of different file formats - 'recog_error_msg': [ "error" ], # . - - #opt = { 'tmp_file': "02.bmp", # and drawing/marking the - # 'recog_cmd': (self.temp+"02.bmp", [ None ], utils.ocr.RunLibdmtx), } # processed region(s)... - #opt = { 'tmp_file': "02.png", # (but this should work for 'tif') - # 'recog_cmd': (self.temp+"02.png", [ None ], utils.ocr.RunLibdmtx), } # - 'resolution': 150, } - elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) - self.on_placement_value_changed() # scan selected range - self.on_orientation_changed() # orientation mode - opt = { 'tmp_file': "02.png", - 'recog_class': utils.RunExternal, - 'recog_cmd': self.cmd_pdf417dec % (self.temp+"02",), - 'recog_error_msg': [ "wine: cannot find", "pdf417decode.exe imagefile|string.txt|-i", "Decoding failed." ], - 'resolution': 300, } + #os.chdir(home_path) # (still needed?) + self.refresh() + if self.__stop: return - #os.chdir(home_path) # (still needed?) - self.refresh() - if self.__stop: return + # Scaning and retrieving data OR reading from image file + # (tesseract has a direct python interface: http://code.google.com/p/pytesser/) + # (1/?) + if source_mode: # SANE scanning interface + self.progress(1./max_steps, "Scanning data...") + self.inp_file = self.temp+"01.tif" + #self.run_sane = utils.ocr.RunExternal(self.cmd_scan % ( self.scan_koords + (inp_file,) ), [ "no SANE devices found" ]) + self.run_sane.post_init(self.scan_koords, self.inp_file) # utils.ocr.RunSANE().post_init(...) 2nd part of __init__(...) + self.run_sane.resolution = opt["resolution"] + if self.run_sane(): + print self.run_sane.stderr + self.progress(0., self.run_sane.stderr) + return None + #del self.run_sane + else: # direct file input + self.progress(1./max_steps, "Reading image...") + #self.inp_file = self.filechooserbutton.get_filename() + #if not os.path.exists(self.inp_file): + # self.progress(0., "File not found!") + # return None + self.refresh() + if self.__stop: return - # Scaning and retrieving data OR reading from image file - # (tesseract has a direct python interface: http://code.google.com/p/pytesser/) - # (1/?) - if source_mode: # SANE scanning interface - self.progress(1./max_steps, "Scanning data...") - self.inp_file = self.temp+"01.tif" - #self.run_sane = utils.ocr.RunExternal(self.cmd_scan % ( self.scan_koords + (inp_file,) ), [ "no SANE devices found" ]) - self.run_sane.post_init(self.scan_koords, self.inp_file) # utils.ocr.RunSANE().post_init(...) 2nd part of __init__(...) - self.run_sane.resolution = opt["resolution"] - if self.run_sane(): - print self.run_sane.stderr - self.progress(0., self.run_sane.stderr) - return None - #del self.run_sane - else: # direct file input - self.progress(1./max_steps, "Reading image...") - #self.inp_file = self.filechooserbutton.get_filename() - #if not os.path.exists(self.inp_file): - # self.progress(0., "File not found!") - # return None - self.refresh() - if self.__stop: return + # Adjust and rotate the retrieved data + # (2/?) + self.progress(2./max_steps, "Adjusting image/picture data...") + mode = self.mode + try: + self.inp_file + except: + print "No input file. Please select input file or SANE Interface." + self.progress(0., "No input file. Please select input file or SANE Interface.") + return None + self.run_convert = utils.RunExternal(self.cmd_convert % (self.inp_file, mode, self.temp+opt['tmp_file']), error_msg=[ "convert: unable to open image" ]) +# self.run_convert = utils.RunMagickWand(inp_file, mode*90, self.temp+opt['tmp_file']) + # improve quality by using imagemagicks filter and conversion capabilities... + if self.run_convert(): + self.progress(0., self.run_convert.stderr[:-1]) + return None + #if (op_mode == self.MDE['invoices']): # 0: invoices + self.setimage( self.temp+opt['tmp_file'] ) + if source_mode: # SANE scanning interface + os.remove(self.inp_file) # clean-up + del self.run_convert + self.refresh() + if self.__stop: return - # Adjust and rotate the retrieved data - # (2/?) - self.progress(2./max_steps, "Adjusting image/picture data...") - mode = self.mode - try: - self.inp_file - except: - print "No input file. Please select input file or SANE Interface." - self.progress(0., "No input file. Please select input file or SANE Interface.") - return None - self.run_convert = utils.RunExternal(self.cmd_convert % (self.inp_file, mode, self.temp+opt['tmp_file']), error_msg=[ "convert: unable to open image" ]) -# self.run_convert = utils.RunMagickWand(inp_file, mode*90, self.temp+opt['tmp_file']) - # improve quality by using imagemagicks filter and conversion capabilities... - if self.run_convert(): - self.progress(0., self.run_convert.stderr[:-1]) - return None - #if (op_mode == self.MDE['invoices']): # 0: invoices - self.setimage( self.temp+opt['tmp_file'] ) - if source_mode: # SANE scanning interface - os.remove(self.inp_file) # clean-up - del self.run_convert - self.refresh() - if self.__stop: return + # Data character recognition / Barcode search and recognition + # (3/?) + self.progress(3./max_steps, "Recognition...") + self.run_recognition = opt['recog_class'](opt['recog_cmd'], error_msg=opt['recog_error_msg']) + if self.run_recognition(): + # create debug info output + os.rename(self.temp+opt['tmp_file'], self.debug[0]+opt['tmp_file'][-4:]) + #print "debug info output in '%s'" % self.debug[0] - # Data character recognition / Barcode search and recognition - # (3/?) - self.progress(3./max_steps, "Recognition...") - self.run_recognition = opt['recog_class'](opt['recog_cmd'], error_msg=opt['recog_error_msg']) - if self.run_recognition(): - # create debug info output - os.rename(self.temp+opt['tmp_file'], self.debug[0]+opt['tmp_file'][-4:]) - #print "debug info output in '%s'" % self.debug[0] + print self.run_recognition.stderr[:-1] + " Look at debug info!" + self.progress(0., self.run_recognition.stderr[:-1] + " Look at debug info!") + return None - print self.run_recognition.stderr[:-1] + " Look at debug info!" - self.progress(0., self.run_recognition.stderr[:-1] + " Look at debug info!") - return None + if (op_mode == self.MDE['invoices']): # 0: invoices + # Simple workaround: The program simply continuous if no text is found at all + # and therefore no txt-file is generated. + if not os.path.exists(self.temp+"03.txt"): + origdata = "$" + data = "$" + else: + df = file(self.temp+"03.txt", "r") + data = df.read(-1) + df.close() + origdata = data + os.remove(self.temp+"03.txt") # clean-up + + elif (op_mode == self.MDE['barcode']): # 1: barcode + # (cheap'n'ugly but working...) + raw_data = self.regex_gocr.search(self.run_recognition.stdout).groups() + raw_data = raw_data[0].strip() + raw_data = raw_data.replace("=", ":") + raw_data = raw_data.replace('" ', '", "') + raw_data = raw_data.replace(':"', '":"') + raw_data = '{ "' + raw_data + ' }' + data = eval( raw_data ) + origdata = str(data) + elif (op_mode == self.MDE['DataMatrix']): # 2: DataMatrix (libdmtx) + data = self.run_recognition.stdout + #pydmtx recognition +# if self.run_recognition.count == 1: +# data = self.run_recognition.message[0] +# else: +# data = str(self.run_recognition.message) +# origdata = str(self.run_recognition.stats) + elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) + data = self.run_recognition.stdout.split("\r\n")[1] + origdata = data + self.refresh() + if self.__stop: return - if (op_mode == self.MDE['invoices']): # 0: invoices - # Simple workaround: The program simply continuous if no text is found at all - # and therefore no txt-file is generated. - if not os.path.exists(self.temp+"03.txt"): - origdata = "$" - data = "$" - else: - df = file(self.temp+"03.txt", "r") - data = df.read(-1) - df.close() - origdata = data - os.remove(self.temp+"03.txt") # clean-up - - elif (op_mode == self.MDE['barcode']): # 1: barcode - # (cheap'n'ugly but working...) - raw_data = self.regex_gocr.search(self.run_recognition.stdout).groups() - raw_data = raw_data[0].strip() - raw_data = raw_data.replace("=", ":") - raw_data = raw_data.replace('" ', '", "') - raw_data = raw_data.replace(':"', '":"') - raw_data = '{ "' + raw_data + ' }' - data = eval( raw_data ) - origdata = str(data) - elif (op_mode == self.MDE['DataMatrix']): # 2: DataMatrix (libdmtx) - data = self.run_recognition.stdout - #pydmtx recognition -# if self.run_recognition.count == 1: -# data = self.run_recognition.message[0] -# else: -# data = str(self.run_recognition.message) -# origdata = str(self.run_recognition.stats) - elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) - data = self.run_recognition.stdout.split("\r\n")[1] - origdata = data - self.refresh() - if self.__stop: return + # Data character correction + # (4/?) + if (op_mode == self.MDE['invoices']): # 0: invoices + self.progress(4./max_steps, "Character correction...") + print "*** " * 10 + data = utils.ocr.char_correction(data) + self.refresh() + if self.__stop: return - # Data character correction - # (4/?) - if (op_mode == self.MDE['invoices']): # 0: invoices - self.progress(4./max_steps, "Character correction...") - print "*** " * 10 - data = utils.ocr.char_correction(data) - self.refresh() - if self.__stop: return + # Data validity check + # (5/?) + self.progress(5./max_steps, "Check on validity...") + if (op_mode == self.MDE['invoices']): # 0: invoices + check = (not "?" in data) or (not "!" in data) # any unrecognized char in code? + check = check and ( len(data) in opt['valid_code_len'] ) # correct code len? + if check: + tmp = data[:-1].split(">") + amount = tmp[0] + tmp = tmp[1].split("+ ") + reference = tmp[0] + account = tmp[1] + # initialize modulo10 checksum + m10 = modulo10(amount, account, reference) + # check amount, account number and reference number + print "Amount: " + str(m10.amount) +" "+ str(m10.checksum_b) + print "Account number: " +str(m10.account) +" "+ str(m10.checksum_k) + print "Reference number: "+ str(m10.reference) +" "+ str(m10.checksum_r) + + checksum = m10.checksum + +# 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 +# if check: +# # modulo10 checksum for betrag +# checknr = modulo10().run(betrag[:-1]) +# print "Checknr: ",checknr +# checknr = ( checknr == int(betrag[-1]) ) + elif (op_mode == self.MDE['barcode']): # 1: barcode + check = not (data['type'] == "unknown") + if check: + check = check and ( int(data['crc']) == 0 ) # CRC error check? + check = check and (float(data['error']) < 0.15) # recognizion errors? + print 'type:' +" "+ data['type'] + print 'chars:' +" "+ data['chars'] + print 'crc:' +" "+ data['crc'] + print 'error:' +" "+ data['error'] + data = data['code'] + else: + data = "type: " + data['type'] + #check = check and ( len(data) in opt['valid_code_len'] ) # correct code len? + elif (op_mode == self.MDE['DataMatrix']): # 2: DataMatrix (libdmtx) + check = not (self.run_recognition.error == "error") + #pydmtx recognition +# check = not self.run_recognition.error +# if check: +# print self.run_recognition.decode +# print self.run_recognition.count +# #print self.run_recognition.message +# print self.run_recognition.stats + + elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) + check = not self.run_recognition.error + print data +" "+ str(len(data)) +" "+ str(check) + del self.run_recognition + self.refresh() + if self.__stop: return - # Data validity check - # (5/?) - self.progress(5./max_steps, "Check on validity...") - if (op_mode == self.MDE['invoices']): # 0: invoices - check = (not "?" in data) or (not "!" in data) # any unrecognized char in code? - check = check and ( len(data) in opt['valid_code_len'] ) # correct code len? - if check: - tmp = data[:-1].split(">") - amount = tmp[0] - tmp = tmp[1].split("+ ") - reference = tmp[0] - account = tmp[1] - # initialize modulo10 checksum - m10 = modulo10(amount, account, reference) - # check amount, account number and reference number - print "Amount: " + str(m10.amount) +" "+ str(m10.checksum_b) - print "Account number: " +str(m10.account) +" "+ str(m10.checksum_k) - print "Reference number: "+ str(m10.reference) +" "+ str(m10.checksum_r) - - checksum = m10.checksum - -# 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 -# if check: -# # modulo10 checksum for betrag -# checknr = modulo10().run(betrag[:-1]) -# print "Checknr: ",checknr -# checknr = ( checknr == int(betrag[-1]) ) - elif (op_mode == self.MDE['barcode']): # 1: barcode - check = not (data['type'] == "unknown") - if check: - check = check and ( int(data['crc']) == 0 ) # CRC error check? - check = check and (float(data['error']) < 0.15) # recognizion errors? - print 'type:' +" "+ data['type'] - print 'chars:' +" "+ data['chars'] - print 'crc:' +" "+ data['crc'] - print 'error:' +" "+ data['error'] - data = data['code'] - else: - data = "type: " + data['type'] - #check = check and ( len(data) in opt['valid_code_len'] ) # correct code len? - elif (op_mode == self.MDE['DataMatrix']): # 2: DataMatrix (libdmtx) - check = not (self.run_recognition.error == "error") - #pydmtx recognition -# check = not self.run_recognition.error -# if check: -# print self.run_recognition.decode -# print self.run_recognition.count -# #print self.run_recognition.message -# print self.run_recognition.stats - - elif (op_mode == self.MDE['PDF417']): # 3: PDF417 barcode (pdf417decode/wine) - check = not self.run_recognition.error - print data +" "+ str(len(data)) +" "+ str(check) - del self.run_recognition - self.refresh() - if self.__stop: return + # Data final output + # (6/?) + self.progress(6./max_steps, "Final data output...") + if check: + os.remove(self.temp+opt['tmp_file']) # clean-up - # Data final output - # (6/?) - self.progress(6./max_steps, "Final data output...") - if check: - os.remove(self.temp+opt['tmp_file']) # clean-up + self.output.set_text(data) - self.output.set_text(data) + # get the clipboard + clipboard = gtk.clipboard_get() + # set the clipboard text data + clipboard.set_text(data) + # make our data available to other applications + clipboard.store() + #print "data sent to (gtk/gnome) clipboard" + if checksum: + self.progress(1., "Code recognized and sent to clipboard. Finished.") + else: + self.progress(1., "Code recognized and sent to clipboard, BUT checksum failed! CHECK code again! Finished.") + else: + # create debug info output + log = file(self.debug[1], "w") + for i in range(len(origdata)): + log.write(str( (origdata[i], ord(origdata[i])) )) + log.write("\n") + for i in range(len(data)): + log.write(str( (data[i], ord(data[i])) )) + log.close() + #print "debug info output in '%s'" % self.debug[1] + os.rename(self.temp+opt['tmp_file'], self.debug[0]+opt['tmp_file'][-4:]) + #print "debug info output in '%s'" % self.debug[0] - # get the clipboard - clipboard = gtk.clipboard_get() - # set the clipboard text data - clipboard.set_text(data) - # make our data available to other applications - clipboard.store() - #print "data sent to (gtk/gnome) clipboard" - if checksum: - self.progress(1., "Code recognized and sent to clipboard. Finished.") - else: - self.progress(1., "Code recognized and sent to clipboard, BUT checksum failed! CHECK code again! Finished.") - else: - # create debug info output - log = file(self.debug[1], "w") - for i in range(len(origdata)): - log.write(str( (origdata[i], ord(origdata[i])) )) - log.write("\n") - for i in range(len(data)): - log.write(str( (data[i], ord(data[i])) )) - log.close() - #print "debug info output in '%s'" % self.debug[1] - os.rename(self.temp+opt['tmp_file'], self.debug[0]+opt['tmp_file'][-4:]) - #print "debug info output in '%s'" % self.debug[0] + self.progress(1., "Code could not be recognized correct. Look at debug info!") + self.refresh() + if self.__stop: return - self.progress(1., "Code could not be recognized correct. Look at debug info!") - self.refresh() - if self.__stop: return + # Done + # (7/7) + return check - # Done - # (7/7) - return check + ## Refresh window during running processes. + def refresh(self): + self.main_window.queue_draw() + time.sleep(0.1) # give also some time to the user... :) + while gtk.events_pending(): + gtk.main_iteration() - ## Refresh window during running processes. - def refresh(self): - self.main_window.queue_draw() - time.sleep(0.1) # give also some time to the user... :) - while gtk.events_pending(): - gtk.main_iteration() + ## 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 + # original file name + self.imageFile = imageFile + # load file + im1 = Image.open(self.imageFile) + else: + #convert Image + self.run_convert = utils.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 + # 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 + #get needed size + width = self.main_image.allocation.width + height = self.main_image.allocation.height + ratio = min(float(width)/im_width,float(height)/im_height) #calculate resizing ratio + self.new_width = int(im_width*ratio) + self.new_height = int(im_height*ratio) + + # use one of these filter options to resize the image + + #im = im1.resize((new_width, new_height), Image.NEAREST) # use nearest neighbour + im = im1.resize((self.new_width, self.new_height), Image.BILINEAR) # linear interpolation in a 2x2 environment + #im = im1.resize((new_width, new_height), Image.BICUBIC) # cubic spline interpolation in a 4x4 environment + #im = im1.resize((new_width, new_height), Image.ANTIALIAS) # best down-sizing filter + #ext = ".jpg" + + # set image preview + self.image_file_small = self.temp+"05.jpg" + im.save( self.image_file_small ) + self.main_image.set_from_file( self.image_file_small ) - ## 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 - # original file name - self.imageFile = imageFile - # load file - im1 = Image.open(self.imageFile) - else: - #convert Image - self.run_convert = utils.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 - # 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 - #get needed size - width = self.main_image.allocation.width - height = self.main_image.allocation.height - ratio = min(float(width)/im_width,float(height)/im_height) #calculate resizing ratio - self.new_width = int(im_width*ratio) - self.new_height = int(im_height*ratio) - - # use one of these filter options to resize the image - - #im = im1.resize((new_width, new_height), Image.NEAREST) # use nearest neighbour - im = im1.resize((self.new_width, self.new_height), Image.BILINEAR) # linear interpolation in a 2x2 environment - #im = im1.resize((new_width, new_heigh... [truncated message content] |
From: <drt...@us...> - 2011-12-22 22:42:34
|
Revision: 59 http://pycodeocr.svn.sourceforge.net/pycodeocr/?rev=59&view=rev Author: drtrigon Date: 2011-12-22 22:42:28 +0000 (Thu, 22 Dec 2011) Log Message: ----------- bug fix; 'None' could not be converted into string in 'ocr.py' some additional minor changes for simpler debugging and others Modified Paths: -------------- trunk/PyCodeOCR.py trunk/utils/ocr.py Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-09-17 18:41:11 UTC (rev 58) +++ trunk/PyCodeOCR.py 2011-12-22 22:42:28 UTC (rev 59) @@ -56,7 +56,9 @@ utils.requirements.check_all_pycodeocr_requirements() sys.exit() +debug = ("--debug" in sys.argv) + # GTK, PyGTK, GLADE (GNOME) modules import pygtk pygtk.require('2.0') @@ -156,7 +158,7 @@ MDE = { 'invoices': 0, 'barcode': 1, 'DataMatrix': 2, 'PDF417': 3 } ## Initialize - def __init__(self): + def __init__(self, BlacklistMgr): # # retrieve widgets # # main_window - main window # ## gladefile raw_path.glade @@ -260,12 +262,14 @@ # redirect print self.logging = utils.logging(self.textbuffer) - sys.stdout = self.logging - sys.stderr = self.logging + if not debug: + sys.stdout = self.logging + sys.stderr = self.logging # initialize treeviews in Blacklist Manager - BlacklistMgr.post_init(self.device_treeview, self.blacklist_treeview, local_path) + self.BlacklistMgr = BlacklistMgr + self.BlacklistMgr.post_init(self.device_treeview, self.blacklist_treeview, local_path) print "---------",strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime()),"----------" @@ -282,10 +286,11 @@ self.device_chooser_event = threading.Event() ## initialize sane - self.run_sane = utils.ocr.RunSANE(self.notebook, self.progress, self.device_chooser_button, BlacklistMgr,self.device_chooser_event,self.device_info_text) + self.run_sane = utils.ocr.RunSANE(self.notebook, self.progress, self.device_chooser_button, self.BlacklistMgr,self.device_chooser_event,self.device_info_text) self.run_sane.start() # redirect print again to old textbuffer - sys.stdout = self.logging + if not debug: + sys.stdout = self.logging gtk.main() @@ -374,11 +379,11 @@ ## add device to blacklist def blacklist_add(self, widget=None): - BlacklistMgr.blacklist_add() + self.BlacklistMgr.blacklist_add() ## remove device from blacklist def blacklist_remove(self, widget=None): - BlacklistMgr.blacklist_remove() + self.BlacklistMgr.blacklist_remove() ## one of the placement coordinates changed def on_placement_value_changed(self, source=None, event=None): @@ -808,11 +813,9 @@ self.refresh() if __name__ == '__main__': - global BlacklistMgr - global main ## initialize Blacklist Manager BlacklistMgr = utils.blacklist_manager() ## run main application - main = MainWindowGTK() + main = MainWindowGTK(BlacklistMgr) main.run() Modified: trunk/utils/ocr.py =================================================================== --- trunk/utils/ocr.py 2011-09-17 18:41:11 UTC (rev 58) +++ trunk/utils/ocr.py 2011-12-22 22:42:28 UTC (rev 59) @@ -259,7 +259,7 @@ print "\n" print 'Device options:' for opt in self.opts: - print opt[2]+ ": " + opt[3] + print "%s: %s" % (opt[2], opt[3]) def retry(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <drt...@us...> - 2013-11-03 16:19:43
|
Revision: 61 http://sourceforge.net/p/pycodeocr/code/61 Author: drtrigon Date: 2013-11-03 16:19:40 +0000 (Sun, 03 Nov 2013) Log Message: ----------- * support for Pillow (PIL replacement) * add ')' -> '>' substitution for ocr Modified Paths: -------------- trunk/PyCodeOCR.py trunk/utils/ocr.py Modified: trunk/PyCodeOCR.py =================================================================== --- trunk/PyCodeOCR.py 2011-12-22 23:07:40 UTC (rev 60) +++ trunk/PyCodeOCR.py 2013-11-03 16:19:40 UTC (rev 61) @@ -68,8 +68,8 @@ from utils.checksum import modulo10 -# PIL image library and it's SANE bindings -import Image, ImageDraw +# PIL/Pillow image library and it's SANE bindings +from PIL import Image, ImageDraw #from PIL import Image from time import gmtime, strftime Modified: trunk/utils/ocr.py =================================================================== --- trunk/utils/ocr.py 2011-12-22 23:07:40 UTC (rev 60) +++ trunk/utils/ocr.py 2013-11-03 16:19:40 UTC (rev 61) @@ -72,6 +72,7 @@ ("'", ""), #('\xbb', 187)('\x99', 153)('\x98', 152) ("\+", "+ "), + ("\)", ">"), ("\x92", "1"), # post correction ] for item in corrections: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |