comparison rhodecode/lib/__init__.py @ 2031:82a88013a3fd

merge 1.3 into stable
author Marcin Kuzminski <marcin@python-works.com>
date Sun, 26 Feb 2012 17:25:09 +0200
parents 54e84659cb3a 6020e3884a58
children abe75448253c
comparison
equal deleted inserted replaced
2005:ab0e122b38a7 2031:82a88013a3fd
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
28 from rhodecode.lib.vcs.utils.lazy import LazyProperty
29
27 30
28 def __get_lem(): 31 def __get_lem():
29 from pygments import lexers 32 from pygments import lexers
30 from string import lower 33 from string import lower
31 from collections import defaultdict 34 from collections import defaultdict
64 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP 67 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
65 ADDITIONAL_MAPPINGS = {'xaml': 'XAML'} 68 ADDITIONAL_MAPPINGS = {'xaml': 'XAML'}
66 69
67 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS) 70 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
68 71
72 # list of readme files to search in file tree and display in summary
73 # attached weights defines the search order lower is first
74 ALL_READMES = [
75 ('readme', 0), ('README', 0), ('Readme', 0),
76 ('doc/readme', 1), ('doc/README', 1), ('doc/Readme', 1),
77 ('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),
80 ]
81
82 # extension together with weights to search lower is first
83 RST_EXTS = [
84 ('', 0), ('.rst', 1), ('.rest', 1),
85 ('.RST', 2), ('.REST', 2),
86 ('.txt', 3), ('.TXT', 3)
87 ]
88
89 MARKDOWN_EXTS = [
90 ('.md', 1), ('.MD', 1),
91 ('.mkdn', 2), ('.MKDN', 2),
92 ('.mdown', 3), ('.MDOWN', 3),
93 ('.markdown', 4), ('.MARKDOWN', 4)
94 ]
95
96 PLAIN_EXTS = [('.text', 2), ('.TEXT', 2)]
97
98 ALL_EXTS = MARKDOWN_EXTS + RST_EXTS + PLAIN_EXTS
99
69 100
70 def str2bool(_str): 101 def str2bool(_str):
71 """ 102 """
72 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
73 string into boolean 104 string into boolean
105 line = replace(line, '\r', '\n') 136 line = replace(line, '\r', '\n')
106 elif mode == 1: 137 elif mode == 1:
107 line = replace(line, '\r\n', '\r') 138 line = replace(line, '\r\n', '\r')
108 line = replace(line, '\n', '\r') 139 line = replace(line, '\n', '\r')
109 elif mode == 2: 140 elif mode == 2:
110 import re
111 line = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", line) 141 line = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", line)
112 return line 142 return line
113 143
114 144
115 def detect_mode(line, default): 145 def detect_mode(line, default):
149 salt = _RandomNameSequence().next() 179 salt = _RandomNameSequence().next()
150 180
151 return hashlib.sha1(username + salt).hexdigest() 181 return hashlib.sha1(username + salt).hexdigest()
152 182
153 183
154 def safe_unicode(str_, from_encoding='utf8'): 184 def safe_unicode(str_, from_encoding=None):
155 """ 185 """
156 safe unicode function. Does few trick to turn str_ into unicode 186 safe unicode function. Does few trick to turn str_ into unicode
157 187
158 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
159 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
162 :rtype: unicode 192 :rtype: unicode
163 :returns: unicode object 193 :returns: unicode object
164 """ 194 """
165 if isinstance(str_, unicode): 195 if isinstance(str_, unicode):
166 return str_ 196 return str_
197
198 if not from_encoding:
199 import rhodecode
200 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
201 from_encoding = DEFAULT_ENCODING
167 202
168 try: 203 try:
169 return unicode(str_) 204 return unicode(str_)
170 except UnicodeDecodeError: 205 except UnicodeDecodeError:
171 pass 206 pass
182 raise Exception() 217 raise Exception()
183 return str_.decode(encoding) 218 return str_.decode(encoding)
184 except (ImportError, UnicodeDecodeError, Exception): 219 except (ImportError, UnicodeDecodeError, Exception):
185 return unicode(str_, from_encoding, 'replace') 220 return unicode(str_, from_encoding, 'replace')
186 221
187 def safe_str(unicode_, to_encoding='utf8'): 222
223 def safe_str(unicode_, to_encoding=None):
188 """ 224 """
189 safe str function. Does few trick to turn unicode_ into string 225 safe str function. Does few trick to turn unicode_ into string
190 226
191 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
192 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
193 229
194 :param unicode_: unicode to encode 230 :param unicode_: unicode to encode
195 :rtype: str 231 :rtype: str
197 """ 233 """
198 234
199 if not isinstance(unicode_, basestring): 235 if not isinstance(unicode_, basestring):
200 return str(unicode_) 236 return str(unicode_)
201 237
238 if not isinstance(unicode_, basestring):
239 return str(unicode_)
240
202 if isinstance(unicode_, str): 241 if isinstance(unicode_, str):
203 return unicode_ 242 return unicode_
243
244 if not to_encoding:
245 import rhodecode
246 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
247 to_encoding = DEFAULT_ENCODING
204 248
205 try: 249 try:
206 return unicode_.encode(to_encoding) 250 return unicode_.encode(to_encoding)
207 except UnicodeEncodeError: 251 except UnicodeEncodeError:
208 pass 252 pass
219 return unicode_.encode(to_encoding, 'replace') 263 return unicode_.encode(to_encoding, 'replace')
220 264
221 return safe_str 265 return safe_str
222 266
223 267
224
225 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs): 268 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
226 """ 269 """
227 Custom engine_from_config functions that makes sure we use NullPool for 270 Custom engine_from_config functions that makes sure we use NullPool for
228 file based sqlite databases. This prevents errors on sqlite. This only 271 file based sqlite databases. This prevents errors on sqlite. This only
229 applies to sqlalchemy versions < 0.7.0 272 applies to sqlalchemy versions < 0.7.0
230 273
231 """ 274 """
232 import sqlalchemy 275 import sqlalchemy
233 from sqlalchemy import engine_from_config as efc 276 from sqlalchemy import engine_from_config as efc
282 325
283 326
284 def age(curdate): 327 def age(curdate):
285 """ 328 """
286 turns a datetime into an age string. 329 turns a datetime into an age string.
287 330
288 :param curdate: datetime object 331 :param curdate: datetime object
289 :rtype: unicode 332 :rtype: unicode
290 :returns: unicode words describing age 333 :returns: unicode words describing age
291 """ 334 """
292 335
293 from datetime import datetime 336 from datetime import datetime
294 from webhelpers.date import time_ago_in_words 337 from webhelpers.date import time_ago_in_words
295 338
296 _ = lambda s:s 339 _ = lambda s: s
297 340
298 if not curdate: 341 if not curdate:
299 return '' 342 return ''
300 343
301 agescales = [(_(u"year"), 3600 * 24 * 365), 344 agescales = [(_(u"year"), 3600 * 24 * 365),
308 age = datetime.now() - curdate 351 age = datetime.now() - curdate
309 age_seconds = (age.days * agescales[2][1]) + age.seconds 352 age_seconds = (age.days * agescales[2][1]) + age.seconds
310 pos = 1 353 pos = 1
311 for scale in agescales: 354 for scale in agescales:
312 if scale[1] <= age_seconds: 355 if scale[1] <= age_seconds:
313 if pos == 6:pos = 5 356 if pos == 6:
357 pos = 5
314 return '%s %s' % (time_ago_in_words(curdate, 358 return '%s %s' % (time_ago_in_words(curdate,
315 agescales[pos][0]), _('ago')) 359 agescales[pos][0]), _('ago'))
316 pos += 1 360 pos += 1
317 361
318 return _(u'just now') 362 return _(u'just now')
319 363
320 364
321 def uri_filter(uri): 365 def uri_filter(uri):
322 """ 366 """
323 Removes user:password from given url string 367 Removes user:password from given url string
324 368
325 :param uri: 369 :param uri:
326 :rtype: unicode 370 :rtype: unicode
327 :returns: filtered list of strings 371 :returns: filtered list of strings
328 """ 372 """
329 if not uri: 373 if not uri:
330 return '' 374 return ''
331 375
332 proto = '' 376 proto = ''
351 395
352 396
353 def credentials_filter(uri): 397 def credentials_filter(uri):
354 """ 398 """
355 Returns a url with removed credentials 399 Returns a url with removed credentials
356 400
357 :param uri: 401 :param uri:
358 """ 402 """
359 403
360 uri = uri_filter(uri) 404 uri = uri_filter(uri)
361 #check if we have port 405 #check if we have port
362 if len(uri) > 2 and uri[2]: 406 if len(uri) > 2 and uri[2]:
363 uri[2] = ':' + uri[2] 407 uri[2] = ':' + uri[2]
364 408
365 return ''.join(uri) 409 return ''.join(uri)
366 410
411
367 def get_changeset_safe(repo, rev): 412 def get_changeset_safe(repo, rev):
368 """ 413 """
369 Safe version of get_changeset if this changeset doesn't exists for a 414 Safe version of get_changeset if this changeset doesn't exists for a
370 repo it returns a Dummy one instead 415 repo it returns a Dummy one instead
371 416
372 :param repo: 417 :param repo:
373 :param rev: 418 :param rev:
374 """ 419 """
375 from vcs.backends.base import BaseRepository 420 from rhodecode.lib.vcs.backends.base import BaseRepository
376 from vcs.exceptions import RepositoryError 421 from rhodecode.lib.vcs.exceptions import RepositoryError
377 if not isinstance(repo, BaseRepository): 422 if not isinstance(repo, BaseRepository):
378 raise Exception('You must pass an Repository ' 423 raise Exception('You must pass an Repository '
379 'object as first argument got %s', type(repo)) 424 'object as first argument got %s', type(repo))
380 425
381 try: 426 try:
388 433
389 def get_current_revision(quiet=False): 434 def get_current_revision(quiet=False):
390 """ 435 """
391 Returns tuple of (number, id) from repository containing this package 436 Returns tuple of (number, id) from repository containing this package
392 or None if repository could not be found. 437 or None if repository could not be found.
393 438
394 :param quiet: prints error for fetching revision if True 439 :param quiet: prints error for fetching revision if True
395 """ 440 """
396 441
397 try: 442 try:
398 from vcs import get_repo 443 from rhodecode.lib.vcs import get_repo
399 from vcs.utils.helpers import get_scm 444 from rhodecode.lib.vcs.utils.helpers import get_scm
400 repopath = os.path.join(os.path.dirname(__file__), '..', '..') 445 repopath = os.path.join(os.path.dirname(__file__), '..', '..')
401 scm = get_scm(repopath)[0] 446 scm = get_scm(repopath)[0]
402 repo = get_repo(path=repopath, alias=scm) 447 repo = get_repo(path=repopath, alias=scm)
403 tip = repo.get_changeset() 448 tip = repo.get_changeset()
404 return (tip.revision, tip.short_id) 449 return (tip.revision, tip.short_id)
406 if not quiet: 451 if not quiet:
407 print ("Cannot retrieve rhodecode's revision. Original error " 452 print ("Cannot retrieve rhodecode's revision. Original error "
408 "was: %s" % err) 453 "was: %s" % err)
409 return None 454 return None
410 455
456
457 def extract_mentioned_users(s):
458 """
459 Returns unique usernames from given string s that have @mention
460
461 :param s: string to get mentions
462 """
463 usrs = {}
464 for username in re.findall(r'(?:^@|\s@)(\w+)', s):
465 usrs[username] = username
466
467 return sorted(usrs.keys())