2 Commits
Author SHA1 Message Date
sarah 68e33861a9 Merge pull request #49 from SRHTNIN/SarahTest
SarahTest=>Main
2026-04-29 07:52:33 +02:00
sarah f0b2ec62ef Added function to InputDirConf, including pattern and if the input
should sort directories or not. Also added zipping functions to move
said directories. TODO: Add unzipping functions.
2026-04-29 07:50:04 +02:00
5 changed files with 93 additions and 17 deletions

No files matched your search

+21 -4
View File
@@ -1,5 +1,5 @@
# SaraSortd # SaraSortd
(Version = "5.1") (Version = "6.0")
A python daemon that can automatically sort your files to your liking without using AI. A python daemon that can automatically sort your files to your liking without using AI.
@@ -48,7 +48,7 @@ Here's a step-by-step tutorial (in case you don't want to watch the video).
``` ```
Title = "SaraSortd Config" # NOTE: Do not change the title. This is so that the program knows which config file is which. Title = "SaraSortd Config" # NOTE: Do not change the title. This is so that the program knows which config file is which.
Version = "5.1" # Just the version number for the config file. Version = "6.0" # Just the version number for the config file.
SafeMode = 1 # If SaraSortd should stop if an error with the config appears. 1 is stop, 0 is continue. SafeMode = 1 # If SaraSortd should stop if an error with the config appears. 1 is stop, 0 is continue.
@@ -128,6 +128,15 @@ ValueSet = "Set: %%." # When a value in a config is set.
Unset = "Error: %% is not set." # When a value isn't set. Unset = "Error: %% is not set." # When a value isn't set.
# %% here is just the parameter who's value was either "Unset" or None. E.G: "RootDir". # %% here is just the parameter who's value was either "Unset" or None. E.G: "RootDir".
Zipping = "Zipping: %%." # When a directory is zipped.
# %% here is the path to the directory being zipped.
Unzipping = "Unzipping: %%." # When a directory gets unzipped.
# %% is the path to the directory being unzipped.
NoPermission = "Error: No permission to %%." # When SaraSortd lacks permission to do something.
# %% is the action that the program had no permission to do. E.G. "remove directory /home/bob/exampledir".
``` ```
@@ -138,7 +147,7 @@ The output directory config references the SaraSortd config (GlobalConf.toml). T
``` ```
Title = "Unset" # NOTE: Do not change the title. This is so that the program knows which config file is which. Title = "Unset" # NOTE: Do not change the title. This is so that the program knows which config file is which.
Version = "5.1" # The version number of the config. Version = "6.0" # The version number of the config.
LastFile = "Unset" # The last file that was sorted to this directory. It gets automatically updated whenever a file gets sorted to this directory. LastFile = "Unset" # The last file that was sorted to this directory. It gets automatically updated whenever a file gets sorted to this directory.
@@ -186,7 +195,15 @@ Overwrite = 1 # Whether this specific file type can be overwritten by others of
``` ```
Title = "Unset" # NOTE: Do not change the title. This is so that the program knows which config file is which. Title = "Unset" # NOTE: Do not change the title. This is so that the program knows which config file is which.
Version = "5.1" Version = "6.0"
ParentDir = "Unset" # The name of this directory. It gets automatically updated when this config gets copied to an output directory. ParentDir = "Unset" # The name of this directory. It gets automatically updated when this config gets copied to an output directory.
SortDirs = 0
[[Files]] # The double brackets means that you can add multiple types of files to be sorted here. Just copy [[Files]] and all the parameters under it, and paste it under or over this section, then you may change the values of the new parameters.
Pattern = "*" # A pattern used to decide if a file should be sorted or not. * is a wildcard; ? is a one-character wildcard. E.G: if Pattern is "*.png", all files ending with .png in this directory will try to be sorted.
CaseSensitive = 0 # Whether Pattern is case-sensitive or not. If CaseSensitive = 1 and your pattern is "*.PNG", then a file named "example.png" won't be sorted.
``` ```
+5 -2
View File
@@ -1,5 +1,5 @@
Title = "SaraSortd Config" Title = "SaraSortd Config"
Version = "5.1" Version = "6.0"
SafeMode = 1 SafeMode = 1
SilentMode = 0 SilentMode = 0
CheckInput = 5 CheckInput = 5
@@ -22,7 +22,7 @@ Second = "[s]"
VarCall = "%%" VarCall = "%%"
[DirectoryPaths] [DirectoryPaths]
RootDir = "Unset" RootDir = "C:/Users/StigOscarAadalen-Aas/OneDrive - Telemark fylkeskommune/Desktop/Testdir"
InputDir = [ "%RootDir%/Input" ] InputDir = [ "%RootDir%/Input" ]
OutputDir = [ "%RootDir%/Output" ] OutputDir = [ "%RootDir%/Output" ]
LogDir = "%RootDir%/.Logs" LogDir = "%RootDir%/.Logs"
@@ -44,3 +44,6 @@ Sorted = "Sorted %%."
NotSorted = "Error: Failed to sort %%. No valid output directory." NotSorted = "Error: Failed to sort %%. No valid output directory."
ValueSet = "Set %%." ValueSet = "Set %%."
Unset = "Error: %% is not set." Unset = "Error: %% is not set."
Zipping = "Zipping: %%."
Unzipping = "Unzipping: %%."
NoPermission = "Error: No permission to %%."
+6 -1
View File
@@ -1,3 +1,8 @@
Title = "Unset" Title = "Unset"
Version = "5.1" Version = "6.0"
ParentDir = "Unset" ParentDir = "Unset"
SortDirs = 0
[[Files]]
Pattern = "*"
CaseSensitive = 0
+1 -1
View File
@@ -1,5 +1,5 @@
Title = "Unset" Title = "Unset"
Version = "5.1" Version = "6.0"
LastFile = "Unset" LastFile = "Unset"
ParentDir = "Unset" ParentDir = "Unset"
ValidInputDirs = ["*"] ValidInputDirs = ["*"]
+60 -9
View File
@@ -6,7 +6,7 @@ import shutil
import time import time
import toml import toml
# Version = "5.1" # Version = "6.0"
ConfPath = "./GlobalConf.toml" ConfPath = "./GlobalConf.toml"
@@ -217,27 +217,45 @@ def Clone(Source, Destination, NewName, Delete = False):
os.remove(Source) os.remove(Source)
def Dir(Path, Output = True, CopyConf = True): def Dir(Path, Output = True, CopyConf = "OutputDirConf.toml"):
ParentName = os.path.basename(Path) ParentName = os.path.basename(Path)
os.makedirs(Path, exist_ok=True) os.makedirs(Path, exist_ok=True)
if CopyConf: if CopyConf:
NewOutDirConf = f"{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml" if "Out" in CopyConf:
if Conf["OverwriteDirConf"] == 1 or not os.path.exists( NewDirConf = f"{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml"
os.path.join(f"{Path}/{NewOutDirConf}")
): if Conf["OverwriteDirConf"] == 1 or not os.path.exists(os.path.join(f"{Path}/{NewDirConf}")):
Clone("OutputDirConf.toml", Path, NewOutDirConf) Clone(CopyConf, Path, NewDirConf)
UpdateConf( UpdateConf(
f"{Path}/{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml", f"{Path}/{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml",
"ParentDir", "ParentDir",
ParentName, ParentName,
) )
UpdateConf( UpdateConf(
f"{Path}/{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml", f"{Path}/{Parse(String = ConfNames['OutDirConfName'], Path = ConfPath, Parent = ParentName)}.toml",
"Title", "Title",
f"{ParentName} Config", 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 Output: if Output:
ParsedPath = Parse(String = Path) ParsedPath = Parse(String = Path)
ParsedOutputs = [Parse(String = Dir) for Dir in ConfDirs["OutputDir"]] ParsedOutputs = [Parse(String = Dir) for Dir in ConfDirs["OutputDir"]]
@@ -432,7 +450,7 @@ def Init():
if Start: if Start:
for InputDir in ConfDirs["InputDir"]: for InputDir in ConfDirs["InputDir"]:
InputDir = Parse(String = InputDir, Path = ConfPath, Parent = os.path.basename(os.path.dirname(InputDir))) InputDir = Parse(String = InputDir, Path = ConfPath, Parent = os.path.basename(os.path.dirname(InputDir)))
Dir(InputDir, Output = False, CopyConf = False) Dir(InputDir, Output = False, CopyConf = "InputDirConf.toml")
for Output in ConfDirs["OutputDir"]: for Output in ConfDirs["OutputDir"]:
Output = Parse(String = Output, Parent = os.path.basename(os.path.dirname(Output))) Output = Parse(String = Output, Parent = os.path.basename(os.path.dirname(Output)))
@@ -477,6 +495,9 @@ def Main():
if not os.path.exists(InputPath): if not os.path.exists(InputPath):
continue continue
InputDirConfPath = f"{InputPath}/{Parse(ConfNames["InDirConfName"], Parent = os.path.basename(InputPath))}.toml"
InputDirConf = toml.load(InputDirConfPath)
for Output in ConfDirs["OutputDir"]: for Output in ConfDirs["OutputDir"]:
OutputPath = Parse(Output) OutputPath = Parse(Output)
@@ -490,12 +511,42 @@ def Main():
for FileName in os.listdir(InputPath): for FileName in os.listdir(InputPath):
FilePath = f"{InputPath}/{FileName}" FilePath = f"{InputPath}/{FileName}"
if os.path.isdir(FilePath) and InputDirConf["SortDirs"] == 0:
continue
if os.path.isfile(FilePath):
FileName = os.path.basename(FilePath) FileName = os.path.basename(FilePath)
if FileName.startswith(".") and Conf["DotFiles"] == 0: if FileName.startswith(".") and Conf["DotFiles"] == 0:
continue continue
for ConfFile in InputDirConf["Files"]:
if ConfFile["CaseSensitive"] == 1:
Match = fnmatch.fnmatchcase(FileName, Parse(ConfFile["Pattern"], Parent = os.path.basename(InputPath)))
else:
Match = fnmatch.fnmatchcase(FileName.lower(), (Parse(ConfFile["Pattern"], Parent = os.path.basename(InputPath))).lower())
if Match:
break
if Match:
if os.path.isdir(FilePath) and InputDirConf["SortDirs"] == 1:
TextOutput = Parse(String = ConfLog["Zipping"], VarCall = FilePath)
LogWrite(TextOutput)
Speak(TextOutput)
shutil.make_archive(FilePath, "zip", FilePath)
try:
os.rmdir(FilePath)
except PermissionError:
TextOutput = Parse(String = ConfLog["NoPermission"], VarCall = f"remove directory {InputPath}/{FileName}")
LogWrite(TextOutput)
Speak(TextOutput)
continue
FilePath = f"{FilePath}.zip"
if RecurseDir: if RecurseDir:
HistoryFile = toml.load(FileHistoryPath) HistoryFile = toml.load(FileHistoryPath)