##// END OF EJS Templates
merge
marcink -
r2044:fa74e916 merge default
parent child Browse files
Show More
@@ -1,92 +1,92 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.__init__
3 rhodecode.__init__
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 RhodeCode, a web based repository management based on pylons
6 RhodeCode, a web based repository management based on pylons
7 versioning implementation: http://semver.org/
7 versioning implementation: http://semver.org/
8
8
9 :created_on: Apr 9, 2010
9 :created_on: Apr 9, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import sys
26 import sys
27 import platform
27 import platform
28
28
29 VERSION = (1, 3, 0)
29 VERSION = (1, 3, 1)
30 __version__ = '.'.join((str(each) for each in VERSION[:4]))
30 __version__ = '.'.join((str(each) for each in VERSION[:4]))
31 __dbversion__ = 5 # defines current db version for migrations
31 __dbversion__ = 5 # defines current db version for migrations
32 __platform__ = platform.system()
32 __platform__ = platform.system()
33 __license__ = 'GPLv3'
33 __license__ = 'GPLv3'
34 __py_version__ = sys.version_info
34 __py_version__ = sys.version_info
35
35
36 PLATFORM_WIN = ('Windows')
36 PLATFORM_WIN = ('Windows')
37 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS')
37 PLATFORM_OTHERS = ('Linux', 'Darwin', 'FreeBSD', 'OpenBSD', 'SunOS')
38
38
39 requirements = [
39 requirements = [
40 "Pylons==1.0.0",
40 "Pylons==1.0.0",
41 "Beaker==1.6.2",
41 "Beaker==1.6.2",
42 "WebHelpers>=1.2",
42 "WebHelpers>=1.2",
43 "formencode==1.2.4",
43 "formencode==1.2.4",
44 "SQLAlchemy==0.7.4",
44 "SQLAlchemy==0.7.4",
45 "Mako==0.5.0",
45 "Mako==0.5.0",
46 "pygments>=1.4",
46 "pygments>=1.4",
47 "whoosh>=2.3.0,<2.4",
47 "whoosh>=2.3.0,<2.4",
48 "celery>=2.2.5,<2.3",
48 "celery>=2.2.5,<2.3",
49 "babel",
49 "babel",
50 "python-dateutil>=1.5.0,<2.0.0",
50 "python-dateutil>=1.5.0,<2.0.0",
51 "dulwich>=0.8.0,<0.9.0",
51 "dulwich>=0.8.0,<0.9.0",
52 "webob==1.0.8",
52 "webob==1.0.8",
53 "markdown==2.1.1",
53 "markdown==2.1.1",
54 "docutils==0.8.1",
54 "docutils==0.8.1",
55 ]
55 ]
56
56
57 if __py_version__ < (2, 6):
57 if __py_version__ < (2, 6):
58 requirements.append("simplejson")
58 requirements.append("simplejson")
59 requirements.append("pysqlite")
59 requirements.append("pysqlite")
60
60
61 if __platform__ in PLATFORM_WIN:
61 if __platform__ in PLATFORM_WIN:
62 requirements.append("mercurial>=2.1,<2.2")
62 requirements.append("mercurial>=2.1,<2.2")
63 else:
63 else:
64 requirements.append("py-bcrypt")
64 requirements.append("py-bcrypt")
65 requirements.append("mercurial>=2.1,<2.2")
65 requirements.append("mercurial>=2.1,<2.2")
66
66
67
67
68 try:
68 try:
69 from rhodecode.lib import get_current_revision
69 from rhodecode.lib import get_current_revision
70 _rev = get_current_revision(quiet=True)
70 _rev = get_current_revision(quiet=True)
71 except ImportError:
71 except ImportError:
72 # this is needed when doing some setup.py operations
72 # this is needed when doing some setup.py operations
73 _rev = False
73 _rev = False
74
74
75 if len(VERSION) > 3 and _rev:
75 if len(VERSION) > 3 and _rev:
76 __version__ += ' [rev:%s]' % _rev[0]
76 __version__ += ' [rev:%s]' % _rev[0]
77
77
78
78
79 def get_version():
79 def get_version():
80 """Returns shorter version (digit parts only) as string."""
80 """Returns shorter version (digit parts only) as string."""
81
81
82 return '.'.join((str(each) for each in VERSION[:3]))
82 return '.'.join((str(each) for each in VERSION[:3]))
83
83
84 BACKENDS = {
84 BACKENDS = {
85 'hg': 'Mercurial repository',
85 'hg': 'Mercurial repository',
86 'git': 'Git repository',
86 'git': 'Git repository',
87 }
87 }
88
88
89 CELERY_ON = False
89 CELERY_ON = False
90
90
91 # link to config for pylons
91 # link to config for pylons
92 CONFIG = {}
92 CONFIG = {}
@@ -1,464 +1,465 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.__init__
3 rhodecode.lib.__init__
4 ~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Some simple helper functions
6 Some simple helper functions
7
7
8 :created_on: Jan 5, 2011
8 :created_on: Jan 5, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import os
26 import os
27 import re
27 import re
28 from rhodecode.lib.vcs.utils.lazy import LazyProperty
28 from rhodecode.lib.vcs.utils.lazy import LazyProperty
29
29
30
30
31 def __get_lem():
31 def __get_lem():
32 from pygments import lexers
32 from pygments import lexers
33 from string import lower
33 from string import lower
34 from collections import defaultdict
34 from collections import defaultdict
35
35
36 d = defaultdict(lambda: [])
36 d = defaultdict(lambda: [])
37
37
38 def __clean(s):
38 def __clean(s):
39 s = s.lstrip('*')
39 s = s.lstrip('*')
40 s = s.lstrip('.')
40 s = s.lstrip('.')
41
41
42 if s.find('[') != -1:
42 if s.find('[') != -1:
43 exts = []
43 exts = []
44 start, stop = s.find('['), s.find(']')
44 start, stop = s.find('['), s.find(']')
45
45
46 for suffix in s[start + 1:stop]:
46 for suffix in s[start + 1:stop]:
47 exts.append(s[:s.find('[')] + suffix)
47 exts.append(s[:s.find('[')] + suffix)
48 return map(lower, exts)
48 return map(lower, exts)
49 else:
49 else:
50 return map(lower, [s])
50 return map(lower, [s])
51
51
52 for lx, t in sorted(lexers.LEXERS.items()):
52 for lx, t in sorted(lexers.LEXERS.items()):
53 m = map(__clean, t[-2])
53 m = map(__clean, t[-2])
54 if m:
54 if m:
55 m = reduce(lambda x, y: x + y, m)
55 m = reduce(lambda x, y: x + y, m)
56 for ext in m:
56 for ext in m:
57 desc = lx.replace('Lexer', '')
57 desc = lx.replace('Lexer', '')
58 d[ext].append(desc)
58 d[ext].append(desc)
59
59
60 return dict(d)
60 return dict(d)
61
61
62 # language map is also used by whoosh indexer, which for those specified
62 # language map is also used by whoosh indexer, which for those specified
63 # extensions will index it's content
63 # extensions will index it's content
64 LANGUAGES_EXTENSIONS_MAP = __get_lem()
64 LANGUAGES_EXTENSIONS_MAP = __get_lem()
65
65
66 # Additional mappings that are not present in the pygments lexers
66 # Additional mappings that are not present in the pygments lexers
67 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
67 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
68 ADDITIONAL_MAPPINGS = {'xaml': 'XAML'}
68 ADDITIONAL_MAPPINGS = {'xaml': 'XAML'}
69
69
70 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
70 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
71
71
72 # list of readme files to search in file tree and display in summary
72 # list of readme files to search in file tree and display in summary
73 # attached weights defines the search order lower is first
73 # attached weights defines the search order lower is first
74 ALL_READMES = [
74 ALL_READMES = [
75 ('readme', 0), ('README', 0), ('Readme', 0),
75 ('readme', 0), ('README', 0), ('Readme', 0),
76 ('doc/readme', 1), ('doc/README', 1), ('doc/Readme', 1),
76 ('doc/readme', 1), ('doc/README', 1), ('doc/Readme', 1),
77 ('Docs/readme', 2), ('Docs/README', 2), ('Docs/Readme', 2),
77 ('Docs/readme', 2), ('Docs/README', 2), ('Docs/Readme', 2),
78 ('DOCS/readme', 2), ('DOCS/README', 2), ('DOCS/Readme', 2),
78 ('DOCS/readme', 2), ('DOCS/README', 2), ('DOCS/Readme', 2),
79 ('docs/readme', 2), ('docs/README', 2), ('docs/Readme', 2),
79 ('docs/readme', 2), ('docs/README', 2), ('docs/Readme', 2),
80 ]
80 ]
81
81
82 # extension together with weights to search lower is first
82 # extension together with weights to search lower is first
83 RST_EXTS = [
83 RST_EXTS = [
84 ('', 0), ('.rst', 1), ('.rest', 1),
84 ('', 0), ('.rst', 1), ('.rest', 1),
85 ('.RST', 2), ('.REST', 2),
85 ('.RST', 2), ('.REST', 2),
86 ('.txt', 3), ('.TXT', 3)
86 ('.txt', 3), ('.TXT', 3)
87 ]
87 ]
88
88
89 MARKDOWN_EXTS = [
89 MARKDOWN_EXTS = [
90 ('.md', 1), ('.MD', 1),
90 ('.md', 1), ('.MD', 1),
91 ('.mkdn', 2), ('.MKDN', 2),
91 ('.mkdn', 2), ('.MKDN', 2),
92 ('.mdown', 3), ('.MDOWN', 3),
92 ('.mdown', 3), ('.MDOWN', 3),
93 ('.markdown', 4), ('.MARKDOWN', 4)
93 ('.markdown', 4), ('.MARKDOWN', 4)
94 ]
94 ]
95
95
96 PLAIN_EXTS = [('.text', 2), ('.TEXT', 2)]
96 PLAIN_EXTS = [('.text', 2), ('.TEXT', 2)]
97
97
98 ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS
98 ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS
99
99
100
100
101 def str2bool(_str):
101 def str2bool(_str):
102 """
102 """
103 returs True/False value from given string, it tries to translate the
103 returs True/False value from given string, it tries to translate the
104 string into boolean
104 string into boolean
105
105
106 :param _str: string value to translate into boolean
106 :param _str: string value to translate into boolean
107 :rtype: boolean
107 :rtype: boolean
108 :returns: boolean from given string
108 :returns: boolean from given string
109 """
109 """
110 if _str is None:
110 if _str is None:
111 return False
111 return False
112 if _str in (True, False):
112 if _str in (True, False):
113 return _str
113 return _str
114 _str = str(_str).strip().lower()
114 _str = str(_str).strip().lower()
115 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
115 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
116
116
117
117
118 def convert_line_endings(line, mode):
118 def convert_line_endings(line, mode):
119 """
119 """
120 Converts a given line "line end" accordingly to given mode
120 Converts a given line "line end" accordingly to given mode
121
121
122 Available modes are::
122 Available modes are::
123 0 - Unix
123 0 - Unix
124 1 - Mac
124 1 - Mac
125 2 - DOS
125 2 - DOS
126
126
127 :param line: given line to convert
127 :param line: given line to convert
128 :param mode: mode to convert to
128 :param mode: mode to convert to
129 :rtype: str
129 :rtype: str
130 :return: converted line according to mode
130 :return: converted line according to mode
131 """
131 """
132 from string import replace
132 from string import replace
133
133
134 if mode == 0:
134 if mode == 0:
135 line = replace(line, '\r\n', '\n')
135 line = replace(line, '\r\n', '\n')
136 line = replace(line, '\r', '\n')
136 line = replace(line, '\r', '\n')
137 elif mode == 1:
137 elif mode == 1:
138 line = replace(line, '\r\n', '\r')
138 line = replace(line, '\r\n', '\r')
139 line = replace(line, '\n', '\r')
139 line = replace(line, '\n', '\r')
140 elif mode == 2:
140 elif mode == 2:
141 line = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", line)
141 line = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", line)
142 return line
142 return line
143
143
144
144
145 def detect_mode(line, default):
145 def detect_mode(line, default):
146 """
146 """
147 Detects line break for given line, if line break couldn't be found
147 Detects line break for given line, if line break couldn't be found
148 given default value is returned
148 given default value is returned
149
149
150 :param line: str line
150 :param line: str line
151 :param default: default
151 :param default: default
152 :rtype: int
152 :rtype: int
153 :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
153 :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
154 """
154 """
155 if line.endswith('\r\n'):
155 if line.endswith('\r\n'):
156 return 2
156 return 2
157 elif line.endswith('\n'):
157 elif line.endswith('\n'):
158 return 0
158 return 0
159 elif line.endswith('\r'):
159 elif line.endswith('\r'):
160 return 1
160 return 1
161 else:
161 else:
162 return default
162 return default
163
163
164
164
165 def generate_api_key(username, salt=None):
165 def generate_api_key(username, salt=None):
166 """
166 """
167 Generates unique API key for given username, if salt is not given
167 Generates unique API key for given username, if salt is not given
168 it'll be generated from some random string
168 it'll be generated from some random string
169
169
170 :param username: username as string
170 :param username: username as string
171 :param salt: salt to hash generate KEY
171 :param salt: salt to hash generate KEY
172 :rtype: str
172 :rtype: str
173 :returns: sha1 hash from username+salt
173 :returns: sha1 hash from username+salt
174 """
174 """
175 from tempfile import _RandomNameSequence
175 from tempfile import _RandomNameSequence
176 import hashlib
176 import hashlib
177
177
178 if salt is None:
178 if salt is None:
179 salt = _RandomNameSequence().next()
179 salt = _RandomNameSequence().next()
180
180
181 return hashlib.sha1(username + salt).hexdigest()
181 return hashlib.sha1(username + salt).hexdigest()
182
182
183
183
184 def safe_unicode(str_, from_encoding=None):
184 def safe_unicode(str_, from_encoding=None):
185 """
185 """
186 safe unicode function. Does few trick to turn str_ into unicode
186 safe unicode function. Does few trick to turn str_ into unicode
187
187
188 In case of UnicodeDecode error we try to return it with encoding detected
188 In case of UnicodeDecode error we try to return it with encoding detected
189 by chardet library if it fails fallback to unicode with errors replaced
189 by chardet library if it fails fallback to unicode with errors replaced
190
190
191 :param str_: string to decode
191 :param str_: string to decode
192 :rtype: unicode
192 :rtype: unicode
193 :returns: unicode object
193 :returns: unicode object
194 """
194 """
195 if isinstance(str_, unicode):
195 if isinstance(str_, unicode):
196 return str_
196 return str_
197
197
198 if not from_encoding:
198 if not from_encoding:
199 import rhodecode
199 import rhodecode
200 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
200 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
201 from_encoding = DEFAULT_ENCODING
201 from_encoding = DEFAULT_ENCODING
202
202
203 try:
203 try:
204 return unicode(str_)
204 return unicode(str_)
205 except UnicodeDecodeError:
205 except UnicodeDecodeError:
206 pass
206 pass
207
207
208 try:
208 try:
209 return unicode(str_, from_encoding)
209 return unicode(str_, from_encoding)
210 except UnicodeDecodeError:
210 except UnicodeDecodeError:
211 pass
211 pass
212
212
213 try:
213 try:
214 import chardet
214 import chardet
215 encoding = chardet.detect(str_)['encoding']
215 encoding = chardet.detect(str_)['encoding']
216 if encoding is None:
216 if encoding is None:
217 raise Exception()
217 raise Exception()
218 return str_.decode(encoding)
218 return str_.decode(encoding)
219 except (ImportError, UnicodeDecodeError, Exception):
219 except (ImportError, UnicodeDecodeError, Exception):
220 return unicode(str_, from_encoding, 'replace')
220 return unicode(str_, from_encoding, 'replace')
221
221
222
222
223 def safe_str(unicode_, to_encoding=None):
223 def safe_str(unicode_, to_encoding=None):
224 """
224 """
225 safe str function. Does few trick to turn unicode_ into string
225 safe str function. Does few trick to turn unicode_ into string
226
226
227 In case of UnicodeEncodeError we try to return it with encoding detected
227 In case of UnicodeEncodeError we try to return it with encoding detected
228 by chardet library if it fails fallback to string with errors replaced
228 by chardet library if it fails fallback to string with errors replaced
229
229
230 :param unicode_: unicode to encode
230 :param unicode_: unicode to encode
231 :rtype: str
231 :rtype: str
232 :returns: str object
232 :returns: str object
233 """
233 """
234
234
235 # if it's not basestr cast to str
235 if not isinstance(unicode_, basestring):
236 if not isinstance(unicode_, basestring):
236 return str(unicode_)
237 return str(unicode_)
237
238
238 if isinstance(unicode_, str):
239 if isinstance(unicode_, str):
239 return unicode_
240 return unicode_
240
241
241 if not to_encoding:
242 if not to_encoding:
242 import rhodecode
243 import rhodecode
243 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
244 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
244 to_encoding = DEFAULT_ENCODING
245 to_encoding = DEFAULT_ENCODING
245
246
246 try:
247 try:
247 return unicode_.encode(to_encoding)
248 return unicode_.encode(to_encoding)
248 except UnicodeEncodeError:
249 except UnicodeEncodeError:
249 pass
250 pass
250
251
251 try:
252 try:
252 import chardet
253 import chardet
253 encoding = chardet.detect(unicode_)['encoding']
254 encoding = chardet.detect(unicode_)['encoding']
254 print encoding
255 print encoding
255 if encoding is None:
256 if encoding is None:
256 raise UnicodeEncodeError()
257 raise UnicodeEncodeError()
257
258
258 return unicode_.encode(encoding)
259 return unicode_.encode(encoding)
259 except (ImportError, UnicodeEncodeError):
260 except (ImportError, UnicodeEncodeError):
260 return unicode_.encode(to_encoding, 'replace')
261 return unicode_.encode(to_encoding, 'replace')
261
262
262 return safe_str
263 return safe_str
263
264
264
265
265 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
266 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
266 """
267 """
267 Custom engine_from_config functions that makes sure we use NullPool for
268 Custom engine_from_config functions that makes sure we use NullPool for
268 file based sqlite databases. This prevents errors on sqlite. This only
269 file based sqlite databases. This prevents errors on sqlite. This only
269 applies to sqlalchemy versions < 0.7.0
270 applies to sqlalchemy versions < 0.7.0
270
271
271 """
272 """
272 import sqlalchemy
273 import sqlalchemy
273 from sqlalchemy import engine_from_config as efc
274 from sqlalchemy import engine_from_config as efc
274 import logging
275 import logging
275
276
276 if int(sqlalchemy.__version__.split('.')[1]) < 7:
277 if int(sqlalchemy.__version__.split('.')[1]) < 7:
277
278
278 # This solution should work for sqlalchemy < 0.7.0, and should use
279 # This solution should work for sqlalchemy < 0.7.0, and should use
279 # proxy=TimerProxy() for execution time profiling
280 # proxy=TimerProxy() for execution time profiling
280
281
281 from sqlalchemy.pool import NullPool
282 from sqlalchemy.pool import NullPool
282 url = configuration[prefix + 'url']
283 url = configuration[prefix + 'url']
283
284
284 if url.startswith('sqlite'):
285 if url.startswith('sqlite'):
285 kwargs.update({'poolclass': NullPool})
286 kwargs.update({'poolclass': NullPool})
286 return efc(configuration, prefix, **kwargs)
287 return efc(configuration, prefix, **kwargs)
287 else:
288 else:
288 import time
289 import time
289 from sqlalchemy import event
290 from sqlalchemy import event
290 from sqlalchemy.engine import Engine
291 from sqlalchemy.engine import Engine
291
292
292 log = logging.getLogger('sqlalchemy.engine')
293 log = logging.getLogger('sqlalchemy.engine')
293 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
294 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
294 engine = efc(configuration, prefix, **kwargs)
295 engine = efc(configuration, prefix, **kwargs)
295
296
296 def color_sql(sql):
297 def color_sql(sql):
297 COLOR_SEQ = "\033[1;%dm"
298 COLOR_SEQ = "\033[1;%dm"
298 COLOR_SQL = YELLOW
299 COLOR_SQL = YELLOW
299 normal = '\x1b[0m'
300 normal = '\x1b[0m'
300 return ''.join([COLOR_SEQ % COLOR_SQL, sql, normal])
301 return ''.join([COLOR_SEQ % COLOR_SQL, sql, normal])
301
302
302 if configuration['debug']:
303 if configuration['debug']:
303 #attach events only for debug configuration
304 #attach events only for debug configuration
304
305
305 def before_cursor_execute(conn, cursor, statement,
306 def before_cursor_execute(conn, cursor, statement,
306 parameters, context, executemany):
307 parameters, context, executemany):
307 context._query_start_time = time.time()
308 context._query_start_time = time.time()
308 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
309 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
309
310
310
311
311 def after_cursor_execute(conn, cursor, statement,
312 def after_cursor_execute(conn, cursor, statement,
312 parameters, context, executemany):
313 parameters, context, executemany):
313 total = time.time() - context._query_start_time
314 total = time.time() - context._query_start_time
314 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
315 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
315
316
316 event.listen(engine, "before_cursor_execute",
317 event.listen(engine, "before_cursor_execute",
317 before_cursor_execute)
318 before_cursor_execute)
318 event.listen(engine, "after_cursor_execute",
319 event.listen(engine, "after_cursor_execute",
319 after_cursor_execute)
320 after_cursor_execute)
320
321
321 return engine
322 return engine
322
323
323
324
324 def age(curdate):
325 def age(curdate):
325 """
326 """
326 turns a datetime into an age string.
327 turns a datetime into an age string.
327
328
328 :param curdate: datetime object
329 :param curdate: datetime object
329 :rtype: unicode
330 :rtype: unicode
330 :returns: unicode words describing age
331 :returns: unicode words describing age
331 """
332 """
332
333
333 from datetime import datetime
334 from datetime import datetime
334 from webhelpers.date import time_ago_in_words
335 from webhelpers.date import time_ago_in_words
335
336
336 _ = lambda s: s
337 _ = lambda s: s
337
338
338 if not curdate:
339 if not curdate:
339 return ''
340 return ''
340
341
341 agescales = [(_(u"year"), 3600 * 24 * 365),
342 agescales = [(_(u"year"), 3600 * 24 * 365),
342 (_(u"month"), 3600 * 24 * 30),
343 (_(u"month"), 3600 * 24 * 30),
343 (_(u"day"), 3600 * 24),
344 (_(u"day"), 3600 * 24),
344 (_(u"hour"), 3600),
345 (_(u"hour"), 3600),
345 (_(u"minute"), 60),
346 (_(u"minute"), 60),
346 (_(u"second"), 1), ]
347 (_(u"second"), 1), ]
347
348
348 age = datetime.now() - curdate
349 age = datetime.now() - curdate
349 age_seconds = (age.days * agescales[2][1]) + age.seconds
350 age_seconds = (age.days * agescales[2][1]) + age.seconds
350 pos = 1
351 pos = 1
351 for scale in agescales:
352 for scale in agescales:
352 if scale[1] <= age_seconds:
353 if scale[1] <= age_seconds:
353 if pos == 6:
354 if pos == 6:
354 pos = 5
355 pos = 5
355 return '%s %s' % (time_ago_in_words(curdate,
356 return '%s %s' % (time_ago_in_words(curdate,
356 agescales[pos][0]), _('ago'))
357 agescales[pos][0]), _('ago'))
357 pos += 1
358 pos += 1
358
359
359 return _(u'just now')
360 return _(u'just now')
360
361
361
362
362 def uri_filter(uri):
363 def uri_filter(uri):
363 """
364 """
364 Removes user:password from given url string
365 Removes user:password from given url string
365
366
366 :param uri:
367 :param uri:
367 :rtype: unicode
368 :rtype: unicode
368 :returns: filtered list of strings
369 :returns: filtered list of strings
369 """
370 """
370 if not uri:
371 if not uri:
371 return ''
372 return ''
372
373
373 proto = ''
374 proto = ''
374
375
375 for pat in ('https://', 'http://'):
376 for pat in ('https://', 'http://'):
376 if uri.startswith(pat):
377 if uri.startswith(pat):
377 uri = uri[len(pat):]
378 uri = uri[len(pat):]
378 proto = pat
379 proto = pat
379 break
380 break
380
381
381 # remove passwords and username
382 # remove passwords and username
382 uri = uri[uri.find('@') + 1:]
383 uri = uri[uri.find('@') + 1:]
383
384
384 # get the port
385 # get the port
385 cred_pos = uri.find(':')
386 cred_pos = uri.find(':')
386 if cred_pos == -1:
387 if cred_pos == -1:
387 host, port = uri, None
388 host, port = uri, None
388 else:
389 else:
389 host, port = uri[:cred_pos], uri[cred_pos + 1:]
390 host, port = uri[:cred_pos], uri[cred_pos + 1:]
390
391
391 return filter(None, [proto, host, port])
392 return filter(None, [proto, host, port])
392
393
393
394
394 def credentials_filter(uri):
395 def credentials_filter(uri):
395 """
396 """
396 Returns a url with removed credentials
397 Returns a url with removed credentials
397
398
398 :param uri:
399 :param uri:
399 """
400 """
400
401
401 uri = uri_filter(uri)
402 uri = uri_filter(uri)
402 #check if we have port
403 #check if we have port
403 if len(uri) > 2 and uri[2]:
404 if len(uri) > 2 and uri[2]:
404 uri[2] = ':' + uri[2]
405 uri[2] = ':' + uri[2]
405
406
406 return ''.join(uri)
407 return ''.join(uri)
407
408
408
409
409 def get_changeset_safe(repo, rev):
410 def get_changeset_safe(repo, rev):
410 """
411 """
411 Safe version of get_changeset if this changeset doesn't exists for a
412 Safe version of get_changeset if this changeset doesn't exists for a
412 repo it returns a Dummy one instead
413 repo it returns a Dummy one instead
413
414
414 :param repo:
415 :param repo:
415 :param rev:
416 :param rev:
416 """
417 """
417 from rhodecode.lib.vcs.backends.base import BaseRepository
418 from rhodecode.lib.vcs.backends.base import BaseRepository
418 from rhodecode.lib.vcs.exceptions import RepositoryError
419 from rhodecode.lib.vcs.exceptions import RepositoryError
419 if not isinstance(repo, BaseRepository):
420 if not isinstance(repo, BaseRepository):
420 raise Exception('You must pass an Repository '
421 raise Exception('You must pass an Repository '
421 'object as first argument got %s', type(repo))
422 'object as first argument got %s', type(repo))
422
423
423 try:
424 try:
424 cs = repo.get_changeset(rev)
425 cs = repo.get_changeset(rev)
425 except RepositoryError:
426 except RepositoryError:
426 from rhodecode.lib.utils import EmptyChangeset
427 from rhodecode.lib.utils import EmptyChangeset
427 cs = EmptyChangeset(requested_revision=rev)
428 cs = EmptyChangeset(requested_revision=rev)
428 return cs
429 return cs
429
430
430
431
431 def get_current_revision(quiet=False):
432 def get_current_revision(quiet=False):
432 """
433 """
433 Returns tuple of (number, id) from repository containing this package
434 Returns tuple of (number, id) from repository containing this package
434 or None if repository could not be found.
435 or None if repository could not be found.
435
436
436 :param quiet: prints error for fetching revision if True
437 :param quiet: prints error for fetching revision if True
437 """
438 """
438
439
439 try:
440 try:
440 from rhodecode.lib.vcs import get_repo
441 from rhodecode.lib.vcs import get_repo
441 from rhodecode.lib.vcs.utils.helpers import get_scm
442 from rhodecode.lib.vcs.utils.helpers import get_scm
442 repopath = os.path.join(os.path.dirname(__file__), '..', '..')
443 repopath = os.path.join(os.path.dirname(__file__), '..', '..')
443 scm = get_scm(repopath)[0]
444 scm = get_scm(repopath)[0]
444 repo = get_repo(path=repopath, alias=scm)
445 repo = get_repo(path=repopath, alias=scm)
445 tip = repo.get_changeset()
446 tip = repo.get_changeset()
446 return (tip.revision, tip.short_id)
447 return (tip.revision, tip.short_id)
447 except Exception, err:
448 except Exception, err:
448 if not quiet:
449 if not quiet:
449 print ("Cannot retrieve rhodecode's revision. Original error "
450 print ("Cannot retrieve rhodecode's revision. Original error "
450 "was: %s" % err)
451 "was: %s" % err)
451 return None
452 return None
452
453
453
454
454 def extract_mentioned_users(s):
455 def extract_mentioned_users(s):
455 """
456 """
456 Returns unique usernames from given string s that have @mention
457 Returns unique usernames from given string s that have @mention
457
458
458 :param s: string to get mentions
459 :param s: string to get mentions
459 """
460 """
460 usrs = {}
461 usrs = {}
461 for username in re.findall(r'(?:^@|\s@)(\w+)', s):
462 for username in re.findall(r'(?:^@|\s@)(\w+)', s):
462 usrs[username] = username
463 usrs[username] = username
463
464
464 return sorted(usrs.keys())
465 return sorted(usrs.keys())
General Comments 0
You need to be logged in to leave comments. Login now