mirror of
https://git.srhtnin.garden/sarah/SaraSort.git
synced 2026-10-15 02:53:17 +02:00
Follow SaraSortd 7.3: catch-alls as fallback, path parsing, nested variables
The tester tries specific patterns before catch-alls, directory paths only get %Name% lookups and date/time variables, and nested %Name%s resolve. Warnings for what 7.3 fixed are gone; a SaraSortd older than 7.3 gets a warning. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
28252e3101
commit
d0e5eb2086
2 files changed
+87
-60
No files matched your search
@@ -59,6 +59,11 @@ def GetConf(Parameter: str, Data: dict) -> Any:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def IsCatchAll(Pattern: str) -> bool:
|
||||||
|
"""SaraSortd 7.3's IsCatchAll: a pattern of only "*" takes any file, so it's a fallback."""
|
||||||
|
return Pattern != "" and set(Pattern) == {"*"}
|
||||||
|
|
||||||
|
|
||||||
def MajorVersion(Version: str) -> str:
|
def MajorVersion(Version: str) -> str:
|
||||||
return str(Version).split(".")[0]
|
return str(Version).split(".")[0]
|
||||||
|
|
||||||
@@ -177,12 +182,44 @@ class Setup:
|
|||||||
if not Content:
|
if not Content:
|
||||||
return str(VarCall) if VarCall is not None else ""
|
return str(VarCall) if VarCall is not None else ""
|
||||||
Found = GetConf(Content, ConfData)
|
Found = GetConf(Content, ConfData)
|
||||||
return str(Found) if Found is not None else Match.group(0)
|
return self.ResolveLookups(str(Found), ConfData) if Found is not None else Match.group(0)
|
||||||
|
|
||||||
return re.sub(f"{re.escape(Call[0])}(.*?){re.escape(Call[1])}", Replacer, String)
|
return re.sub(f"{re.escape(Call[0])}(.*?){re.escape(Call[1])}", Replacer, String)
|
||||||
|
|
||||||
|
def ResolveLookups(self, String: str, ConfData: Optional[dict] = None, Depth: int = 0) -> str:
|
||||||
|
"""SaraSortd 7.3's ResolveLookups: %Name% lookups, also inside the values
|
||||||
|
they bring in (ImageDir = "%RootDir%/Images" used as "%ImageDir%").
|
||||||
|
Unknown names are left as they are."""
|
||||||
|
ConfData = self.Data if ConfData is None else ConfData
|
||||||
|
Call = self.Vars.get("VarCall", "%%")
|
||||||
|
if len(Call) < 2:
|
||||||
|
return String
|
||||||
|
|
||||||
|
def Replacer(Match: re.Match) -> str:
|
||||||
|
Found = GetConf(Match.group(1), ConfData) if Match.group(1) else None
|
||||||
|
if Found is None or Depth >= 10:
|
||||||
|
return Match.group(0)
|
||||||
|
return self.ResolveLookups(str(Found), ConfData, Depth + 1)
|
||||||
|
|
||||||
|
return re.sub(f"{re.escape(Call[0])}(.*?){re.escape(Call[1])}", Replacer, String)
|
||||||
|
|
||||||
|
def ParsePath(self, String: str) -> str:
|
||||||
|
"""SaraSortd 7.3's ParsePath: directory paths only get %Name% lookups and
|
||||||
|
the date and time variables, so "~/Stuff&Things" stays as it is; a
|
||||||
|
leading "~" is the home directory."""
|
||||||
|
Now = datetime.datetime.now()
|
||||||
|
V = self.Vars
|
||||||
|
for Key, Value in {
|
||||||
|
V.get("Year"): str(Now.year), V.get("Month"): str(Now.month).rjust(2, "0"),
|
||||||
|
V.get("Day"): str(Now.day).rjust(2, "0"), V.get("Hour"): str(Now.hour).rjust(2, "0"),
|
||||||
|
V.get("Minute"): str(Now.minute).rjust(2, "0"), V.get("Second"): str(Now.second).rjust(2, "0"),
|
||||||
|
}.items():
|
||||||
|
if Key and Key in String:
|
||||||
|
String = String.replace(Key, Value)
|
||||||
|
return os.path.expanduser(self.ResolveLookups(String))
|
||||||
|
|
||||||
def ResolveDir(self, Raw: str) -> str:
|
def ResolveDir(self, Raw: str) -> str:
|
||||||
return self.Parse(Raw)
|
return self.ParsePath(Raw)
|
||||||
|
|
||||||
def DirList(self, Key: str) -> list[str]:
|
def DirList(self, Key: str) -> list[str]:
|
||||||
Value = self.Dirs.get(Key, [])
|
Value = self.Dirs.get(Key, [])
|
||||||
@@ -216,14 +253,14 @@ class Setup:
|
|||||||
|
|
||||||
def ConfFolder(self, PathText: str) -> Path:
|
def ConfFolder(self, PathText: str) -> Path:
|
||||||
"""SaraSortd's ConfFolder: relative paths count from GlobalConf.toml's folder."""
|
"""SaraSortd's ConfFolder: relative paths count from GlobalConf.toml's folder."""
|
||||||
Parsed = self.Parse(str(PathText))
|
Parsed = self.ParsePath(str(PathText))
|
||||||
if os.path.isabs(Parsed):
|
if os.path.isabs(Parsed):
|
||||||
return Path(os.path.normpath(Parsed))
|
return Path(os.path.normpath(Parsed))
|
||||||
return Path(os.path.normpath(self.GlobalPath.parent / Parsed))
|
return Path(os.path.normpath(self.GlobalPath.parent / Parsed))
|
||||||
|
|
||||||
def FlatName(self, DirPath: str) -> str:
|
def FlatName(self, DirPath: str) -> str:
|
||||||
"""SaraSortd's FlatName: "%RootDir%/Pictures/Cats" -> "Pictures_Cats"."""
|
"""SaraSortd's FlatName: "%RootDir%/Pictures/Cats" -> "Pictures_Cats"."""
|
||||||
Root = self.Parse(str(self.Dirs.get("RootDir", ""))).rstrip("/")
|
Root = self.ParsePath(str(self.Dirs.get("RootDir", ""))).rstrip("/")
|
||||||
DirPath = DirPath.rstrip("/")
|
DirPath = DirPath.rstrip("/")
|
||||||
if Root and DirPath.startswith(Root + "/"):
|
if Root and DirPath.startswith(Root + "/"):
|
||||||
Relative = DirPath[len(Root) + 1:]
|
Relative = DirPath[len(Root) + 1:]
|
||||||
@@ -235,7 +272,7 @@ class Setup:
|
|||||||
"""SaraSortd 7.2: a config named in [DirConfs], or one in DirConfDir.
|
"""SaraSortd 7.2: a config named in [DirConfs], or one in DirConfDir.
|
||||||
None when the config lives inside the directory."""
|
None when the config lives inside the directory."""
|
||||||
for Key, Value in (self.Data.get("DirConfs") or {}).items():
|
for Key, Value in (self.Data.get("DirConfs") or {}).items():
|
||||||
if self.Parse(str(Key)).rstrip("/") == DirPath.rstrip("/"):
|
if self.ParsePath(str(Key)).rstrip("/") == DirPath.rstrip("/"):
|
||||||
if isinstance(Value, dict):
|
if isinstance(Value, dict):
|
||||||
Value = Value.get(Kind)
|
Value = Value.get(Kind)
|
||||||
if Value:
|
if Value:
|
||||||
@@ -343,9 +380,8 @@ class Setup:
|
|||||||
|
|
||||||
def _DirAccepts(self, OutConf: dict, OutputPath: str, InputPath: str) -> bool:
|
def _DirAccepts(self, OutConf: dict, OutputPath: str, InputPath: str) -> bool:
|
||||||
"""The output directory's own ValidInputDirs, as DecideNewPath checks it."""
|
"""The output directory's own ValidInputDirs, as DecideNewPath checks it."""
|
||||||
Parent = GetConf("ParentDir", OutConf)
|
|
||||||
for Valid in GetConf("ValidInputDirs", OutConf) or []:
|
for Valid in GetConf("ValidInputDirs", OutConf) or []:
|
||||||
if fnmatch.fnmatchcase(InputPath, self.Parse(str(Valid), Parent=Parent)):
|
if fnmatch.fnmatchcase(InputPath, self.ParsePath(str(Valid))):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -354,8 +390,7 @@ class Setup:
|
|||||||
Own = Entry.get("ValidInputDirs")
|
Own = Entry.get("ValidInputDirs")
|
||||||
if Own is None:
|
if Own is None:
|
||||||
return True
|
return True
|
||||||
Parent = os.path.basename(OutputPath)
|
return any(fnmatch.fnmatchcase(InputPath, self.ParsePath(str(Valid))) for Valid in Own)
|
||||||
return any(fnmatch.fnmatchcase(InputPath, self.Parse(str(Valid), Parent=Parent)) for Valid in Own)
|
|
||||||
|
|
||||||
def Edges(self) -> list[Edge]:
|
def Edges(self) -> list[Edge]:
|
||||||
Edges = []
|
Edges = []
|
||||||
@@ -580,7 +615,6 @@ class Setup:
|
|||||||
return "That rule no longer exists."
|
return "That rule no longer exists."
|
||||||
Entry = Files[Index]
|
Entry = Files[Index]
|
||||||
Own = Entry.get("ValidInputDirs")
|
Own = Entry.get("ValidInputDirs")
|
||||||
Parent = os.path.basename(OutputPath)
|
|
||||||
if Own is None:
|
if Own is None:
|
||||||
# It took files from every input: list the others explicitly.
|
# It took files from every input: list the others explicitly.
|
||||||
Others = [Other for Other in self.ConnectedInputs(OutputPath) if Other != InputPath]
|
Others = [Other for Other in self.ConnectedInputs(OutputPath) if Other != InputPath]
|
||||||
@@ -588,7 +622,7 @@ class Setup:
|
|||||||
Own = Entry["ValidInputDirs"]
|
Own = Entry["ValidInputDirs"]
|
||||||
else:
|
else:
|
||||||
for Position in reversed(range(len(Own))):
|
for Position in reversed(range(len(Own))):
|
||||||
if self.Parse(str(Own[Position]), Parent=Parent) == InputPath:
|
if self.ParsePath(str(Own[Position])) == InputPath:
|
||||||
del Own[Position]
|
del Own[Position]
|
||||||
Message = None
|
Message = None
|
||||||
if self._EntryAccepts(Entry.unwrap(), OutputPath, InputPath):
|
if self._EntryAccepts(Entry.unwrap(), OutputPath, InputPath):
|
||||||
@@ -636,8 +670,7 @@ class Setup:
|
|||||||
if Own is None:
|
if Own is None:
|
||||||
Remaining = [self.Shorthand(Other) for Other in Others]
|
Remaining = [self.Shorthand(Other) for Other in Others]
|
||||||
else:
|
else:
|
||||||
Parent = os.path.basename(OutputPath)
|
Remaining = [Valid for Valid in Own if self.ParsePath(str(Valid)) != InputPath]
|
||||||
Remaining = [Valid for Valid in Own if self.Parse(str(Valid), Parent=Parent) != InputPath]
|
|
||||||
Test = dict(Entry.unwrap(), ValidInputDirs=Remaining)
|
Test = dict(Entry.unwrap(), ValidInputDirs=Remaining)
|
||||||
if self._EntryAccepts(Test, OutputPath, InputPath):
|
if self._EntryAccepts(Test, OutputPath, InputPath):
|
||||||
Remaining = None # a wildcard still matches this input: can't split it off
|
Remaining = None # a wildcard still matches this input: can't split it off
|
||||||
@@ -675,20 +708,18 @@ class Setup:
|
|||||||
Changed = False
|
Changed = False
|
||||||
DirValid = Document.get("ValidInputDirs")
|
DirValid = Document.get("ValidInputDirs")
|
||||||
if isinstance(DirValid, list):
|
if isinstance(DirValid, list):
|
||||||
Parent = Document.get("ParentDir")
|
|
||||||
for Position in reversed(range(len(DirValid))):
|
for Position in reversed(range(len(DirValid))):
|
||||||
if self.Parse(str(DirValid[Position]), Parent=Parent) == PathText:
|
if self.ParsePath(str(DirValid[Position])) == PathText:
|
||||||
del DirValid[Position]
|
del DirValid[Position]
|
||||||
Changed = True
|
Changed = True
|
||||||
Files = Document.get("Files")
|
Files = Document.get("Files")
|
||||||
Parent = os.path.basename(OutputPath)
|
|
||||||
for Index in reversed(range(len(Files) if Files is not None else 0)):
|
for Index in reversed(range(len(Files) if Files is not None else 0)):
|
||||||
Own = Files[Index].get("ValidInputDirs")
|
Own = Files[Index].get("ValidInputDirs")
|
||||||
if not isinstance(Own, list):
|
if not isinstance(Own, list):
|
||||||
continue
|
continue
|
||||||
Before = len(Own)
|
Before = len(Own)
|
||||||
for Position in reversed(range(Before)):
|
for Position in reversed(range(Before)):
|
||||||
if self.Parse(str(Own[Position]), Parent=Parent) == PathText:
|
if self.ParsePath(str(Own[Position])) == PathText:
|
||||||
del Own[Position]
|
del Own[Position]
|
||||||
if len(Own) != Before:
|
if len(Own) != Before:
|
||||||
Changed = True
|
Changed = True
|
||||||
@@ -729,6 +760,7 @@ class Setup:
|
|||||||
Steps.append("None of the input's own patterns match, so it stays where it is.")
|
Steps.append("None of the input's own patterns match, so it stays where it is.")
|
||||||
return SimulationResult(Steps, None, "Skipped")
|
return SimulationResult(Steps, None, "Skipped")
|
||||||
|
|
||||||
|
Candidates = []
|
||||||
for OutputPath in self.Outputs:
|
for OutputPath in self.Outputs:
|
||||||
OutConf = self.LoadDirConf(OutputPath, "Out")
|
OutConf = self.LoadDirConf(OutputPath, "Out")
|
||||||
if OutConf is None:
|
if OutConf is None:
|
||||||
@@ -746,24 +778,30 @@ class Setup:
|
|||||||
if Count >= Limit:
|
if Count >= Limit:
|
||||||
Steps.append(f"{OutputPath}: full ({Count}/{Limit} files).")
|
Steps.append(f"{OutputPath}: full ({Count}/{Limit} files).")
|
||||||
continue
|
continue
|
||||||
for Entry in OutConf.get("Files", []):
|
Candidates.append((OutputPath, OutConf))
|
||||||
if not self._EntryAccepts(Entry, OutputPath, InputPath):
|
|
||||||
continue
|
# SaraSortd 7.3: specific patterns first, catch-alls ("*") only as a fallback.
|
||||||
Pattern = str(Entry.get("Pattern", ""))
|
for CatchAll in (False, True):
|
||||||
if Entry.get("CaseSensitive", 0) == 1:
|
if CatchAll:
|
||||||
Match = fnmatch.fnmatchcase(FileName, Pattern)
|
Steps.append("No specific pattern takes it; trying catch-alls (\"*\").")
|
||||||
else:
|
for OutputPath, OutConf in Candidates:
|
||||||
Match = fnmatch.fnmatch(FileName.lower(), Pattern.lower())
|
for Entry in OutConf.get("Files", []):
|
||||||
if not Match:
|
Pattern = str(Entry.get("Pattern", ""))
|
||||||
continue
|
if IsCatchAll(Pattern) != CatchAll or not self._EntryAccepts(Entry, OutputPath, InputPath):
|
||||||
NewName = self.PreviewName(str(Entry.get("NewFileName", "~^")), FileName, OutputPath, Entry, OutConf)
|
continue
|
||||||
if Entry.get("Overwrite", 1) == 0 and os.path.exists(os.path.join(OutputPath, NewName)):
|
if Entry.get("CaseSensitive", 0) == 1:
|
||||||
Steps.append(f"{OutputPath}: {Pattern} matches, but {NewName} exists and Overwrite = 0.")
|
Match = fnmatch.fnmatchcase(FileName, Pattern)
|
||||||
continue
|
else:
|
||||||
Action = "moved" if OutConf.get("DeleteOrg", 1) == 1 else "copied"
|
Match = fnmatch.fnmatch(FileName.lower(), Pattern.lower())
|
||||||
Steps.append(f"{OutputPath}: {Pattern} matches, so it's {Action} and named {NewName}.")
|
if not Match:
|
||||||
return SimulationResult(Steps, f"{OutputPath}/{NewName}", "Sorted")
|
continue
|
||||||
Steps.append(f"{OutputPath}: no pattern matches.")
|
NewName = self.PreviewName(str(Entry.get("NewFileName", "~^")), FileName, OutputPath, Entry, OutConf)
|
||||||
|
if Entry.get("Overwrite", 1) == 0 and os.path.exists(os.path.join(OutputPath, NewName)):
|
||||||
|
Steps.append(f"{OutputPath}: {Pattern} matches, but {NewName} exists and Overwrite = 0.")
|
||||||
|
continue
|
||||||
|
Action = "moved" if OutConf.get("DeleteOrg", 1) == 1 else "copied"
|
||||||
|
Steps.append(f"{OutputPath}: {Pattern} matches, so it's {Action} and named {NewName}.")
|
||||||
|
return SimulationResult(Steps, f"{OutputPath}/{NewName}", "Sorted")
|
||||||
Failed = self.SpecialDir("FailedDir")
|
Failed = self.SpecialDir("FailedDir")
|
||||||
Steps.append(f"No output takes it, so it goes to {Failed}.")
|
Steps.append(f"No output takes it, so it goes to {Failed}.")
|
||||||
return SimulationResult(Steps, f"{Failed}/{FileName}" if Failed else None, "Failed")
|
return SimulationResult(Steps, f"{Failed}/{FileName}" if Failed else None, "Failed")
|
||||||
@@ -813,7 +851,7 @@ class Setup:
|
|||||||
for Key in ("InputDir", "OutputDir"):
|
for Key in ("InputDir", "OutputDir"):
|
||||||
for Raw in self.DirList(Key):
|
for Raw in self.DirList(Key):
|
||||||
if Leftover.search(self.ResolveDir(Raw)):
|
if Leftover.search(self.ResolveDir(Raw)):
|
||||||
Found.append(("Error", f"{Raw} doesn't resolve (SaraSortd only replaces one level of variables)."))
|
Found.append(("Error", f"{Raw} uses a %Name% that GlobalConf.toml doesn't define."))
|
||||||
|
|
||||||
Inputs = list(dict.fromkeys(self.Inputs))
|
Inputs = list(dict.fromkeys(self.Inputs))
|
||||||
Outputs = list(dict.fromkeys(self.Outputs))
|
Outputs = list(dict.fromkeys(self.Outputs))
|
||||||
@@ -844,20 +882,14 @@ class Setup:
|
|||||||
UsesOwnInputs = UsesOwnInputs or "ValidInputDirs" in Entry
|
UsesOwnInputs = UsesOwnInputs or "ValidInputDirs" in Entry
|
||||||
for Missing in ("Pattern", "NewFileName", "NextNum", "NextChar", "CaseSensitive", "Overwrite"):
|
for Missing in ("Pattern", "NewFileName", "NextNum", "NextChar", "CaseSensitive", "Overwrite"):
|
||||||
if Missing not in Entry:
|
if Missing not in Entry:
|
||||||
Found.append(("Error", f"{OutputPath}: [[Files]] #{Position + 1} has no {Missing}; SaraSortd will crash on it."))
|
if Missing != "Pattern" and Daemon and VersionAtLeast(Daemon, (7, 3)):
|
||||||
if Entry.get("Pattern") == "*" and "ValidInputDirs" not in Entry and Position < len(Entries) - 1:
|
Found.append(("Info", f"{OutputPath}: [[Files]] #{Position + 1} has no {Missing}; SaraSortd fills it in from the template on its next start."))
|
||||||
Found.append(("Warning", f"{OutputPath}: [[Files]] #{Position + 1} is a catch-all \"*\", so the entries after it never get a file."))
|
else:
|
||||||
for InputPath in Inputs:
|
Found.append(("Error", f"{OutputPath}: [[Files]] #{Position + 1} has no {Missing}; SaraSortd will crash on it."))
|
||||||
# SaraSortd tries outputs in OutputDir order and stops at the first match.
|
if Daemon and not VersionAtLeast(Daemon, (7, 3)):
|
||||||
CatchAll = None
|
Found.append(("Warning", f"SaraSort shows how SaraSortd 7.3 sorts, and SaraSortd {Daemon} differs: a catch-all (\"*\") "
|
||||||
for FoundEdge in sorted(
|
"output listed first takes every file, nested %Name%s don't resolve, and ! & @ ~ ^ in "
|
||||||
(FoundEdge for FoundEdge in Edges if FoundEdge.Input == InputPath),
|
"paths get swapped. Update SaraSortd to 7.3."))
|
||||||
key=lambda FoundEdge: Outputs.index(FoundEdge.Output),
|
|
||||||
):
|
|
||||||
if CatchAll:
|
|
||||||
Found.append(("Warning", f"{CatchAll} takes every file from {InputPath} first, so {FoundEdge.Output} never gets any ({', '.join(FoundEdge.Patterns)})."))
|
|
||||||
elif "*" in FoundEdge.Patterns:
|
|
||||||
CatchAll = FoundEdge.Output
|
|
||||||
Central = self.CentralFolder()
|
Central = self.CentralFolder()
|
||||||
if (Central or self.Data.get("DirConfs")) and Daemon and not VersionAtLeast(Daemon, (7, 2)):
|
if (Central or self.Data.get("DirConfs")) and Daemon and not VersionAtLeast(Daemon, (7, 2)):
|
||||||
Found.append(("Error", f"Directory configs are kept outside their directories (DirConfDir / [DirConfs]), "
|
Found.append(("Error", f"Directory configs are kept outside their directories (DirConfDir / [DirConfs]), "
|
||||||
@@ -870,10 +902,5 @@ class Setup:
|
|||||||
if UsesOwnInputs and Daemon and not VersionAtLeast(Daemon, (7, 1)):
|
if UsesOwnInputs and Daemon and not VersionAtLeast(Daemon, (7, 1)):
|
||||||
Found.append(("Error", f"Some [[Files]] entries have their own ValidInputDirs, which SaraSortd {Daemon} ignores. Update SaraSortd to 7.1."))
|
Found.append(("Error", f"Some [[Files]] entries have their own ValidInputDirs, which SaraSortd {Daemon} ignores. Update SaraSortd to 7.1."))
|
||||||
|
|
||||||
for Raw in self.DirList("InputDir") + self.DirList("OutputDir"):
|
|
||||||
Odd = [Char for Char in (self.Vars.get(Key) for Key in ("NextNum", "NextChar", "Parent", "OrgFileName", "OrgFileType")) if Char and Char in Raw]
|
|
||||||
if Odd:
|
|
||||||
Found.append(("Warning", f"{Raw} contains {', '.join(Odd)}, which SaraSortd swaps for a variable."))
|
|
||||||
|
|
||||||
Order = {"Error": 0, "Warning": 1, "Info": 2}
|
Order = {"Error": 0, "Warning": 1, "Info": 2}
|
||||||
return sorted(Found, key=lambda Item: Order[Item[0]])
|
return sorted(Found, key=lambda Item: Order[Item[0]])
|
||||||
+5
-5
@@ -151,12 +151,12 @@ def Backup(Config: AppConfig) -> Optional[Path]:
|
|||||||
return BackupPath
|
return BackupPath
|
||||||
|
|
||||||
|
|
||||||
def _RemapList(TheSetup: Setup, Values, Remap: dict[str, str], Parent: Optional[str] = None) -> None:
|
def _RemapList(TheSetup: Setup, Values, Remap: dict[str, str]) -> None:
|
||||||
"""Points entries that resolve to a moved directory at its new path."""
|
"""Points entries that resolve to a moved directory at its new path."""
|
||||||
if not isinstance(Values, list):
|
if not isinstance(Values, list):
|
||||||
return
|
return
|
||||||
for Index in range(len(Values)):
|
for Index in range(len(Values)):
|
||||||
Resolved = TheSetup.Parse(str(Values[Index]), Parent=Parent)
|
Resolved = TheSetup.ParsePath(str(Values[Index]))
|
||||||
if Resolved in Remap:
|
if Resolved in Remap:
|
||||||
Values[Index] = TheSetup.Shorthand(Remap[Resolved])
|
Values[Index] = TheSetup.Shorthand(Remap[Resolved])
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ def ApplyBundle(Config: AppConfig, TheBundle: Bundle, Remap: dict[str, str]) ->
|
|||||||
# A moved directory keeps its own config file from [DirConfs] (SaraSortd 7.2).
|
# A moved directory keeps its own config file from [DirConfs] (SaraSortd 7.2).
|
||||||
DirConfs = GlobalDoc.get("DirConfs")
|
DirConfs = GlobalDoc.get("DirConfs")
|
||||||
for Key in list(DirConfs.keys()) if DirConfs is not None else []:
|
for Key in list(DirConfs.keys()) if DirConfs is not None else []:
|
||||||
Resolved = TheSetup.Parse(str(Key)).rstrip("/")
|
Resolved = TheSetup.ParsePath(str(Key)).rstrip("/")
|
||||||
if Resolved in Remap:
|
if Resolved in Remap:
|
||||||
DirConfs[TheSetup.Shorthand(Remap[Resolved])] = DirConfs[Key]
|
DirConfs[TheSetup.Shorthand(Remap[Resolved])] = DirConfs[Key]
|
||||||
del DirConfs[Key]
|
del DirConfs[Key]
|
||||||
@@ -191,9 +191,9 @@ def ApplyBundle(Config: AppConfig, TheBundle: Bundle, Remap: dict[str, str]) ->
|
|||||||
Target = Remap.get(Entry.Directory, Entry.Directory)
|
Target = Remap.get(Entry.Directory, Entry.Directory)
|
||||||
Document = tomlkit.parse(Entry.Content)
|
Document = tomlkit.parse(Entry.Content)
|
||||||
Parent = os.path.basename(Entry.Directory)
|
Parent = os.path.basename(Entry.Directory)
|
||||||
_RemapList(TheSetup, Document.get("ValidInputDirs"), Remap, Parent)
|
_RemapList(TheSetup, Document.get("ValidInputDirs"), Remap)
|
||||||
for FileEntry in Document.get("Files", []):
|
for FileEntry in Document.get("Files", []):
|
||||||
_RemapList(TheSetup, FileEntry.get("ValidInputDirs"), Remap, Parent)
|
_RemapList(TheSetup, FileEntry.get("ValidInputDirs"), Remap)
|
||||||
NewName = os.path.basename(Target)
|
NewName = os.path.basename(Target)
|
||||||
if NewName != Parent:
|
if NewName != Parent:
|
||||||
if "ParentDir" in Document:
|
if "ParentDir" in Document:
|
||||||
|
|||||||
Reference in new issue
Block a user