Commit | Line | Data |
---|---|---|
fbad3a9f | 1 | # GNU MediaGoblin -- federated, autonomous media hosting |
7f4ebeed | 2 | # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. |
fbad3a9f E |
3 | # |
4 | # This program is free software: you can redistribute it and/or modify | |
5 | # it under the terms of the GNU Affero General Public License as published by | |
6 | # the Free Software Foundation, either version 3 of the License, or | |
7 | # (at your option) any later version. | |
8 | # | |
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU Affero General Public License for more details. | |
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | ||
7f9d3ca7 | 18 | from sqlalchemy.ext.mutable import Mutable |
1e3a0e0c | 19 | from sqlalchemy.types import TypeDecorator, Unicode, TEXT |
cf27accc | 20 | import json |
02db7e0a E |
21 | |
22 | ||
23 | class PathTupleWithSlashes(TypeDecorator): | |
24 | "Represents a Tuple of strings as a slash separated string." | |
25 | ||
26 | impl = Unicode | |
27 | ||
28 | def process_bind_param(self, value, dialect): | |
29 | if value is not None: | |
51fba991 E |
30 | if len(value) == 0: |
31 | value = None | |
32 | else: | |
33 | value = '/'.join(value) | |
02db7e0a E |
34 | return value |
35 | ||
36 | def process_result_value(self, value, dialect): | |
37 | if value is not None: | |
38 | value = tuple(value.split('/')) | |
39 | return value | |
cf27accc E |
40 | |
41 | ||
7f9d3ca7 | 42 | # The following two classes and only these two classes is in very |
cf27accc E |
43 | # large parts based on example code from sqlalchemy. |
44 | # | |
45 | # The original copyright notice and license follows: | |
46 | # Copyright (C) 2005-2011 the SQLAlchemy authors and contributors <see AUTHORS file> | |
47 | # | |
48 | # This module is part of SQLAlchemy and is released under | |
49 | # the MIT License: http://www.opensource.org/licenses/mit-license.php | |
50 | # | |
51 | class JSONEncoded(TypeDecorator): | |
52 | "Represents an immutable structure as a json-encoded string." | |
53 | ||
1e3a0e0c | 54 | impl = TEXT |
cf27accc E |
55 | |
56 | def process_bind_param(self, value, dialect): | |
57 | if value is not None: | |
58 | value = json.dumps(value) | |
59 | return value | |
60 | ||
61 | def process_result_value(self, value, dialect): | |
62 | if value is not None: | |
63 | value = json.loads(value) | |
64 | return value | |
7f9d3ca7 RE |
65 | |
66 | ||
67 | class MutationDict(Mutable, dict): | |
68 | @classmethod | |
69 | def coerce(cls, key, value): | |
70 | "Convert plain dictionaries to MutationDict." | |
71 | ||
72 | if not isinstance(value, MutationDict): | |
73 | if isinstance(value, dict): | |
74 | return MutationDict(value) | |
75 | ||
76 | # this call will raise ValueError | |
77 | return Mutable.coerce(key, value) | |
78 | else: | |
79 | return value | |
80 | ||
81 | def __setitem__(self, key, value): | |
82 | "Detect dictionary set events and emit change events." | |
83 | ||
84 | dict.__setitem__(self, key, value) | |
85 | self.changed() | |
86 | ||
87 | def __delitem__(self, key): | |
88 | "Detect dictionary del events and emit change events." | |
89 | ||
90 | dict.__delitem__(self, key) | |
91 | self.changed() |