-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand.py
More file actions
120 lines (99 loc) · 2.84 KB
/
Copy pathcommand.py
File metadata and controls
120 lines (99 loc) · 2.84 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from os import walk, path
from typing import Optional, List, Generator
import click
import eyed3
from dataclasses import dataclass
from mutagen.flac import FLAC, StreamInfo
import sqlite3
file_extensions = ['mp3', 'flac']
@dataclass
class MusicFile:
title: str
artist: str
album: str
album_artist: str
track_number: int
full_path: str
length: int
def file_extension(filename):
return filename.split('.')[-1]
def mp3_handler(file_path) -> MusicFile:
audiofile = eyed3.load(file_path)
return MusicFile(
title = audiofile.tag.title,
artist = audiofile.tag.artist,
album = audiofile.tag.album,
album_artist = audiofile.tag.album_artist,
track_number = audiofile.tag.track_num,
full_path = file_path,
length = 0
)
def flac_handler(file_path) -> MusicFile:
audiofile = FLAC(file_path)
stream_info: StreamInfo = audiofile.info
metadata = {k: v for (k, v) in audiofile.metadata_blocks[2]}
return MusicFile(
title = metadata['TITLE'],
artist = metadata['ARTIST'],
album = metadata['ALBUM'],
album_artist = metadata['ALBUMARTIST'],
track_number = int(metadata['TRACKNUMBER']),
full_path = file_path,
length = 0
)
handlers = {
'mp3': lambda f: mp3_handler(f),
'flac': lambda f: flac_handler(f)
}
def index_files(search_path) -> Generator[MusicFile, None, None]:
for root, dirs, files in walk(search_path):
music_files = ((f, file_extension(f)) for f in files if file_extension(f) in file_extensions)
for filename, extension in music_files:
handler = handlers.get(extension)
if not handler:
print(f"Couldn't find handler for file type {extension}")
else:
music_file = handler(path.join(root, filename))
yield music_file
def escape(in_str) -> str:
if not in_str or type(in_str) is not str:
return "unknown"
in_str = in_str.replace('\'', '')
return r""+in_str
@click.command()
@click.option('--search_path', help = 'Path to your music files')
@click.option('--database', help = 'Path to output SQLite data files')
def index(search_path, database):
"""
Index files and build a database.
"""
music_files = index_files(search_path)
conn = sqlite3.connect(database)
conn.execute(f"""
create table if not exists music_files (
title text,
artist text,
album text,
album_artist text,
track_number integer,
full_path text,
length integer
)
""")
for mf in music_files:
sql = f"""
insert into music_files
(title, artist, album, album_artist, track_number, full_path, length)
values (
'{escape(mf.title)}',
'{escape(mf.artist)}',
'{escape(mf.album)}',
'{escape(mf.album_artist)}',
'{escape(mf.track_number)}',
'{escape(mf.full_path)}',
{mf.length}
)
"""
conn.execute(sql)
conn.commit()
conn.close()