def add_tags(tag_list, filename, verbose=False): if not os.path.isabs(filename): raise TagException("{f} must be in absolute full file path".format(f=filename)) if not os.path.isfile(filename): raise IOError(filename + " is not a valid file") tag_dict = load_tag_dict() filename = os.path.normpath(filename.lower()) appended_list = [] for tag in tag_list: tag = tag.strip().lower() if tag not in tag_dict: print "Creating new tag:", tag tag_dict[tag] = [filename] log_tag_changes("add", tag, filename) elif filename not in tag_dict[tag]: tag_dict[tag].append(filename) appended_list.append(tag) log_tag_changes("add", tag, filename) else: error_alert(filename + " is already in tag: " + tag) if verbose and len(appended_list) > 0: print "Appended to tags:", ", ".join(appended_list) write_tag_file(tag_dict)
def dl_single_song(vid_link, target_dir): yt_dl_opts = ("--quiet --no-mtime --audio-format best --audio-quality 0 --no-overwrites " + "--extract-audio --output").split() vid_title = get_vid_title(vid_link) cleaned_vid_title = clean_filenames.clean_string(vid_title) vid_id = vid_link[vid_link.rindex("=") + 1:] file_title = "{t} {id}".format(t=cleaned_vid_title, id=vid_id) log_title = u"{t} {id}".format(t=vid_title, id=vid_id) clean_filenames.append_line_to_log(log_title.encode("utf-8") + ": " + file_title) yt_dl_output_file = "{td}\\{t}.%(ext)s".format( td=target_dir, t=file_title.encode("mbcs")) # prev sys.getfilesystemencoding() dl_music_cmd = [YT_DL_PROG, vid_link] + yt_dl_opts + [yt_dl_output_file] if not already_downloaded(log_title, music_dir): print "Downloading:", file_title, "\n" proc = subprocess.Popen(dl_music_cmd) proc.wait() log_dled_song(log_title) else: error_alert(file_title + " already downloaded")
def validate_tag_dict_files(tag_dict): file_list = [] for v in tag_dict.itervalues(): file_list.extend(v) file_list = set(file_list) changes_made = False for f in file_list: if not os.path.isfile(f): removed_from_tags = [] for tag in tag_dict.iterkeys(): if f in tag_dict[tag]: tag_dict[tag].remove(f) removed_from_tags.append(tag) changes_made = True log_tag_changes("remove", tag, f) if len(tag_dict[tag]) == 0: print "Empty files list for: " + tag + "; Removing from tags" del tag_dict[tag] m = "Removed invalid file {f_} from tags: {t_}".format(f_=f, t_=", ".join(removed_from_tags)) print m log_invalid_removed_tag_and_file(m) error_alert("Invalid file " + f + "\n\tRemoved from: " + ", ".join(removed_from_tags)) if changes_made: write_tag_file(tag_dict) return tag_dict
def remove_tags_from_filename(filename): tag_list = get_tags_for_file(filename) if len(tag_list) > 0: choice_list = get_user_choices(tag_list) for chosen_tag in choice_list: remove_file_from_tags([chosen_tag], filename) else: error_alert("No tags found for given file: {f}".format(f=filename))
def confirmation_resume(): print "Type 'continue' and press enter to resume" user_input = raw_input().lower() if user_input == "continue": return True else: print "You typed : ", user_input error_alert("Type 'continue' and press enter to resume") return False
def remove_files_from_tag(tag): try: f_list = get_files_from_tags(tag) choice_list = get_user_choices(f_list) for chosen_file in choice_list: remove_file_from_tags([tag], chosen_file) except TagException as e: error_alert(str(e))
def tag_multiple_files(tag, file_list): remove_invalid_files(file_list) if len(file_list) > 0: for f in file_list: add_tags([tag], f) else: error_alert("No valid file to add. No changes have been made.")
def handle_keep(music_filename): try: remove_file_from_tags(["screen"], music_filename) move(music_filename, music_dir) print "Moving complete\n" except Shutil_error: error_alert( "{m} already exists in music directory.\nDeleting {m}".format( m=music_filename)) handle_delete(music_filename)
def handle_delete(music_filename): try: remove_file_from_tags(["screen"], music_filename) os_remove(music_filename) print "Deleted {mf}\n".format(mf=music_filename) log_deleted_song(music_filename) except OSError, e: error_alert( "Failed to delete file {}. No changes have been made.".format( music_filename)) print e.message raise
def handle_tagging(screen_fname): try: copy(screen_fname, music_dir) music_fname = path.join(music_dir, slice_off_dir(screen_fname)) tag_list = raw_input("Enter tag(s). Separate with commas\n").split(',') tag_list = map(str.strip, tag_list) add_tags(tag_list, music_fname, verbose=True) kill_vlc() handle_delete(screen_fname) except Shutil_error: error_alert(("{m} already exists in music directory." + "\nDeleting {m}").format(m=screen_fname)) handle_delete(screen_fname)
def screen_songs(song_list): global glob_vlc_proc_pid stop_screening = False for song in song_list: invalid_key_press = 0 if stop_screening is False: play_music_command = ([MEDIA_PLAYER_PROGRAM] + MEDIA_PLAYER_OPTIONS + [song]) glob_vlc_proc_pid = Popen(play_music_command).pid print "Playing: ", song key_press = get_key_press() while key_press not in [KEEP_KEY, TAG_KEY, DELETE_KEY, QUIT_KEY]: print "Invalid selection" invalid_key_press += 1 if invalid_key_press > 2: confirm_resume = False error_alert("Too many invalid keypresses; Pausing") while confirm_resume is False: confirm_resume = confirmation_resume() key_press = get_key_press() else: char_func_mapping = { KEEP_KEY: lambda: handle_keep(song), DELETE_KEY: lambda: handle_delete(song), TAG_KEY: lambda: handle_tagging(song), } if key_press != TAG_KEY: # handle_tagging calls kill_vlc since vlc will be playing while tagging kill_vlc() if key_press == QUIT_KEY: stop_screening = True else: char_func_mapping[key_press]() song_list.remove(song)
def remove_file_from_tags(tag_list, fname, verbose=True): tag_dict = load_tag_dict() fname = os.path.normpath(fname.lower()) for tag in tag_list: tag = tag.strip().lower() if fname in tag_dict[tag]: log_tag_changes("remove", tag, fname) if verbose: print "Removed {f} from {t}".format(f=fname.encode("unicode_escape"), t=tag) tag_dict[tag].remove(fname) if len(tag_dict[tag]) == 0: print "Empty files list for: " + tag + "; Removing from tags." del tag_dict[tag] else: error_alert("Tag: " + tag + " doesn't have filename: " + fname) log_removed_file(fname, ", ".join(tag_list)) write_tag_file(tag_dict)
def get_newest_file(args_): global args args = args_ if stdin.isatty() is False: print "Piping" f_list = list_from_piped("".join(map(str, stdin.readlines()))) display_full_filepath = True else: f_list = get_file_list() display_full_filepath = False pruned_list = prune_targ_words_from_file_list(f_list, args_.targ_words) sorted_list_ac = sort_by_creation_time(pruned_list) sorted_list = map(lambda x: str(x.file.encode("unicode_escape")), sorted_list_ac) if len(sorted_list) > 0: present_result(sorted_list, display_full_filepath) else: error_alert("Either empty directory or search term(s) not found.")
def rename_files(changes_dict, directory): with open(cleaned_fnames_log, 'a') as writer: # log renaming changes for key in changes_dict.keys(): write_inline("Renamed {n} out of {t} files".format(n=changes_dict.keys().index(key) + 1, t=len(changes_dict.keys()))) try: orig_name = path.join(directory, key) new_name = path.join(directory, changes_dict[key]) if path.isfile(orig_name): # dir won't have tags tag_rename(orig_name, new_name) else: rename(orig_name, new_name) writer.write(key.encode('utf-8') + ": " + changes_dict[key]) writer.write("\n") except WindowsError, e: error_alert("Unable to rename " + key.encode("unicode_escape") + " in to " + changes_dict[key].encode("unicode_escape") + ". Stopping program." + "\n" + str(e)) raise
def merge_changes_to_base_tag_file(base_tag_file_log, tag_file_changes_log): print "Merging tag changes log with base file" with open(tag_file_changes_log) as reader: change_lines = reader.read().split('\n') with open(base_tag_file_log) as reader: base_tag_dict = json.load(reader, object_pairs_hook=collections.OrderedDict) change_lines = [l for l in change_lines if len(l) > 0] for line in change_lines: # last change won't be written yet, can only validate up to all changes except last parse_change_line_to_tag_dict(line, base_tag_dict) # noinspection PyArgumentList base_tag_dict = collections.OrderedDict(sorted(base_tag_dict.items(), key=lambda item: item[0])) # validate backup similar to original log file orig_tag_dict = load_tag_dict() if base_tag_dict == orig_tag_dict: with open(base_tag_file_log, 'w') as writer: tag_dict_str = json.dumps(base_tag_dict, indent=2, ensure_ascii=False, encoding="utf-8", separators=(',', ': ')) writer.write(tag_dict_str.encode("utf-8")) open(tag_file_changes_log, 'w').close() create_backup(base_tag_file_log, backup_dir=os.path.join(default_backup_dir, "tag_file")) else: error_alert("Backup contents not similar to original. Merge aborted!") keys_not_in_orig = [key for key in base_tag_dict if key not in orig_tag_dict] keys_not_in_new = [key for key in orig_tag_dict if key not in base_tag_dict] if len(keys_not_in_orig) > 0: print "Keys in new but not in original", keys_not_in_orig if len(keys_not_in_new) > 0: print "Keys in original but not in new", keys_not_in_new elif len(keys_not_in_new) == 0 and len(keys_not_in_orig) == 0: for k in orig_tag_dict: if orig_tag_dict[k] != base_tag_dict[k]: print k, set(orig_tag_dict[k]).symmetric_difference(set(base_tag_dict[k]))
def main(directory): if path.isdir(directory): changes_dict = clean_file_names(directory) if args.verbose: for key in changes_dict.keys(): print key.encode("unicode_escape") + " ---> " + changes_dict[key] if args.dry_run: print "Dry-run: printing only. No file changes have been made." print str(len(changes_dict)) + " files would have been renamed." else: rename_files(changes_dict, directory) print "renamed " + str(len(changes_dict)) + " files." if path.realpath(directory) == path.realpath(screening_dir): screen_tagging() else: error_alert("Argument must be a valid directory") sys_exit(1)
def clean_string(dirty_str, log_warnings=False): kanji_cleaned_str = kanji_to_romaji(dirty_str) if "\u" in kanji_cleaned_str: untranslated_warn_msg = "Untranslated unicode character found in " + kanji_cleaned_str error_alert(untranslated_warn_msg) if log_warnings: append_line_to_log(untranslated_warn_msg) cleaned = clean_chars(kanji_cleaned_str) token = path.splitext(cleaned) fn_only = token[0] result = cleaned if len(cleaned) == 0 or len(fn_only) == 0: all_inval_warn_msg = dirty_str.encode("unicode_escape") + \ " only consists of invalid characters. Cannot be cleaned." error_alert(all_inval_warn_msg) if log_warnings: append_line_to_log(all_inval_warn_msg) result = dirty_str return result
if key_press == QUIT_KEY: stop_screening = True else: char_func_mapping[key_press]() song_list.remove(song) if __name__ == "__main__": MEDIA_PLAYER_PROGRAM = get_media_player_path() MEDIA_PLAYER_OPTIONS = "--qt-start-minimized " \ "--playlist-enqueue --playlist-autostart --no-crashdump -L".split() KEEP_KEY = 'k' TAG_KEY = 't' DELETE_KEY = 'd' QUIT_KEY = 'q' glob_vlc_proc_pid = None song_list_ = get_files_from_tags(["screen"]) shuffle(song_list_) if len(song_list_) > 0: screen_songs(song_list_) else: error_alert("No music to be screened available")
def remove_invalid_files(file_list): for f in file_list[:]: if not os.path.isfile(f): error_alert(f + " is not a valid file. Removing from file list.") file_list.remove(f)
Sets program to sleep for time_limit minutes Hibernate log is created after sleep with time stamp Calls view_to_do_list to be viewable when resuming from hibernation Sets the computer to hibernate :param time_limit: time limit in minutes """ for i in range(int(time_limit), 0, -1): output = "Time remaining until hibernation: {}".format(str(i)) loading_splash(60, output) create_log() hibernate() view_to_do_list() if __name__ == "__main__": # windll.kernel32.SetConsoleCtrlHandler(0, 1) # disables sigint / ctrl + c if len(argv) < 2: error_alert("Missing time parameter") else: try: main(int(argv[1])) except ValueError: error_alert("Argument must be an integer")