bgneal@700: """This file houses various core utility functions"""
bgneal@976: from contextlib import contextmanager
bgneal@176: import datetime
bgneal@700: import logging
bgneal@700: import os
bgneal@227: import re
bgneal@964: import tempfile
gremmie@1: 
gremmie@1: from django.contrib.sites.models import Site
gremmie@1: from django.conf import settings
bgneal@522: import django.core.mail
gremmie@1: 
bgneal@1032: from .tasks import send_mail as send_mail_task
bgneal@181: 
gremmie@1: 
bgneal@964: class TemporaryFile(object):
bgneal@964:     """Context manager class for working with temporary files.
bgneal@964: 
bgneal@964:     The file will be closed and removed when the context is exited.
bgneal@964:     """
bgneal@964:     def __init__(self, **kwargs):
bgneal@964:         """kwargs will be passed to mkstemp."""
bgneal@964:         self.kwargs = kwargs
bgneal@964: 
bgneal@964:     def __enter__(self):
bgneal@964:         self.fd, self.filename = tempfile.mkstemp(**self.kwargs)
bgneal@964:         self.file = os.fdopen(self.fd, 'w+b')
bgneal@964:         return self
bgneal@964: 
bgneal@964:     def __exit__(self, exc_type, exc_value, traceback):
bgneal@964:         self.file.close()
bgneal@964:         os.remove(self.filename)
bgneal@700: 
bgneal@700: 
bgneal@976: @contextmanager
bgneal@976: def remove_file(path):
bgneal@976:     """Context manager for removing a file when the context is exited."""
bgneal@976:     try:
bgneal@976:         yield path
bgneal@976:     finally:
bgneal@976:         os.remove(path)
bgneal@976: 
bgneal@976: 
bgneal@892: def send_mail(subject, message, from_email, recipient_list, reply_to=None, defer=True):
gremmie@1:     """
bgneal@513:     The main send email function. Use this function to send email from the
bgneal@513:     site. All applications should use this function instead of calling
bgneal@513:     Django's directly.
bgneal@522:     If defer is True, the email will be sent to a Celery task to actually send
bgneal@522:     the email. Otherwise it is sent on the caller's thread. In any event, the
bgneal@513:     email will be logged at the DEBUG level.
bgneal@513: 
bgneal@513:     """
bgneal@513:     # Guard against empty email addresses
bgneal@418:     recipient_list = [dest for dest in recipient_list if dest]
bgneal@418:     if not recipient_list:
bgneal@418:         logging.warning("Empty recipient_list in send_mail")
bgneal@418:         return
gremmie@1: 
bgneal@892:     logging.debug('EMAIL:\nFrom: %s\nTo: %s\nReply-To: %s\nSubject: %s\nMessage:\n%s',
bgneal@892:         from_email, str(recipient_list), reply_to, subject, message)
bgneal@892: 
bgneal@892:     headers = {'Reply-To': reply_to} if reply_to else None
bgneal@892:     msg_kwargs = {
bgneal@892:         'subject': subject,
bgneal@892:         'body': message,
bgneal@892:         'from_email': from_email,
bgneal@892:         'to': recipient_list,
bgneal@892:         'headers': headers,
bgneal@892:     }
gremmie@1: 
bgneal@522:     if defer:
bgneal@1032:         send_mail_task.delay(**msg_kwargs)
bgneal@522:     else:
bgneal@892:         msg = django.core.mail.EmailMessage(**msg_kwargs)
bgneal@892:         msg.send()
bgneal@513: 
gremmie@1: 
gremmie@1: def email_admins(subject, message):
gremmie@1:     """Emails the site admins. Goes through the site send_mail function."""
gremmie@1:     site = Site.objects.get_current()
gremmie@1:     subject = '[%s] %s' % (site.name, subject)
bgneal@316:     send_mail(subject,
bgneal@316:             message,
gremmie@1:             '%s@%s' % (settings.GPP_NO_REPLY_EMAIL, site.domain),
gremmie@1:             [mail_tuple[1] for mail_tuple in settings.ADMINS])
gremmie@1: 
gremmie@1: 
gremmie@1: def email_managers(subject, message):
gremmie@1:     """Emails the site managers. Goes through the site send_mail function."""
gremmie@1:     site = Site.objects.get_current()
gremmie@1:     subject = '[%s] %s' % (site.name, subject)
bgneal@316:     send_mail(subject,
bgneal@700:             message,
gremmie@1:             '%s@%s' % (settings.GPP_NO_REPLY_EMAIL, site.domain),
gremmie@1:             [mail_tuple[1] for mail_tuple in settings.MANAGERS])
gremmie@1: 
gremmie@1: 
gremmie@1: def get_full_name(user):
gremmie@1:     """Returns the user's full name if available, otherwise falls back
gremmie@1:     to the username."""
gremmie@1:     full_name = user.get_full_name()
gremmie@1:     if full_name:
gremmie@1:         return full_name
gremmie@1:     return user.username
bgneal@9: 
bgneal@176: 
bgneal@176: BASE_YEAR = 2010
bgneal@176: 
bgneal@176: def copyright_str():
bgneal@176:     curr_year = datetime.datetime.now().year
bgneal@176:     if curr_year == BASE_YEAR:
bgneal@176:         year_range = str(BASE_YEAR)
bgneal@176:     else:
bgneal@176:         year_range = "%d - %d" % (BASE_YEAR, curr_year)
bgneal@176: 
bgneal@176:     return 'Copyright (C) %s, SurfGuitar101.com' % year_range
bgneal@227: 
bgneal@227: 
bgneal@227: IP_PAT = re.compile('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
bgneal@227: 
bgneal@227: def get_ip(request):
bgneal@227:     """Returns the IP from the request or None if it cannot be retrieved."""
bgneal@227:     ip = request.META.get('HTTP_X_FORWARDED_FOR',
bgneal@227:             request.META.get('REMOTE_ADDR'))
bgneal@227: 
bgneal@227:     if ip:
bgneal@227:         match = IP_PAT.match(ip)
bgneal@227:         ip = match.group(1) if match else None
bgneal@227: 
bgneal@227:     return ip
bgneal@241: 
bgneal@241: 
bgneal@241: def get_page(qdict):
bgneal@241:     """Attempts to retrieve the value for "page" from the given query dict and
bgneal@241:     return it as an integer. If the key cannot be found or converted to an
bgneal@241:     integer, 1 is returned.
bgneal@241:     """
bgneal@241:     n = qdict.get('page', 1)
bgneal@241:     try:
bgneal@241:         n = int(n)
bgneal@241:     except ValueError:
bgneal@241:         n = 1
bgneal@241:     return n
bgneal@566: 
bgneal@566: 
bgneal@566: def quote_message(who, message):
bgneal@566:     """
bgneal@566:     Builds a message reply by quoting the existing message in a
bgneal@566:     typical email-like fashion. The quoting is compatible with Markdown.
bgneal@566:     """
bgneal@816:     msg = "> %s" % message.rstrip().replace('\n', '\n> ')
bgneal@566:     if msg.endswith('\n> '):
bgneal@566:         msg = msg[:-2]
bgneal@566: 
bgneal@566:     return "*%s wrote:*\n\n%s\n\n" % (who, msg)