annotate core/functions.py @ 1191:cc4683870919

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