def order(): """ order by date using exif info """ log_function_call(order.__name__) inpath = os.getcwd() Tagdict = read_exiftags(file_types=settings.image_types, ignore_model=True) timeJumpDetector = TimeJumpDetector() time_old = giveDatetime() dircounter = 1 filenames = [] leng = len(list(Tagdict.values())[0]) dirNameDict_firsttime = OrderedDict() dirNameDict_lasttime = OrderedDict() time = giveDatetime(create_model(Tagdict, 0).get_date()) daystring = dateformating(time, "YYMMDD_") dirName = daystring + "%02d" % dircounter dirNameDict_firsttime[time] = dirName log().info('Number of JPG: %d', leng) for i in range(leng): model = create_model(Tagdict, i) time = giveDatetime(model.get_date()) if timeJumpDetector.isJump(time, len(filenames)): dirNameDict_lasttime[time_old] = dirName moveFiles(filenames, os.path.join(inpath, dirName)) filenames = [] if newdate(time, time_old): daystring = dateformating(time, "YYMMDD_") dircounter = 1 else: dircounter += 1 dirName = daystring + "%02d" % dircounter dirNameDict_firsttime[time] = dirName filenames.append((model.dir, model.filename)) time_old = time dirNameDict_lasttime[time_old] = dirName moveFiles(filenames, os.path.join(inpath, dirName)) print_firstlast_of_dirname(dirNameDict_firsttime, dirNameDict_lasttime) Tagdict_mp4 = read_exiftags(file_types=settings.video_types) if len(Tagdict_mp4) == 0: return leng = len(list(Tagdict_mp4.values())[0]) log().info('Number of mp4: %d', leng) for i in range(leng): model = create_model(Tagdict_mp4, i) time = giveDatetime(model.get_date()) dirName = find_dir_with_closest_time(dirNameDict_firsttime, dirNameDict_lasttime, time) if dirName: move(model.filename, model.dir, os.path.join(inpath, dirName, "mp4")) else: log().warning("Did not move %s to %s", model.filename, dirName)
def rename_back(timestring="", fileext=".JPG"): """ rename back using backup in saves; change to directory you want to rename back :param timestring: time of backup :param fileext: file extension :return: """ log_function_call(rename_back.__name__) dirname = get_saves_dir() tagFile = os.path.join(dirname, "Tags" + fileext + "_" + timestring + ".npz") if not timestring or os.path.isfile(tagFile): tagFiles = [x for x in os.listdir(dirname) if ".npz" in x] tagFile = os.path.join(dirname, tagFiles[-1]) Tagdict = np.load(tagFile, allow_pickle=True)["Tagdict"].item() temppostfix = renameTemp(Tagdict["Directory"], Tagdict["File Name new"]) log().debug("length of Tagdict: %d", len(list(Tagdict.values())[0])) for i in range(len(list(Tagdict.values())[0])): filename = Tagdict["File Name new"][i] + temppostfix if not os.path.isfile(os.path.join(Tagdict["Directory"][i], filename)): continue filename_old = Tagdict["File Name"][i] renameInPlace(Tagdict["Directory"][i], filename, filename_old) Tagdict["File Name new"][i], Tagdict["File Name"][i] = Tagdict[ "File Name"][i], Tagdict["File Name new"][i] timestring = dateformating(dt.datetime.now(), "_MMDDHHmmss") np.savez_compressed(os.path.join(dirname, "Tags" + fileext + timestring), Tagdict=Tagdict)
def shift_time(hours: int = 0, minutes: int = 0, seconds: int = 0, is_video: bool = False): """ shift DateTimeOriginal to correct for wrong camera time setting :example: to adjust time zone by one, set hours=-1 :param hours: hours to shift :param minutes: minutes to shift :param seconds: seconds to shift :param is_video: whether to modify videos, if false modifies pictures """ log_function_call(shift_time.__name__, hours, minutes, seconds, is_video) inpath = os.getcwd() delta_t = dt.timedelta(hours=hours, minutes=minutes, seconds=seconds) Tagdict = read_exiftags(inpath, settings.video_types if is_video else settings.image_types) if has_not_keys(Tagdict, keys=["Directory", "File Name", "Date/Time Original"]): return leng = len(list(Tagdict.values())[0]) time_tags = ["DateTimeOriginal", "CreateDate", "ModifyDate"] time_tags_mp4 = ["TrackCreateDate", "TrackModifyDate", "MediaCreateDate", "MediaModifyDate"] dir_change_printer = DirChangePrinter(Tagdict["Directory"][0]) for i in range(leng): model = create_model(Tagdict, i) time = giveDatetime(model.get_date()) newtime = time + delta_t timestring = dateformating(newtime, "YYYY:MM:DD HH:mm:ss") outTagDict = {} for time_tag in time_tags: outTagDict[time_tag] = timestring if is_video: for time_tag in time_tags_mp4: outTagDict[time_tag] = timestring write_exiftag(outTagDict, model.dir, model.filename) dir_change_printer.update(model.dir) dir_change_printer.finish()
def fake_date(start='2000:01:01', write=True, folder_dict: OrderedDict = None): """ each file in a directory is one second later each dir is one day later :param start: the date on which to start generate fake dates :param write: whether should write or only print :param folder_dict: foldername to date """ log_function_call(fake_date.__name__, start) inpath = os.getcwd() start_time_part = ' 06:00:00.000' start_time = giveDatetime(start + start_time_part) dir_counter = -1 for (dirpath, dirnames, filenames) in os.walk(inpath): if is_invalid_path(dirpath): continue filenames = filterFiles(filenames, settings.image_types + settings.video_types) if not filenames or len(filenames) == 0: continue if folder_dict: dirpath_rel = os.path.relpath(dirpath, inpath) if not dirpath_rel in folder_dict: continue else: dirtime = giveDatetime(folder_dict[dirpath_rel] + start_time_part) else: dir_counter += 1 dirtime = start_time + dt.timedelta(days=dir_counter) log().info(dirtime) secounds = 0 minutes = 0 lastname = "" for filename in filenames: if len(filename) == len(lastname) and remove_ext(filename)[:-2] == remove_ext(lastname)[:-2]: secounds += 1 else: secounds = 0 minutes += 1 lastname = filename time = dirtime + dt.timedelta(minutes=minutes, seconds=secounds) time_string = dateformating(time, "YYYY:MM:DD HH:mm:ss") if write: # CreateDate is sometimes set and google fotos gives it precedence over DateTimeOriginal write_exiftag({"DateTimeOriginal": time_string}, dirpath, filename, ["-DateCreated=", "-TimeCreated=", "-CreateDate=", "-Artist=", "-DigitalCreationDate=", "-ModifyDate=", "-DateTimeDigitized="])
def rename(Prefix="", dateformat='YYMM-DD', startindex=1, onlyprint=False, keeptags=True, is_video=False, name=""): """ Rename into Format: [Prefix][dateformat](_[name])_[Filenumber][SeriesType][SeriesSubNumber]_[PhotoMode] :param Prefix: prefix has to fulfil regex [-a-zA-Z]* :param dateformat: Y:Year,M:Month,D:Day,N:DayCounter; Number of occurrences determine number of digits :param startindex: minimal counter :param onlyprint: do not rename; only output file of proposed renaming into saves directory :param keeptags: any tags - name or postfixes will be preserved :param is_video: is video file extension :param name: optional name between date and filenumber, seldom used """ log_function_call(rename.__name__, Prefix, dateformat, startindex, onlyprint, keeptags, is_video, name) Tagdict = read_exiftags( file_types=settings.video_types if is_video else settings.image_types) if not Tagdict: return # rename temporary if not onlyprint: temppostfix = renameTemp(Tagdict["Directory"], Tagdict["File Name"]) else: temppostfix = "" # initialize outstring = "" Tagdict["File Name new"] = [] time_old = giveDatetime() counter = startindex - 1 digits = _count_files_for_each_date(Tagdict, startindex, dateformat) number_of_files = len(list(Tagdict.values())[0]) daystring = "" for i in range(number_of_files): model = create_model(Tagdict, i) time = giveDatetime(model.get_date()) filename = model.filename if newdate(time, time_old, 'D' in dateformat or 'N' in dateformat): daystring = dateformating(time, dateformat) if not i == 0: counter = 0 filenameBuilder = FilenameBuilder(filename) filenameBuilder.add_main(Prefix + daystring) filenameBuilder.add_main(model.get_model_abbr()) filenameBuilder.add_main(name) if is_video: counter += 1 counterString = "M%02d" % counter filenameBuilder.add_post(model.get_recMode()) else: # SequenceNumber sequence_number = model.get_sequence_number() if sequence_number < 2 and not time == time_old or model.ignore_same_date( ): counter += 1 counterString = ("%0" + digits + "d") % counter if not "HDR" in filename: counterString += model.get_sequence_string() filenameBuilder.add_main(counterString) filenameBuilder.add_post(model.get_mode()) if keeptags: filenameBuilder.use_old_tags() newname = filenameBuilder.build() # handle already exiting filename - its ok when they are in different directories # its not ok to have to files with one uppercase and another lowercase -> equals with ignore case if len(Tagdict["File Name new"]) > 0: if newname.lower() == Tagdict["File Name new"][-1].lower() and \ Tagdict["Directory"][i].lower() == Tagdict["Directory"][i - 1].lower(): log().warning("%s already exists - postfix it with V%d", os.path.join(model.dir, newname), 1) newname = filenameBuilder.set_version("V%d" % 1).build() for version in range(2, 100): indexes_samename = [ i for i, name in enumerate(Tagdict["File Name new"]) if name.lower() == newname.lower() ] if indexes_samename: if Tagdict["Directory"][i] == Tagdict["Directory"][ indexes_samename[0]]: log().warning( "%s already exists - postfix it with V%d", os.path.join(model.dir, newname), version) newname = filenameBuilder.set_version("V%d" % version).build() else: break else: break time_old = time Tagdict["File Name new"].append(newname) outstring += _write(model.dir, filename, temppostfix, newname, onlyprint) dirname = get_saves_dir() timestring = dateformating(dt.datetime.now(), "_MMDDHHmmss") video_str = "_video" if is_video else "" np.savez_compressed(os.path.join(dirname, "Tags" + video_str + timestring), Tagdict=Tagdict) writeToFile( os.path.join(dirname, "newnames" + video_str + timestring + ".txt"), outstring)