-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_recent_set.py
108 lines (93 loc) · 4.41 KB
/
get_recent_set.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
import os
import re
import argparse
import logging
import getpass
import string
# from sys import platform
logging.basicConfig(format='%(message)s')
live_folder_prefix = 'Live '
live_folder_regex = "{prefix}(\d*)\.*(\d*)\.*(\d*)".format(
prefix=live_folder_prefix)
def parse_live_version_from_folder_name(version):
major, minor, patch = re.search(live_folder_regex, version).groups()
return int(major or 0), int(minor or 0), int(patch or 0)
def get_live_version_folder(root_pref_folder, live_version=''):
live_folders = [name for name in os.listdir(root_pref_folder) if os.path.isdir(
os.path.join(root_pref_folder, name)) and live_folder_prefix in name]
if not live_folders:
logging.error('There are no Ableton Live preferences folders in "{folder}"\
that match format "{format}"'.format(folder=root_pref_folder, format=live_folder_regex))
return
# if a live version was specified via command args look for it's corresponding folder
if live_version:
live_folder = ''.join([live_folder_prefix, live_version])
if live_folder not in live_folders:
logging.error('Preferences folder for Live version "{version}" was not found in "{dir}"'.format(
version=live_version, dir=root_pref_folder))
return
return live_folders[live_folders.index(live_folder)]
# otherwise use the latest version
return max(live_folders, key=parse_live_version_from_folder_name)
def get_live_preferences_filepath(live_version=''):
user = getpass.getuser()
root_pref_folder = '/Users/{user}/Library/Preferences/Ableton'.format(
user=user)
# if platform == 'win32':
# root_pref_folder = 'C:\\Users\\{user}\\AppData\\Roaming\\Ableton\\'.format(user=user)
if not os.path.isdir(root_pref_folder):
logging.error('Root directory "{folder}" does not exist'.format(
folder=root_pref_folder))
return
live_folder = get_live_version_folder(root_pref_folder, live_version)
if not live_folder:
return
pref_filename = 'Preferences.cfg'
# if platform == 'win32':
# pref_filename = '\\Preferences\\Preferences.cfg'
return os.path.join(root_pref_folder, live_folder, pref_filename)
def get_recent_set(live_version=''):
recent_set = None
prefs_filepath = get_live_preferences_filepath(live_version)
if not prefs_filepath:
return
if not os.path.exists(prefs_filepath):
logging.error('Attempted to use preferences file "{filepath}" but the file does not exist'.format(
filepath=prefs_filepath))
return
# Preferences.cfg is a binary file and this is the horrible way it's being parsed at the moment.
# It looks like this file has some sort of xml structure. It would be great to be able to parse
# that and reference keys to get the most recent file instead of the method below
with open(prefs_filepath, mode='rb') as file:
prefs_content = file.read().decode('latin1')
# attempt to filter out a lot of the garbage we get back after reading the file in as binary.
# filtering on `string.printable` is a temporary solution and will cause problems for set names
# that have unicode or emoji in them
filtered_prefs_content = ''
for c in prefs_content:
if c in set(string.printable):
filtered_prefs_content += c
# split on 'FileRef' and then look for the first item containing '.als'
for chunk in filtered_prefs_content.split('FileRef'):
if chunk.find('.als') > -1:
recent_set = chunk
break
if not recent_set:
logging.error('Recent set could not be found in preferences file "{filepath}"'.format(
filepath=prefs_filepath))
return
# remove random chars that are added before each fileref val
while not os.path.isfile(recent_set):
recent_set = recent_set[recent_set.find('/'):]
return recent_set
def main():
parser = argparse.ArgumentParser(
description='Display the filepath of the most recent Ableton Live set by parsing Ableton\'s Preferences.cfg.')
parser.add_argument("-v", "--live_version",
help="Preferred Live version to use (defaults to the latest version if omitted)", required=False, default="")
argument = parser.parse_args()
recent_set = get_recent_set(argument.live_version)
if recent_set:
print(recent_set)
if __name__ == "__main__":
main()