utils.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals
  3. import os
  4. import hashlib
  5. import binascii
  6. import base64
  7. import html2text
  8. import re
  9. from datetime import date, timedelta
  10. from django.core.mail import EmailMultiAlternatives
  11. from django.core.files.storage import FileSystemStorage
  12. from django.conf import settings
  13. from django.template.loader import get_template
  14. from django.template import Context, TemplateDoesNotExist
  15. from django.contrib.sites.models import Site
  16. from django.utils.translation import ugettext_lazy as _
  17. # Stockage des fichiers privés (comme les factures par exemple)
  18. private_files_storage = FileSystemStorage(location=settings.PRIVATE_FILES_ROOT)
  19. # regexp which matches for ex irc://irc.example.tld/#channel
  20. re_chat_url = re.compile(r'(?P<protocol>\w+://)(?P<server>[\w\.]+)/(?P<channel>.*)')
  21. def str_or_none(obj):
  22. return str(obj) if obj else None
  23. def ldap_hash(password):
  24. """Hash a password for use with LDAP. If the password is already hashed,
  25. do nothing."""
  26. if password and not password.startswith('{SSHA}'):
  27. salt = binascii.hexlify(os.urandom(8))
  28. digest = hashlib.sha1(password.encode() + salt).digest()
  29. return '{SSHA}' + base64.b64encode(digest + salt).decode()
  30. else:
  31. return password
  32. def send_templated_email(to, subject_template, body_template, context={}, attachements=[]):
  33. """
  34. Send a multialternative email based on html and optional txt template.
  35. """
  36. # Ensure arrays when needed
  37. if not isinstance(to, list):
  38. to = [to]
  39. if not isinstance(attachements, list):
  40. attachements = [attachements]
  41. # Add domain in context
  42. context['domain'] = Site.objects.get_current()
  43. # If .html/.txt is specified in template name remove it
  44. body_template = body_template.split('.')[0]
  45. subject_template = subject_template.split('.')[0]
  46. # Get html template for body, fail if not exists
  47. template_html = get_template('%s.html' % (body_template,))
  48. html_content = template_html.render(Context(context))
  49. # Get txt template for subject, fail if not exists
  50. subject_template = get_template('%s.txt' % (subject_template,))
  51. subject = subject_template.render(Context(context))
  52. # Get rid of newlines
  53. subject = subject.strip().replace('\n', '')
  54. # Try to get a txt version, convert from html to markdown style
  55. # (using html2text) if fail
  56. try:
  57. template_txt = get_template('%s.txt' % (body_template,))
  58. text_content = template_txt.render_to_string(Context(context))
  59. except TemplateDoesNotExist:
  60. text_content = html2text.html2text(html_content)
  61. # make multipart email default : text, alternative : html
  62. msg = EmailMultiAlternatives(subject=subject, body=text_content, to=to)
  63. msg.attach_alternative(html_content, "text/html")
  64. # Set attachements
  65. for attachement in attachements:
  66. msg.attach_file(attachement)
  67. # Send email
  68. msg.send()
  69. def delete_selected(modeladmin, request, queryset):
  70. """Overrides QuerySet's delete() function to remove objects one by one
  71. so, that they are deleted in the LDAP (Redmine issue #195)."""
  72. for obj in queryset:
  73. obj.delete()
  74. delete_selected.short_description = _("Delete all selected objects.")
  75. # Time-related functions
  76. def in_one_year():
  77. return date.today() + timedelta(365)
  78. def start_of_month():
  79. return date(date.today().year, date.today().month, 1)
  80. def end_of_month():
  81. today = date.today()
  82. if today.month == 12:
  83. return date(today.year + 1, 1, 1) - timedelta(days=1)
  84. else:
  85. return date(today.year, today.month + 1, 1) - timedelta(days=1)
  86. if __name__ == '__main__':
  87. print(ldap_hash('coin'))