Skip to content

Commit 122bd9a

Browse files
committed
add dirganize
1 parent 9afe678 commit 122bd9a

File tree

4 files changed

+159
-0
lines changed

4 files changed

+159
-0
lines changed

dirganize/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""Package dirganize.
2+
3+
Declutter you folders and get peace of mind.
4+
A command-line tool to organize files into category directories.
5+
6+
MIT License
7+
8+
Copyright (c) 2021 Aahnik Daw
9+
10+
https://github.com/aahnik/dirganize
11+
"""
12+
13+
from importlib.metadata import version
14+
15+
from dirganize.dirganize import dirganize
16+
17+
__version__ = version(__package__)

dirganize/cli.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""Command line interface for dirganize."""
2+
3+
import logging
4+
import os
5+
from typing import Optional
6+
7+
import typer
8+
from rich.logging import RichHandler
9+
10+
from dirganize import __version__
11+
from dirganize.dirganize import dirganize
12+
13+
app = typer.Typer(add_completion=False)
14+
15+
16+
def version_callback(value: bool):
17+
"""Show current version and exit."""
18+
if value:
19+
print(__version__)
20+
raise typer.Exit()
21+
22+
23+
def verbosity_callback(value: bool):
24+
"""Set logging level."""
25+
if value:
26+
logging.basicConfig(
27+
level=logging.INFO,
28+
format="[dim]%(name)s[/dim]\t%(message)s",
29+
handlers=[
30+
RichHandler(
31+
markup=True,
32+
show_path=False,
33+
)
34+
],
35+
)
36+
logging.info("Loud logging enabled.")
37+
38+
39+
@app.command()
40+
def main(
41+
path: str = typer.Option(
42+
os.getcwd(),
43+
"--path",
44+
"-p",
45+
help="Path of the directory to dirganize",
46+
),
47+
verbose: Optional[bool] = typer.Option( # pylint: disable=unused-argument
48+
None,
49+
"--loud",
50+
"-l",
51+
callback=verbosity_callback,
52+
envvar="LOUD",
53+
help="Increase output verbosity.",
54+
),
55+
version: Optional[bool] = typer.Option( # pylint: disable=unused-argument
56+
None,
57+
"--version",
58+
"-v",
59+
callback=version_callback,
60+
help="Show version and exit.",
61+
),
62+
):
63+
"""Declutter you folders and get peace of mind.
64+
65+
A command-line tool to organize files into category directories.
66+
"""
67+
dirganize(path=path)

dirganize/conf.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Configuration manager for dirganize."""
2+
3+
import logging
4+
import os
5+
from typing import Dict
6+
7+
import yaml
8+
9+
CONFIG_FILE = ".dirganize.yml"
10+
11+
12+
def get_mapping() -> Dict[str, str]:
13+
"""Parse the .dirganize.yml file and return mapping of extension -> folder."""
14+
structure = {"Documents": ["pdf", "docx"]}
15+
mapping = {}
16+
17+
if os.path.isfile(CONFIG_FILE):
18+
with open(CONFIG_FILE) as stream:
19+
structure.update(yaml.safe_load(stream))
20+
21+
logging.info(structure)
22+
23+
for folder, extensions in structure.items():
24+
for ext in extensions:
25+
mapping[ext] = folder
26+
27+
logging.info(mapping)
28+
29+
return mapping

dirganize/dirganize.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""Dirganize your directory."""
2+
3+
import logging
4+
import os
5+
from mimetypes import guess_type
6+
from typing import Dict
7+
8+
from rich.progress import track
9+
10+
from dirganize.conf import get_mapping
11+
12+
13+
def _guess_type(filename) -> str:
14+
try:
15+
return guess_type(filename)[0].split("/")[0].title() + "s" # type: ignore
16+
except: # pylint: disable=bare-except
17+
return "Others"
18+
19+
20+
def _get_dir(filename: str, mapping: Dict[str, str]) -> str:
21+
ext = filename.split(".")[-1]
22+
folder = mapping.get(ext)
23+
if not folder:
24+
folder = _guess_type(filename)
25+
return folder
26+
27+
28+
def dirganize(path: str):
29+
"""Organizes files into folders."""
30+
os.chdir(path)
31+
mapping = get_mapping()
32+
logging.info("Current working directory is %s", os.getcwd())
33+
all_files = [file for file in os.listdir() if os.path.isfile(file)]
34+
logging.info(all_files)
35+
36+
for file in track(all_files, description="Moving files "):
37+
if file.startswith("."):
38+
continue
39+
new_parent_dir = _get_dir(file, mapping)
40+
if new_parent_dir:
41+
new_file = os.path.join(new_parent_dir, file)
42+
if not os.path.isdir(new_parent_dir):
43+
os.makedirs(new_parent_dir)
44+
os.rename(file, new_file)
45+
logging.info("%s renamed to %s", file, new_file)
46+
return os.walk(".")

0 commit comments

Comments
 (0)