annotate core/functions.py @ 974:d260aef91ad7

Prevent post preview from allowing mixed content. Apply image_check() to post previews and display an error message instead of the preview if it fails.
author Brian Neal <bgneal@gmail.com>
date Thu, 01 Oct 2015 20:18:48 -0500
parents 51a2051588f5
children f5aa74dcdd7a
rev   line source
bgneal@700 1 """This file houses various core utility functions"""
bgneal@176 2 import datetime
bgneal@700 3 import logging
bgneal@700 4 import os
bgneal@227 5 import re
bgneal@964 6 import tempfile
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@964 15 class TemporaryFile(object):
bgneal@964 16 """Context manager class for working with temporary files.
bgneal@964 17
bgneal@964 18 The file will be closed and removed when the context is exited.
bgneal@964 19 """
bgneal@964 20 def __init__(self, **kwargs):
bgneal@964 21 """kwargs will be passed to mkstemp."""
bgneal@964 22 self.kwargs = kwargs
bgneal@964 23
bgneal@964 24 def __enter__(self):
bgneal@964 25 self.fd, self.filename = tempfile.mkstemp(**self.kwargs)
bgneal@964 26 self.file = os.fdopen(self.fd, 'w+b')
bgneal@964 27 return self
bgneal@964 28
bgneal@964 29 def __exit__(self, exc_type, exc_value, traceback):
bgneal@964 30 self.file.close()
bgneal@964 31 os.remove(self.filename)
bgneal@700 32
bgneal@700 33
bgneal@892 34 def send_mail(subject, message, from_email, recipient_list, reply_to=None, defer=True):
gremmie@1 35 """
bgneal@513 36 The main send email function. Use this function to send email from the
bgneal@513 37 site. All applications should use this function instead of calling
bgneal@513 38 Django's directly.
bgneal@522 39 If defer is True, the email will be sent to a Celery task to actually send
bgneal@522 40 the email. Otherwise it is sent on the caller's thread. In any event, the
bgneal@513 41 email will be logged at the DEBUG level.
bgneal@513 42
bgneal@513 43 """
bgneal@513 44 # Guard against empty email addresses
bgneal@418 45 recipient_list = [dest for dest in recipient_list if dest]
bgneal@418 46 if not recipient_list:
bgneal@418 47 logging.warning("Empty recipient_list in send_mail")
bgneal@418 48 return
gremmie@1 49
bgneal@892 50 logging.debug('EMAIL:\nFrom: %s\nTo: %s\nReply-To: %s\nSubject: %s\nMessage:\n%s',
bgneal@892 51 from_email, str(recipient_list), reply_to, subject, message)
bgneal@892 52
bgneal@892 53 headers = {'Reply-To': reply_to} if reply_to else None
bgneal@892 54 msg_kwargs = {
bgneal@892 55 'subject': subject,
bgneal@892 56 'body': message,
bgneal@892 57 'from_email': from_email,
bgneal@892 58 'to': recipient_list,
bgneal@892 59 'headers': headers,
bgneal@892 60 }
gremmie@1 61
bgneal@522 62 if defer:
bgneal@892 63 core.tasks.send_mail.delay(**msg_kwargs)
bgneal@522 64 else:
bgneal@892 65 msg = django.core.mail.EmailMessage(**msg_kwargs)
bgneal@892 66 msg.send()
bgneal@513 67
gremmie@1 68
gremmie@1 69 def email_admins(subject, message):
gremmie@1 70 """Emails the site admins. Goes through the site send_mail function."""
gremmie@1 71 site = Site.objects.get_current()
gremmie@1 72 subject = '[%s] %s' % (site.name, subject)
bgneal@316 73 send_mail(subject,
bgneal@316 74 message,
gremmie@1 75 '%s@%s' % (settings.GPP_NO_REPLY_EMAIL, site.domain),
gremmie@1 76 [mail_tuple[1] for mail_tuple in settings.ADMINS])
gremmie@1 77
gremmie@1 78
gremmie@1 79 def email_managers(subject, message):
gremmie@1 80 """Emails the site managers. Goes through the site send_mail function."""
gremmie@1 81 site = Site.objects.get_current()
gremmie@1 82 subject = '[%s] %s' % (site.name, subject)
bgneal@316 83 send_mail(subject,
bgneal@700 84 message,
gremmie@1 85 '%s@%s' % (settings.GPP_NO_REPLY_EMAIL, site.domain),
gremmie@1 86 [mail_tuple[1] for mail_tuple in settings.MANAGERS])
gremmie@1 87
gremmie@1 88
gremmie@1 89 def get_full_name(user):
gremmie@1 90 """Returns the user's full name if available, otherwise falls back
gremmie@1 91 to the username."""
gremmie@1 92 full_name = user.get_full_name()
gremmie@1 93 if full_name:
gremmie@1 94 return full_name
gremmie@1 95 return user.username
bgneal@9 96
bgneal@176 97
bgneal@176 98 BASE_YEAR = 2010
bgneal@176 99
bgneal@176 100 def copyright_str():
bgneal@176 101 curr_year = datetime.datetime.now().year
bgneal@176 102 if curr_year == BASE_YEAR:
bgneal@176 103 year_range = str(BASE_YEAR)
bgneal@176 104 else:
bgneal@176 105 year_range = "%d - %d" % (BASE_YEAR, curr_year)
bgneal@176 106
bgneal@176 107 return 'Copyright (C) %s, SurfGuitar101.com' % year_range
bgneal@227 108
bgneal@227 109
bgneal@227 110 IP_PAT = re.compile('(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
bgneal@227 111
bgneal@227 112 def get_ip(request):
bgneal@227 113 """Returns the IP from the request or None if it cannot be retrieved."""
bgneal@227 114 ip = request.META.get('HTTP_X_FORWARDED_FOR',
bgneal@227 115 request.META.get('REMOTE_ADDR'))
bgneal@227 116
bgneal@227 117 if ip:
bgneal@227 118 match = IP_PAT.match(ip)
bgneal@227 119 ip = match.group(1) if match else None
bgneal@227 120
bgneal@227 121 return ip
bgneal@241 122
bgneal@241 123
bgneal@241 124 def get_page(qdict):
bgneal@241 125 """Attempts to retrieve the value for "page" from the given query dict and
bgneal@241 126 return it as an integer. If the key cannot be found or converted to an
bgneal@241 127 integer, 1 is returned.
bgneal@241 128 """
bgneal@241 129 n = qdict.get('page', 1)
bgneal@241 130 try:
bgneal@241 131 n = int(n)
bgneal@241 132 except ValueError:
bgneal@241 133 n = 1
bgneal@241 134 return n
bgneal@566 135
bgneal@566 136
bgneal@566 137 def quote_message(who, message):
bgneal@566 138 """
bgneal@566 139 Builds a message reply by quoting the existing message in a
bgneal@566 140 typical email-like fashion. The quoting is compatible with Markdown.
bgneal@566 141 """
bgneal@816 142 msg = "> %s" % message.rstrip().replace('\n', '\n> ')
bgneal@566 143 if msg.endswith('\n> '):
bgneal@566 144 msg = msg[:-2]
bgneal@566 145
bgneal@566 146 return "*%s wrote:*\n\n%s\n\n" % (who, msg)