send_to¶
Organize files using Window’s shell:sendto.
release v0.4.0
This project aids in the creation of scripts that organize files, passed to it as arguments. The scripts can be placed inside Window’s shell:sendto directory.
How it works?¶
The function send_to(cfg) follows the configuration that is set in the
passed Cfg object. This object holds configuration such as: the
destination path, wheter the files will be moved or copied, the names of the
user defined functions, etc.
The user defined functions are used to determine: if the files will be further categorized in a subdirectory, wheter a file will be skipped, wheter a file will be renamed and a function for doing post-processing on the destination files.
How to use it?¶
This project is meant to be used as a library module, create the actual Python
script file and import the function send_to(cfg), the classes
Cfg and Info and the enum Operation from the
send_to module.
from send_to import send_to, Cfg, Info, Operation
Setting the configuration (Cfg)¶
Instantiate an object from the Cfg class and set it data members.
cfg = Cfg()
cfg.version = 0
cfg.dst_path = os.path.dirname(sys.argv[0]) # use script's location
cfg.operation = Operation.MOVE
# user defined functions (explained later)
cfg.subdir = subdir
cfg.skip = skip
cfg.rename = rename
cfg.post_process = post_process
Cfg member variables:¶
- Cfg.version: int = 0¶
Set it to the major version of the
send_tomodule that the script is currently developed for.
- Cfg.dst_path: str¶
Destination path for the processed files.
- Cfg.operation: Operation = 1¶
Operation the will be performed on the files - copy or move.
- Cfg.date_fmt: str = '%Y-%m-%d'¶
String format of the date.
- Cfg.ask_for_date: bool = True¶
Prompt the user to input a date/date shift.
- Cfg.ask_for_desc: bool = True¶
Prompt the user to input a description.
- Cfg.overwrite_file: bool = False¶
Overwrite files with the same name in the destination.
- Cfg.dry_run: bool = False¶
Just print the console messages without actually doing anything.
- Cfg.debug: bool = True¶
Print more console messages.
- Cfg.subdir: Callable[[Info], str]¶
User defined function for determining the name of the subdirectory under
dst_pathwhere the files will be placed.
- Cfg.skip: Callable[[Info], bool]¶
User defined function for determining if a file will be skipped.
- Cfg.rename: Callable[[Info], str]¶
User defined function for determining how the destination file will be named.
- Cfg.post_process: Callable[[str], None]¶
User defined function for doing post-processing on a destination file.
Creating the callback functions¶
There are 4 (optional) user defined functions that’ll be called by
send_to(cfg). They can be created in the script file and their names
are set in the Cfg object. These functions usually take an Info
object as an argument.
The Info class¶
Information such as: source file path, destination path, date and description is stored in an Info object. This object is then passed to some of the user defined functions so this information can be used in e.g. naming the subdirectory, the file etc.
- Info.file_path: str = ''¶
The path of the currently processed file.
- Info.dst_path: str = ''¶
Destination path
- Info.date: str = ''¶
Date
- Info.desc: str = ''¶
Description
Subdirectory function¶
def subdir(info: Info) -> str:
"""Use this function to construct a subdirectory name based on the
information provided by the passed `Info` object. If no subdirectory is
required - return an empty string.
Args:
info (Info)
Returns:
str: subdirectory name or empty string
"""
def my_subdir_func(info: Info) -> str:
"""Tell `send_to(cfg)` to create a subdirectory named "{date}
{description}" e.g. "2023-08-26 summer"."""
return (f'{info.date} {info.desc}').strip()
cfg.subdir = my_sudir_func
Skip function¶
def skip(info: Info) -> bool:
"""Use this function to determine if the currently processed file should
be skipped or not.
Args:
info (Info)
Returns:
bool: True to skip the current file, False otherwise
"""
def skip_jpgs(info: Info) -> str:
"""Tell `send_to(cfg)` to skip JPGs."""
file = os.path.basename(info.file_path)
file_name, file_ext = os.path.splitext(file)
if file_ext.lower() == '.jpg':
return True
else:
return False
cfg.skip = skip_jpgs
Rename function¶
def rename(info: Info) -> str:
"""Use this function to determine how the currently processed file should
be renamed.
Args:
info (Info)
Returns:
str: new file name or empty string to keep the original name
"""
def append_desc(info: Info) -> str:
"""Tell `send_to(cfg)` to append description to the destination file
name."""
file = os.path.basename(info.file_path)
file_name, file_ext = os.path.splitext(file)
return (f"{file_name} {info.desc}{file_ext}")
cfg.rename = append_desc
Post-processing function¶
def post_process(file_path: str) -> None:
"""Use this function to do post-processing on the destination file.
Args:
file_path (str): path of the destination file
"""
def resize(file_path: str) -> None:
"""Resize destination files to 1080p."""
resize_img(file_path, file_path + "_1080p", "1920x1080")
cfg.post_process = resize
Executing send_to(cfg)¶
Call send_to(cfg), passing it the configuration object Cfg.
send_to(cfg)