|
1
|
1 |
|
from plugin.core.environment import Environment |
|
2
|
1 |
|
from plugin.preferences.options import OPTIONS |
|
3
|
|
|
|
|
4
|
1 |
|
from exception_wrappers import DisabledError |
|
5
|
|
|
import logging |
|
6
|
1 |
|
|
|
7
|
|
|
log = logging.getLogger(__name__) |
|
8
|
|
|
|
|
9
|
1 |
|
|
|
10
|
1 |
|
class Preferences(object): |
|
11
|
1 |
|
@classmethod |
|
12
|
|
|
def initialize(cls, account=None): |
|
13
|
|
|
scope = 'account' if account is not None else 'server' |
|
14
|
|
|
|
|
15
|
|
|
# Initialize preferences |
|
16
|
|
|
for key, option in OPTIONS_BY_KEY.items(): |
|
17
|
|
|
if option.scope != scope: |
|
18
|
|
|
continue |
|
19
|
|
|
|
|
20
|
|
|
try: |
|
21
|
1 |
|
option.get(account) |
|
22
|
1 |
|
except DisabledError: |
|
23
|
|
|
return |
|
24
|
|
|
except Exception as ex: |
|
|
|
|
|
|
25
|
|
|
log.warn('Unable to initialize option %r: %s', key, ex, exc_info=True) |
|
26
|
|
|
|
|
27
|
|
|
@classmethod |
|
28
|
|
|
def get(cls, key, account=None): |
|
29
|
|
|
if not key: |
|
30
|
|
|
raise ValueError('Invalid value provided for "key"') |
|
31
|
|
|
|
|
32
|
|
|
if key not in OPTIONS_BY_KEY: |
|
33
|
|
|
raise ValueError('Unknown option: %r' % key) |
|
34
|
|
|
|
|
35
|
1 |
|
# Retrieve option from database |
|
36
|
1 |
|
option_cls = OPTIONS_BY_KEY[key] |
|
37
|
|
|
|
|
38
|
|
|
try: |
|
39
|
|
|
option = option_cls.get(account) |
|
40
|
|
|
except DisabledError: |
|
41
|
|
|
return option_cls.default |
|
42
|
|
|
except Exception as ex: |
|
|
|
|
|
|
43
|
|
|
log.warn('Unable to retrieve option %r: %s', key, ex, exc_info=True) |
|
44
|
|
|
return option_cls.default |
|
45
|
|
|
|
|
46
|
|
|
# Return option value |
|
47
|
|
|
return option.value |
|
48
|
|
|
|
|
49
|
|
|
@classmethod |
|
50
|
|
|
def migrate(cls, account=None): |
|
51
|
1 |
|
scope = 'account' if account is not None else 'server' |
|
52
|
1 |
|
|
|
53
|
|
|
# Migrate preferences to database |
|
54
|
|
|
for key, option in OPTIONS_BY_PREFERENCE.items(): |
|
55
|
|
|
if option.scope == scope: |
|
56
|
|
|
success = Preferences.on_plex_changed(key, Environment.prefs[key], account=account) |
|
57
|
|
|
elif option.scope == scope: |
|
58
|
|
|
success = Preferences.on_plex_changed(key, Environment.prefs[key]) |
|
59
|
|
|
else: |
|
60
|
|
|
continue |
|
61
|
|
|
|
|
62
|
|
|
if success: |
|
63
|
|
|
log.debug('Updated %r option in database', key) |
|
64
|
|
|
|
|
65
|
|
|
@classmethod |
|
66
|
|
|
def update(cls, key, value, account=None): |
|
67
|
1 |
|
if not key: |
|
68
|
1 |
|
raise ValueError('Invalid value provided for "key"') |
|
69
|
|
|
|
|
70
|
|
|
if key not in OPTIONS_BY_KEY: |
|
71
|
|
|
raise ValueError('Unknown option: %r' % key) |
|
72
|
|
|
|
|
73
|
|
|
# Update option in database |
|
74
|
|
|
option = OPTIONS_BY_KEY[key] |
|
75
|
|
|
option.update(value, account) |
|
76
|
|
|
|
|
77
|
|
|
# |
|
78
|
|
|
# Event handlers |
|
79
|
|
|
# |
|
80
|
|
|
|
|
81
|
|
|
@classmethod |
|
82
|
|
|
def on_database_changed(cls, key, value, account=None): |
|
83
|
|
|
if not key: |
|
84
|
|
|
raise ValueError('Invalid value provided for "key"') |
|
85
|
|
|
|
|
86
|
|
|
if key not in OPTIONS_BY_KEY: |
|
87
|
1 |
|
raise ValueError('Unknown option: %r' % key) |
|
88
|
1 |
|
|
|
89
|
|
|
option = OPTIONS_BY_KEY[key] |
|
90
|
|
|
|
|
91
|
|
|
try: |
|
92
|
|
|
value = option.on_database_changed(value, account=account) |
|
93
|
|
|
|
|
94
|
|
|
option.on_changed(value, account=account) |
|
95
|
|
|
return True |
|
96
|
|
|
except Exception: |
|
|
|
|
|
|
97
|
|
|
log.warn('Unable to process database preference change for %r', key, exc_info=True) |
|
98
|
|
|
|
|
99
|
|
|
return False |
|
100
|
|
|
|
|
101
|
|
|
@classmethod |
|
102
|
|
|
def on_plex_changed(cls, key, value, account=None): |
|
103
|
|
|
if not key: |
|
104
|
|
|
raise ValueError('Invalid value provided for "key"') |
|
105
|
|
|
|
|
106
|
|
|
if key not in OPTIONS_BY_PREFERENCE: |
|
107
|
|
|
raise ValueError('Unknown option: %r' % key) |
|
108
|
|
|
|
|
109
|
1 |
|
option = OPTIONS_BY_PREFERENCE[key] |
|
110
|
|
|
|
|
111
|
|
|
try: |
|
112
|
1 |
|
value = option.on_plex_changed(value, account=account) |
|
113
|
|
|
|
|
114
|
|
|
option.on_changed(value, account=account) |
|
115
|
|
|
return True |
|
116
|
|
|
except Exception: |
|
|
|
|
|
|
117
|
|
|
log.warn('Unable to process plex preference change for %r', key, exc_info=True) |
|
118
|
1 |
|
|
|
119
|
|
|
return False |
|
120
|
|
|
|
|
121
|
|
|
|
|
122
|
|
|
# Construct options |
|
123
|
|
|
OPTIONS = [o(Preferences) for o in OPTIONS] |
|
124
|
|
|
|
|
125
|
|
|
# Build option maps |
|
126
|
|
|
OPTIONS_BY_KEY = dict([ |
|
127
|
|
|
(o.key, o) |
|
128
|
|
|
for o in OPTIONS |
|
129
|
|
|
if o.key |
|
130
|
|
|
]) |
|
131
|
|
|
|
|
132
|
|
|
OPTIONS_BY_PREFERENCE = dict([ |
|
133
|
|
|
(o.preference, o) |
|
134
|
|
|
for o in OPTIONS |
|
135
|
|
|
if o.preference |
|
136
|
|
|
]) |
|
137
|
|
|
|
Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.
So, unless you specifically plan to handle any error, consider adding a more specific exception.