Show More
@@ -1,162 +1,162 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 | # This program is free software: you can redistribute it and/or modify |
|
2 | # This program is free software: you can redistribute it and/or modify | |
3 | # it under the terms of the GNU General Public License as published by |
|
3 | # it under the terms of the GNU General Public License as published by | |
4 | # the Free Software Foundation, either version 3 of the License, or |
|
4 | # the Free Software Foundation, either version 3 of the License, or | |
5 | # (at your option) any later version. |
|
5 | # (at your option) any later version. | |
6 | # |
|
6 | # | |
7 | # This program is distributed in the hope that it will be useful, |
|
7 | # This program is distributed in the hope that it will be useful, | |
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | # GNU General Public License for more details. |
|
10 | # GNU General Public License for more details. | |
11 | # |
|
11 | # | |
12 | # You should have received a copy of the GNU General Public License |
|
12 | # You should have received a copy of the GNU General Public License | |
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
13 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
14 |
|
14 | |||
15 | """ |
|
15 | """ | |
16 | kallithea.lib.inifile |
|
16 | kallithea.lib.inifile | |
17 | ~~~~~~~~~~~~~~~~~~~~~ |
|
17 | ~~~~~~~~~~~~~~~~~~~~~ | |
18 |
|
18 | |||
19 | Handling of .ini files, mainly creating them from Mako templates and adding |
|
19 | Handling of .ini files, mainly creating them from Mako templates and adding | |
20 | other custom values. |
|
20 | other custom values. | |
21 | """ |
|
21 | """ | |
22 |
|
22 | |||
23 | import logging |
|
23 | import logging | |
24 | import os |
|
24 | import os | |
25 | import re |
|
25 | import re | |
26 |
|
26 | |||
27 | import mako.template |
|
27 | import mako.template | |
28 |
|
28 | |||
29 |
|
29 | |||
30 | log = logging.getLogger(__name__) |
|
30 | log = logging.getLogger(__name__) | |
31 |
|
31 | |||
32 |
|
32 | |||
33 | template_file = os.path.join( |
|
33 | template_file = os.path.join( | |
34 | os.path.dirname(os.path.dirname(os.path.dirname(__file__))), |
|
34 | os.path.dirname(os.path.dirname(os.path.dirname(__file__))), | |
35 | 'kallithea/lib/paster_commands/template.ini.mako') |
|
35 | 'kallithea/lib/paster_commands/template.ini.mako') | |
36 |
|
36 | |||
37 | default_variables = { |
|
37 | default_variables = { | |
38 | 'database_engine': 'sqlite', |
|
38 | 'database_engine': 'sqlite', | |
39 | 'http_server': 'waitress', |
|
39 | 'http_server': 'waitress', | |
40 | 'host': '127.0.0.1', |
|
40 | 'host': '127.0.0.1', | |
41 | 'port': '5000', |
|
41 | 'port': '5000', | |
42 | 'uuid': lambda: 'VERY-SECRET', |
|
42 | 'uuid': lambda: 'VERY-SECRET', | |
43 | } |
|
43 | } | |
44 |
|
44 | |||
45 |
|
45 | |||
46 | def expand(template, mako_variable_values, settings): |
|
46 | def expand(template, mako_variable_values, settings): | |
47 | """Expand mako template and tweak it. |
|
47 | """Expand mako template and tweak it. | |
48 | Not entirely stable for random templates as input, but good enough for our |
|
48 | Not entirely stable for random templates as input, but good enough for our | |
49 | single template. |
|
49 | single template. | |
50 |
|
50 | |||
51 | >>> template = ''' |
|
51 | >>> template = ''' | |
52 | ... [first-section] |
|
52 | ... [first-section] | |
53 | ... |
|
53 | ... | |
54 | ... variable=${mako_variable} |
|
54 | ... variable=${mako_variable} | |
55 | ... variable2 =\tvalue after tab |
|
55 | ... variable2 =\tvalue after tab | |
56 | ... ## This section had some whitespace and stuff |
|
56 | ... ## This section had some whitespace and stuff | |
57 | ... |
|
57 | ... | |
58 | ... |
|
58 | ... | |
59 | ... # ${mako_function()} |
|
59 | ... # ${mako_function()} | |
60 | ... [second-section] |
|
60 | ... [second-section] | |
61 | ... %if conditional_options == 'option-a': |
|
61 | ... %if conditional_options == 'option-a': | |
62 | ... # option a was chosen |
|
62 | ... # option a was chosen | |
63 | ... %elif conditional_options == 'option-b': |
|
63 | ... %elif conditional_options == 'option-b': | |
64 | ... some_variable = "never mind - option-b will not be used anyway ..." |
|
64 | ... some_variable = "never mind - option-b will not be used anyway ..." | |
65 | ... %endif |
|
65 | ... %endif | |
66 | ... ''' |
|
66 | ... ''' | |
67 | >>> selected_mako_conditionals = [] |
|
67 | >>> selected_mako_conditionals = [] | |
68 | >>> mako_variable_values = {'mako_variable': 'VALUE', 'mako_function': (lambda: 'FUNCTION RESULT'), |
|
68 | >>> mako_variable_values = {'mako_variable': 'VALUE', 'mako_function': (lambda: 'FUNCTION RESULT'), | |
69 | ... 'conditional_options': 'option-a'} |
|
69 | ... 'conditional_options': 'option-a'} | |
70 | >>> settings = { # only partially used |
|
70 | >>> settings = { # only partially used | |
71 | ... '[first-section]': {'variable2': 'VAL2', 'first_extra': 'EXTRA'}, |
|
71 | ... '[first-section]': {'variable2': 'VAL2', 'first_extra': 'EXTRA'}, | |
72 | ... '[third-section]': {'third_extra': ' 3'}, |
|
72 | ... '[third-section]': {'third_extra': ' 3'}, | |
73 | ... '[fourth-section]': {'fourth_extra': '4', 'fourth': '"four"'}, |
|
73 | ... '[fourth-section]': {'fourth_extra': '4', 'fourth': '"four"'}, | |
74 | ... } |
|
74 | ... } | |
75 | >>> print expand(template, mako_variable_values, settings) |
|
75 | >>> print expand(template, mako_variable_values, settings) | |
76 | <BLANKLINE> |
|
76 | <BLANKLINE> | |
77 | [first-section] |
|
77 | [first-section] | |
78 | <BLANKLINE> |
|
78 | <BLANKLINE> | |
79 | variable=VALUE |
|
79 | variable=VALUE | |
80 | #variable2 = value after tab |
|
80 | #variable2 = value after tab | |
81 | variable2 = VAL2 |
|
81 | variable2 = VAL2 | |
82 | <BLANKLINE> |
|
82 | <BLANKLINE> | |
83 | first_extra = EXTRA |
|
83 | first_extra = EXTRA | |
84 | <BLANKLINE> |
|
84 | <BLANKLINE> | |
85 | <BLANKLINE> |
|
85 | <BLANKLINE> | |
86 | # FUNCTION RESULT |
|
86 | # FUNCTION RESULT | |
87 | [second-section] |
|
87 | [second-section] | |
88 | # option a was chosen |
|
88 | # option a was chosen | |
89 | <BLANKLINE> |
|
89 | <BLANKLINE> | |
90 | [fourth-section] |
|
90 | [fourth-section] | |
91 | fourth = "four" |
|
91 | fourth = "four" | |
92 | fourth_extra = 4 |
|
92 | fourth_extra = 4 | |
93 | <BLANKLINE> |
|
93 | <BLANKLINE> | |
94 | [third-section] |
|
94 | [third-section] | |
95 | third_extra = 3 |
|
95 | third_extra = 3 | |
96 | <BLANKLINE> |
|
96 | <BLANKLINE> | |
97 | """ |
|
97 | """ | |
98 | mako_variables = dict(default_variables) |
|
98 | mako_variables = dict(default_variables) | |
99 | mako_variables.update(mako_variable_values or {}) |
|
99 | mako_variables.update(mako_variable_values or {}) | |
100 | settings = dict((k, dict(v)) for k, v in settings.items()) # deep copy before mutating |
|
100 | settings = dict((k, dict(v)) for k, v in settings.items()) # deep copy before mutating | |
101 |
|
101 | |||
102 | ini_lines = mako.template.Template(template).render(**mako_variables) |
|
102 | ini_lines = mako.template.Template(template).render(**mako_variables) | |
103 |
|
103 | |||
104 | def process_section(m): |
|
104 | def process_section(m): | |
105 | """process a ini section, replacing values as necessary""" |
|
105 | """process a ini section, replacing values as necessary""" | |
106 | sectionname, lines = m.groups() |
|
106 | sectionname, lines = m.groups() | |
107 | if sectionname in settings: |
|
107 | if sectionname in settings: | |
108 | section_settings = settings.pop(sectionname) |
|
108 | section_settings = settings.pop(sectionname) | |
109 |
|
109 | |||
110 | def process_line(m): |
|
110 | def process_line(m): | |
111 | """process a section line and update value if necessary""" |
|
111 | """process a section line and update value if necessary""" | |
112 | key, value = m.groups() |
|
112 | key, value = m.groups() | |
113 | line = m.group(0) |
|
113 | line = m.group(0) | |
114 | if key in section_settings: |
|
114 | if key in section_settings: | |
115 | new_line = '%s = %s' % (key, section_settings.pop(key)) |
|
115 | new_line = '%s = %s' % (key, section_settings.pop(key)) | |
116 | if new_line != line: |
|
116 | if new_line != line: | |
117 | # keep old entry as example - comments might refer to it |
|
117 | # keep old entry as example - comments might refer to it | |
118 | line = '#%s\n%s' % (line, new_line) |
|
118 | line = '#%s\n%s' % (line, new_line) | |
119 | return line.rstrip() |
|
119 | return line.rstrip() | |
120 |
|
120 | |||
121 | # process lines that not are comments or empty and look like name=value |
|
121 | # process lines that not are comments or empty and look like name=value | |
122 | lines = re.sub(r'^([^#\n\s]*)[ \t]*=[ \t]*(.*)$', process_line, lines, flags=re.MULTILINE) |
|
122 | lines = re.sub(r'^([^#\n\s]*)[ \t]*=[ \t]*(.*)$', process_line, lines, flags=re.MULTILINE) | |
123 | # add unused section settings |
|
123 | # add unused section settings | |
124 | if section_settings: |
|
124 | if section_settings: | |
125 | lines += '\n' + ''.join('%s = %s\n' % (key, value) for key, value in sorted(section_settings.items())) |
|
125 | lines += '\n' + ''.join('%s = %s\n' % (key, value) for key, value in sorted(section_settings.items())) | |
126 |
|
126 | |||
127 | return sectionname + '\n' + lines |
|
127 | return sectionname + '\n' + lines | |
128 |
|
128 | |||
129 | # process sections until comments before next section or end |
|
129 | # process sections until comments before next section or end | |
130 | ini_lines = re.sub(r'''^ |
|
130 | ini_lines = re.sub(r'''^ | |
131 | (\[.*\])\n |
|
131 | (\[.*\])\n | |
132 | # after the section name, a number of chunks with: |
|
132 | # after the section name, a number of chunks with: | |
133 | ( |
|
133 | ( | |
134 | (?: |
|
134 | (?: | |
135 | # a number of comments or empty lines |
|
135 | # a number of comments or empty lines | |
136 | (?:[#].*\n|\n)* |
|
136 | (?:[#].*\n|\n)* | |
137 | # one or more non-empty non-comments non-section-start lines |
|
137 | # one or more non-empty non-comments non-section-start lines | |
138 | (?:[^\n#[].*\n)+ |
|
138 | (?:[^\n#[].*\n)+ | |
139 | # a number of comments - not empty lines |
|
139 | # a number of comments - not empty lines | |
140 | (?:[#].*\n)* |
|
140 | (?:[#].*\n)* | |
141 | )* |
|
141 | )* | |
142 | ) |
|
142 | ) | |
143 | ''', |
|
143 | ''', | |
144 | process_section, ini_lines, flags=re.MULTILINE|re.VERBOSE) \ |
|
144 | process_section, ini_lines, flags=re.MULTILINE | re.VERBOSE) \ | |
145 | + \ |
|
145 | + \ | |
146 | ''.join( |
|
146 | ''.join( | |
147 | '\n' + sectionname + '\n' + ''.join('%s = %s\n' % (key, value) for key, value in sorted(section_settings.items())) |
|
147 | '\n' + sectionname + '\n' + ''.join('%s = %s\n' % (key, value) for key, value in sorted(section_settings.items())) | |
148 | for sectionname, section_settings in sorted(settings.items()) |
|
148 | for sectionname, section_settings in sorted(settings.items()) | |
149 | if section_settings) |
|
149 | if section_settings) | |
150 |
|
150 | |||
151 | return ini_lines |
|
151 | return ini_lines | |
152 |
|
152 | |||
153 |
|
153 | |||
154 | def create(dest_file, mako_variable_values, settings): |
|
154 | def create(dest_file, mako_variable_values, settings): | |
155 | """Create an ini file at dest_file""" |
|
155 | """Create an ini file at dest_file""" | |
156 | with open(template_file, 'rb') as f: |
|
156 | with open(template_file, 'rb') as f: | |
157 | template = f.read().decode('utf-8') |
|
157 | template = f.read().decode('utf-8') | |
158 |
|
158 | |||
159 | ini_lines = expand(template, mako_variable_values, settings) |
|
159 | ini_lines = expand(template, mako_variable_values, settings) | |
160 |
|
160 | |||
161 | with open(dest_file, 'wb') as f: |
|
161 | with open(dest_file, 'wb') as f: | |
162 | f.write(ini_lines.encode('utf-8')) |
|
162 | f.write(ini_lines.encode('utf-8')) |
@@ -1,47 +1,47 b'' | |||||
1 | #!/usr/bin/env python2 |
|
1 | #!/usr/bin/env python2 | |
2 |
|
2 | |||
3 | import re |
|
3 | import re | |
4 | import sys |
|
4 | import sys | |
5 |
|
5 | |||
6 |
|
6 | |||
7 | logre = r''' |
|
7 | logre = r''' | |
8 | (log\.(?:error|info|warning|debug) |
|
8 | (log\.(?:error|info|warning|debug) | |
9 | [(][ \n]* |
|
9 | [(][ \n]* | |
10 | ) |
|
10 | ) | |
11 | %s |
|
11 | %s | |
12 | ( |
|
12 | ( | |
13 | [ \n]*[)] |
|
13 | [ \n]*[)] | |
14 | ) |
|
14 | ) | |
15 | ''' |
|
15 | ''' | |
16 |
|
16 | |||
17 |
|
17 | |||
18 | res = [ |
|
18 | res = [ | |
19 | # handle % () - keeping spaces around the old % |
|
19 | # handle % () - keeping spaces around the old % | |
20 | (re.compile(logre % r'''("[^"]*"|'[^']*') ([\n ]*) % ([\n ]*) \( ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) \) ''', flags=re.MULTILINE|re.VERBOSE), r'\1\2,\3\4\5\6'), |
|
20 | (re.compile(logre % r'''("[^"]*"|'[^']*') ([\n ]*) % ([\n ]*) \( ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) \) ''', flags=re.MULTILINE | re.VERBOSE), r'\1\2,\3\4\5\6'), | |
21 | # handle % without () - keeping spaces around the old % |
|
21 | # handle % without () - keeping spaces around the old % | |
22 | (re.compile(logre % r'''("[^"]*"|'[^']*') ([\n ]*) % ([\n ]*) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) ''', flags=re.MULTILINE|re.VERBOSE), r'\1\2,\3\4\5\6'), |
|
22 | (re.compile(logre % r'''("[^"]*"|'[^']*') ([\n ]*) % ([\n ]*) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) ''', flags=re.MULTILINE | re.VERBOSE), r'\1\2,\3\4\5\6'), | |
23 | # remove extra space if it is on next line |
|
23 | # remove extra space if it is on next line | |
24 | (re.compile(logre % r'''("[^"]*"|'[^']*') , (\n [ ]) ([ ][\n ]*) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) ''', flags=re.MULTILINE|re.VERBOSE), r'\1\2,\3\4\5\6'), |
|
24 | (re.compile(logre % r'''("[^"]*"|'[^']*') , (\n [ ]) ([ ][\n ]*) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) ''', flags=re.MULTILINE | re.VERBOSE), r'\1\2,\3\4\5\6'), | |
25 | # remove extra space if it is on same line |
|
25 | # remove extra space if it is on same line | |
26 | (re.compile(logre % r'''("[^"]*"|'[^']*') , [ ]+ () ( [\n ]+) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) ''', flags=re.MULTILINE|re.VERBOSE), r'\1\2,\3\4\5\6'), |
|
26 | (re.compile(logre % r'''("[^"]*"|'[^']*') , [ ]+ () ( [\n ]+) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* ) ''', flags=re.MULTILINE | re.VERBOSE), r'\1\2,\3\4\5\6'), | |
27 | # remove trailing , and space |
|
27 | # remove trailing , and space | |
28 | (re.compile(logre % r'''("[^"]*"|'[^']*') , () ( [\n ]*) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* [^(), \n] ) [ ,]*''', flags=re.MULTILINE|re.VERBOSE), r'\1\2,\3\4\5\6'), |
|
28 | (re.compile(logre % r'''("[^"]*"|'[^']*') , () ( [\n ]*) ( (?:[^()]|\n)* (?: \( (?:[^()]|\n)* \) (?:[^()]|\n)* )* [^(), \n] ) [ ,]*''', flags=re.MULTILINE | re.VERBOSE), r'\1\2,\3\4\5\6'), | |
29 | ] |
|
29 | ] | |
30 |
|
30 | |||
31 |
|
31 | |||
32 | def rewrite(f): |
|
32 | def rewrite(f): | |
33 | s = open(f).read() |
|
33 | s = open(f).read() | |
34 | for r, t in res: |
|
34 | for r, t in res: | |
35 | s = r.sub(t, s) |
|
35 | s = r.sub(t, s) | |
36 | open(f, 'w').write(s) |
|
36 | open(f, 'w').write(s) | |
37 |
|
37 | |||
38 |
|
38 | |||
39 | if __name__ == '__main__': |
|
39 | if __name__ == '__main__': | |
40 | if len(sys.argv) < 2: |
|
40 | if len(sys.argv) < 2: | |
41 | print 'Cleanup of superfluous % formatting of log statements.' |
|
41 | print 'Cleanup of superfluous % formatting of log statements.' | |
42 | print 'Usage:' |
|
42 | print 'Usage:' | |
43 | print ''' hg revert `hg loc '*.py'|grep -v logformat.py` && scripts/logformat.py `hg loc '*.py'` && hg diff''' |
|
43 | print ''' hg revert `hg loc '*.py'|grep -v logformat.py` && scripts/logformat.py `hg loc '*.py'` && hg diff''' | |
44 | raise SystemExit(1) |
|
44 | raise SystemExit(1) | |
45 |
|
45 | |||
46 | for f in sys.argv[1:]: |
|
46 | for f in sys.argv[1:]: | |
47 | rewrite(f) |
|
47 | rewrite(f) |
General Comments 0
You need to be logged in to leave comments.
Login now