Merge lp:~jfb-tempo-consulting/unifield-web/us-812 into lp:unifield-web
- us-812
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 4778 |
Proposed branch: | lp:~jfb-tempo-consulting/unifield-web/us-812 |
Merge into: | lp:unifield-web |
Diff against target: |
599 lines (+353/-29) 11 files modified
addons/openerp/controllers/actions.py (+20/-6) addons/openerp/controllers/database.py (+44/-11) addons/openerp/utils/serve_file.py (+142/-0) addons/openerp/utils/tools.py (+2/-1) doc/openerp-web-oc.cfg (+5/-0) doc/openerp-web-win.cfg (+93/-0) doc/openerp-web.cfg (+2/-1) openobject/__init__.py (+6/-3) openobject/commands.py (+32/-3) openobject/tools/_expose.py (+4/-2) setup.nsi (+3/-2) |
To merge this branch: | bzr merge lp:~jfb-tempo-consulting/unifield-web/us-812 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Reviewer Team | Pending | ||
Review via email: mp+283073@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'addons/openerp/controllers/actions.py' | |||
2 | --- addons/openerp/controllers/actions.py 2015-12-18 16:10:29 +0000 | |||
3 | +++ addons/openerp/controllers/actions.py 2016-01-19 10:40:01 +0000 | |||
4 | @@ -27,7 +27,7 @@ | |||
5 | 27 | import zlib | 27 | import zlib |
6 | 28 | 28 | ||
7 | 29 | import cherrypy | 29 | import cherrypy |
9 | 30 | from openerp.utils import rpc, common, expr_eval, TinyDict | 30 | from openerp.utils import rpc, common, expr_eval, TinyDict, is_server_local, serve_file |
10 | 31 | 31 | ||
11 | 32 | from form import Form | 32 | from form import Form |
12 | 33 | from openobject import tools | 33 | from openobject import tools |
13 | @@ -36,6 +36,7 @@ | |||
14 | 36 | from wizard import Wizard | 36 | from wizard import Wizard |
15 | 37 | import urllib | 37 | import urllib |
16 | 38 | import re | 38 | import re |
17 | 39 | import os | ||
18 | 39 | 40 | ||
19 | 40 | def execute_window(view_ids, model, res_id=False, domain=None, view_type='form', context=None, | 41 | def execute_window(view_ids, model, res_id=False, domain=None, view_type='form', context=None, |
20 | 41 | mode='form,tree', name=None, target=None, limit=None, search_view=None, | 42 | mode='form,tree', name=None, target=None, limit=None, search_view=None, |
21 | @@ -127,17 +128,29 @@ | |||
22 | 127 | } | 128 | } |
23 | 128 | 129 | ||
24 | 129 | def _print_data(data): | 130 | def _print_data(data): |
27 | 130 | 131 | if 'result' not in data and 'path' not in data: | |
26 | 131 | if 'result' not in data: | ||
28 | 132 | raise common.message(_('Error no report')) | 132 | raise common.message(_('Error no report')) |
29 | 133 | 133 | ||
30 | 134 | cherrypy.response.headers['Content-Type'] = PRINT_FORMATS[data['format']] | ||
31 | 134 | if data.get('code','normal')=='zlib': | 135 | if data.get('code','normal')=='zlib': |
32 | 135 | import zlib | 136 | import zlib |
33 | 136 | content = zlib.decompress(base64.decodestring(data['result'])) | 137 | content = zlib.decompress(base64.decodestring(data['result'])) |
34 | 137 | else: | 138 | else: |
35 | 139 | if not data.get('result') and data.get('path'): | ||
36 | 140 | try: | ||
37 | 141 | return serve_file.serve_file(data['path'], "application/x-download", 'attachment', delete=data.get('delete', False)) | ||
38 | 142 | except Exception, e: | ||
39 | 143 | cherrypy.response.headers['Content-Type'] = 'text/html' | ||
40 | 144 | if 'Content-Disposition' in cherrypy.response.headers: | ||
41 | 145 | del(cherrypy.response.headers['Content-Disposition']) | ||
42 | 146 | raise common.warning(e) | ||
43 | 147 | finally: | ||
44 | 148 | if data.get('delete', False) and os.path.exists(data['path']): | ||
45 | 149 | os.remove(data['path']) | ||
46 | 150 | # return cherrypy.lib.static.serve_file(data['path'], "application/x-download", 'attachment') | ||
47 | 151 | |||
48 | 138 | content = base64.decodestring(data['result']) | 152 | content = base64.decodestring(data['result']) |
49 | 139 | 153 | ||
50 | 140 | cherrypy.response.headers['Content-Type'] = PRINT_FORMATS[data['format']] | ||
51 | 141 | return content | 154 | return content |
52 | 142 | 155 | ||
53 | 143 | def execute_report(name, **data): | 156 | def execute_report(name, **data): |
54 | @@ -162,6 +175,8 @@ | |||
55 | 162 | try: | 175 | try: |
56 | 163 | ctx = dict(rpc.session.context) | 176 | ctx = dict(rpc.session.context) |
57 | 164 | ctx.update(datas.get('context', {})) | 177 | ctx.update(datas.get('context', {})) |
58 | 178 | if is_server_local(): | ||
59 | 179 | ctx['report_fromfile'] = 1 | ||
60 | 165 | report_id = rpc.session.execute('report', 'report', name, ids, datas, ctx) | 180 | report_id = rpc.session.execute('report', 'report', name, ids, datas, ctx) |
61 | 166 | state = False | 181 | state = False |
62 | 167 | attempt = 0 | 182 | attempt = 0 |
63 | @@ -189,8 +204,7 @@ | |||
64 | 189 | if datas.get('force_attach'): | 204 | if datas.get('force_attach'): |
65 | 190 | attachment = 'attachment;' | 205 | attachment = 'attachment;' |
66 | 191 | if background_id: | 206 | if background_id: |
69 | 192 | bg_report = rpc.session.execute('object', 'execute', 'memory.background.report', 'write', [background_id], {'report_id': report_id, 'report_name': report_name}) | 207 | bg_report = rpc.session.execute('object', 'execute', 'memory.background.report', 'write', [background_id], {'report_id': background_id, 'report_name': report_name}) |
68 | 193 | |||
70 | 194 | 208 | ||
71 | 195 | while not state: | 209 | while not state: |
72 | 196 | val = rpc.session.execute('report', 'report_get', report_id) | 210 | val = rpc.session.execute('report', 'report_get', report_id) |
73 | 197 | 211 | ||
74 | === modified file 'addons/openerp/controllers/database.py' | |||
75 | --- addons/openerp/controllers/database.py 2015-05-28 10:07:02 +0000 | |||
76 | +++ addons/openerp/controllers/database.py 2016-01-19 10:40:01 +0000 | |||
77 | @@ -21,6 +21,7 @@ | |||
78 | 21 | import base64 | 21 | import base64 |
79 | 22 | import re | 22 | import re |
80 | 23 | import time | 23 | import time |
81 | 24 | import os | ||
82 | 24 | 25 | ||
83 | 25 | import cherrypy | 26 | import cherrypy |
84 | 26 | import formencode | 27 | import formencode |
85 | @@ -31,7 +32,9 @@ | |||
86 | 31 | import openobject.errors | 32 | import openobject.errors |
87 | 32 | 33 | ||
88 | 33 | from openerp import validators | 34 | from openerp import validators |
90 | 34 | from openerp.utils import rpc, get_server_version | 35 | from openerp.utils import rpc, get_server_version, is_server_local, serve_file |
91 | 36 | from tempfile import NamedTemporaryFile | ||
92 | 37 | import shutil | ||
93 | 35 | 38 | ||
94 | 36 | def get_lang_list(): | 39 | def get_lang_list(): |
95 | 37 | langs = [('en_US', 'English (US)')] | 40 | langs = [('en_US', 'English (US)')] |
96 | @@ -94,14 +97,19 @@ | |||
97 | 94 | fields = [openobject.widgets.SelectField(name='dbname', options=get_db_list, label=_('Database:'), validator=validators.String(not_empty=True)), | 97 | fields = [openobject.widgets.SelectField(name='dbname', options=get_db_list, label=_('Database:'), validator=validators.String(not_empty=True)), |
98 | 95 | openobject.widgets.PasswordField(name='password', label=_('Backup password:'), validator=formencode.validators.NotEmpty())] | 98 | openobject.widgets.PasswordField(name='password', label=_('Backup password:'), validator=formencode.validators.NotEmpty())] |
99 | 96 | 99 | ||
100 | 100 | class FileField(openobject.widgets.FileField): | ||
101 | 101 | def adjust_value(self, value, **params): | ||
102 | 102 | return False | ||
103 | 103 | |||
104 | 97 | class FormRestore(DBForm): | 104 | class FormRestore(DBForm): |
105 | 98 | name = "restore" | 105 | name = "restore" |
106 | 99 | string = _('Restore database') | 106 | string = _('Restore database') |
107 | 100 | action = '/openerp/database/do_restore' | 107 | action = '/openerp/database/do_restore' |
108 | 101 | submit_text = _('Restore') | 108 | submit_text = _('Restore') |
110 | 102 | fields = [openobject.widgets.FileField(name="filename", label=_('File:')), | 109 | fields = [FileField(name="filename", label=_('File:')), |
111 | 103 | openobject.widgets.PasswordField(name='password', label=_('Restore password:'), validator=formencode.validators.NotEmpty()), | 110 | openobject.widgets.PasswordField(name='password', label=_('Restore password:'), validator=formencode.validators.NotEmpty()), |
112 | 104 | openobject.widgets.TextField(name='dbname', label=_('New database name:'), validator=formencode.validators.NotEmpty(), readonly=1, attrs={'readonly': ''})] | 111 | openobject.widgets.TextField(name='dbname', label=_('New database name:'), validator=formencode.validators.NotEmpty(), readonly=1, attrs={'readonly': ''})] |
113 | 112 | hidden_fields = [openobject.widgets.HiddenField(name='fpath', label=_('Path:'))] | ||
114 | 105 | 113 | ||
115 | 106 | class FormPassword(DBForm): | 114 | class FormPassword(DBForm): |
116 | 107 | name = "password" | 115 | name = "password" |
117 | @@ -245,15 +253,24 @@ | |||
118 | 245 | def do_backup(self, dbname, password, **kw): | 253 | def do_backup(self, dbname, password, **kw): |
119 | 246 | self.msg = {} | 254 | self.msg = {} |
120 | 247 | try: | 255 | try: |
121 | 248 | res = rpc.session.execute_db('dump', password, dbname) | ||
122 | 249 | filename = [dbname, time.strftime('%Y%m%d-%H%M%S')] | 256 | filename = [dbname, time.strftime('%Y%m%d-%H%M%S')] |
123 | 250 | version = get_server_version() | 257 | version = get_server_version() |
124 | 251 | if version: | 258 | if version: |
125 | 252 | filename.append(version) | 259 | filename.append(version) |
130 | 253 | if res: | 260 | |
131 | 254 | cherrypy.response.headers['Content-Type'] = "application/data" | 261 | if is_server_local(): |
132 | 255 | cherrypy.response.headers['Content-Disposition'] = 'filename="%s.dump"' % '-'.join(filename) | 262 | res = rpc.session.execute_db('dump_file', password, dbname) |
133 | 256 | return base64.decodestring(res) | 263 | try: |
134 | 264 | return serve_file.serve_file(res, "application/x-download", 'attachment', '%s.dump' % '-'.join(filename), delete=True) | ||
135 | 265 | finally: | ||
136 | 266 | if os.path.exists(res): | ||
137 | 267 | os.remove(res) | ||
138 | 268 | else: | ||
139 | 269 | res = rpc.session.execute_db('dump', password, dbname) | ||
140 | 270 | if res: | ||
141 | 271 | cherrypy.response.headers['Content-Type'] = "application/data" | ||
142 | 272 | cherrypy.response.headers['Content-Disposition'] = 'filename="%s.dump"' % '-'.join(filename) | ||
143 | 273 | return base64.decodestring(res) | ||
144 | 257 | except openobject.errors.AccessDenied, e: | 274 | except openobject.errors.AccessDenied, e: |
145 | 258 | self.msg = {'message': _('Wrong password'), | 275 | self.msg = {'message': _('Wrong password'), |
146 | 259 | 'title' : e.title} | 276 | 'title' : e.title} |
147 | @@ -293,14 +310,30 @@ | |||
148 | 293 | 'title': _('Error')} | 310 | 'title': _('Error')} |
149 | 294 | return self.restore() | 311 | return self.restore() |
150 | 295 | try: | 312 | try: |
153 | 296 | data = base64.encodestring(filename.file.read()) | 313 | if is_server_local(): |
154 | 297 | rpc.session.execute_db('restore', password, dbname, data) | 314 | if not filename.filename and kw.get('fpath'): |
155 | 315 | filename = kw.get('fpath') | ||
156 | 316 | else: | ||
157 | 317 | newfile = NamedTemporaryFile(delete=False) | ||
158 | 318 | shutil.copyfileobj(filename.file, newfile) | ||
159 | 319 | filename = newfile.name | ||
160 | 320 | newfile.close() | ||
161 | 321 | rpc.session.execute_db('restore_file', password, dbname, filename) | ||
162 | 322 | else: | ||
163 | 323 | data = base64.encodestring(filename.file.read()) | ||
164 | 324 | rpc.session.execute_db('restore', password, dbname, data) | ||
165 | 298 | except openobject.errors.AccessDenied, e: | 325 | except openobject.errors.AccessDenied, e: |
166 | 299 | self.msg = {'message': _('Wrong password'), | 326 | self.msg = {'message': _('Wrong password'), |
167 | 300 | 'title' : e.title} | 327 | 'title' : e.title} |
168 | 328 | if hasattr(cherrypy.request, 'input_values') and filename: | ||
169 | 329 | cherrypy.request.input_values['fpath'] = filename | ||
170 | 301 | return self.restore() | 330 | return self.restore() |
173 | 302 | except Exception: | 331 | except Exception, e: |
174 | 303 | self.msg = {'message': _("Could not restore database")} | 332 | msg = _("Could not restore database") |
175 | 333 | if isinstance(e, openobject.errors.TinyException): | ||
176 | 334 | if 'Database already exists' in e.message: | ||
177 | 335 | msg = _("Could not restore: database already exists") | ||
178 | 336 | self.msg = {'message': msg} | ||
179 | 304 | return self.restore() | 337 | return self.restore() |
180 | 305 | raise redirect('/openerp/login', db=dbname) | 338 | raise redirect('/openerp/login', db=dbname) |
181 | 306 | 339 | ||
182 | 307 | 340 | ||
183 | === added file 'addons/openerp/utils/serve_file.py' | |||
184 | --- addons/openerp/utils/serve_file.py 1970-01-01 00:00:00 +0000 | |||
185 | +++ addons/openerp/utils/serve_file.py 2016-01-19 10:40:01 +0000 | |||
186 | @@ -0,0 +1,142 @@ | |||
187 | 1 | import mimetypes | ||
188 | 2 | mimetypes.init() | ||
189 | 3 | mimetypes.types_map['.dwg']='image/x-dwg' | ||
190 | 4 | mimetypes.types_map['.ico']='image/x-icon' | ||
191 | 5 | |||
192 | 6 | import os | ||
193 | 7 | import re | ||
194 | 8 | import stat | ||
195 | 9 | import time | ||
196 | 10 | import urllib | ||
197 | 11 | import tempfile | ||
198 | 12 | import cherrypy | ||
199 | 13 | from cherrypy.lib import cptools, http, file_generator_limited | ||
200 | 14 | |||
201 | 15 | def serve_file(path, content_type=None, disposition=None, name=None, delete=False): | ||
202 | 16 | """Set status, headers, and body in order to serve the given file. | ||
203 | 17 | |||
204 | 18 | The Content-Type header will be set to the content_type arg, if provided. | ||
205 | 19 | If not provided, the Content-Type will be guessed by the file extension | ||
206 | 20 | of the 'path' argument. | ||
207 | 21 | |||
208 | 22 | If disposition is not None, the Content-Disposition header will be set | ||
209 | 23 | to "<disposition>; filename=<name>". If name is None, it will be set | ||
210 | 24 | to the basename of path. If disposition is None, no Content-Disposition | ||
211 | 25 | header will be written. | ||
212 | 26 | """ | ||
213 | 27 | |||
214 | 28 | response = cherrypy.response | ||
215 | 29 | |||
216 | 30 | # If path is relative, users should fix it by making path absolute. | ||
217 | 31 | # That is, CherryPy should not guess where the application root is. | ||
218 | 32 | # It certainly should *not* use cwd (since CP may be invoked from a | ||
219 | 33 | # variety of paths). If using tools.static, you can make your relative | ||
220 | 34 | # paths become absolute by supplying a value for "tools.static.root". | ||
221 | 35 | if not os.path.isabs(path): | ||
222 | 36 | raise ValueError("'%s' is not an absolute path." % path) | ||
223 | 37 | |||
224 | 38 | try: | ||
225 | 39 | st = os.stat(path) | ||
226 | 40 | except OSError: | ||
227 | 41 | raise cherrypy.NotFound() | ||
228 | 42 | |||
229 | 43 | # Check if path is a directory. | ||
230 | 44 | if stat.S_ISDIR(st.st_mode): | ||
231 | 45 | # Let the caller deal with it as they like. | ||
232 | 46 | raise cherrypy.NotFound() | ||
233 | 47 | |||
234 | 48 | # Set the Last-Modified response header, so that | ||
235 | 49 | # modified-since validation code can work. | ||
236 | 50 | response.headers['Last-Modified'] = http.HTTPDate(st.st_mtime) | ||
237 | 51 | cptools.validate_since() | ||
238 | 52 | |||
239 | 53 | if content_type is None: | ||
240 | 54 | # Set content-type based on filename extension | ||
241 | 55 | ext = "" | ||
242 | 56 | i = path.rfind('.') | ||
243 | 57 | if i != -1: | ||
244 | 58 | ext = path[i:].lower() | ||
245 | 59 | content_type = mimetypes.types_map.get(ext, "text/plain") | ||
246 | 60 | response.headers['Content-Type'] = content_type | ||
247 | 61 | |||
248 | 62 | if disposition is not None: | ||
249 | 63 | if name is None: | ||
250 | 64 | name = os.path.basename(path) | ||
251 | 65 | cd = '%s; filename="%s"' % (disposition, name) | ||
252 | 66 | response.headers["Content-Disposition"] = cd | ||
253 | 67 | |||
254 | 68 | # Set Content-Length and use an iterable (file object) | ||
255 | 69 | # this way CP won't load the whole file in memory | ||
256 | 70 | c_len = st.st_size | ||
257 | 71 | if delete: | ||
258 | 72 | flag = os.O_RDWR | os.O_EXCL | ||
259 | 73 | if hasattr(os, 'O_BINARY'): | ||
260 | 74 | flag |= os.O_BINARY | ||
261 | 75 | if os.name == 'nt': | ||
262 | 76 | flag |= os.O_TEMPORARY | ||
263 | 77 | fd = os.open(path, flag) | ||
264 | 78 | file = os.fdopen(fd, 'rb') | ||
265 | 79 | bodyfile = file | ||
266 | 80 | else: | ||
267 | 81 | bodyfile = open(path, 'rb') | ||
268 | 82 | |||
269 | 83 | # HTTP/1.0 didn't have Range/Accept-Ranges headers, or the 206 code | ||
270 | 84 | if cherrypy.request.protocol >= (1, 1): | ||
271 | 85 | response.headers["Accept-Ranges"] = "bytes" | ||
272 | 86 | r = http.get_ranges(cherrypy.request.headers.get('Range'), c_len) | ||
273 | 87 | if r == []: | ||
274 | 88 | response.headers['Content-Range'] = "bytes */%s" % c_len | ||
275 | 89 | message = "Invalid Range (first-byte-pos greater than Content-Length)" | ||
276 | 90 | raise cherrypy.HTTPError(416, message) | ||
277 | 91 | if r: | ||
278 | 92 | if len(r) == 1: | ||
279 | 93 | # Return a single-part response. | ||
280 | 94 | start, stop = r[0] | ||
281 | 95 | if stop > c_len: | ||
282 | 96 | stop = c_len | ||
283 | 97 | r_len = stop - start | ||
284 | 98 | response.status = "206 Partial Content" | ||
285 | 99 | response.headers['Content-Range'] = ("bytes %s-%s/%s" % | ||
286 | 100 | (start, stop - 1, c_len)) | ||
287 | 101 | response.headers['Content-Length'] = r_len | ||
288 | 102 | bodyfile.seek(start) | ||
289 | 103 | response.body = file_generator_limited(bodyfile, r_len) | ||
290 | 104 | else: | ||
291 | 105 | # Return a multipart/byteranges response. | ||
292 | 106 | response.status = "206 Partial Content" | ||
293 | 107 | import mimetools | ||
294 | 108 | boundary = mimetools.choose_boundary() | ||
295 | 109 | ct = "multipart/byteranges; boundary=%s" % boundary | ||
296 | 110 | response.headers['Content-Type'] = ct | ||
297 | 111 | if response.headers.has_key("Content-Length"): | ||
298 | 112 | # Delete Content-Length header so finalize() recalcs it. | ||
299 | 113 | del response.headers["Content-Length"] | ||
300 | 114 | |||
301 | 115 | def file_ranges(): | ||
302 | 116 | # Apache compatibility: | ||
303 | 117 | yield "\r\n" | ||
304 | 118 | |||
305 | 119 | for start, stop in r: | ||
306 | 120 | yield "--" + boundary | ||
307 | 121 | yield "\r\nContent-type: %s" % content_type | ||
308 | 122 | yield ("\r\nContent-range: bytes %s-%s/%s\r\n\r\n" | ||
309 | 123 | % (start, stop - 1, c_len)) | ||
310 | 124 | bodyfile.seek(start) | ||
311 | 125 | for chunk in file_generator_limited(bodyfile, stop-start): | ||
312 | 126 | yield chunk | ||
313 | 127 | yield "\r\n" | ||
314 | 128 | # Final boundary | ||
315 | 129 | yield "--" + boundary + "--" | ||
316 | 130 | |||
317 | 131 | # Apache compatibility: | ||
318 | 132 | yield "\r\n" | ||
319 | 133 | response.body = file_ranges() | ||
320 | 134 | else: | ||
321 | 135 | response.headers['Content-Length'] = c_len | ||
322 | 136 | response.body = bodyfile | ||
323 | 137 | else: | ||
324 | 138 | response.headers['Content-Length'] = c_len | ||
325 | 139 | response.body = bodyfile | ||
326 | 140 | response.stream = True | ||
327 | 141 | return response.body | ||
328 | 142 | |||
329 | 0 | 143 | ||
330 | === modified file 'addons/openerp/utils/tools.py' | |||
331 | --- addons/openerp/utils/tools.py 2011-06-30 13:58:31 +0000 | |||
332 | +++ addons/openerp/utils/tools.py 2016-01-19 10:40:01 +0000 | |||
333 | @@ -253,5 +253,6 @@ | |||
334 | 253 | def __deepcopy__(self, visit): | 253 | def __deepcopy__(self, visit): |
335 | 254 | return self | 254 | return self |
336 | 255 | 255 | ||
338 | 256 | 256 | def is_server_local(): | |
339 | 257 | return cherrypy.config.get('openerp.server.host') in ['127.0.0.1', 'localhost'] | ||
340 | 257 | # vim: ts=4 sts=4 sw=4 si et | 258 | # vim: ts=4 sts=4 sw=4 si et |
341 | 258 | 259 | ||
342 | === added file 'doc/openerp-web-oc.cfg' | |||
343 | --- doc/openerp-web-oc.cfg 1970-01-01 00:00:00 +0000 | |||
344 | +++ doc/openerp-web-oc.cfg 2016-01-19 10:40:01 +0000 | |||
345 | @@ -0,0 +1,5 @@ | |||
346 | 1 | [global] | ||
347 | 2 | |||
348 | 3 | # Web tcp/port, default port is 8061 | ||
349 | 4 | #server.socket_port = 8061 | ||
350 | 5 | |||
351 | 0 | 6 | ||
352 | === added file 'doc/openerp-web-win.cfg' | |||
353 | --- doc/openerp-web-win.cfg 1970-01-01 00:00:00 +0000 | |||
354 | +++ doc/openerp-web-win.cfg 2016-01-19 10:40:01 +0000 | |||
355 | @@ -0,0 +1,93 @@ | |||
356 | 1 | [global] | ||
357 | 2 | server.environment = "development" | ||
358 | 3 | |||
359 | 4 | # Some server parameters that you may want to tweak | ||
360 | 5 | server.socket_host = "0.0.0.0" | ||
361 | 6 | server.socket_port = 8061 | ||
362 | 7 | |||
363 | 8 | # Sets the number of threads the server uses | ||
364 | 9 | server.thread_pool = 40 | ||
365 | 10 | |||
366 | 11 | tools.sessions.on = True | ||
367 | 12 | tools.sessions.persistent = False | ||
368 | 13 | |||
369 | 14 | # Simple code profiling | ||
370 | 15 | server.profile_on = False | ||
371 | 16 | server.profile_dir = "profile" | ||
372 | 17 | # Max size: 10GB | ||
373 | 18 | server.max_request_body_size = 10737418240 | ||
374 | 19 | # disable monitor which raises an error at the end of the request | ||
375 | 20 | engine.timeout_monitor.on = False | ||
376 | 21 | |||
377 | 22 | # if this is part of a larger site, you can set the path | ||
378 | 23 | # to the TurboGears instance here | ||
379 | 24 | #server.webpath = "" | ||
380 | 25 | |||
381 | 26 | # Set to True if you are deploying your App behind a proxy | ||
382 | 27 | # e.g. Apache using mod_proxy | ||
383 | 28 | #tools.proxy.on = True | ||
384 | 29 | |||
385 | 30 | # If your proxy does not add the X-Forwarded-Host header, set | ||
386 | 31 | # the following to the *public* host url. | ||
387 | 32 | #tools.proxy.base = 'http://mydomain.com' | ||
388 | 33 | |||
389 | 34 | # logging | ||
390 | 35 | #log.screen = False | ||
391 | 36 | #log.access_file = "/var/log/openerp-web/access.log" | ||
392 | 37 | #log.error_file = "/var/log/openerp-web/error.log" | ||
393 | 38 | log.error_file = "../ServerLog/openerp-web.log" | ||
394 | 39 | log.access_level = "INFO" | ||
395 | 40 | log.error_level = "INFO" | ||
396 | 41 | # Replaces the cherrypy-created FileHandler by a TimedRotatingFileHandler, | ||
397 | 42 | # requires that access_file and error_file be uncommented and set correctly | ||
398 | 43 | # (they will be used to configure the rotating file handlers). | ||
399 | 44 | # Value should be a dictionary providing TimedRotatingFileHandler's optional | ||
400 | 45 | # arguments (any argument can be provided but `filename`). | ||
401 | 46 | # See the documentation at http://docs.python.org/library/logging.handlers.html#logging.handlers.TimedRotatingFileHandler | ||
402 | 47 | # for more informations on TimedRotatingFileHandler | ||
403 | 48 | log.rotate = {'when' : 'D'} | ||
404 | 49 | |||
405 | 50 | # Set to false to disable CSRF checks | ||
406 | 51 | tools.csrf.on = True | ||
407 | 52 | |||
408 | 53 | # replace builtin traceback tools by cgitb | ||
409 | 54 | tools.log_tracebacks.on: False | ||
410 | 55 | tools.cgitb.on: True | ||
411 | 56 | # a default install can probably avoid logging those via cgitb as they're | ||
412 | 57 | # available in the server log | ||
413 | 58 | tools.cgitb.ignore=( | ||
414 | 59 | openobject.errors.Concurrency, | ||
415 | 60 | openobject.errors.TinyException) | ||
416 | 61 | |||
417 | 62 | # if enable this force cookie to be sent over a secure channel 'ssl' | ||
418 | 63 | # (make sure you site is reachable on https before activating this) | ||
419 | 64 | #tools.secure_cookies.on = True | ||
420 | 65 | |||
421 | 66 | # if enable for browse who understand this, the cookie will not be | ||
422 | 67 | # readable by scripts, see: http://www.owasp.org/index.php/HttpOnly | ||
423 | 68 | tools.httponly_cookies.on = True | ||
424 | 69 | |||
425 | 70 | # fix support of cherrpy 3.1.2 tools.sessions.persistant = False | ||
426 | 71 | tools.fix_312_session_persistent.on = True | ||
427 | 72 | |||
428 | 73 | # OpenERP Server | ||
429 | 74 | openerp.server.host = 'localhost' | ||
430 | 75 | openerp.server.port = '8070' | ||
431 | 76 | openerp.server.protocol = 'socket' | ||
432 | 77 | openerp.server.timeout = 1800 | ||
433 | 78 | |||
434 | 79 | # Web client settings | ||
435 | 80 | [openerp-web] | ||
436 | 81 | # filter dblists based on url pattern? | ||
437 | 82 | # NONE: No Filter | ||
438 | 83 | # EXACT: Exact Hostname | ||
439 | 84 | # UNDERSCORE: Hostname_ | ||
440 | 85 | # BOTH: Exact Hostname or Hostname_ | ||
441 | 86 | |||
442 | 87 | dblist.filter = 'NONE' | ||
443 | 88 | |||
444 | 89 | # whether to show Databases button on Login screen or not | ||
445 | 90 | dbbutton.visible = True | ||
446 | 91 | |||
447 | 92 | # will be applied on company logo | ||
448 | 93 | company.url = '' | ||
449 | 0 | 94 | ||
450 | === modified file 'doc/openerp-web.cfg' | |||
451 | --- doc/openerp-web.cfg 2015-10-01 08:55:14 +0000 | |||
452 | +++ doc/openerp-web.cfg 2016-01-19 10:40:01 +0000 | |||
453 | @@ -14,7 +14,8 @@ | |||
454 | 14 | # Simple code profiling | 14 | # Simple code profiling |
455 | 15 | server.profile_on = False | 15 | server.profile_on = False |
456 | 16 | server.profile_dir = "profile" | 16 | server.profile_dir = "profile" |
458 | 17 | server.max_request_body_size = 209715200 | 17 | # Max size: 10GB |
459 | 18 | server.max_request_body_size = 10737418240 | ||
460 | 18 | # disable monitor which raises an error at the end of the request | 19 | # disable monitor which raises an error at the end of the request |
461 | 19 | engine.timeout_monitor.on = False | 20 | engine.timeout_monitor.on = False |
462 | 20 | 21 | ||
463 | 21 | 22 | ||
464 | === modified file 'openobject/__init__.py' | |||
465 | --- openobject/__init__.py 2011-06-22 09:35:20 +0000 | |||
466 | +++ openobject/__init__.py 2016-01-19 10:40:01 +0000 | |||
467 | @@ -128,8 +128,11 @@ | |||
468 | 128 | error_handler = handlers.TimedRotatingFileHandler(error_file, **rotate) | 128 | error_handler = handlers.TimedRotatingFileHandler(error_file, **rotate) |
469 | 129 | error_handler.setLevel(error_level) | 129 | error_handler.setLevel(error_level) |
470 | 130 | log.error_log.addHandler(error_handler) | 130 | log.error_log.addHandler(error_handler) |
471 | 131 | log.error_file = '' | ||
472 | 131 | 132 | ||
473 | 132 | # Make a new RotatingFileHandler for the access log. | 133 | # Make a new RotatingFileHandler for the access log. |
477 | 133 | access_handler = handlers.TimedRotatingFileHandler(access_file, **rotate) | 134 | if access_file: |
478 | 134 | access_handler.setLevel(access_level) | 135 | access_handler = handlers.TimedRotatingFileHandler(access_file, **rotate) |
479 | 135 | log.access_log.addHandler(access_handler) | 136 | access_handler.setLevel(access_level) |
480 | 137 | log.access_log.addHandler(access_handler) | ||
481 | 138 | log.access_file = '' | ||
482 | 136 | 139 | ||
483 | === modified file 'openobject/commands.py' | |||
484 | --- openobject/commands.py 2013-02-04 11:48:01 +0000 | |||
485 | +++ openobject/commands.py 2016-01-19 10:40:01 +0000 | |||
486 | @@ -19,6 +19,15 @@ | |||
487 | 19 | 19 | ||
488 | 20 | DISTRIBUTION_CONFIG = os.path.join('doc', 'openerp-web.cfg') | 20 | DISTRIBUTION_CONFIG = os.path.join('doc', 'openerp-web.cfg') |
489 | 21 | FROZEN_DISTRIBUTION_CONFIG = os.path.join('conf', 'openerp-web.cfg') | 21 | FROZEN_DISTRIBUTION_CONFIG = os.path.join('conf', 'openerp-web.cfg') |
490 | 22 | OVERRIDE_CONFIG = os.path.join('conf', 'openerp-web-oc.cfg') | ||
491 | 23 | def get_config_override_file(): | ||
492 | 24 | if hasattr(sys, 'frozen'): | ||
493 | 25 | configfile = os.path.join(openobject.paths.root(), OVERRIDE_CONFIG) | ||
494 | 26 | if os.path.exists(configfile): | ||
495 | 27 | return configfile | ||
496 | 28 | |||
497 | 29 | return False | ||
498 | 30 | |||
499 | 22 | def get_config_file(): | 31 | def get_config_file(): |
500 | 23 | if hasattr(sys, 'frozen'): | 32 | if hasattr(sys, 'frozen'): |
501 | 24 | configfile = os.path.join(openobject.paths.root(), FROZEN_DISTRIBUTION_CONFIG) | 33 | configfile = os.path.join(openobject.paths.root(), FROZEN_DISTRIBUTION_CONFIG) |
502 | @@ -37,6 +46,8 @@ | |||
503 | 37 | parser = OptionParser(version="%s" % (openobject.release.version)) | 46 | parser = OptionParser(version="%s" % (openobject.release.version)) |
504 | 38 | parser.add_option("-c", "--config", metavar="FILE", dest="config", | 47 | parser.add_option("-c", "--config", metavar="FILE", dest="config", |
505 | 39 | help="configuration file", default=get_config_file()) | 48 | help="configuration file", default=get_config_file()) |
506 | 49 | parser.add_option("--config-override", metavar="FILE", dest="config_override", | ||
507 | 50 | help="override configuration file", default=get_config_override_file()) | ||
508 | 40 | parser.add_option("-a", "--address", help="host address, overrides server.socket_host") | 51 | parser.add_option("-a", "--address", help="host address, overrides server.socket_host") |
509 | 41 | parser.add_option("-p", "--port", help="port number, overrides server.socket_port") | 52 | parser.add_option("-p", "--port", help="port number, overrides server.socket_port") |
510 | 42 | parser.add_option("--openerp-host", dest="openerp_host", help="overrides openerp.server.host") | 53 | parser.add_option("--openerp-host", dest="openerp_host", help="overrides openerp.server.host") |
511 | @@ -50,13 +61,26 @@ | |||
512 | 50 | if not os.path.exists(options.config): | 61 | if not os.path.exists(options.config): |
513 | 51 | raise ConfigurationError(_("Could not find configuration file: %s") % | 62 | raise ConfigurationError(_("Could not find configuration file: %s") % |
514 | 52 | options.config) | 63 | options.config) |
516 | 53 | 64 | ||
517 | 65 | error_config = False | ||
518 | 54 | app_config = as_dict(options.config) | 66 | app_config = as_dict(options.config) |
520 | 55 | 67 | if options.config_override: | |
521 | 68 | try: | ||
522 | 69 | over_config = as_dict(options.config_override) | ||
523 | 70 | for section, value in over_config.iteritems(): | ||
524 | 71 | app_config.setdefault(section, {}).update(value) | ||
525 | 72 | except Exception, error_config: | ||
526 | 73 | pass | ||
527 | 56 | openobject.configure(app_config) | 74 | openobject.configure(app_config) |
528 | 75 | |||
529 | 76 | if error_config: | ||
530 | 77 | cherrypy.log('Unable to parse %s\nError: %s' % (options.config_override, error_config), "ERROR") | ||
531 | 78 | raise ConfigurationError(_("Unable to parse: %s") % | ||
532 | 79 | options.config_override) | ||
533 | 80 | |||
534 | 57 | if options.static: | 81 | if options.static: |
535 | 58 | openobject.enable_static_paths() | 82 | openobject.enable_static_paths() |
537 | 59 | 83 | ||
538 | 60 | if options.address: | 84 | if options.address: |
539 | 61 | cherrypy.config['server.socket_host'] = options.address | 85 | cherrypy.config['server.socket_host'] = options.address |
540 | 62 | if options.port: | 86 | if options.port: |
541 | @@ -64,6 +88,11 @@ | |||
542 | 64 | cherrypy.config['server.socket_port'] = int(options.port) | 88 | cherrypy.config['server.socket_port'] = int(options.port) |
543 | 65 | except: | 89 | except: |
544 | 66 | pass | 90 | pass |
545 | 91 | port = cherrypy.config.get('server.socket_port') | ||
546 | 92 | if not isinstance(port, (int, long)) or port < 1 or port > 65535: | ||
547 | 93 | cherrypy.log('Wrong configuration socket_port: %s' % (port,), "ERROR") | ||
548 | 94 | raise ConfigurationError(_("Wrong configuration socket_port: %s") % | ||
549 | 95 | port) | ||
550 | 67 | if options.openerp_host: | 96 | if options.openerp_host: |
551 | 68 | cherrypy.config['openerp.server.host'] = options.openerp_host | 97 | cherrypy.config['openerp.server.host'] = options.openerp_host |
552 | 69 | if options.openerp_port: | 98 | if options.openerp_port: |
553 | 70 | 99 | ||
554 | === modified file 'openobject/tools/_expose.py' | |||
555 | --- openobject/tools/_expose.py 2011-01-20 18:50:26 +0000 | |||
556 | +++ openobject/tools/_expose.py 2016-01-19 10:40:01 +0000 | |||
557 | @@ -29,7 +29,8 @@ | |||
558 | 29 | from openobject import i18n | 29 | from openobject import i18n |
559 | 30 | import _utils as utils | 30 | import _utils as utils |
560 | 31 | import resources | 31 | import resources |
562 | 32 | 32 | import types | |
563 | 33 | import tempfile | ||
564 | 33 | 34 | ||
565 | 34 | __all__ = ['load_template', 'render_template', 'expose', 'register_template_vars'] | 35 | __all__ = ['load_template', 'render_template', 'expose', 'register_template_vars'] |
566 | 35 | 36 | ||
567 | @@ -220,7 +221,8 @@ | |||
568 | 220 | jset.add(script) | 221 | jset.add(script) |
569 | 221 | 222 | ||
570 | 222 | return render_template(_template, res).encode("utf-8") | 223 | return render_template(_template, res).encode("utf-8") |
572 | 223 | 224 | if isinstance(res, types.GeneratorType) and hasattr(res, '__name__') and res.__name__ == 'file_generator': | |
573 | 225 | return res | ||
574 | 224 | if not isinstance(res, basestring): | 226 | if not isinstance(res, basestring): |
575 | 225 | return unicode(res).encode("utf-8") | 227 | return unicode(res).encode("utf-8") |
576 | 226 | 228 | ||
577 | 227 | 229 | ||
578 | === modified file 'setup.nsi' | |||
579 | --- setup.nsi 2010-12-29 19:48:48 +0000 | |||
580 | +++ setup.nsi 2016-01-19 10:40:01 +0000 | |||
581 | @@ -151,7 +151,8 @@ | |||
582 | 151 | File "win32\stop.bat" | 151 | File "win32\stop.bat" |
583 | 152 | 152 | ||
584 | 153 | SetOutPath "$INSTDIR\conf" | 153 | SetOutPath "$INSTDIR\conf" |
586 | 154 | File "/oname=openerp-web.cfg" ".\doc\openerp-web.cfg" | 154 | File "/oname=openerp-web.cfg" ".\doc\openerp-web-win.cfg" |
587 | 155 | File "/oname=openerp-web-oc.cfg" ".\doc\openerp-web-oc.cfg" | ||
588 | 155 | 156 | ||
589 | 156 | !insertmacro MUI_STARTMENU_WRITE_BEGIN Application | 157 | !insertmacro MUI_STARTMENU_WRITE_BEGIN Application |
590 | 157 | ;Create shortcuts | 158 | ;Create shortcuts |
591 | @@ -159,7 +160,7 @@ | |||
592 | 159 | 160 | ||
593 | 160 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Start OpenERP Web.lnk" "$INSTDIR\service\start.bat" | 161 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Start OpenERP Web.lnk" "$INSTDIR\service\start.bat" |
594 | 161 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Stop OpenERP Web.lnk" "$INSTDIR\service\stop.bat" | 162 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Stop OpenERP Web.lnk" "$INSTDIR\service\stop.bat" |
596 | 162 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Edit Web Config.lnk" "notepad.exe" "$INSTDIR\conf\openerp-web.cfg" | 163 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Edit Web Config.lnk" "notepad.exe" "$INSTDIR\conf\openerp-web-oc.cfg" |
597 | 163 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\uninstall.exe" | 164 | CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\uninstall.exe" |
598 | 164 | !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Forum" "http://www.openerp.com/forum" | 165 | !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Forum" "http://www.openerp.com/forum" |
599 | 165 | !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Translation" "https://translations.launchpad.net/openobject" | 166 | !insertmacro CreateInternetShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Translation" "https://translations.launchpad.net/openobject" |