def __init__(self, input_fw, xmlroot, tag, hashval): self.exists = False xml = xmlroot.find("%s[@%s='%s']"%(tag, Settings.hash_attrib, hashval)) if xml is None: # DNE. index = self.getNextIndex(xmlroot, tag) xml = XmlUtils.getOrAddChild(xmlroot, tag, {Settings.index_attrib:str(index), Settings.hash_attrib:hashval}) else: self.exists = True index = xml.get(Settings.index_attrib) self.output_fw = input_fw.getExtended("%s%s"%(tag, index)) self.xml = xml # If dir already exists, nothing happens. if not self.output_fw.createDir(): raise Exception()
def run(self): # For each matrix in the input source set: i = 0 for fw in self.input_fw.getSortedDirContents(): if len(self.xmlmerged) > 0: xmlmergedmatrix = self.xmlmerged.find( "%s[@%s='%d']" % (Settings.matrix_tag, Settings.index_attrib, i)) if xmlmergedmatrix is None: # FIXME: getting here indicates current input set matrix count != expected. # Raise a custom exception. raise Exception if Utils.isDecoded(xmlmergedmatrix): # DECODED ALREADY #print "Already processed (skipping): %s"%(Utils.prettyPrint1(xmlmergedmatrix)) i += 1 continue else: xmlmergedmatrix = None xmlmatrix = XmlUtils.getOrAddChild(self.xmlset, Settings.matrix_tag, {Settings.index_attrib: str(i)}) qrcode = QRCode.QRCode(self, PngUtils.PngWrapper(fw), self.output_fw, Dimension.matrix, xmlmergedmatrix, xmlmatrix) # Schedule a worker: self.scheduleWorker(qrcode, qrcode.work) i += 1 # Start the workers: self.startWorkers() # All workers complete without error? if not self.joinWorkers(): # FIXME: raise QRCode.FatalDecodeError( str("SetManager:run(): fatal error raised")) # First time run there will be no merged session branch so create it now by copying the first session run branch: if len(self.xmlmerged) == 0: for worker in self: self.xmlmerged.append(copy.deepcopy(worker.xml))
def run(self): if self.input_fw.isExistingDir(): # The input is assumed to be a directory of ORDERED source files (single set), so this structure will be created: # # <path to>/project/src/setx <--- input source will be copied to here # Where 'x' is the next available set index. # Generate input hash over input src: hasher = FileHasher.FileHasher(Settings.hashing_algorithm) srclist = [] for f in self.input_fw.getSortedDirContents(): if (f.isExistingFile()) and (f.getExtension(False).lower() == "png"): srclist.append(f.getPath()) hasher.addFile(srclist) hashval = hasher.getHash() xmlset = self.xml.find( "%s[@%s='%s']" % (Settings.set_tag, Settings.hash_attrib, hashval)) if xmlset is None: nextIndex = len(self.xml) xmlset = XmlUtils.getOrAddChild( self.xml, Settings.set_tag, { Settings.index_attrib: "%d" % (nextIndex), Settings.hash_attrib: hashval }) self.targetsets.append(xmlset) set_fw = self.output_fw.getExtended( "%s%d" % (Settings.matrix_set, nextIndex)) if not set_fw.createDir(): raise OSError("Error: could not create directory: %s" % (set_fw.getPath())) i = 0 for f in srclist: try: shutil.copyfile(f, (set_fw.getExtended( "%s-%d.png" % (Settings.converted_pdf, i)).getPath())) except: raise Exception( "Error: could not copy '%s' to: %s" % (f, set_fw.getExtended( "%s-%d.png" % (Settings.converted_pdf, i)).getPath())) # FIX ME: RAISE EXCEPTION INSTEAD i += 1 # Assert that input is a .pdf file # FIXME: is there a better check than just checking the extension??? elif (self.input_fw.isExistingFile()) and ( self.input_fw.getExtension() == ".pdf"): # The input is assumed to be a file that is required to be converted into source files (across multiple sets), so this structure will be created: # # <path to>/project/src/setx/ <--- converted files will be written here # <path to>/project/src/sety/ <--- converted files will be written here # <path to>/project/src/setz/ <--- converted files will be written here # etc. # Where 'x', 'y', 'z' are set indices incremented from the next available one. i = 0 while self.density.inRange(i): # Generate input hash over input src file + conversion params: hasher = FileHasher.FileHasher(Settings.hashing_algorithm) hasher.addFile([self.input_fw.getPath()]) Settings.getHash(hasher, Settings.hashlist2, i) hashval = hasher.getHash() xmlset = self.xml.find( "%s[@%s='%s']" % (Settings.set_tag, Settings.hash_attrib, hashval)) if xmlset is not None: # A converted set APPEARS (according to our xml config) to already exist. # We'll just silently skip over then... #print "Converted source set already exists: %s"%(hashval) pass else: # No converted set exists. We'll have to create one then. nextIndex = len(self.xml) xmlset = XmlUtils.getOrAddChild( self.xml, Settings.set_tag, { Settings.index_attrib: "%d" % (nextIndex), Settings.hash_attrib: hashval }) set_fw = self.output_fw.getExtended( "%s%d" % (Settings.matrix_set, nextIndex)) # FIXME: is this check too much? #if set_fw.isExistingDir(): # raise Exception("Error: directory already exists: %s"%(set_fw.getPath())) # Can't we get the workers to do this? # Short answer: no. There seem to be not properly understood issues at play. if not set_fw.createDir(): raise OSError("Error: could not create directory: %s" % (set_fw.getPath())) # Create a worker: worker = ConversionWorker(self.input_fw, set_fw) args = [self.density.getVal(i), self.depth, self.quality] # Schedule the worker: self.scheduleWorker(worker, worker.work, args) self.targetsets.append(xmlset) i += 1 # Start the workers: self.startWorkers() if not self.joinWorkers(): raise AssertionError( "Not all workers have completed succesfully!") else: # FIXME raise Exception("Invalid input: %s" % (self.input_fw.getPath()))
exit(-1) # Does xml config file exists? if xml_config_fw.isExistingFile(): # Yes. Open it. et = ElementTree.parse(xml_config_fw.getPath()) xmlroot = et.getroot() else: # No. Create it. xmlroot = ElementTree.Element(Settings.project_tag) et = ElementTree.ElementTree(xmlroot) ################################################################################################################# # ACQUAINT OURSELVES WITH PREVIOUS SESSION DATA xmlmerged = XmlUtils.getOrAddChild(xmlroot, Settings.merged_tag) target_qr_count = -1 prev_decoded_qr_count = 0 if len(xmlmerged) > 0: print "" print "Previous session detected..." # At this stage, all subsequent input have to contain this many QR codes (for consistency): xmlqrcount = xmlmerged.find("%s[@%s]"%(Settings.qr_tag, Settings.count_attrib)) if xmlqrcount is not None: target_qr_count = int(xmlqrcount.get(Settings.count_attrib)) print " QR count: %d"%(target_qr_count) else: print "Error: invalid config file: %s"%(xml_config_fw) exit(-1)
def run(self): ############################# for target in self.srcmanager.targetsets: i = target.get(Settings.index_attrib) srcset = "%s%s" % (Settings.matrix_set, i) input_fw = self.srcmanager.output_fw.getExtended("%s" % (srcset)) output_fw = self.output_fw.getExtended("%s/%s" % (Settings.session, srcset)) # FIXME: can't we get the workers to do this? if not output_fw.createDir(): raise OSError("Error: could not create directory: %s" % (output_fw.getPath())) extract_params = Extract.Parameters(Settings.x_tolerance, Settings.y_tolerance, Settings.region_tolerance, Settings.first_dimension) test = Extract.QRExtractor(input_fw, output_fw) extractcount = test.run(extract_params) print "%d QRs extracted" % (extractcount) decode_params = Decode.Parameters( Settings.maxpayloadsize, Settings.minpayloadsize, Settings.minimum_resize_dimension, Settings.maximum_resize_dimension, Settings.resize_increment) test2 = Decode.QRDecoder( output_fw, FilePathWrapper.FilePathWrapper("/tmp/jeremy")) test2.run(decode_params) exit(-1) ############################ # Get merged sessions (if available): xmlmerged = XmlUtils.getOrAddChild(self.xml, Settings.merged_tag) # Get hash over the decode args (the "session" hash): hasher = FileHasher.FileHasher(Settings.hashing_algorithm) Settings.getHash(hasher, Settings.hashlist1, 0) hashval = hasher.getHash() # Get a previous existing session or create a new one. # NOTE: getting a previous existing session is OK, because we might have new source sets with which to attempt decoding. xmlsession = XmlUtils.getOrAddChild(self.xml, Settings.session_tag, {Settings.hash_attrib: hashval}) index = xmlsession.get(Settings.index_attrib) if index is None: index = len(self.xml) - 2 xmlsession.set(Settings.index_attrib, str(index)) else: index = int(index) #print "Found previous session..." s = "" s += "\nPREVIOUS SESSION\n" s += "----------------\n" s += "QR count: %d\n" % (Utils.getQRCount(xmlmerged)) s += "Decoded total: %d\n" % (Utils.getDecodedCount(xmlmerged)) s += "Decoded remaining: %d" % (Utils.getQRCount(xmlmerged) - Utils.getDecodedCount(xmlmerged)) print s i2 = 0 # FIXME: also need a way to get ALL available sets, not just the targets (Settings option) # For each target source set: for target in self.srcmanager.targetsets: i = target.get(Settings.index_attrib) # Have we already attempted to decode this source set? xmlset = xmlsession.find( "%s[@%s='%s']" % (Settings.set_tag, Settings.index_attrib, i)) if xmlset is not None: # Yes. Skip it. i2 += 1 continue else: # No. Schedule it. xmlset = XmlUtils.getOrAddChild(xmlsession, Settings.set_tag, {Settings.index_attrib: i}) srcset = "%s%s" % (Settings.matrix_set, i) input_fw = self.srcmanager.output_fw.getExtended("%s" % (srcset)) output_fw = self.output_fw.getExtended( "%s%s/%s" % (Settings.session, index, srcset)) # FIXME: can't we get the workers to do this? if not output_fw.createDir(): raise OSError("Error: could not create directory: %s" % (output_fw.getPath())) prevDecodeCount = Utils.getDecodedCount(xmlmerged) # Create a setmanager instance: setManager = SetManager(input_fw, output_fw, xmlmerged, xmlset) setManager.run() currDecodeCount = Utils.getDecodedCount(xmlmerged) qrCount = Utils.getQRCount(xmlmerged) s = "" s += "\nPASS %d\n" % (i2 + 1) s += "---------\n" s += "QR count: %d\n" % (qrCount) s += "Decoded now: %d\n" % (currDecodeCount - prevDecodeCount) s += "Decoded total: %d\n" % (currDecodeCount) s += "Decoded remaining: %d" % (qrCount - currDecodeCount) print s i2 += 1
def work(self, rtargs=None): self.prework() status = WorkerStatus.completed_success # print "Analyzing: %s (%s)"%(Utils.prettyPrint1(self.xml), Utils.prettyPrint2(self.xml)) # Get nextdimension nextdimension = self.dimension.next() strtarget = "%s-%s"%(str(self.dimension), self.xml.get(Settings.index_attrib)) nextoutput_fw = self.output_fw.getExtended("%s"%(strtarget)) if not nextoutput_fw.createDir(): raise OSError("Could not create directory: %s"%(nextoutput_fw.getPath())) # FIXME: Writing the image processing artefacts to disk is not strictly necessary: if Settings.dump_artefacts: if self.dimension == Dimension.matrix: shutil.copy(str(self.png.img_fw), str(self.output_fw)) else: pngfile = "%s/%s.png"%(self.output_fw.getPath(), strtarget) cv2.imwrite(pngfile, self.png.getImgCV2()) ################################################################################################### # PROCESSING A MATRIX OF QR CODES: if nextdimension != None: coordspace = self.getCoordSpace(self.png, Settings.region_tolerance, nextdimension) self.verifyCoordSpace(nextdimension, coordspace) i = 0 for coords in coordspace: nextpng = self.getRegion(self.png, nextdimension, coords) # PHASE IN: if self.xmlmerged is not None: nextxmlmerged = self.xmlmerged.find("%s[@%s='%d']"%(str(nextdimension), Settings.index_attrib, i)) if nextxmlmerged is not None: if Utils.isDecoded(nextxmlmerged): # DECODED ALREADY # print "Already processed (skipping): %s"%(Utils.prettyPrint1(nextxmlmerged)) i += 1 continue else: nextxmlmerged = None nextxml = XmlUtils.getOrAddChild(self.xml, str(nextdimension), {Settings.index_attrib:str(i)}) qrcode = QRCode(self, nextpng, nextoutput_fw, nextdimension, nextxmlmerged, nextxml) # Schedule a worker: self.scheduleWorker(qrcode, qrcode.work) i += 1 # Start the workers: self.startWorkers() # All workers complete without error? if not self.joinWorkers(): raise FatalDecodeError(str(self)) ################################################################################################### # PROCESSING A SINGLE QR CODE else: data1 = self.decode(self.png, Settings.maxpayloadsize, Settings.minimum_resize_dimension, Settings.resize_increment, True) if len(data1) < Settings.maxpayloadsize: # Suboptimal? Try instead applying a up-resize strategy: data2 = self.decode(self.png, Settings.maxpayloadsize, Settings.maximum_resize_dimension, Settings.resize_increment, False) if (len(data1) > len(data2)): data = data1 else: data = data2 else: data = data1 if len(data) >= Settings.minpayloadsize: #print "DECODE SUCCESS: %s (%s)"%(Utils.prettyPrint1(self.xml), Utils.prettyPrint2(self.xml)) try: FileUtils.writeToFile((nextoutput_fw.getExtended("/%s.txt"%(strtarget))).getPath(), data) self.xml.text = "1" # First time round, self.xmlmerged will be None if self.xmlmerged is not None: if self.xmlmerged.text == "0": #print "UPDATING: %s"%(Utils.prettyPrint1(self.xmlmerged)) self.xmlmerged.text = "1" except IOError: # print "Could not write: %s"%(data_fw.getPath()) status = WorkerStatus.completed_fatal_error # FIXME : return me out of here! else: #print "DECODE FAILURE: %s (%s)"%(Utils.prettyPrint1(self.xml), Utils.prettyPrint2(self.xml)) self.xml.text = "0" status = WorkerStatus.completed_not_successful ################################################################################################### # Finish work: self.postwork(status)