utils.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.utils
  4. ~~~~~~~~~~~~~~~~~~~~
  5. A few utils that are used by flaskbb
  6. :copyright: (c) 2013 by the FlaskBB Team.
  7. :license: BSD, see LICENSE for more details.
  8. """
  9. import random
  10. from datetime import datetime
  11. from wtforms.widgets.core import Select, HTMLString, html_params
  12. def generate_random_pass(length=8):
  13. return "".join(chr(random.randint(33, 126)) for i in range(length))
  14. def time_delta_format(dt, default=None):
  15. """
  16. Returns string representing "time since" e.g.
  17. 3 days ago, 5 hours ago etc.
  18. Ref: https://bitbucket.org/danjac/newsmeme/src/a281babb9ca3/newsmeme/
  19. """
  20. if default is None:
  21. default = 'just now'
  22. now = datetime.utcnow()
  23. diff = now - dt
  24. periods = (
  25. (diff.days / 365, 'year', 'years'),
  26. (diff.days / 30, 'month', 'months'),
  27. (diff.days / 7, 'week', 'weeks'),
  28. (diff.days, 'day', 'days'),
  29. (diff.seconds / 3600, 'hour', 'hours'),
  30. (diff.seconds / 60, 'minute', 'minutes'),
  31. (diff.seconds, 'second', 'seconds'),
  32. )
  33. for period, singular, plural in periods:
  34. if not period:
  35. continue
  36. if period == 1:
  37. return u'%d %s ago' % (period, singular)
  38. else:
  39. return u'%d %s ago' % (period, plural)
  40. return default
  41. class SelectDateWidget(object):
  42. """
  43. Renders a DateTime field with 3 selects.
  44. For more information see: http://stackoverflow.com/a/14664504
  45. """
  46. FORMAT_CHOICES = {
  47. '%d': [(x, str(x)) for x in range(1, 32)],
  48. '%m': [(x, str(x)) for x in range(1, 13)]
  49. }
  50. FORMAT_CLASSES = {
  51. '%d': 'select_date_day',
  52. '%m': 'select_date_month',
  53. '%Y': 'select_date_year'
  54. }
  55. def __init__(self, years=range(1930, datetime.utcnow().year+1)):
  56. super(SelectDateWidget, self).__init__()
  57. self.FORMAT_CHOICES['%Y'] = [(x, str(x)) for x in years]
  58. def __call__(self, field, **kwargs):
  59. field_id = kwargs.pop('id', field.id)
  60. html = []
  61. allowed_format = ['%d', '%m', '%Y']
  62. for format in field.format.split():
  63. if (format in allowed_format):
  64. choices = self.FORMAT_CHOICES[format]
  65. id_suffix = format.replace('%', '-')
  66. id_current = field_id + id_suffix
  67. kwargs['class'] = self.FORMAT_CLASSES[format]
  68. try:
  69. del kwargs['placeholder']
  70. except:
  71. pass
  72. html.append('<select %s>' % html_params(name=field.name,
  73. id=id_current,
  74. **kwargs))
  75. if field.data:
  76. current_value = int(field.data.strftime(format))
  77. else:
  78. current_value = None
  79. for value, label in choices:
  80. selected = (value == current_value)
  81. html.append(Select.render_option(value, label, selected))
  82. html.append('</select>')
  83. else:
  84. html.append(format)
  85. html.append(
  86. """<input type="hidden" value="{}" {}></input>""".format(
  87. html_params(name=field.name, id=id_current, **kwargs)))
  88. html.append(' ')
  89. return HTMLString(''.join(html))