storage:util:mapfile: fix YAML -> JSON in docstrings.
[be.git] / libbe / storage / util / mapfile.py
1 # Copyright (C) 2005-2012 Aaron Bentley <abentley@panoramicfeedback.com>
2 #                         Chris Ball <cjb@laptop.org>
3 #                         Gianluca Montecchi <gian@grys.it>
4 #                         W. Trevor King <wking@tremily.us>
5 #
6 # This file is part of Bugs Everywhere.
7 #
8 # Bugs Everywhere is free software: you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by the Free
10 # Software Foundation, either version 2 of the License, or (at your option) any
11 # later version.
12 #
13 # Bugs Everywhere is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16 # more details.
17 #
18 # You should have received a copy of the GNU General Public License along with
19 # Bugs Everywhere.  If not, see <http://www.gnu.org/licenses/>.
20
21 """Serializing and deserializing dictionaries of parameters.
22
23 The serialized "mapfiles" should be clear, flat-text strings, and allow
24 easy merging of independent/conflicting changes.
25 """
26
27 import errno
28 import json
29 import os.path
30
31 import libbe
32 if libbe.TESTING == True:
33     import doctest
34
35
36 class InvalidMapfileContents (Exception):
37     def __init__(self, contents):
38         super(InvalidMapfileContents, self).__init__('Invalid JSON contents')
39         self.contents = contents
40
41
42 def generate(map):
43     """Generate a JSON mapfile content string.
44
45     Examples
46     --------
47
48     >>> import sys
49     >>> sys.stdout.write(generate({}))
50     {}
51     >>> sys.stdout.write(generate({'q':'p'}))
52     {
53     <BLANKLINE>
54     <BLANKLINE>
55     <BLANKLINE>
56     <BLANKLINE>
57     <BLANKLINE>
58     <BLANKLINE>
59         "q": "p"
60     <BLANKLINE>
61     <BLANKLINE>
62     <BLANKLINE>
63     <BLANKLINE>
64     <BLANKLINE>
65     <BLANKLINE>
66     }
67     >>> generate({'q':u'Fran\u00e7ais'})
68     '{\\n\\n\\n\\n\\n\\n\\n    "q": "Fran\\\\u00e7ais"\\n\\n\\n\\n\\n\\n\\n}\\n'
69     >>> generate({'q':u'hello'})
70     '{\\n\\n\\n\\n\\n\\n\\n    "q": "hello"\\n\\n\\n\\n\\n\\n\\n}\\n'
71     >>> sys.stdout.write(generate(
72     ...         {'p':'really long line\\n'*10, 'q': 'the next entry'}))
73     {
74     <BLANKLINE>
75     <BLANKLINE>
76     <BLANKLINE>
77     <BLANKLINE>
78     <BLANKLINE>
79     <BLANKLINE>
80         "p": "really long line\\nreally long line\\nreally long line\\nreally long line\\nreally long line\\nreally long line\\nreally long line\\nreally long line\\nreally long line\\nreally long line\\n", 
81     <BLANKLINE>
82     <BLANKLINE>
83     <BLANKLINE>
84     <BLANKLINE>
85     <BLANKLINE>
86     <BLANKLINE>
87         "q": "the next entry"
88     <BLANKLINE>
89     <BLANKLINE>
90     <BLANKLINE>
91     <BLANKLINE>
92     <BLANKLINE>
93     <BLANKLINE>
94     }
95
96     See Also
97     --------
98     parse : inverse
99     """
100     lines = json.dumps(map, sort_keys=True, indent=4).splitlines()
101     # add blank lines for context-less merging
102     return '\n\n\n\n\n\n\n'.join(lines) + '\n'
103
104 def parse(contents):
105     """Parse a JSON mapfile string.
106
107     Examples
108     --------
109
110     >>> parse('{"q": "p"}')['q']
111     u'p'
112     >>> contents = generate({'a':'b', 'c':'d', 'e':'f'})
113     >>> dict = parse(contents)
114     >>> dict['a']
115     u'b'
116     >>> dict['c']
117     u'd'
118     >>> dict['e']
119     u'f'
120     >>> contents = generate({'q':u'Fran\u00e7ais'})
121     >>> dict = parse(contents)
122     >>> dict['q']
123     u'Fran\\xe7ais'
124     >>> dict = parse('a!')
125     Traceback (most recent call last):
126       ...
127     InvalidMapfileContents: Invalid JSON contents
128
129     See Also
130     --------
131     generate : inverse
132
133     """
134     try:
135         return json.loads(contents)
136     except ValueError:
137         raise InvalidMapfileContents(contents)
138
139 if libbe.TESTING == True:
140     suite = doctest.DocTestSuite()