Cleanups, fixes, use decorator lib for argspec-preserving decorators.
[audiomangler.git] / audiomangler / config.py
bloba8783a2305b3ba1f0174bc9af6cbfb2a4f01e102
1 # -*- coding: utf-8 -*-
2 ###########################################################################
3 # Copyright (C) 2008 by Andrew Mahone
4 # <andrew.mahone@gmail.com>
6 # Copyright: See COPYING file that comes with this distribution
8 ###########################################################################
9 import os, os.path
10 import sys
11 from functools import wraps
12 from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
14 def clear_cache(func):
15 @wraps(func)
16 def proxy(self, *args, **kw):
17 self._cache.clear()
18 return func(self, *args, **kw)
19 return proxy
21 class AMConfig(RawConfigParser):
22 def __init__(self, defaults):
23 self._current_values = {}
24 self._cache = {}
25 RawConfigParser.__init__(self)
26 for section in defaults:
27 items = section[1:]
28 section = section[0]
29 self.add_section(section)
30 for key, value in items:
31 self.set(section, key, value)
33 def __setitem__(self, key, value):
34 self._cache.clear()
35 self._current_values[key] = value
37 def __getitem__(self, key):
38 if key in self._cache:
39 return self._cache[key]
40 if key in self._current_values:
41 self._cache[key] = self._current_values[key]
42 return self._current_values[key]
43 trysources = {
44 'preset':('profile', 'type', 'defaults'),
45 'type':('profile', 'defaults'),
46 'profile':('defaults', )
47 }.get(key, ('profile', 'type', 'preset', 'defaults'))
48 for source in trysources:
49 if source == 'preset':
50 source = [self['type']]
51 if not source[0]:
52 continue
53 source.extend(('_', self['preset']))
54 if not source[2]:
55 continue
56 source = ''.join(source)
57 elif source != 'defaults':
58 source = self[source]
59 if not source:
60 continue
61 try:
62 ret = RawConfigParser.get(self, source, key)
63 except (NoOptionError, NoSectionError):
64 continue
65 else:
66 self._cache[key] = ret
67 return ret
68 self._cache[key] = None
70 def get(self, key, default=None):
71 ret = self[key]
72 return ret if ret is not None else default
75 for n in ('read', 'readfp', 'remove_option', 'remove_section', 'set'):
76 locals()[n] = clear_cache(getattr(RawConfigParser, n))
78 Config = AMConfig(
80 ('defaults',
81 ('onsplit', 'abort'),
82 ('groupby',
83 "first("
84 "('album', musicbrainz_albumid), "
85 "('meta', first(albumartist, artist), album, first(catalognumber, asin, isrc)), "
86 "('dir', dir)"
87 ")"
89 ('loglevel', 'INFO'),
90 ('consolelevel', 'INFO'),
91 ('trackid',
92 "first("
93 "('mbid', musicip_puid, musicbrainz_albumid, first(tracknumber)), "
94 "('meta', title, artist, album, first(year), first(catalognumber, asin, isrc), first(tracknumber))"
95 ")"
97 ('sortby', "(first(discnumber), first(tracknumber), first(filename))"),
98 ('base', '.'),
99 ('filename',
100 "$/first('$type/', '')"
101 "$first(releasetype == 'soundtrack' and 'Soundtrack', albumartist, "
102 "artist)/$album/"
103 "$first('%02d.' % discnumber if discnumber > 0 else '', '')"
104 "$first('%02d ' % tracknumber, '')"
105 "$title$first('.%s' % ext, '')"
107 ('fs_encoding', 'utf8'),
108 ('fs_encoding_error', 'replace'),
110 ('mp3',
111 ('preset', 'standard')
113 ('mp3_medium',
114 ('encopts', '--preset medium')
116 ('mp3_standard',
117 ('encopts', '--preset standard')
119 ('mp3_extreme',
120 ('encopts', '--preset extreme')
122 ('mp3_insane',
123 ('encopts', '--preset insane')
125 ('wavpack',
126 ('preset', 'standard')
128 ('wavpack_fast',
129 ('encopts', '-f')
131 ('wavpack_standard',
132 ('encopts', '')
134 ('wavpack_high',
135 ('encopts', '-h')
137 ('wavpack_higher',
138 ('encopts', '-hh')
140 ('oggvorbis',
141 ('preset', 'q3')
143 ('oggvorbis_q1',
144 ('encopts', '-q1')
146 ('oggvorbis_q3',
147 ('encopts', '-q3')
149 ('oggvorbis_q5',
150 ('encopts', '-q5')
152 ('oggvorbis_q7',
153 ('encopts', '-q7')
155 ('oggvorbis_q9',
156 ('encopts', '-q9')
158 ('flac',
159 ('preset', 'standard')
161 ('flac_standard',
162 ('encopts', '')
164 ('flac_fast',
165 ('encopts', '--fast')
167 ('flac_best',
168 ('encopts', '--best')
173 homedir = os.getenv('HOME')
174 if homedir is not None:
175 configfile = os.path.join(homedir, '.audiomangler', 'config')
176 else:
177 configfile = 'audiomangler.cfg'
178 Config.read(configfile)
180 def from_config(*names):
181 locals_ = getattr(getattr(sys._getframe(), 'f_back', None),
182 'f_locals', None)
183 if locals_ is None:
184 return
185 ret = []
186 for key in names:
187 val = locals_.get(key)
188 if val is None:
189 val = Config[key]
190 ret.append(val)
191 return(ret)
192 __all__ = ['Config', 'from_config']