Skip to content

Commit

Permalink
Added group --group-by-xmp to recreate grouping that were already wri…
Browse files Browse the repository at this point in the history
…tten in dc:description.
  • Loading branch information
Claudius Röhl committed Feb 23, 2025
1 parent 65d9641 commit 84958dd
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 0 deletions.
8 changes: 8 additions & 0 deletions modules/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@
action="store_true",
)

groupparser.add_argument(
"--group-by-xmp",
help="Group by xmp data. If set will look into dc:description. If existent, will use this as groupname. If not, will do nothing.",
action="store_true",
dest="group_by_xmp",
)

rateparser.add_argument(
"-o",
"--overrule",
Expand Down Expand Up @@ -380,6 +387,7 @@ def main():
undoAutomatedGrouping=args.group_undogrouping,
addMissingTimestampsToSubfolders=args.group_timestamps,
checkSequence=args.group_check_seq,
groupByXmp=args.group_by_xmp,
)
elif should_execute_stage("rate", args):
mow.rate(
Expand Down
29 changes: 29 additions & 0 deletions modules/general/mediagrouper.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class GrouperInput(TransitionerInput):
addMissingTimestampsToSubfolders: bool = False
separationDistanceInHours: bool = 12
checkSequence: bool = False
groupByXmp: bool = False


class MediaGrouper(MediaTransitioner):
Expand Down Expand Up @@ -125,13 +126,41 @@ def prepareTransition(self):
)
self.checkCorrectSequence()
return
if self.input.groupByXmp:
self.print_info("Start grouping by XMP..")
self.groupByXmp()
return

self.print_info("Start transitioning from group stage..")
grouped, self.toTransition = self.getCorrectlyGroupedFiles()

self.printStatisticsOf(grouped)
self.setOptionalXMP(grouped)

def groupByXmp(self):
fileToGroup: dict[MediaFile, str] = {}
for mediaFile in track(self.toTreat):
relative_subfolders = (
Path(mediaFile.getAllFileNames()[0]).relative_to(self.src).parents
)
# treat only files in the root folder
if len(relative_subfolders) > 1:
continue
desc = self.fm.read_tags(
mediaFile.getAllFileNames()[0], [MowTag.description]
)
if MowTag.description in desc and desc[MowTag.description] != "":
groupname = desc[MowTag.description]
fileToGroup[mediaFile] = groupname
self.logger.debug(f"Found groupname '{groupname}' for file {mediaFile}")

self.logger.info(
f"Found {len(fileToGroup)} files with groupname in dc:description tag."
)
if not self.dry:
for file, groupname in fileToGroup.items():
file.moveTo(join(self.src, groupname, basename(str(file))))

def getTasks(self) -> list[TransitionTask]:
self.prepareTransition()
return self.toTransition
Expand Down
2 changes: 2 additions & 0 deletions modules/mow/mow.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def group(
undoAutomatedGrouping=False,
addMissingTimestampsToSubfolders=False,
checkSequence=False,
groupByXmp=False,
):
src, dst = self._getSrcDstForStage("group")
self._printEmphasized("Stage Group")
Expand All @@ -165,6 +166,7 @@ def group(
addMissingTimestampsToSubfolders=addMissingTimestampsToSubfolders,
undoAutomatedGrouping=undoAutomatedGrouping,
checkSequence=checkSequence,
groupByXmp=groupByXmp,
**self.basicInputParameter,
)
)()
Expand Down
2 changes: 2 additions & 0 deletions modules/mow/mowtags.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
import json
import os
from pathlib import Path
from time import sleep
Expand Down Expand Up @@ -56,6 +57,7 @@ class InternalTag(StrEnum):

def __init__(self):
self.et = ExifToolHelper()
self.et.encoding = "utf8"

def read_tags(
self,
Expand Down
62 changes: 62 additions & 0 deletions tests/test_grouper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from modules.mow.mowtags import MowTag

from modules.mow.mowtags import MowTagFileManipulator

from ..modules.general.mediagrouper import MediaGrouper, GrouperInput

testfolder = "tests"
Expand Down Expand Up @@ -636,3 +638,63 @@ def test_addMissingTimestampWillWorkIfSomeNumberAndNotDateDashesArePresent():
assert exists(
join(src, "2022-12-12@120000 TEST122-122-122", "2022-12-12@120000_test.JPG")
)


def test_groupByXMPdoesWork():
fullname = join(src, "2022-12-12@120000_test.JPG")
prepareTest(srcname=fullname)

assert exists(fullname)

group = "2022-12-12@120000 Subfolder"
MowTagFileManipulator().write_tags(
Path(fullname),
{MowTag.description: group},
)

MediaGrouper(
input=GrouperInput(
src=src,
dst=dst,
dry=False,
separationDistanceInHours=4,
automaticGrouping=False,
undoAutomatedGrouping=False,
addMissingTimestampsToSubfolders=False,
groupByXmp=True,
)
)()

assert not exists(fullname)
assert exists(join(src, group, "2022-12-12@120000_test.JPG"))


def test_groupByXMPNotExecutedIfAlreadyInGroupSubfolder():
fullname = join(
src, "2022-12-12@120000 TEST122-122-122", "2022-12-12@120000_test.JPG"
)
prepareTest(srcname=fullname)

assert exists(fullname)

group = "2022-12-12@120000 Subfolder"
MowTagFileManipulator().write_tags(
Path(fullname),
{MowTag.description: group},
)

MediaGrouper(
input=GrouperInput(
src=src,
dst=dst,
dry=False,
separationDistanceInHours=4,
automaticGrouping=False,
undoAutomatedGrouping=False,
addMissingTimestampsToSubfolders=False,
groupByXmp=True,
)
)()

assert exists(fullname)
assert not exists(join(src, group, "2022-12-12@120000_test.JPG"))

0 comments on commit 84958dd

Please sign in to comment.