forked from 16pierre/traktorBeetsIntegration
-
Notifications
You must be signed in to change notification settings - Fork 0
/
import_utils.py
153 lines (124 loc) · 5.18 KB
/
import_utils.py
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
from typing import Dict, List, Iterable
from data import Track, Playlist, TagsConfiguration
from pathlib import Path
import os
import re
import sys
import traktor
import beets_manager
import scanner
import json
from constants import *
from auto_generated_playlist import AutoGeneratedPlaylistManager
_RECORDING_PATTERN = re.compile("\d{4}-\d{2}-\d{1,2}(_\d{1,2}h\d{2}m\d{2})?(_\d{1,2}h\d{2}m\d{2})?\.wav")
def remove_links_when_imported_in_beets_and_update_traktor_paths(
traktor_nml_path: str,
traktor_tracks: Dict[str, Track],
beets_tracks: Dict[str, Track],
volume: str
):
tracks_symlinked_count = 0
symlinks_removed_count = 0
relocations = {}
for beet_track in beets_tracks.values():
symlinks = []
last_symlink = beet_track.path
while last_symlink.is_symlink():
symlinks.append(last_symlink)
last_symlink = Path(os.readlink(str(last_symlink)).lower())
if not symlinks:
continue
if last_symlink in [t.path for t in traktor_tracks.values()]:
tracks_symlinked_count += 1
print("Symlink target %s found in Traktor ! Paths: %s" % (last_symlink, symlinks))
for l in symlinks:
l.unlink()
symlinks_removed_count += 1
os.rename(str(last_symlink), str(symlinks[0]))
relocations[last_symlink] = symlinks[0]
_cleanup_empty_directories([last_symlink] + symlinks)
print("Total number of symlinked tracks: %s ; removed links: %s" % (tracks_symlinked_count, symlinks_removed_count))
print("Relocating tracks in Traktor...")
traktor.update_tracks_locations(traktor_nml_path, relocations, volume)
def _cleanup_empty_directories(original_paths: Iterable[Path]):
directories_to_cleanup = set([p.parent for p in original_paths])
next_cleanup = set()
for d in directories_to_cleanup:
if d.is_dir() and not os.listdir(str(d)):
os.rmdir(str(d))
next_cleanup.add(d.parent)
print("Cleaned up empty dir %s" % d)
if next_cleanup:
_cleanup_empty_directories(next_cleanup)
def create_links_to_files_imported_in_traktor_but_not_in_beets(
symlink_directory: Path,
traktor_tracks: Dict[str, Track],
beets_tracks: Dict[str, Track]):
symlink_directory.mkdir(parents=True, exist_ok=True)
not_in_beets = {p: t for p, t in traktor_tracks.items() if p not in beets_tracks}
count = 0
for t in not_in_beets.values():
if _create_temporary_symlink_path_for_track(symlink_directory, t):
count += 1
print("Created %s symlinks to beet import in %s" % (count, symlink_directory))
def _get_temporary_symlink_path_for_track(
symlink_directory: Path,
track: Track) -> Path:
if track.album is not None:
symlink_directory = symlink_directory.joinpath(track.album)
symlink_path = symlink_directory.joinpath(track.path.name)
return symlink_path
def _create_temporary_symlink_path_for_track(
symlink_directory: Path,
track: Track):
if bool(_RECORDING_PATTERN.match(track.path.name)):
return
if "native instruments" in str(track.path).lower():
return
if "traktor" in str(track.path).lower():
return
symlink_path = _get_temporary_symlink_path_for_track(symlink_directory, track)
symlink_path.parent.mkdir(parents=True, exist_ok=True)
if symlink_path.exists() or symlink_path.is_symlink():
return
symlink_path.symlink_to(track.path)
return True
if __name__ == "__main__":
assert bool(_RECORDING_PATTERN.match("2020-07-11_2h12m15.wav"))
assert bool(_RECORDING_PATTERN.match("2020-08-01_21h12m27_00h57m46.wav"))
if len(sys.argv) < 2:
config_path = DEFAULT_PATH_FOR_JSON_FILE
else:
config_path = sys.argv[1]
with open(config_path) as json_file:
config = json.load(json_file)
volume = config.get("volume")
tags_configuration_json_file = config.get("tagsConfiguration")
auto_generated_playlists_directory_name = config.get("generatedPlaylistsDirectoryName")
traktor_collection = config.get("traktor")
beets_db = config.get("beetsLibrary")
with open(tags_configuration_json_file) as json_file:
tags_configuration_dict = json.load(json_file)
tags_configuration = TagsConfiguration.from_dict(tags_configuration_dict)
playlist_manager = AutoGeneratedPlaylistManager(
tags_configuration.tag_models,
tags_configuration.playlists_to_generate)
traktor_tracks = traktor.get_tracks(
traktor_collection,
volume,
auto_generated_playlists_directory_name,
playlist_manager)
beets_tracks = beets_manager.get_tracks(beets_db, scanner.TAGS_MODEL.keys())
print("\n===== Starting running utils for beet import ======")
symlink_directory = Path(config.get("temporaryFolderForTracksImportedInTraktorButNotInBeets"))
create_links_to_files_imported_in_traktor_but_not_in_beets(
symlink_directory,
traktor_tracks,
beets_tracks
)
remove_links_when_imported_in_beets_and_update_traktor_paths(
traktor_collection,
traktor_tracks,
beets_tracks,
volume
)