1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#!/usr/bin/env -S guix shell python -- python3
''' Imports '''
import argparse
import logging
import sys
import glob
import os
''' Global variables '''
logger = logging.getLogger('sort_music.py')
'''-----------------------------------------'''
def parse_arguments():
''' Parse command line arguments '''
parser = argparse.ArgumentParser()
parser.add_argument('-a', '--album', help='EXACT album name shared across designated files.',
required=True)
parser.add_argument('-f', '--format', help='ncmpcpp format of files. Default is %t_%a_%b_%y. Read the documentation for that program for more information. It MUST include an artist name (%a) and year (%y).',
default="%t_%a_%b_%y")
parser.add_argument('-v', '--verbose', help='Enable full debug output.',
action='store_true')
return parser.parse_args()
def configure_logs(verbose):
''' Configure program logging level '''
level = logging.DEBUG if verbose else logging.INFO
''' Configure stream handler '''
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setFormatter(logging.Formatter('%(name)s - %(levelname)s - %(message)s'))
''' For main logger '''
logger.addHandler(stream_handler)
logger.setLevel(level)
'''-----------------------------------------'''
class SortMusic():
def __init__(self, logger, args):
self.logger = logger
self.album = args.album
self.delimiter = args.format[2]
self.artist_index = args.format.split(self.delimiter).index('%a')
self.year_index = args.format.split(self.delimiter).index('%y')
logger.info(f'Starting rename with file extension {self.album} and artist_index {self.artist_index}')
self.files = None # list of relevant files in specified directory
self.artist = None
self.year = None
def run(self):
self._find_files()
self._prompt()
self._organize()
def _find_files(self):
self.files = list(glob.glob(f"*{self.album}*"))
if len(self.files) == 0:
self.logger.error(f'Files in this album NOT found!')
exit(1)
self.artist = self.files[0].split(self.delimiter).pop(self.artist_index).rsplit(".",1)[0] # remove file extension (sometimes occurs)
self.year = self.files[0].split(self.delimiter).pop(self.year_index).rsplit(".",1)[0]
def _prompt(self):
self.logger.info(f'Found {len(self.files)} files written by {self.artist} in {self.year}.')
quit = input(f'Files will now be organized (y/n)\t').lower()
if not quit.startswith('y'):
exit(1)
def _organize(self):
path = f'./{self.artist}/({self.year}) {self.album}'
if not os.path.exists(path):
logger.info(f'Creating previously missing path {path}')
os.makedirs(path)
for file in self.files:
os.rename(f'./{file}', f'{path}/{file}')
'''-----------------------------------------'''
def main():
''' This is the main function '''
args = parse_arguments()
configure_logs(args.verbose)
''' Initialize and run '''
sorter = SortMusic(logger, args)
sorter.run()
if __name__ == '__main__':
main()
|