class ModelCopySelected(object): """ Implemantation MVC de la procedure copySelected """ def __init__(self): """ """ self.__label = "Un moment..." self.startSignal = Signal() self.refreshSignal = Signal() self.finishSignal = Signal() self.NbrJobsSignal = Signal() def start(self, lstFiles): """ Lance les calculs @param lstFiles: list of files to process """ self.startSignal.emit(self.__label, max(1, len(lstFiles))) if config.Filigrane: filigrane = Signature(config.FiligraneSource) else: filigrane = None SelectedDir = os.path.join(config.DefaultRepository, config.SelectedDirectory) self.refreshSignal.emit(-1, "copie des fichiers existants") if not os.path.isdir(SelectedDir): fileutils.mkdir(SelectedDir) #####first of all : copy the subfolders into the day folder to help mixing the files for day in os.listdir(SelectedDir): for File in os.listdir(os.path.join(SelectedDir, day)): if File.find(config.PagePrefix) == 0: if os.path.isdir(os.path.join(SelectedDir, day, File)): for strImageFile in os.listdir(os.path.join(SelectedDir, day, File)): src = os.path.join(SelectedDir, day, File, strImageFile) dst = os.path.join(SelectedDir, day, strImageFile) if os.path.isfile(src) and not os.path.exists(dst): shutil.move(src, dst) if (os.path.isdir(src)) and (os.path.split(src)[1] in [config.ScaledImages["Suffix"], config.Thumbnails["Suffix"]]): shutil.rmtree(src) #######then copy the selected files to their folders########################### globalCount = 0 for File in lstFiles: dest = os.path.join(SelectedDir, File) src = os.path.join(config.DefaultRepository, File) destdir = os.path.dirname(dest) self.refreshSignal.emit(globalCount, File) globalCount += 1 if not os.path.isdir(destdir): fileutils.makedir(destdir) if not os.path.exists(dest): if filigrane: image = Image.open(src) filigrane.substract(image).save(dest, quality=config.FiligraneQuality, optimize=config.FiligraneOptimize, progressive=config.FiligraneOptimize) else: shutil.copy(src, dest) try: os.chmod(dest, config.DefaultFileMode) except OSError: logger.warning("In ModelCopySelected: unable to chmod %s", dest) else : logger.info("In ModelCopySelected: %s already exists", dest) ######copy the comments of the directory to the Selected directory AlreadyDone = [] for File in lstFiles: directory = os.path.split(File)[0] if directory in AlreadyDone: continue else: AlreadyDone.append(directory) dst = os.path.join(SelectedDir, directory, config.CommentFile) src = os.path.join(config.DefaultRepository, directory, config.CommentFile) if os.path.isfile(src): shutil.copy(src, dst) self.finishSignal.emit()
class ModelRangeTout(object): """Implemantation MVC de la procedure rangeTout moves all the JPEG files to a directory named from their day and with the name according to the time""" def __init__(self): """ """ self.__label = "Initial renaming of new images .... " self.startSignal = Signal() self.refreshSignal = Signal() self.finishSignal = Signal() self.NbrJobsSignal = Signal() def start(self, rootDir): """ Lance les calculs @param rootDir: top level directory to start processing @return: 2tuple containing the list of all images and the start-index @rtype: (list,integer) """ config.DefaultRepository = rootDir AllJpegs = fileutils.findFiles(rootDir) AllFilesToProcess = [] AllreadyDone = [] NewFiles = [] uid = os.getuid() gid = os.getgid() for i in AllJpegs: if i.find(config.TrashDirectory) == 0: continue if i.find(config.SelectedDirectory) == 0: continue try: a = int(i[:4]) m = int(i[5:7]) j = int(i[8:10]) if (a >= 0000) and (m <= 12) and (j <= 31) and (i[4] in ["-", "_", "."]) and (i[7] in ["-", "_"]): AllreadyDone.append(i) else: AllFilesToProcess.append(i) except ValueError: AllFilesToProcess.append(i) AllFilesToProcess.sort() NumFiles = len(AllFilesToProcess) self.startSignal.emit(self.__label, NumFiles) for h in range(NumFiles): i = AllFilesToProcess[h] self.refreshSignal.emit(h, i) myPhoto = Photo(i, dontCache=True) data = myPhoto.readExif() try: datei, heurei = data["Heure"].split() date = re.sub(":", "-", datei) heurej = re.sub(":", "h", heurei, 1) model = data["Modele"].split(",")[-1] heure = unicode2ascii("%s-%s.jpg" % (re.sub(":", "m", heurej, 1), re.sub("/", "", re.sub(" ", "_", model)))) except ValueError: date = time.strftime("%Y-%m-%d", time.gmtime(os.path.getctime(os.path.join(rootDir, i)))) heure = unicode2ascii("%s-%s.jpg" % (time.strftime("%Hh%Mm%S", time.gmtime(os.path.getctime(os.path.join(rootDir, i)))), re.sub("/", "-", re.sub(" ", "_", os.path.splitext(i)[0])))) if not (os.path.isdir(os.path.join(rootDir, date))) : fileutils.mkdir(os.path.join(rootDir, date)) # strImageFile = os.path.join(rootDir, date, heure) ToProcess = os.path.join(date, heure) bSkipFile = False for strImageFile in fileutils.list_files_in_named_dir(rootDir, date, heure): logger.warning("%s -x-> %s", i, strImageFile) existing = Photo(strImageFile, dontCache=True) try: existing.readExif() originalName = existing.exif["Exif.Photo.UserComment"] except: logger.error("in ModelRangeTout: reading Exif for %s", i) else: if "human_value" in dir(originalName): originalName = originalName.human_value if os.path.basename(originalName) == os.path.basename(i): logger.info("File already in repository, leaving as it is") bSkipFile = True continue #to next file, i.e. leave the existing one if bSkipFile: continue else: strImageFile = os.path.join(rootDir, date, heure) if os.path.isfile(strImageFile): s = 0 for j in os.listdir(os.path.join(rootDir, date)): if j.find(heure[:-4]) == 0:s += 1 ToProcess = os.path.join(date, heure[:-4] + "-%s.jpg" % s) strImageFile = os.path.join(rootDir, ToProcess) shutil.move(os.path.join(rootDir, i), strImageFile) try: os.chown(strImageFile, uid, gid) os.chmod(strImageFile, config.DefaultFileMode) except OSError: logger.warning("in ModelRangeTout: unable to chown ot chmod %s" , strImageFile) myPhoto = Photo(strImageFile, dontCache=True) # Save the old image name in exif tag myPhoto.storeOriginalName(i) if config.AutoRotate: myPhoto.autorotate() AllreadyDone.append(ToProcess) NewFiles.append(ToProcess) AllreadyDone.sort() self.finishSignal.emit() if len(NewFiles) > 0: FirstImage = min(NewFiles) return AllreadyDone, AllreadyDone.index(FirstImage) else: return AllreadyDone, 0
class ModelProcessSelected(object): """ Implemantation MVC de la procedure processSelected """ def __init__(self): """ """ self.__label = "Un moment..." self.startSignal = Signal() self.refreshSignal = Signal() self.finishSignal = Signal() self.NbrJobsSignal = Signal() def start(self, lstFiles): """ Lance les calculs pour "processSelected" i.e. @param lstFiles: list of files to process """ def splitIntoPages(pathday, globalCount): """Split a directory (pathday) into pages of 20 images (see config.NbrPerPage) @param pathday: @param globalCount: @return: the number of images for current page """ logger.debug("In splitIntoPages %s %s", pathday, globalCount) files = [] for i in os.listdir(pathday): if os.path.splitext(i)[1] in config.Extensions:files.append(i) files.sort() if len(files) > config.NbrPerPage: pages = 1 + (len(files) - 1) / config.NbrPerPage for i in range(1, pages + 1): folder = os.path.join(pathday, config.PagePrefix + str(i)) fileutils.mkdir(folder) for j in range(len(files)): i = 1 + (j) / config.NbrPerPage filename = os.path.join(pathday, config.PagePrefix + str(i), files[j]) self.refreshSignal.emit(globalCount, files[j]) globalCount += 1 shutil.move(os.path.join(pathday, files[j]), filename) scaleImage(filename, filigrane) else: for j in files: self.refreshSignal.emit(globalCount, j) globalCount += 1 scaleImage(os.path.join(pathday, j), filigrane) return globalCount def arrangeOneFile(dirname, filename): """ @param dirname: @param filename: """ try: timetuple = time.strptime(filename[:19], "%Y-%m-%d_%Hh%Mm%S") suffix = filename[19:] except ValueError: try: timetuple = time.strptime(filename[:11], "%Y-%m-%d_") suffix = filename[11:] except ValueError: logger.warning("Unable to handle such file: %s" % filename) return daydir = os.path.join(SelectedDir, time.strftime("%Y-%m-%d", timetuple)) os.mkdir(daydir) shutil.move(os.path.join(dirname, filename), os.path.join(daydir, time.strftime("%Hh%Mm%S", timetuple) + suffix)) logger.debug("In Process Selected" + " ".join(lstFiles)) self.startSignal.emit(self.__label, max(1, len(lstFiles))) if config.Filigrane: filigrane = Signature(config.FiligraneSource) else: filigrane = None SelectedDir = os.path.join(config.DefaultRepository, config.SelectedDirectory) self.refreshSignal.emit(-1, "copie des fichiers existants") if not os.path.isdir(SelectedDir): fileutils.mkdir(SelectedDir) #####first of all : copy the subfolders into the day folder to help mixing the files AlsoProcess = 0 for day in os.listdir(SelectedDir): #if SingleDir : revert to a foldered structure DayOrFile = os.path.join(SelectedDir, day) if os.path.isfile(DayOrFile): arrangeOneFile(SelectedDir, day) AlsoProcess += 1 #end SingleDir normalization elif os.path.isdir(DayOrFile): if day in [config.ScaledImages["Suffix"], config.Thumbnails["Suffix"]]: fileutils.recursive_delete(DayOrFile) elif day.find(config.PagePrefix) == 0: #subpages in SIngleDir mode that need to be flatten for File in os.listdir(DayOrFile): if os.path.isfile(os.path.join(DayOrFile, File)): arrangeOneFile(DayOrFile, File) AlsoProcess += 1 # elif os.path.isdir(os.path.join(DayOrFile,File)) and File in [config.ScaledImages["Suffix"],config.Thumbnails["Suffix"]]: # recursive_delete(os.path.join(DayOrFile,File)) fileutils.recursive_delete(DayOrFile) else: for File in os.listdir(DayOrFile): if File.find(config.PagePrefix) == 0: if os.path.isdir(os.path.join(SelectedDir, day, File)): for strImageFile in os.listdir(os.path.join(SelectedDir, day, File)): src = os.path.join(SelectedDir, day, File, strImageFile) dst = os.path.join(SelectedDir, day, strImageFile) if os.path.isfile(src) and not os.path.exists(dst): shutil.move(src, dst) AlsoProcess += 1 if (os.path.isdir(src)) and (os.path.split(src)[1] in [config.ScaledImages["Suffix"], config.Thumbnails["Suffix"]]): shutil.rmtree(src) else: if os.path.splitext(File)[1] in config.Extensions: AlsoProcess += 1 #######then copy the selected files to their folders########################### for File in lstFiles: dest = os.path.join(SelectedDir, File) src = os.path.join(config.DefaultRepository, File) destdir = os.path.dirname(dest) if not os.path.isdir(destdir): fileutils.makedir(destdir) if not os.path.exists(dest): logger.info("copie de %s " % File) shutil.copy(src, dest) try: os.chmod(dest, config.DefaultFileMode) except OSError: logger.warning("Unable to chmod %s" % dest) AlsoProcess += 1 else : logger.warning("%s existe déja" % dest) if AlsoProcess > 0:self.NbrJobsSignal.emit(AlsoProcess) ######copy the comments of the directory to the Selected directory AlreadyDone = [] for File in lstFiles: directory = os.path.split(File)[0] if directory in AlreadyDone: continue else: AlreadyDone.append(directory) dst = os.path.join(SelectedDir, directory, config.CommentFile) src = os.path.join(config.DefaultRepository, directory, config.CommentFile) if os.path.isfile(src): shutil.copy(src, dst) ########finaly recreate the structure with pages or make a single page ######################## logger.debug("in ModelProcessSelected, SelectedDir= %s", SelectedDir) dirs = [ i for i in os.listdir(SelectedDir) if os.path.isdir(os.path.join(SelectedDir, i))] dirs.sort() if config.ExportSingleDir: #SingleDir #first move all files to the root for day in dirs: daydir = os.path.join(SelectedDir, day) for filename in os.listdir(daydir): try: timetuple = time.strptime(day[:10] + "_" + filename[:8], "%Y-%m-%d_%Hh%Mm%S") suffix = filename[8:] except ValueError: try: timetuple = time.strptime(day[:10], "%Y-%m-%d") suffix = filename except ValueError: logger.info("Unable to handle dir: %s\t file: %s" , day, filename) continue src = os.path.join(daydir, filename) dst = os.path.join(SelectedDir, time.strftime("%Y-%m-%d_%Hh%Mm%S", timetuple) + suffix) shutil.move(src, dst) fileutils.recursive_delete(daydir) splitIntoPages(SelectedDir, 0) else: #Multidir logger.debug("in Multidir, dirs= " + " ".join(dirs)) globalCount = 0 for day in dirs: globalCount = splitIntoPages(os.path.join(SelectedDir, day), globalCount) self.finishSignal.emit()