/vcs/utils/__init__.py

https://github.com/codeinn/vcs · Python · 190 lines · 106 code · 31 blank · 53 comment · 36 complexity · 9a7c6f72a1eff48a2f98e0e28c1ac59f MD5 · raw file

  1. """
  2. This module provides some useful tools for ``vcs`` like annotate/diff html
  3. output. It also includes some internal helpers.
  4. """
  5. import sys
  6. import time
  7. import datetime
  8. def makedate():
  9. lt = time.localtime()
  10. if lt[8] == 1 and time.daylight:
  11. tz = time.altzone
  12. else:
  13. tz = time.timezone
  14. return time.mktime(lt), tz
  15. def aslist(obj, sep=None, strip=True):
  16. """
  17. Returns given string separated by sep as list
  18. :param obj:
  19. :param sep:
  20. :param strip:
  21. """
  22. if isinstance(obj, (basestring)):
  23. lst = obj.split(sep)
  24. if strip:
  25. lst = [v.strip() for v in lst]
  26. return lst
  27. elif isinstance(obj, (list, tuple)):
  28. return obj
  29. elif obj is None:
  30. return []
  31. else:
  32. return [obj]
  33. def date_fromtimestamp(unixts, tzoffset=0):
  34. """
  35. Makes a local datetime object out of unix timestamp
  36. :param unixts:
  37. :param tzoffset:
  38. """
  39. return datetime.datetime.fromtimestamp(float(unixts))
  40. def safe_int(val, default=None):
  41. """
  42. Returns int() of val if val is not convertable to int use default
  43. instead
  44. :param val:
  45. :param default:
  46. """
  47. try:
  48. val = int(val)
  49. except (ValueError, TypeError):
  50. val = default
  51. return val
  52. def safe_unicode(str_, from_encoding=None):
  53. """
  54. safe unicode function. Does few trick to turn str_ into unicode
  55. In case of UnicodeDecode error we try to return it with encoding detected
  56. by chardet library if it fails fallback to unicode with errors replaced
  57. :param str_: string to decode
  58. :rtype: unicode
  59. :returns: unicode object
  60. """
  61. if isinstance(str_, unicode):
  62. return str_
  63. if not from_encoding:
  64. from vcs.conf import settings
  65. from_encoding = settings.DEFAULT_ENCODINGS
  66. if not isinstance(from_encoding, (list, tuple)):
  67. from_encoding = [from_encoding]
  68. try:
  69. return unicode(str_)
  70. except UnicodeDecodeError:
  71. pass
  72. for enc in from_encoding:
  73. try:
  74. return unicode(str_, enc)
  75. except UnicodeDecodeError:
  76. pass
  77. try:
  78. import chardet
  79. encoding = chardet.detect(str_)['encoding']
  80. if encoding is None:
  81. raise Exception()
  82. return str_.decode(encoding)
  83. except (ImportError, UnicodeDecodeError, Exception):
  84. return unicode(str_, from_encoding[0], 'replace')
  85. def safe_str(unicode_, to_encoding=None):
  86. """
  87. safe str function. Does few trick to turn unicode_ into string
  88. In case of UnicodeEncodeError we try to return it with encoding detected
  89. by chardet library if it fails fallback to string with errors replaced
  90. :param unicode_: unicode to encode
  91. :rtype: str
  92. :returns: str object
  93. """
  94. # if it's not basestr cast to str
  95. if not isinstance(unicode_, basestring):
  96. return str(unicode_)
  97. if isinstance(unicode_, str):
  98. return unicode_
  99. if not to_encoding:
  100. from vcs.conf import settings
  101. to_encoding = settings.DEFAULT_ENCODINGS
  102. if not isinstance(to_encoding, (list, tuple)):
  103. to_encoding = [to_encoding]
  104. for enc in to_encoding:
  105. try:
  106. return unicode_.encode(enc)
  107. except UnicodeEncodeError:
  108. pass
  109. try:
  110. import chardet
  111. encoding = chardet.detect(unicode_)['encoding']
  112. if encoding is None:
  113. raise UnicodeEncodeError()
  114. return unicode_.encode(encoding)
  115. except (ImportError, UnicodeEncodeError):
  116. return unicode_.encode(to_encoding[0], 'replace')
  117. return safe_str
  118. def author_email(author):
  119. """
  120. returns email address of given author.
  121. If any of <,> sign are found, it fallbacks to regex findall()
  122. and returns first found result or empty string
  123. Regex taken from http://www.regular-expressions.info/email.html
  124. """
  125. import re
  126. r = author.find('>')
  127. l = author.find('<')
  128. if l == -1 or r == -1:
  129. # fallback to regex match of email out of a string
  130. email_re = re.compile(r"""[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!"""
  131. r"""#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z"""
  132. r"""0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]"""
  133. r"""*[a-z0-9])?""", re.IGNORECASE)
  134. m = re.findall(email_re, author)
  135. return m[0] if m else ''
  136. return author[l + 1:r].strip()
  137. def author_name(author):
  138. """
  139. get name of author, or else username.
  140. It'll try to find an email in the author string and just cut it off
  141. to get the username
  142. """
  143. if not '@' in author:
  144. return author
  145. else:
  146. return author.replace(author_email(author), '').replace('<', '')\
  147. .replace('>', '').strip()