pip install fotools
To run
fotools -h
fotools is an extensible file searching and organization tool.
It can help you:
- Organize your files into alphabetic groups e.g a-e, f-z
- Organize your files by file type e.g pdf, html, mpeg files
- Organize your files by type groups e.g Source codes, Audio, Videos, Documents
- Search for files using fuzzy search with tunable ratio
- Rename files using regex extracted part from their names
- Reverse the above actions.
Lets examine some scenarios where thi program will be useful.
Say we have the following folder structure.
files
├──bg2.jpg
├──bg4.jpg
├──bg5.jpg
├──bg.jpg
├──blog.js
├──elf.png
├──facebook.png
├──favicon.ico
├──fonts
│ ├──1.jpg
│ ├──2.jpg
│ ├──adventpro.ttf
│ ├──LICENSE.txt
│ ├──logo.png
│ ├──luckiest-guy.zip
│ ├──Roboto-BlackItalic.ttf
│ └──Roboto-Black.ttf
├──jquery.js
├──photo1.jpg
├──Roboto.zip
├──RSS.png
├──sunset.png
└──webdes.jpg
We'll start simple.
To list all png/jpg files
wisdom@wisdom:~/yun/files$ fotool.py -y png,jpg -r /home/wisdom/yun/files/RSS.png /home/wisdom/yun/files/bg.jpg /home/wisdom/yun/files/webdes.jpg /home/wisdom/yun/files/elf.png /home/wisdom/yun/files/bg4.jpg /home/wisdom/yun/files/bg5.jpg /home/wisdom/yun/files/bg2.jpg /home/wisdom/yun/files/sunset.png /home/wisdom/yun/files/photo1.jpg /home/wisdom/yun/files/favicon.ico /home/wisdom/yun/files/facebook.png /home/wisdom/yun/files/fonts/1.jpg /home/wisdom/yun/files/fonts/2.jpg /home/wisdom/yun/files/fonts/logo.png
To use fuzzy search to find "LCENSE"
wisdom@wisdom:~/yun/files$ fotool.py -s LCENSE -r /home/wisdom/yun/files/fonts/LICENSE.txt
To organize the files into groups
wisdom@wisdom:~/yun/files$ fotool -a move -r -g wisdom@wisdom:~/yun/files$ tree . ├──action_log ├──Archives │ ├──luckiest-guy.zip │ └──Roboto.zip ├──Documents │ └──LICENSE.txt ├──fonts ├──Fonts │ ├──adventpro.ttf │ ├──Roboto-BlackItalic.ttf │ └──Roboto-Black.ttf ├──Images │ ├──1.jpg │ ├──2.jpg │ ├──bg2.jpg │ ├──bg4.jpg │ ├──bg5.jpg │ ├──bg.jpg │ ├──elf.png │ ├──facebook.png │ ├──favicon.ico │ ├──logo.png │ ├──photo1.jpg │ ├──RSS.png │ ├──sunset.png │ └──webdes.jpg └──Source_Codes ├──blog.js └──jquery.js
To reverse the above action or any action that's happened in this folder
wisdom@wisdom:~/yun/files$ fotool -j /home/wisdom/yun/files/RSS.png /home/wisdom/yun/files/bg.jpg /home/wisdom/yun/files/webdes.jpg /home/wisdom/yun/files/elf.png /home/wisdom/yun/files/bg4.jpg /home/wisdom/yun/files/bg5.jpg /home/wisdom/yun/files/bg2.jpg /home/wisdom/yun/files/sunset.png /home/wisdom/yun/files/blog.js /home/wisdom/yun/files/action_log /home/wisdom/yun/files/jquery.js /home/wisdom/yun/files/photo1.jpg /home/wisdom/yun/files/Roboto.zip /home/wisdom/yun/files/favicon.ico /home/wisdom/yun/files/facebook.png wisdom@wisdom:~/yun/files$ tree . ├──action_log ├──bg2.jpg ├──bg4.jpg ├──bg5.jpg ├──bg.jpg ├──blog.js ├──elf.png ├──facebook.png ├──favicon.ico ├──fonts │ ├──1.jpg │ ├──2.jpg │ ├──adventpro.ttf │ ├──LICENSE.txt │ ├──logo.png │ ├──luckiest-guy.zip │ ├──Roboto-BlackItalic.ttf │ └──Roboto-Black.ttf ├──jquery.js ├──photo1.jpg ├──Roboto.zip ├──RSS.png ├──sunset.png └──webdes.jpg
To organize by file types
wisdom@wisdom:~/yun/files$ fotool -a move -r -t wisdom@wisdom:~/yun/files$ tree . ├──action_log ├──fonts ├──FONT-SFNT Files │ ├──adventpro.ttf │ ├──Roboto-BlackItalic.ttf │ └──Roboto-Black.ttf ├──Javascript Source Files │ ├──blog.js │ └──jquery.js ├──JPEG Files │ ├──1.jpg │ ├──2.jpg │ ├──bg2.jpg │ ├──bg4.jpg │ ├──bg5.jpg │ ├──bg.jpg │ ├──photo1.jpg │ └──webdes.jpg ├──PNG Files │ ├──elf.png │ ├──facebook.png │ ├──favicon.ico │ ├──logo.png │ ├──RSS.png │ └──sunset.png ├──Text File │ └──LICENSE.txt └──ZIP Files ├──luckiest-guy.zip └──Roboto.zip
To remove roboto from the font names
wisdom@wisdom:~/yun/files$ fotool -a move -r -x "(?<=Roboto)(.*)" -s "roboto" -z fonts/ wisdom@wisdom:~/yun/files$ tree . ├──action_log ├──bg2.jpg ├──bg4.jpg ├──bg5.jpg ├──bg.jpg ├──blog.js ├──elf.png ├──facebook.png ├──favicon.ico ├──fonts │ ├──1.jpg │ ├──2.jpg │ ├──adventpro.ttf │ ├──-BlackItalic.ttf │ ├──-Black.ttf │ ├──LICENSE.txt │ ├──logo.png │ └──luckiest-guy.zip ├──jquery.js ├──photo1.jpg ├──RSS.png ├──sunset.png └──webdes.jpg 1 directory, 22 files
To extend fotools, all you need do is create a python file and define an extension
class with its name ending with Extension. eg class DeleteExtension:
.
Then run
fotool.py --install-extension /path/to/extension.py
To extend a function simply create a similar method with name similar to that of the
method name without the 'default_' prepended to it e.g default_fuzzy_search
becomes fuzzy_search
.
To use the extension simply supply the -e
or --extension argument
with the value set to the
filename without .py.
You can list installed extensions with the --list-extensions
flag
This program comes with some extensions (in the extensions folder") which you use as reference. They are:
-
delete - Adds delete command to the
-a
flag.
Example usage:
fotool.py -e delete -a delete -s "__pycache__" -l
-
search_contents - Search the content of allowed types.
See search_contents.py for the list of allowed types
Example usage:
fotool.py -e search_contents -s "william shakespeare" -r
-
pcloud_upload - Uploads matching files to pcloud.
Requires PCLOUD_USER and PCLOUD_PASS environment variables
to be set.
usage: fotools.py [-h] [-s SEARCH_STRING] [-e EXTENSION] [-d DIRECTORY] [-z DESTINATION] [-m MIN_RATIO] [-b GROUPS] [-n NOMATCHDIR] [-a ACTION] [-r] [-q] [-k] [-j [REVERSE]] [-p ACTION_LOG] [-u OPCOUNT] [--reverse-timestamp-start RTSTART] [--reverse-timestamp-stop RTSTOP] [-l | -f] [-i | -g | -t] [-w] [-c | -x GEN_REGEX] [-y FILEEXTENSIONS] [--install-extension EXTENSION_NAME] [--list-extensions] [--extension-help EXTENSION_NAME] optional arguments: -h, --help show this help message and exit -s SEARCH_STRING, --search_string SEARCH_STRING The string to search for. -e EXTENSION, --extension EXTENSION Use extension specified where extension is of the form 'parent_dir.child_dir.extension_module:class' or 'extension_module:class' or 'extension_module' where extension_module is a valid extension python file -d DIRECTORY, --directory DIRECTORY The directory to work on. -z DESTINATION, --destination-directory DESTINATION Target directory for file operations. -m MIN_RATIO, --min-levenshtein-ratio MIN_RATIO This Program uses Levenshtein Distance Algorithm to search for match by default unless the -s or --simple-match options are specified. This option specified the minimun ratio that will be considered a match using partial_set_ratio. Defaults to 75 -b GROUPS, --groups GROUPS Number of groups to divide each class (alphas and nums) will be divided into for generating destination directory based on initials of filenames (used with the -i or --initials arguments) . -n NOMATCHDIR, --nomatchdir NOMATCHDIR Directory to copy or move files to if no match is found. Defaults to ignore. This program allows you to use [:dd:] to reference the directory matched files are moved to (specified with -d or --destination-directory argument). So the move all unmatched files to a folder named 'unknown' in the target directory pass '[:dd:]/unknown' as the value to this argument. -a ACTION, --action ACTION The action to carry out on matched files, valid options are: print, move, copy_rename, rename, copy. Defaults to print. You can also add custom actions in extensions -r, --recursive Recursively find files. -q, --newline print a newline after each output -k, --irreversible Disable reversibility i.e action are not written to actionlog to provide the ability to reverse action. -j [REVERSE], --reverse [REVERSE] Reverse last actions from actions log. -p ACTION_LOG, --action-log-file ACTION_LOG File to log actions for reversibility of operations. -u OPCOUNT, --count OPCOUNT Specifies the maximum number of operations to carry out. --reverse-timestamp-start RTSTART Reverse operations that where carried out on or after this timestamp. If reverse-timestamp-stop is specified, then operations carried out between reverse-timestamp-start and reverse-timestamp-stop are reversed --reverse-timestamp-stop RTSTOP Reverse operations that where carried out on or before this timestamp. If reverse-timestamp-start is specified, then operations carried out between reverse-timestamp-start and reverse-timestamp-stop are reversed -l, --simple-match Simple string match. -f, --fuzz-match Fuzzy string match. -i, --initials Use initials of filenames to generate groups. Directories are created with the group name as destination for file operations. -g, --group -t, --type Generate location for matched files by using their filetype. -w, --case-sensitive Makes regex filename generation case-sensitive -c, --generate-combinations Used to generate new names for matched files based on various combinations of characters. -x GEN_REGEX, --generate-regex GEN_REGEX Used to generate new names for matched files based of strings extracted from filenames using regular expressions. -y FILEEXTENSIONS, --file-types FILEEXTENSIONS Only match files of the path type(s)/extension(s) given. Value can be a single file type like 'pdf' or a comma seperated list of file types like 'pdf,txt,html,exe,zip'. There are currently 72 recognized file types and they are: py, html, htm, css, js, cpp, c, rb, pl, php, r, go,java, svg, png, jpg, jpx, gif, webp, cr2, tif, bmp, jxr,psd, ico, heic, mp4, m4v, mkv, webm, mov, avi, wmv, mpg,flv, swf, mid, mp3, m4a, ogg, flac, wav, amr, zip, tar,rar, gz, bz2, 7z, xz, ar, deb, z, lz, exe, cab, pyc, jar,pdf, docx, doc, ppt, pptx, epub, rtf, txt, ps, woff,woff2, ttf, otf, md files. --install-extension EXTENSION_NAME Install a file as an extension --list-extensions List installed extensions --extension-help EXTENSION_NAME View an extension module docstring