From 5d2989f4cb1db9df492fa1054728d96282bb7eb2 Mon Sep 17 00:00:00 2001 From: Timmy Welch Date: Mon, 18 Apr 2022 18:44:20 -0700 Subject: [PATCH 1/3] Improve file renaming Moves to Python format strings for renaming, handles directory structures, moving of files to a destination directory, sanitizes file paths with pathvalidate and takes a different approach to smart filename cleanup using the Python string.Formatter class Moving to Python format strings means we can point to python documentation for syntax and all we have to do is document the properties and types that are attached to the GenericMetadata class. Switching to pathvalidate allows comictagger to more simply handle both directories and symbols in filenames. The only changes to the string.Formatter class is: 1. format_field returns an empty string if the value is none or an empty string regardless of the format specifier. 2. _vformat drops the previous literal text if the field value is an empty string and lstrips the following literal text of closing special characters. --- comicapi/genericmetadata.py | 90 +++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/comicapi/genericmetadata.py b/comicapi/genericmetadata.py index 5045ba0..ed8baf0 100644 --- a/comicapi/genericmetadata.py +++ b/comicapi/genericmetadata.py @@ -332,3 +332,93 @@ class GenericMetadata: outstr += fmt_str.format(i[0] + ":", i[1]) return outstr + + +md_test = GenericMetadata() + +md_test.is_empty = False +md_test.tag_origin = None +md_test.series = "Cory Doctorow's Futuristic Tales of the Here and Now" +md_test.issue = "1" +md_test.title = "Anda's Game" +md_test.publisher = "IDW Publishing" +md_test.month = 10 +md_test.year = 2007 +md_test.day = 1 +md_test.issue_count = 6 +md_test.volume = 1 +md_test.genre = "Sci-Fi" +md_test.language = "en" +md_test.comments = ( + "For 12-year-old Anda, getting paid real money to kill the characters of players who were cheating in her favorite online " + "computer game was a win-win situation. Until she found out who was paying her, and what those characters meant to the " + "livelihood of children around the world." +) +md_test.volume_count = None +md_test.critical_rating = None +md_test.country = None +md_test.alternate_series = "Tales" +md_test.alternate_number = "2" +md_test.alternate_count = 7 +md_test.imprint = "craphound.com" +md_test.notes = "Tagged with ComicTagger 1.3.2a5 using info from Comic Vine on 2022-04-16 15:52:26. [Issue ID 140529]" +md_test.web_link = "https://comicvine.gamespot.com/cory-doctorows-futuristic-tales-of-the-here-and-no/4000-140529/" +md_test.format = "Series" +md_test.manga = "No" +md_test.black_and_white = None +md_test.page_count = 24 +md_test.maturity_rating = "Everyone 10+" +md_test.story_arc = "Here and Now" +md_test.series_group = "Futuristic Tales" +md_test.scan_info = "(CC BY-NC-SA 3.0)" +md_test.characters = "Anda" +md_test.teams = "Fahrenheit" +md_test.locations = "lonely cottage" +md_test.credits = [ + {"person": "Dara Naraghi", "role": "Writer"}, + {"person": "Esteve Polls", "role": "Penciller"}, + {"person": "Esteve Polls", "role": "Inker"}, + {"person": "Neil Uyetake", "role": "Letterer"}, + {"person": "Sam Kieth", "role": "Cover"}, + {"person": "Ted Adams", "role": "Editor"}, +] +md_test.tags = [] +md_test.pages = [ + {"Image": "0", "ImageHeight": "1280", "ImageSize": "195977", "ImageWidth": "800", "Type": "FrontCover"}, + {"Image": "1", "ImageHeight": "2039", "ImageSize": "611993", "ImageWidth": "1327"}, + {"Image": "2", "ImageHeight": "2039", "ImageSize": "783726", "ImageWidth": "1327"}, + {"Image": "3", "ImageHeight": "2039", "ImageSize": "679584", "ImageWidth": "1327"}, + {"Image": "4", "ImageHeight": "2039", "ImageSize": "788179", "ImageWidth": "1327"}, + {"Image": "5", "ImageHeight": "2039", "ImageSize": "864433", "ImageWidth": "1327"}, + {"Image": "6", "ImageHeight": "2039", "ImageSize": "765606", "ImageWidth": "1327"}, + {"Image": "7", "ImageHeight": "2039", "ImageSize": "876427", "ImageWidth": "1327"}, + {"Image": "8", "ImageHeight": "2039", "ImageSize": "852622", "ImageWidth": "1327"}, + {"Image": "9", "ImageHeight": "2039", "ImageSize": "800205", "ImageWidth": "1327"}, + {"Image": "10", "ImageHeight": "2039", "ImageSize": "746243", "ImageWidth": "1326"}, + {"Image": "11", "ImageHeight": "2039", "ImageSize": "718062", "ImageWidth": "1327"}, + {"Image": "12", "ImageHeight": "2039", "ImageSize": "532179", "ImageWidth": "1326"}, + {"Image": "13", "ImageHeight": "2039", "ImageSize": "686708", "ImageWidth": "1327"}, + {"Image": "14", "ImageHeight": "2039", "ImageSize": "641907", "ImageWidth": "1327"}, + {"Image": "15", "ImageHeight": "2039", "ImageSize": "805388", "ImageWidth": "1327"}, + {"Image": "16", "ImageHeight": "2039", "ImageSize": "668927", "ImageWidth": "1326"}, + {"Image": "17", "ImageHeight": "2039", "ImageSize": "710605", "ImageWidth": "1327"}, + {"Image": "18", "ImageHeight": "2039", "ImageSize": "761398", "ImageWidth": "1326"}, + {"Image": "19", "ImageHeight": "2039", "ImageSize": "743807", "ImageWidth": "1327"}, + {"Image": "20", "ImageHeight": "2039", "ImageSize": "552911", "ImageWidth": "1326"}, + {"Image": "21", "ImageHeight": "2039", "ImageSize": "556827", "ImageWidth": "1327"}, + {"Image": "22", "ImageHeight": "2039", "ImageSize": "675078", "ImageWidth": "1326"}, + { + "Bookmark": "Interview", + "Image": "23", + "ImageHeight": "2032", + "ImageSize": "800965", + "ImageWidth": "1338", + "Type": "Letters", + }, +] +md_test.price = None +md_test.is_version_of = None +md_test.rights = None +md_test.identifier = None +md_test.last_mark = None +md_test.cover_image = None From 49839dc0cb137a1e4920435b5f0b16c38b08496b Mon Sep 17 00:00:00 2001 From: Timmy Welch Date: Mon, 18 Apr 2022 18:59:17 -0700 Subject: [PATCH 2/3] Allow switching between old and new rename templates Show a message dialog explaining that there is a new template format Add a dynamic label to show the effect of a rename Add tests for FileRenamer Remove the filename parameter from the determine_name function --- comicapi/genericmetadata.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/comicapi/genericmetadata.py b/comicapi/genericmetadata.py index ed8baf0..280dc84 100644 --- a/comicapi/genericmetadata.py +++ b/comicapi/genericmetadata.py @@ -259,6 +259,15 @@ class GenericMetadata: if not found: self.credits.append(credit) + def get_primary_credit(self, role): + primary = "" + for credit in self.credits: + if (primary == "" and credit["role"].lower() == role.lower()) or ( + credit["role"].lower() == role.lower() and credit["primary"] + ): + primary = credit["person"] + return primary + def __str__(self): vals = [] if self.is_empty: From 6ba74e3566b3778930cfe350d9b60a713253ac75 Mon Sep 17 00:00:00 2001 From: Timmy Welch Date: Mon, 18 Apr 2022 22:46:46 -0700 Subject: [PATCH 3/3] Add a strict mode to file renaming Strict renaming removes all reserved names and characters regardless of operating system, with out strict mode only for the current Operating System Add more edge cases to smart cleanup Add more tests for file renaming --- comicapi/genericmetadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/comicapi/genericmetadata.py b/comicapi/genericmetadata.py index 280dc84..a8d03b3 100644 --- a/comicapi/genericmetadata.py +++ b/comicapi/genericmetadata.py @@ -382,7 +382,7 @@ md_test.series_group = "Futuristic Tales" md_test.scan_info = "(CC BY-NC-SA 3.0)" md_test.characters = "Anda" md_test.teams = "Fahrenheit" -md_test.locations = "lonely cottage" +md_test.locations = "lonely cottage " md_test.credits = [ {"person": "Dara Naraghi", "role": "Writer"}, {"person": "Esteve Polls", "role": "Penciller"},