annotate core/functions.py @ 887:9a15f7c27526

Actually save model object upon change. This commit was tested on the comments model. Additional logging added. Added check for Markdown image references. Added TODOs after observing behavior on comments.
author Brian Neal <bgneal@gmail.com>
date Tue, 03 Feb 2015 21:09:44 -0600
parents 97f8fab9b1a3
children 79a71b9d0a2a
rev   line source
bgneal@700 1 """This file houses various core utility functions"""
bgneal@700 2 from contextlib import contextmanager
bgneal@176 3 import datetime
bgneal@700 4 import logging
bgneal@700 5 import os
bgneal@227 6 import re
gremmie@1 7
gremmie@1 8 from django.contrib.sites.models import Site
gremmie@1 9 from django.conf import settings
bgneal@522 10 import django.core.mail
gremmie@1 11
bgneal@513 12 import core.tasks
bgneal@181 13
gremmie@1 14
bgneal@700 15 @contextmanager
bgneal@700 16 def temp_open(path, mode):
bgneal@700 17 """A context manager for closing and removing temporary files."""
bgneal@700 18 fp = open(path, mode)
bgneal@700 19 try:
bgneal@700 20 yield fp
bgneal@700 21 finally:
bgneal@700 22 fp.close()
bgneal@700 23 os.remove(path)
bgneal@700 24
bgneal@700 25
bgneal@522 26 def send_mail(subject, message, from_email, recipient_list, defer=True, **kwargs):
gremmie@1 27 """
bgneal@513 28 The main send email function. Use this function to send email from the
bgneal@513 29 site. All applications should use this function instead of calling
bgneal@513 30 Django's directly.
bgneal@522 31 If defer is True, the email will be sent to a Celery task to actually send
bgneal@522 32 the email. Otherwise it is sent on the caller's thread. In any event, the
bgneal@513 33 email will be logged at the DEBUG level.
bgneal@513 34
bgneal@513 35 """
bgneal@513 36 # Guard against empty email addresses
bgneal@418 37 recipient_list = [dest for dest in recipient_list if dest]
bgneal@418 38 if not recipient_list:
bgneal@418 39 logging.warning("Empty recipient_list in send_mail")
bgneal@418 40 return
gremmie@1 41
bgneal@316 42 logging.debug('EMAIL:\nFrom: %s\nTo: %s\nSubject: %s\nMessage:\n%s',
bgneal@316 43 from_email, str(recipient_list), subject, message)
gremmie@1 44
bgneal@522 45 if defer:
bgneal@513 46 core.tasks.send_mail.delay(subject, message, from_email, recipient_list,
bgneal@513 47 **kwargs)
bgneal@522 48 else:
bgneal@522 49 django.core.mail.send_mail(subject, message, from_email, recipient_list,
bgneal@522 50 **kwargs)
bgneal@513 51
gremmie@1 52
gremmie@1 53 def email_admins(subject, message):
gremmie@1 54 """Emails the site admins. Goes through the site send_mail function."""
gremmie@1 55 site = Site.objects.get_current()
gremmie@1 56 subject = '[%s] %s' % (site.name, subject)
bgneal@316 57 send_mail(subject,
bgneal@316 58 message,
gremmie@1 59 '%s@%s' % (settings.GPP_NO_REPLY_EMAIL, site.domain),
gremmie@1 60 [mail_tuple[1] for mail_tuple in settings.ADMINS])
gremmie@1 61
gremmie@1 62
gremmie@1 63 def email_managers(subject, message):
gremmie@1 64 """Emails the site managers. Goes through the site send_mail function."""
gremmie@1 65 site = Site.objects.get_current()
gremmie@1 66 subject = '[%s] %s' % (site.name, subject)
bgneal@316 67 send_mail(subject,
bgneal@700 68 message,
gremmie@1 69 '%s@%s' % (settings.GPP_NO_REPLY_EMAIL, site.domain),
gremmie@1 70 [mail_tuple[1] for mail_tuple in settings.MANAGERS])
gremmie@1 71
gremmie@1 72
gremmie@1 73 def get_full_name(user):
gremmie@1 74 """Returns the user's full name if available, otherwise falls back
gremmie@1 75 to the username."""
gremmie@1 76 full_name = user.get_full_name()
gremmie@1 77 if full_name:
gremmie@1 78 return full_name
gremmie@1 79 return user.username
bgneal@9 80
bgneal@176 81
bgneal@176 82 BASE_YEAR = 2010
bgneal@176 83
bgneal@176 84 def copyright_str():
bgneal@176 85 curr_year = datetime.datetime.now().year
bgneal@176 86 if curr_year == BASE_YEAR:
bgneal@176 87 year_range = str(BASE_YEAR)
bgneal@176 88 else:
bgneal@176 89 year_range = "%d - %d" % (BASE_YEAR, curr_year)
bgneal@176 90
bgneal@176 91 return 'Copyright (C) %s, SurfGuitar101.com' % year_range
bgneal@227 92
bgneal@227 93
bgneal@227 94 IP_PAT = re.compile('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
bgneal@227 95
bgneal@227 96 def get_ip(request):
bgneal@227 97 """Returns the IP from the request or None if it cannot be retrieved."""
bgneal@227 98 ip = request.META.get('HTTP_X_FORWARDED_FOR',
bgneal@227 99 request.META.get('REMOTE_ADDR'))
bgneal@227 100
bgneal@227 101 if ip:
bgneal@227 102 match = IP_PAT.match(ip)
bgneal@227 103 ip = match.group(1) if match else None
bgneal@227 104
bgneal@227 105 return ip
bgneal@241 106
bgneal@241 107
bgneal@241 108 def get_page(qdict):
bgneal@241 109 """Attempts to retrieve the value for "page" from the given query dict and
bgneal@241 110 return it as an integer. If the key cannot be found or converted to an
bgneal@241 111 integer, 1 is returned.
bgneal@241 112 """
bgneal@241 113 n = qdict.get('page', 1)
bgneal@241 114 try:
bgneal@241 115 n = int(n)
bgneal@241 116 except ValueError:
bgneal@241 117 n = 1
bgneal@241 118 return n
bgneal@566 119
bgneal@566 120
bgneal@566 121 def quote_message(who, message):
bgneal@566 122 """
bgneal@566 123 Builds a message reply by quoting the existing message in a
bgneal@566 124 typical email-like fashion. The quoting is compatible with Markdown.
bgneal@566 125 """
bgneal@816 126 msg = "> %s" % message.rstrip().replace('\n', '\n> ')
bgneal@566 127 if msg.endswith('\n> '):
bgneal@566 128 msg = msg[:-2]
bgneal@566 129
bgneal@566 130 return "*%s wrote:*\n\n%s\n\n" % (who, msg)