utils.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. from datetime import timedelta
  2. from unidecode import unidecode
  3. from django.http import Http404
  4. from django.core.urlresolvers import resolve, reverse
  5. from django.template.defaultfilters import (slugify as django_slugify,
  6. date as dj_date_format)
  7. from django.utils import html, timezone
  8. from django.utils.translation import ugettext_lazy as _, ungettext_lazy
  9. def slugify(string):
  10. string = unicode(string)
  11. string = unidecode(string)
  12. return django_slugify(string.replace('_', ' ').strip())
  13. def format_plaintext_for_html(string):
  14. return html.linebreaks(html.urlize(html.escape(string)))
  15. """
  16. Mark request as having sensitive parameters
  17. We can't use decorator because of DRF uses custom HttpRequest
  18. that is incompatibile with Django's decorator
  19. """
  20. def hide_post_parameters(request):
  21. request.sensitive_post_parameters = '__ALL__'
  22. """
  23. Return path utility
  24. """
  25. def clean_return_path(request):
  26. if request.method == 'POST' and 'return_path' in request.POST:
  27. return _get_return_path_from_post(request)
  28. else:
  29. return _get_return_path_from_referer(request)
  30. def _get_return_path_from_post(request):
  31. return_path = request.POST.get('return_path')
  32. try:
  33. if not return_path:
  34. raise ValueError()
  35. if not return_path.startswith('/'):
  36. raise ValueError()
  37. resolve(return_path)
  38. return return_path
  39. except (Http404, ValueError):
  40. return None
  41. def _get_return_path_from_referer(request):
  42. referer = request.META.get('HTTP_REFERER')
  43. try:
  44. if not referer:
  45. raise ValueError()
  46. if not referer.startswith(request.scheme):
  47. raise ValueError()
  48. referer = referer[len(request.scheme) + 3:]
  49. if not referer.startswith(request.META['HTTP_HOST']):
  50. raise ValueError()
  51. referer = referer[len(request.META['HTTP_HOST'].rstrip('/')):]
  52. if not referer.startswith('/'):
  53. raise ValueError()
  54. resolve(referer)
  55. return referer
  56. except (Http404, KeyError, ValueError):
  57. return None
  58. """
  59. Utils for resolving requests destination
  60. """
  61. def _is_request_path_under_misago(request):
  62. # We are assuming that forum_index link is root of all Misago links
  63. forum_index = reverse('misago:index')
  64. path_info = request.path_info
  65. if len(forum_index) > len(path_info):
  66. return False
  67. return path_info[:len(forum_index)] == forum_index
  68. def is_request_to_misago(request):
  69. try:
  70. return request._request_to_misago
  71. except AttributeError:
  72. request._request_to_misago = _is_request_path_under_misago(request)
  73. return request._request_to_misago
  74. def is_referer_local(request):
  75. referer = request.META.get('HTTP_REFERER')
  76. if not referer:
  77. return False
  78. if not referer.startswith(request.scheme):
  79. return False
  80. referer = referer[len(request.scheme) + 3:]
  81. if not referer.startswith(request.META['HTTP_HOST']):
  82. return False
  83. referer = referer[len(request.META['HTTP_HOST'].rstrip('/')):]
  84. if not referer.startswith('/'):
  85. return False
  86. return True
  87. """
  88. Utility that humanizes time amount.
  89. Expects number of seconds as first argument
  90. """
  91. def time_amount(value):
  92. delta = timedelta(seconds=value)
  93. units_dict = {
  94. 'd': delta.days,
  95. 'h': 0,
  96. 'm': 0,
  97. 's': delta.seconds,
  98. }
  99. if units_dict['s'] >= 3600:
  100. units_dict['h'] = units_dict['s'] / 3600
  101. units_dict['s'] -= units_dict['h'] * 3600
  102. if units_dict['s'] >= 60:
  103. units_dict['m'] = units_dict['s'] / 60
  104. units_dict['s'] -= units_dict['m'] * 60
  105. precisions = []
  106. if units_dict['d']:
  107. string = ungettext_lazy(
  108. '%(days)s day', '%(days)s days', units_dict['d'])
  109. precisions.append(string % {'days': units_dict['d']})
  110. if units_dict['h']:
  111. string = ungettext_lazy(
  112. '%(hours)s hour', '%(hours)s hours', units_dict['h'])
  113. precisions.append(string % {'hours': units_dict['h']})
  114. if units_dict['m']:
  115. string = ungettext_lazy(
  116. '%(minutes)s minute', '%(minutes)s minutes', units_dict['m'])
  117. precisions.append(string % {'minutes': units_dict['m']})
  118. if units_dict['s']:
  119. string = ungettext_lazy(
  120. '%(seconds)s second', '%(seconds)s seconds', units_dict['s'])
  121. precisions.append(string % {'seconds': units_dict['s']})
  122. if not precisions:
  123. precisions.append(_("0 seconds"))
  124. if len(precisions) == 1:
  125. return precisions[0]
  126. else:
  127. formats = {
  128. 'first_part': ', '.join(precisions[:-1]),
  129. 'and_part': precisions[-1],
  130. }
  131. return _("%(first_part)s and %(and_part)s") % formats
  132. def date_format(date, format=None):
  133. return dj_date_format(timezone.template_localtime(date), format)