mirror of
https://git.srhtnin.garden/sarah/SaraSortd.git
synced 2026-10-14 02:38:12 +02:00
7.2: directory configs can live outside their directories
DirConfDir keeps every directory's config (and history file) in one folder, and [DirConfs] names a file for single directories, like SaraTag's Lexicons and Records. Both are optional; without them configs stay inside the directories as before. Clone now copies straight to the new name. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
aef32f6f3b
commit
4389a1c76e
5 files changed
+97
-53
No files matched your search
+80
-46
@@ -6,7 +6,7 @@ import shutil
|
||||
import time
|
||||
import toml
|
||||
|
||||
# Version = "7.1"
|
||||
# Version = "7.2"
|
||||
|
||||
ConfPath = "./GlobalConf.toml"
|
||||
|
||||
@@ -189,10 +189,69 @@ def Parse(
|
||||
return String
|
||||
|
||||
|
||||
def ConfFolder(PathText):
|
||||
# Relative paths in GlobalConf.toml (DirConfDir, [DirConfs]) count from GlobalConf.toml's own folder.
|
||||
PathText = Parse(String = PathText)
|
||||
if os.path.isabs(PathText):
|
||||
return os.path.normpath(PathText)
|
||||
return os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(ConfPath)), PathText))
|
||||
|
||||
|
||||
def FlatName(Path):
|
||||
# A directory's name for files kept outside it: its path below RootDir (or its whole path), "/" turned into "_".
|
||||
# E.G: "%RootDir%/Pictures/Cats" becomes "Pictures_Cats".
|
||||
Root = Parse(String = ConfDirs.get("RootDir", "")).rstrip("/")
|
||||
Path = Path.rstrip("/")
|
||||
if Root and Path.startswith(Root + "/"):
|
||||
Relative = Path[len(Root) + 1:]
|
||||
else:
|
||||
Relative = Path.strip("/") or os.path.basename(Path)
|
||||
return Relative.replace("/", "_")
|
||||
|
||||
|
||||
def CentralConf(Path, Kind):
|
||||
# Since 7.2, a directory's config can live outside it, like SaraTag's Lexicons:
|
||||
# [DirConfs] names a file per directory ("dir" = "file", or "dir" = { In = "file", Out = "file" }),
|
||||
# and DirConfDir holds the configs of every directory [DirConfs] doesn't name. None means inside the directory.
|
||||
for Key, Value in (Conf.get("DirConfs") or {}).items():
|
||||
if Parse(String = Key).rstrip("/") == Path.rstrip("/"):
|
||||
if isinstance(Value, dict):
|
||||
Value = Value.get(Kind)
|
||||
if Value:
|
||||
return ConfFolder(Value)
|
||||
|
||||
if ConfDirs.get("DirConfDir"):
|
||||
NameKey = "InDirConfName" if Kind == "In" else "OutDirConfName"
|
||||
Name = Parse(String = ConfNames[NameKey], Parent = FlatName(Path)).lstrip(".")
|
||||
return f"{ConfFolder(ConfDirs['DirConfDir'])}/{Name}.toml"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def DirConfPath(Path, Kind):
|
||||
# The config of an input ("In") or output ("Out") directory.
|
||||
Central = CentralConf(Path, Kind)
|
||||
if Central:
|
||||
return Central
|
||||
|
||||
NameKey = "InDirConfName" if Kind == "In" else "OutDirConfName"
|
||||
return f"{Path}/{Parse(String = ConfNames[NameKey], Path = ConfPath, Parent = os.path.basename(Path))}.toml"
|
||||
|
||||
|
||||
def HistoryPath(Path):
|
||||
# The history file of a directory that sorts into itself. It goes next to the directory's config
|
||||
# when that's kept outside the directory.
|
||||
Central = CentralConf(Path, "In") or CentralConf(Path, "Out")
|
||||
if Central:
|
||||
Name = Parse(String = ConfNames["FileHistoryName"], Parent = FlatName(Path)).lstrip(".")
|
||||
return f"{os.path.dirname(Central)}/{Name}.toml"
|
||||
|
||||
return f"{Path}/{Parse(String = ConfNames['FileHistoryName'], Parent = os.path.basename(Path))}.toml"
|
||||
|
||||
|
||||
def Clone(Source, Destination, NewName, Delete = False):
|
||||
if (os.path.dirname(Source) == Destination):
|
||||
FileHistoryPath = f"{Destination}/{Parse(ConfNames["FileHistoryName"], Parent = os.path.basename(Destination))}.toml"
|
||||
print("FileHistoryPath:",FileHistoryPath)
|
||||
FileHistoryPath = HistoryPath(Destination)
|
||||
|
||||
if not os.path.exists(FileHistoryPath):
|
||||
with open(FileHistoryPath, "w", encoding = "utf-8") as HistoryFile:
|
||||
@@ -208,10 +267,9 @@ def Clone(Source, Destination, NewName, Delete = False):
|
||||
return
|
||||
|
||||
Dir(Destination, Output = False, CopyConf = False)
|
||||
shutil.copy2(Source, Destination)
|
||||
|
||||
BaseName = os.path.basename(Source)
|
||||
shutil.move(os.path.join(Destination, BaseName), os.path.join(Destination, NewName))
|
||||
# Straight to the new name: copying under the old name first could land on a file that's already
|
||||
# there (E.G. a template, when DirConfDir is GlobalConf.toml's own folder).
|
||||
shutil.copy2(Source, os.path.join(Destination, NewName))
|
||||
|
||||
if Delete:
|
||||
os.remove(Source)
|
||||
@@ -222,39 +280,16 @@ def Dir(Path, Output = True, CopyConf = "OutputDirConf.toml"):
|
||||
os.makedirs(Path, exist_ok=True)
|
||||
|
||||
if CopyConf:
|
||||
if "Out" in CopyConf:
|
||||
NewDirConf = f"{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml"
|
||||
for Kind in ("Out", "In"):
|
||||
if Kind not in CopyConf:
|
||||
continue
|
||||
|
||||
if Conf["OverwriteDirConf"] == 1 or not os.path.exists(os.path.join(f"{Path}/{NewDirConf}")):
|
||||
Clone(CopyConf, Path, NewDirConf)
|
||||
UpdateConf(
|
||||
f"{Path}/{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml",
|
||||
"ParentDir",
|
||||
ParentName,
|
||||
)
|
||||
DirConf = DirConfPath(Path, Kind)
|
||||
|
||||
UpdateConf(
|
||||
f"{Path}/{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml",
|
||||
"Title",
|
||||
f"{ParentName} Config",
|
||||
)
|
||||
|
||||
if "In" in CopyConf:
|
||||
NewDirConf = f"{Parse(String = ConfNames['InDirConfName'], Path = ConfPath, Parent = ParentName)}.toml"
|
||||
|
||||
if Conf["OverwriteDirConf"] == 1 or not os.path.exists(os.path.join(f"{Path}/{NewDirConf}")):
|
||||
Clone(CopyConf, Path, NewDirConf)
|
||||
UpdateConf(
|
||||
f"{Path}/{Parse(String = ConfNames['InDirConfName'], Path = ConfPath, Parent = ParentName)}.toml",
|
||||
"ParentDir",
|
||||
ParentName,
|
||||
)
|
||||
|
||||
UpdateConf(
|
||||
f"{Path}/{Parse(String = ConfNames['InDirConfName'], Path = ConfPath, Parent = ParentName)}.toml",
|
||||
"Title",
|
||||
f"{ParentName} Config",
|
||||
)
|
||||
if Conf["OverwriteDirConf"] == 1 or not os.path.exists(DirConf):
|
||||
Clone(CopyConf, os.path.dirname(DirConf), os.path.basename(DirConf))
|
||||
UpdateConf(DirConf, "ParentDir", ParentName)
|
||||
UpdateConf(DirConf, "Title", f"{ParentName} Config")
|
||||
|
||||
if Output:
|
||||
ParsedPath = Parse(String = Path)
|
||||
@@ -299,8 +334,7 @@ def DecideNewPath(FilePath):
|
||||
|
||||
ParentName = os.path.basename(Output)
|
||||
|
||||
OutDirConfName = Parse(String = ConfNames["OutDirConfName"], Path = ConfPath, Parent = ParentName)
|
||||
OutDirConfPath = f"{Output}/{OutDirConfName}.toml"
|
||||
OutDirConfPath = DirConfPath(Output, "Out")
|
||||
|
||||
ValidInputDirs = GetConf("ValidInputDirs", OutDirConfPath) or []
|
||||
InputDirValid = False
|
||||
@@ -429,7 +463,7 @@ def Sort(FilePath):
|
||||
NewDirPath = os.path.dirname(NewPath)
|
||||
NewName = os.path.basename(NewPath)
|
||||
|
||||
if (GetConf("DeleteOrg", f"{NewDirPath}/{Parse(String = ConfNames['OutDirConfName'], Parent = (os.path.basename(NewDirPath)))}.toml") == 1):
|
||||
if (GetConf("DeleteOrg", DirConfPath(NewDirPath, "Out")) == 1):
|
||||
Delete = True
|
||||
|
||||
else:
|
||||
@@ -437,7 +471,7 @@ def Sort(FilePath):
|
||||
|
||||
try:
|
||||
Clone(FilePath, NewDirPath, NewName, Delete)
|
||||
UpdateConf(f"{NewDirPath}/{Parse(String = ConfNames['OutDirConfName'], Parent = os.path.basename(NewDirPath))}.toml", "LastFile", NewName)
|
||||
UpdateConf(DirConfPath(NewDirPath, "Out"), "LastFile", NewName)
|
||||
|
||||
TextOutput = Parse(String = ConfLog["Sorted"], VarCall = f"{FilePath} to {NewDirPath}/{NewName}")
|
||||
LogWrite(TextOutput)
|
||||
@@ -470,7 +504,7 @@ def Init():
|
||||
Output = Parse(String = Output, Parent = os.path.basename(os.path.dirname(Output)))
|
||||
Dir(Output)
|
||||
|
||||
OutDirConfPath = f"{Output}/{Parse(String = ConfNames["OutDirConfName"], Parent = os.path.basename(Output))}.toml"
|
||||
OutDirConfPath = DirConfPath(Output, "Out")
|
||||
ConfData = toml.load(OutDirConfPath)
|
||||
|
||||
for Item in ConfData.get("Files", []):
|
||||
@@ -509,12 +543,12 @@ def Main():
|
||||
if not os.path.exists(InputPath):
|
||||
continue
|
||||
|
||||
InputDirConfPath = f"{InputPath}/{Parse(ConfNames["InDirConfName"], Parent = os.path.basename(InputPath))}.toml"
|
||||
InputDirConfPath = DirConfPath(InputPath, "In")
|
||||
InputDirConf = toml.load(InputDirConfPath)
|
||||
|
||||
for Output in ConfDirs["OutputDir"]:
|
||||
OutputPath = Parse(Output)
|
||||
OutDirConfPath = f"{OutputPath}/{Parse(ConfNames["OutDirConfName"], Parent = os.path.basename(OutputPath))}.toml"
|
||||
OutDirConfPath = DirConfPath(OutputPath, "Out")
|
||||
|
||||
if len(GetConf("Unzip", OutDirConfPath)) >= 1:
|
||||
ZipTypes = GetConf("Unzip", OutDirConfPath)
|
||||
@@ -541,7 +575,7 @@ def Main():
|
||||
|
||||
if (OutputPath == InputPath):
|
||||
RecurseDir = True
|
||||
FileHistoryPath = f"{InputPath}/{Parse(ConfNames["FileHistoryName"], Parent = os.path.basename(InputPath))}.toml"
|
||||
FileHistoryPath = HistoryPath(InputPath)
|
||||
|
||||
if not os.path.exists(FileHistoryPath):
|
||||
with open(FileHistoryPath, "w", encoding = "utf-8") as HistoryFile:
|
||||
|
||||
Reference in new issue
Block a user