aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeonard Kugis <leonard@kug.is>2023-03-21 23:49:42 +0100
committerLeonard Kugis <leonard@kug.is>2023-03-21 23:49:42 +0100
commit7c635fed24bba638f10a73fe39134519ecd675bf (patch)
tree52f1097c02e64ea95fda92766e89d0f9b313b2ba
parent23ed1ff2254a3bf70aced1f10534e6dd1f2c3a3c (diff)
Split util and tmsu functions
-rw-r--r--file-tagger.py119
-rw-r--r--gui.py9
-rw-r--r--tmsu.py71
-rw-r--r--util.py79
4 files changed, 161 insertions, 117 deletions
diff --git a/file-tagger.py b/file-tagger.py
index 9812f62..82aacf7 100644
--- a/file-tagger.py
+++ b/file-tagger.py
@@ -5,119 +5,8 @@ from gui import GuiMain, GuiImage, GuiTag
import cv2
import logging
import magic
-import subprocess
-import re
-import platform
-import readline
-
-'''
-Fetch input prompt with prefilled text.
-
-Parameters:
-prompt: Prompt message.
-text: Prefilled input.
-'''
-def input_with_prefill(prompt, text):
- def hook():
- readline.insert_text(text)
- readline.redisplay()
- readline.set_pre_input_hook(hook)
- result = input(prompt)
- readline.set_pre_input_hook()
- return result
-
-'''
-Checks if the given string is a valid path.
-
-Parameters:
-string: String to be checked.
-'''
-def dir_path(string):
- if os.path.isdir(string):
- return string
- else:
- raise NotADirectoryError(string)
-
-'''
-Opens the given file with the platform default handler.
-
-Parameters:
-file: Path to the file.
-'''
-def open_system(file):
- if platform.system() == 'Darwin': # macOS
- subprocess.call(('open', file))
- elif platform.system() == 'Windows': # Windows
- os.startfile(file)
- else: # linux variants
- subprocess.call(('xdg-open', file))
-
-'''
-Initializes TMSU in a given directory.
-Does nothing, if it is already initialized.
-
-Parameters:
-base: Directory to initialize.
-'''
-def tmsu_init(base):
- logger = logging.getLogger(__name__)
- if not os.path.exists(os.path.join(base, ".tmsu")):
- logger.info("TMSU database does not exist, creating ...")
- proc = subprocess.Popen(["tmsu", "init"], cwd=base)
- proc.wait()
- logger.debug("TMSU returncode: {}".format(proc.returncode))
- if proc.returncode != 0:
- logger.error("Could not initialize TMSU database.")
- return False
- return True
-
-'''
-Reads the tags for the specified file.
-
-Parameters:
-base: Base directory for the database.
-file: File to get the tags for.
-'''
-def tmsu_tags(base, file):
- logger = logging.getLogger(__name__)
- logger.debug("Getting existing tags for file {}".format(file))
- tags = set()
- proc = subprocess.Popen(["tmsu", "tags", os.path.relpath(file, base)], cwd=base, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- proc.wait()
- logger.debug("TMSU returncode: {}".format(proc.returncode))
- if proc.returncode == 0:
- ret = proc.stdout.read().decode()
- logger.debug("Raw TMSU tags: {}".format(ret))
- tags.update(re.split("\s", ret.split(":")[1])[1:-1])
- else:
- logger.error("Could not get tags for file {}".format(file))
- return tags
-
-'''
-Sets tags for the specified file.
-
-Parameters:
-base: Base directory for the database.
-file: File to set the tags for.
-tags: Tags to set.
-untag: If True, it will remove all existing tags first. If False, it will just append new tags.
-'''
-def tmsu_tag(base, file, tags, untag=True):
- logger = logging.getLogger(__name__)
- if untag:
- logger.debug("Untagging file")
- proc = subprocess.Popen(["tmsu", "untag", "--all", os.path.relpath(file, base)], cwd=base, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- proc.wait()
- if proc.returncode != 0:
- logger.error("Could not untag file {}".format(file))
- if tags:
- logger.debug("Writing tags {}".format(tags))
- proc = subprocess.Popen(["tmsu", "tag", os.path.relpath(file, base)] + list(tags), cwd=base, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- proc.wait()
- if proc.returncode != 0:
- logger.error("Could not write tags to file {}".format(file))
- else:
- logger.info("Tags are empty, ignoring")
+from tmsu import *
+from util import *
'''
Walk over all files for the given base directory and all subdirectories recursively.
@@ -199,7 +88,7 @@ def walk(args):
elif ret[0] == GuiTag.RETURN_ABORT:
return
- if not args["gui_tag"]:
+ if ((not args["gui_tag"]) and (not args["skip_prompt"])):
tags = set(input_with_prefill("\nTags for file {}:\n".format(file_path), ','.join(tags)).split(","))
logger.info("Tagging {}".format(tags))
@@ -215,6 +104,7 @@ if __name__ == "__main__":
parser.add_argument('--predict-images-top', nargs='?', const=1, default=10, type=int, help='Defines how many top prediction keywords should be used (default: %(default)s)')
parser.add_argument('--gui-tag', nargs='?', const=1, default=False, type=bool, help='Show GUI for tagging (default: %(default)s)')
parser.add_argument('--open-system', nargs='?', const=1, default=False, type=bool, help='Open all files with system default (default: %(default)s)')
+ parser.add_argument('-s', '--skip-prompt', nargs='?', const=1, default=False, type=bool, help='Skip prompt for file tags (default: %(default)s)')
parser.add_argument('-i', '--index', nargs='?', const=1, default=0, type=int, help='Start tagging at the given file index (default: %(default)s)')
parser.add_argument('-v', '--verbose', action="count", default=0, help="Verbosity level")
args = parser.parse_args()
@@ -237,6 +127,7 @@ if __name__ == "__main__":
"predict_images_top": args.predict_images_top,
"gui_tag": args.gui_tag,
"open_system": args.open_system,
+ "skip_prompt": args.skip_prompt,
"index": args.index,
"verbosity": args.verbose
}
diff --git a/gui.py b/gui.py
index d84aa0a..8ab062d 100644
--- a/gui.py
+++ b/gui.py
@@ -16,6 +16,7 @@ class GuiMain(object):
self.__predict_images_top = StringVar(self.__master, value=str(args["predict_images_top"]))
self.__gui_tag = BooleanVar(self.__master, value=args["gui_tag"])
self.__open_system = BooleanVar(self.__master, value=args["open_system"])
+ self.__skip_prompt = BooleanVar(self.__master, value=args["skip_prompt"])
self.__index = StringVar(self.__master, value=str(args["index"]))
validate_number = (self.__master.register(self.__validate_number))
@@ -31,9 +32,10 @@ class GuiMain(object):
Entry(self.__master, textvariable=self.__predict_images_top, validate='all', validatecommand=(validate_number, '%P')).grid(row=3, column=1, columnspan=1)
Checkbutton(self.__master, text="Show GUI for tagging", variable=self.__gui_tag).grid(row=4, column=0, columnspan=4, sticky=W)
Checkbutton(self.__master, text="Open all files with system default", variable=self.__open_system).grid(row=5, column=0, columnspan=4, sticky=W)
- Label(self.__master, text="Start at index:").grid(row=6, column=0)
- Entry(self.__master, textvariable=self.__index, validate='all', validatecommand=(validate_number, '%P')).grid(row=6, column=1, columnspan=1)
- Button(self.__master, text="Start", command=self.__master.destroy).grid(row=7, column=0, columnspan=4)
+ Checkbutton(self.__master, text="Skip prompt for file tags", variable=self.__skip_prompt).grid(row=6, column=0, columnspan=4, sticky=W)
+ Label(self.__master, text="Start at index:").grid(row=7, column=0)
+ Entry(self.__master, textvariable=self.__index, validate='all', validatecommand=(validate_number, '%P')).grid(row=7, column=1, columnspan=1)
+ Button(self.__master, text="Start", command=self.__master.destroy).grid(row=8, column=0, columnspan=4)
def loop(self):
self.__master.mainloop()
@@ -44,6 +46,7 @@ class GuiMain(object):
self.__args["predict_images_top"] = int(self.__predict_images_top.get())
self.__args["gui_tag"] = self.__gui_tag.get()
self.__args["open_system"] = self.__open_system.get()
+ self.__args["skip_prompt"] = self.__skip_prompt.get()
self.__args["index"] = int(self.__index.get())
return self.__args
diff --git a/tmsu.py b/tmsu.py
new file mode 100644
index 0000000..4bd8946
--- /dev/null
+++ b/tmsu.py
@@ -0,0 +1,71 @@
+import subprocess
+import re
+import logging
+import os
+
+'''
+Initializes TMSU in a given directory.
+Does nothing, if it is already initialized.
+
+Parameters:
+base: Directory to initialize.
+'''
+def tmsu_init(base):
+ logger = logging.getLogger(__name__)
+ if not os.path.exists(os.path.join(base, ".tmsu")):
+ logger.info("TMSU database does not exist, creating ...")
+ proc = subprocess.Popen(["tmsu", "init"], cwd=base)
+ proc.wait()
+ logger.debug("TMSU returncode: {}".format(proc.returncode))
+ if proc.returncode != 0:
+ logger.error("Could not initialize TMSU database.")
+ return False
+ return True
+
+'''
+Reads the tags for the specified file.
+
+Parameters:
+base: Base directory for the database.
+file: File to get the tags for.
+'''
+def tmsu_tags(base, file):
+ logger = logging.getLogger(__name__)
+ logger.debug("Getting existing tags for file {}".format(file))
+ tags = set()
+ proc = subprocess.Popen(["tmsu", "tags", os.path.relpath(file, base)], cwd=base, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc.wait()
+ logger.debug("TMSU returncode: {}".format(proc.returncode))
+ if proc.returncode == 0:
+ ret = proc.stdout.read().decode()
+ logger.debug("Raw TMSU tags: {}".format(ret))
+ tags.update(re.split("\s", ret.split(":")[1])[1:-1])
+ else:
+ logger.error("Could not get tags for file {}".format(file))
+ return tags
+
+'''
+Sets tags for the specified file.
+
+Parameters:
+base: Base directory for the database.
+file: File to set the tags for.
+tags: Tags to set.
+untag: If True, it will remove all existing tags first. If False, it will just append new tags.
+'''
+def tmsu_tag(base, file, tags, untag=True):
+ logger = logging.getLogger(__name__)
+ if untag:
+ logger.debug("Untagging file")
+ proc = subprocess.Popen(["tmsu", "untag", "--all", os.path.relpath(file, base)], cwd=base, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc.wait()
+ if proc.returncode != 0:
+ logger.error("Could not untag file {}".format(file))
+ if tags:
+ logger.debug("Writing tags {}".format(tags))
+ proc = subprocess.Popen(["tmsu", "tag", os.path.relpath(file, base)] + list(tags), cwd=base, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ proc.wait()
+ if proc.returncode != 0:
+ logger.error("Could not write tags to file {}".format(file))
+ else:
+ logger.info("Tags are empty, ignoring") \ No newline at end of file
diff --git a/util.py b/util.py
new file mode 100644
index 0000000..2bf4ff8
--- /dev/null
+++ b/util.py
@@ -0,0 +1,79 @@
+import subprocess
+import logging
+import cv2
+import platform
+import readline
+import os
+
+def image_resize(image, width = None, height = None, inter = cv2.INTER_AREA):
+ # initialize the dimensions of the image to be resized and
+ # grab the image size
+ dim = None
+ (h, w) = image.shape[:2]
+
+ # if both the width and height are None, then return the
+ # original image
+ if width is None and height is None:
+ return image
+
+ # check to see if the width is None
+ if width is None:
+ # calculate the ratio of the height and construct the
+ # dimensions
+ r = height / float(h)
+ dim = (int(w * r), height)
+
+ # otherwise, the height is None
+ else:
+ # calculate the ratio of the width and construct the
+ # dimensions
+ r = width / float(w)
+ dim = (width, int(h * r))
+
+ # resize the image
+ resized = cv2.resize(image, dim, interpolation = inter)
+
+ # return the resized image
+ return resized
+
+'''
+Fetch input prompt with prefilled text.
+
+Parameters:
+prompt: Prompt message.
+text: Prefilled input.
+'''
+def input_with_prefill(prompt, text):
+ def hook():
+ readline.insert_text(text)
+ readline.redisplay()
+ readline.set_pre_input_hook(hook)
+ result = input(prompt)
+ readline.set_pre_input_hook()
+ return result
+
+'''
+Checks if the given string is a valid path.
+
+Parameters:
+string: String to be checked.
+'''
+def dir_path(string):
+ if os.path.isdir(string):
+ return string
+ else:
+ raise NotADirectoryError(string)
+
+'''
+Opens the given file with the platform default handler.
+
+Parameters:
+file: Path to the file.
+'''
+def open_system(file):
+ if platform.system() == 'Darwin': # macOS
+ subprocess.call(('open', file))
+ elif platform.system() == 'Windows': # Windows
+ os.startfile(file)
+ else: # linux variants
+ subprocess.call(('xdg-open', file)) \ No newline at end of file