##// END OF EJS Templates
meta: fix write condition.
marcink -
r2539:b5550006 default
parent child Browse files
Show More
@@ -1,322 +1,322 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2018 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20 import io
21 21 import re
22 22 import datetime
23 23 import logging
24 24 import Queue
25 25 import subprocess32
26 26 import os
27 27
28 28
29 29 from dateutil.parser import parse
30 30 from pyramid.i18n import get_localizer
31 31 from pyramid.threadlocal import get_current_request
32 32 from pyramid.interfaces import IRoutesMapper
33 33 from pyramid.settings import asbool
34 34 from pyramid.path import AssetResolver
35 35 from threading import Thread
36 36
37 37 from rhodecode.translation import _ as tsf
38 38 from rhodecode.config.jsroutes import generate_jsroutes_content
39 39 from rhodecode.lib import auth
40 40 from rhodecode.lib.base import get_auth_user
41 41
42 42
43 43 import rhodecode
44 44
45 45
46 46 log = logging.getLogger(__name__)
47 47
48 48
49 49 def add_renderer_globals(event):
50 50 from rhodecode.lib import helpers
51 51
52 52 # TODO: When executed in pyramid view context the request is not available
53 53 # in the event. Find a better solution to get the request.
54 54 request = event['request'] or get_current_request()
55 55
56 56 # Add Pyramid translation as '_' to context
57 57 event['_'] = request.translate
58 58 event['_ungettext'] = request.plularize
59 59 event['h'] = helpers
60 60
61 61
62 62 def add_localizer(event):
63 63 request = event.request
64 64 localizer = request.localizer
65 65
66 66 def auto_translate(*args, **kwargs):
67 67 return localizer.translate(tsf(*args, **kwargs))
68 68
69 69 request.translate = auto_translate
70 70 request.plularize = localizer.pluralize
71 71
72 72
73 73 def set_user_lang(event):
74 74 request = event.request
75 75 cur_user = getattr(request, 'user', None)
76 76
77 77 if cur_user:
78 78 user_lang = cur_user.get_instance().user_data.get('language')
79 79 if user_lang:
80 80 log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang)
81 81 event.request._LOCALE_ = user_lang
82 82
83 83
84 84 def add_request_user_context(event):
85 85 """
86 86 Adds auth user into request context
87 87 """
88 88 request = event.request
89 89
90 90 if hasattr(request, 'vcs_call'):
91 91 # skip vcs calls
92 92 return
93 93
94 94 if hasattr(request, 'rpc_method'):
95 95 # skip api calls
96 96 return
97 97
98 98 auth_user = get_auth_user(request)
99 99 request.user = auth_user
100 100 request.environ['rc_auth_user'] = auth_user
101 101
102 102
103 103 def inject_app_settings(event):
104 104 settings = event.app.registry.settings
105 105 # inject info about available permissions
106 106 auth.set_available_permissions(settings)
107 107
108 108
109 109 def scan_repositories_if_enabled(event):
110 110 """
111 111 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
112 112 does a repository scan if enabled in the settings.
113 113 """
114 114 settings = event.app.registry.settings
115 115 vcs_server_enabled = settings['vcs.server.enable']
116 116 import_on_startup = settings['startup.import_repos']
117 117 if vcs_server_enabled and import_on_startup:
118 118 from rhodecode.model.scm import ScmModel
119 119 from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_base_path
120 120 repositories = ScmModel().repo_scan(get_rhodecode_base_path())
121 121 repo2db_mapper(repositories, remove_obsolete=False)
122 122
123 123
124 124 def write_metadata_if_needed(event):
125 125 """
126 126 Writes upgrade metadata
127 127 """
128 128 import rhodecode
129 129 from rhodecode.lib import system_info
130 130 from rhodecode.lib import ext_json
131 131
132 132 fname = '.rcmetadata.json'
133 133 ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__'))
134 134 metadata_destination = os.path.join(ini_loc, fname)
135 135
136 136 def get_update_age():
137 137 now = datetime.datetime.utcnow()
138 138
139 139 with open(metadata_destination, 'rb') as f:
140 140 data = ext_json.json.loads(f.read())
141 141 if 'created_on' in data:
142 142 update_date = parse(data['created_on'])
143 143 diff = now - update_date
144 144 return diff.total_seconds() / 60.0
145 145
146 146 return 0
147 147
148 148 def write():
149 149 configuration = system_info.SysInfo(
150 150 system_info.rhodecode_config)()['value']
151 151 license_token = configuration['config']['license_token']
152 152
153 153 setup = dict(
154 154 workers=configuration['config']['server:main'].get(
155 155 'workers', '?'),
156 156 worker_type=configuration['config']['server:main'].get(
157 157 'worker_class', 'sync'),
158 158 )
159 159 dbinfo = system_info.SysInfo(system_info.database_info)()['value']
160 160 del dbinfo['url']
161 161
162 162 metadata = dict(
163 163 desc='upgrade metadata info',
164 164 license_token=license_token,
165 165 created_on=datetime.datetime.utcnow().isoformat(),
166 166 usage=system_info.SysInfo(system_info.usage_info)()['value'],
167 167 platform=system_info.SysInfo(system_info.platform_type)()['value'],
168 168 database=dbinfo,
169 169 cpu=system_info.SysInfo(system_info.cpu)()['value'],
170 170 memory=system_info.SysInfo(system_info.memory)()['value'],
171 171 setup=setup
172 172 )
173 173
174 174 with open(metadata_destination, 'wb') as f:
175 175 f.write(ext_json.json.dumps(metadata))
176 176
177 177 settings = event.app.registry.settings
178 178 if settings.get('metadata.skip'):
179 179 return
180 180
181 181 # only write this every 24h, workers restart caused unwanted delays
182 182 try:
183 183 age_in_min = get_update_age()
184 184 except Exception:
185 185 age_in_min = 0
186 186
187 if age_in_min < 60 * 60 * 24:
187 if age_in_min > 60 * 60 * 24:
188 188 return
189 189
190 190 try:
191 191 write()
192 192 except Exception:
193 193 pass
194 194
195 195
196 196 def write_js_routes_if_enabled(event):
197 197 registry = event.app.registry
198 198
199 199 mapper = registry.queryUtility(IRoutesMapper)
200 200 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
201 201
202 202 def _extract_route_information(route):
203 203 """
204 204 Convert a route into tuple(name, path, args), eg:
205 205 ('show_user', '/profile/%(username)s', ['username'])
206 206 """
207 207
208 208 routepath = route.pattern
209 209 pattern = route.pattern
210 210
211 211 def replace(matchobj):
212 212 if matchobj.group(1):
213 213 return "%%(%s)s" % matchobj.group(1).split(':')[0]
214 214 else:
215 215 return "%%(%s)s" % matchobj.group(2)
216 216
217 217 routepath = _argument_prog.sub(replace, routepath)
218 218
219 219 if not routepath.startswith('/'):
220 220 routepath = '/'+routepath
221 221
222 222 return (
223 223 route.name,
224 224 routepath,
225 225 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
226 226 for arg in _argument_prog.findall(pattern)]
227 227 )
228 228
229 229 def get_routes():
230 230 # pyramid routes
231 231 for route in mapper.get_routes():
232 232 if not route.name.startswith('__'):
233 233 yield _extract_route_information(route)
234 234
235 235 if asbool(registry.settings.get('generate_js_files', 'false')):
236 236 static_path = AssetResolver().resolve('rhodecode:public').abspath()
237 237 jsroutes = get_routes()
238 238 jsroutes_file_content = generate_jsroutes_content(jsroutes)
239 239 jsroutes_file_path = os.path.join(
240 240 static_path, 'js', 'rhodecode', 'routes.js')
241 241
242 242 with io.open(jsroutes_file_path, 'w', encoding='utf-8') as f:
243 243 f.write(jsroutes_file_content)
244 244
245 245
246 246 class Subscriber(object):
247 247 """
248 248 Base class for subscribers to the pyramid event system.
249 249 """
250 250 def __call__(self, event):
251 251 self.run(event)
252 252
253 253 def run(self, event):
254 254 raise NotImplementedError('Subclass has to implement this.')
255 255
256 256
257 257 class AsyncSubscriber(Subscriber):
258 258 """
259 259 Subscriber that handles the execution of events in a separate task to not
260 260 block the execution of the code which triggers the event. It puts the
261 261 received events into a queue from which the worker process takes them in
262 262 order.
263 263 """
264 264 def __init__(self):
265 265 self._stop = False
266 266 self._eventq = Queue.Queue()
267 267 self._worker = self.create_worker()
268 268 self._worker.start()
269 269
270 270 def __call__(self, event):
271 271 self._eventq.put(event)
272 272
273 273 def create_worker(self):
274 274 worker = Thread(target=self.do_work)
275 275 worker.daemon = True
276 276 return worker
277 277
278 278 def stop_worker(self):
279 279 self._stop = False
280 280 self._eventq.put(None)
281 281 self._worker.join()
282 282
283 283 def do_work(self):
284 284 while not self._stop:
285 285 event = self._eventq.get()
286 286 if event is not None:
287 287 self.run(event)
288 288
289 289
290 290 class AsyncSubprocessSubscriber(AsyncSubscriber):
291 291 """
292 292 Subscriber that uses the subprocess32 module to execute a command if an
293 293 event is received. Events are handled asynchronously.
294 294 """
295 295
296 296 def __init__(self, cmd, timeout=None):
297 297 super(AsyncSubprocessSubscriber, self).__init__()
298 298 self._cmd = cmd
299 299 self._timeout = timeout
300 300
301 301 def run(self, event):
302 302 cmd = self._cmd
303 303 timeout = self._timeout
304 304 log.debug('Executing command %s.', cmd)
305 305
306 306 try:
307 307 output = subprocess32.check_output(
308 308 cmd, timeout=timeout, stderr=subprocess32.STDOUT)
309 309 log.debug('Command finished %s', cmd)
310 310 if output:
311 311 log.debug('Command output: %s', output)
312 312 except subprocess32.TimeoutExpired as e:
313 313 log.exception('Timeout while executing command.')
314 314 if e.output:
315 315 log.error('Command output: %s', e.output)
316 316 except subprocess32.CalledProcessError as e:
317 317 log.exception('Error while executing command.')
318 318 if e.output:
319 319 log.error('Command output: %s', e.output)
320 320 except:
321 321 log.exception(
322 322 'Exception while executing command %s.', cmd)
General Comments 0
You need to be logged in to leave comments. Login now