def is_local_path(path): """ Determine if path is on local file system. """ media_root = _s('MEDIA_ROOT') resources_root = _s('RESOURCES_ROOT') return path.startswith(media_root) or path.startswith(resources_root)
def send_email(subject, message, recipient_list, from_email=None, fail_silently=False, connection=None): """ Sends a message to each recipient in recipient list. :param subject: email subject :param messge: email message/body :param recipient_list: list/tuple of recipient emails :param from_email: email address for "from:" (defaults to SERVER_EMAIL or DEFAULT_FROM_EMAIL in settings) :param fail_silently: unused :param connection: unused """ if not from_email: from_email = _s('SERVER_EMAIL') or _s('DEFAULT_FROM_EMAIL') try: subj = unicode(subject) except UnicodeDecodeError: subj = subject.decode('utf8') datatuple = [(subj, message, from_email, [recipient],) \ for recipient in recipient_list] send_mass_mail(datatuple)
def url_to_local_path(url): """ Convert an url to ``local file path`` for media storage. """ try: media_root = _s('MEDIA_ROOT') media_url = _s('LOCAL_MEDIA_URL', 'MEDIA_URL') return url.replace(media_url, media_root) except AttributeError: return None
def path_to_url(path): """ Convert a file system path to relative url path for serving media. """ try: media_root = _s('MEDIA_ROOT') media_url = _s('MEDIA_URL') return path.replace(media_root, media_url) except AttributeError: return None
def url_to_path(url): """ Convert an url to local path for media storage. """ try: media_root = _s('MEDIA_ROOT') media_url = _s('MEDIA_URL') return url.replace(media_url, media_root) except AttributeError: return None
class UserInfo(object): """ Simple object to store info for test user. """ # verbose output verbosity = _s('TEST_VERBOSITY', 0) def __init__(self, username, password, email): self.username = username self.password = password self.email = email self.user = self.create_user() def _msg(self, *args, **kwargs): """ Utility method to print out verbose test and debug messages. * print output only if verbosity level is above 2. """ if self.verbosity > 2: msg(*args, **kwargs) def create_user(self): """ Utility method to create user. """ if self.username and self.password and self.email: user = User.objects.create_user( self.username, password=self.password, email=self.email) else: user = None return user def set_staff_status(self, is_staff): """ Change user ``is_staff`` status. :param is_staff: True or False :returns: user instance or None if user not found/some kind of error. """ try: assert self.user and hasattr(self.user, 'is_staff') except AssertionError: pass else: self.user.is_staff = is_staff self.user.save() return self.user def print_user_info(self): """ Utility method to print out user info. """ if self.user: self._msg('username', self.username, first=True) self._msg('user id', str(self.user.id)) self._msg('email', self.email) else: self._msg('user', 'None', first=True)
def ezencode(data, secret_key=None, encoding='base16'): """ Encrypt data and encode in base16 or some other format. """ if not secret_key: secret_key = _s('SECRET_KEY') return encode_data(data, secret_key, pickle_data=True, encoding=encoding)
def login_url(orig_url=None, redirect_back=True): """ Utility function to return url to login form with 'next' query string set to 'orig_url'. :param orig_url: original url to use for "next" value in query string :param redirect_back: if True, set next to 'orig_url', else next='' :returns: login form url (with next in query string) """ if orig_url is None or redirect_back is False: orig_url = '' url = _s('LOGIN_URL') if not url: try: url = reverse('auth_login') except NoReverseMatch: url = _s('DEFAULT_LOGIN_URL', '/') return url_with_qs(url, next=orig_url)
def ezdecode(encrypted, secret_key=None, encoding='base16'): """ Decode and decrypt data previously encoded using my_encode_data. """ if not secret_key: secret_key = _s('SECRET_KEY') return decode_data(encrypted, secret_key, pickle_data=True, encoding=encoding)
def send_email_to_group(group, subject, message, fail_silently=False): """ Send emails to a group. * FIXME: this function should be deprecated and deleted from helpers.email (functionality is redundant -- use send_email instead). :param group: group name or list of recipients :param subject: email subject :param message: email message/body :param fail_silently: if False, will send debug email to admins """ if isinstance(group, basestring): members = get_users_in_group(group) recipients = [user.email for user in members if user.email] elif isinstance(group, (list, tuple)): recipients = group try: assert recipients except AssertionError: if not fail_silently: template = _s('NOTIFICATION_FAILED_TEMPLATE') \ or _template('notification_failed') debug_subj = _s('GROUP_EMAIL_FAILED_SUBJECT') \ or _msg('subject_group_email_failed') emsg = _msg('msg_group_email_failed') debug_msg = '%s: %s' % (emsg, group) site_name = get_current_site().name context = { 'debug_message': debug_msg, 'subject': subject, 'recipients': recipients, 'message': message, 'site_name': site_name } msg = render_to_string(template, context) admins = _s('ADMINS') recipients = [email for name, email in admins] send_email(debug_subj, msg, recipients, fail_silently=False) else: send_email(subject, message, recipients, fail_silently=True)
def send_debug_email(subject, message): """ Send debug email to admins. :param subject: email subject :param messge: email message/body """ if not subject: site = get_current_site() subj = _s('DEBUG_MSG_SUBJECT') or _msg('subject_debug_msg') subject = '%s: %s' % (site.name, subj) mail_admins(subject, message, fail_silently=True)
def create_filename(*args, **kwargs): """ Generate filename based on hash of secret key and supplied params. Example usage: import datatime timestamp = datetime.datetime.utcnow().strftime('%Y%m%d.%H%M%S%Z') group_id = group_profile.id contact_email = group_profile.contact_email unique_filename = create_unique_filename(timestamp, group_id, contact_email) * if args is empty list function will generate file name using timestamp and a random key (of length 'FILENAME_RANDOM_KEY_LEN') :param args: list of basestrings to use to construct file name :param kwargs: options :returns: sha1hashed file name """ # extract options append_random_key = kwargs.get('append_random_key', False) random_key_len = kwargs.get('random_key_len', FILENAME_RANDOM_KEY_LEN) lowercase = kwargs.get('lowercase', False) fext = kwargs.get('fext', '') # construct parts for hashing parts = [] def _add(x): if isinstance(x, (list, tuple)): for a in x: _add(a) else: try: assert x parts.append(str(x)) except (AssertionError, TypeError): pass if not args: args = [datetime.datetime.utcnow().strftime('%Y%m%d.%H%M%S%Z'), random_key(random_key_len)] _add(_s('SECRET_KEY')) _add(args) if append_random_key: _add(random_key(random_key_len)) filename = '%s%s' % (sha1hash('.'.join(parts)), fext) if lowercase: filename = filename.lower() logger().debug('create_filename - parts: %s' % repr(parts)) logger().debug('create_filename - hashed filename: %s' % filename) return filename
def send_html_email(subject, recipient_list, template, context, from_email=None, text_content=None): """ Send email with text and html versions. Reference link: https://docs.djangoproject.com/en/dev/topics/email/ :param subject: email subject :param recipient_list: list/tuple of recipient emails :param template: path to html email template :param context: context for html email template :param from_email: email address for "from:" (defaults to SERVER_EMAIL or DEFAULT_FROM_EMAIL in settings) :param text_content: content for plain text version of email """ if not from_email: from_email = _s('SERVER_EMAIL') or _s('DEFAULT_FROM_EMAIL') try: subj = unicode(subject) except UnicodeDecodeError: subj = subject.decode('utf8') html_content = render_to_string(template, context) if not text_content: text_content = html_to_text(html_content) # create the email and attach the HTML version # * html content will be in EmailMessage's 'alternative' attribute # list msg = EmailMultiAlternatives(subj, text_content, from_email, recipient_list) msg.attach_alternative(html_content, 'text/html') msg.send()
def get_home_url(): """ Get url for site home. """ global HomeURL if HomeURL is None: url = _s('HOME_URL') if not url: try: url = reverse('home') except NoReverseMatch: url = '/' HomeURL = url return HomeURL
def get_test_upload_dir(creat=False): """ Get test storage directory for images. * the upload directory is calculate by appending the following to MEDIA_ROOT: ** MEDIA_TEST_UPLOAD_PATH (testing) Example path: /static/media/tmp/u/abcskdakfhdk.jpg """ media_root = _s('MEDIA_ROOT') path = '%s%s' % (media_root, MEDIA_TEST_UPLOAD_PATH,) if creat: create_dir(path) return path
def get_tmp_upload_dir(creat=False): """ Get temporary storage directory for images. * the upload directory is calculate by appending the following to MEDIA_ROOT: ** MEDIA_TMP_UPLOAD_PATH (tmp) ** MEDIA_TMP_UPLOAD_SUBDIR (u) Example path: /static/media/tmp/u/abcskdakfhdk.jpg """ media_root = _s('MEDIA_ROOT') path = os.path.join('%s%s' % (media_root, MEDIA_TMP_UPLOAD_PATH,), MEDIA_TMP_UPLOAD_SUBDIR) if creat: create_dir(path) return path
def get_user_upload_dir(user_id, creat=False): """ Get upload directory for user. * the user upload directory is calculate by appending the following to MEDIA_ROOT: ** MEDIA_UPLOAD_PATH (default: users) ** MEDIA_UPLOAD_SUBDIR (default: i) ** user id (integer) Example path: /static/media/users/i/1/image.jpg """ media_root = _s('MEDIA_ROOT') path = os.path.join('%s%s' % (media_root, MEDIA_UPLOAD_PATH,), MEDIA_UPLOAD_SUBDIR, str(user_id)) if creat: create_dir(path) return path
def get_group_upload_dir(group_id, creat=False): """ Get upload directory for group. * the group upload directory is calculate by appending the following to MEDIA_ROOT: ** MEDIA_GROUP_UPLOAD_PATH (default: groups) ** MEDIA_UPLOAD_SUBDIR (default: i) ** group id (integer) Example path: /static/media/groups/i/1/image.jpg """ media_root = _s('MEDIA_ROOT') path = os.path.join('%s%s' % (media_root, MEDIA_GROUP_UPLOAD_PATH,), MEDIA_UPLOAD_SUBDIR, str(group_id)) if creat: create_dir(path) return path
def project_context(request): """ THIS DOES NOT WORK default context for project templates. """ user = request.user # site site = Site.objects.get_current() # storage configurations use_remote_storage = _s('USE_REMOTE_STORAGE', False) # media paths and urls site_title = _s('SITE_TITLE') static_root = _s('STATIC_ROOT') static_url = _s('STATIC_URL') local_static_url = _s('LOCAL_STATIC_URL', static_url) media_root = _s('MEDIA_ROOT') media_url = _s('MEDIA_URL') local_media_url = _s('LOCAL_MEDIA_URL', media_url) resources_root = _s('RESOURCES_ROOT', static_root) resources_url = _s('RESOURCES_URL', static_url) local_resources_url = _s('LOCAL_RESOURCES_URL', local_static_url) try: home_url = _s('HOME_URL') or reverse('home') assert home_url except (NoReverseMatch, AssertionError): home_url = '/' search_url = _s('SEARCH_URL', '/search/') return { 'settings': settings, 'use_remote_storage': use_remote_storage, 'static_root': static_root, 'static_url': static_url, 'local_static_url': local_static_url, 'media_root': media_root, 'media_url': media_url, 'local_media_url': local_media_url, 'resources_root': resources_root, 'resources_url': resources_url, 'local_resources_url': local_resources_url, 'home_url': home_url, 'search_url': search_url, 'site_name': site.name, 'site_domain': site.domain, 'site_title': site_title, }
def delete_images(entry, image_fields=None): """ Delete image associated with entry and all its thumbnails. * if image_fields is None, check entry for get_image_fields method. Example usage: ENTRY_IMAGES = ( 'image', 'thumbnail', 'thumbnail_small' ) delete_images(entry, ENTRY_IMAGES) * FIXME: add get_images method to model to fetch image paths directly instead of using field to fetch paths :param entry: object instance :param image_fields: list of field names for thumbnails :returns: number of errors encountered (0 is successful) """ from helpers.files.utils import delete_remote_media use_remote_storage = _s('USE_REMOTE_STORAGE', False) errors = 0 def _delete(url): e = 0 if use_remote_storage: if not is_local_path(url): ok = delete_remote_media(url) if not ok: e += 1 logger().debug('deleted remote image - %s %s' % (ok, url)) path = url_to_path(url) if os.path.isfile(path): os.remove(path) ok = os.path.isfile(path) == False if not ok: e += 1 logger().debug('deleted image - %s %s' % (ok, path)) return e if entry: if image_fields is None: if hasattr(entry, 'get_image_fields'): image_fields = entry.get_image_fields() if isinstance(image_fields, (list, tuple)): for img in image_fields: try: assert img url = getattr(entry, img) assert url except AssertionError: pass else: result = _delete(url) errors += result setattr(entry, img, None) logger().debug('delete_images - errors: %d' % errors) return errors
#-*- coding: utf-8 -*- """ helpers.test.settings Settings for test utils. * created: 2013-07-20 Kevin Chan <*****@*****.**> * updated: 2013-10-27 kchan """ from garage import get_setting as _s # template to define test users # * each part contains a '%s' for appending a suffix to the base # ('username_base', 'password_base', 'email_base',) DEFAULT_TEST_USER_TEMPLATE = ( 'testuser_%s', 'aVCYboFx3x_%s', '*****@*****.**', ) TEST_USER_TEMPLATE = _s('TEST_USER_TEMPLATE', DEFAULT_TEST_USER_TEMPLATE) # divider for test diagnostic printouts (used by msg()) DIVIDER = '# ----------------------------------------------------------------------'
from garage.image_utils import ( get_image_size, resize_image, generate_thumb, get_file_basename, get_img_ext ) from helpers.crypto.utils import random_key from helpers.files.utils import create_dir ### defaults # path to upload images/files to MEDIA_UPLOAD_PATH = _s('MEDIA_UPLOAD_PATH', 'users') MEDIA_GROUP_UPLOAD_PATH = _s('MEDIA_GROUP_UPLOAD_PATH', 'groups') MEDIA_UPLOAD_SUBDIR = _s('MEDIA_UPLOAD_SUBDIR', 'i') MEDIA_TMP_UPLOAD_PATH = _s('MEDIA_TMP_UPLOAD_PATH', 'tmp') MEDIA_TMP_UPLOAD_SUBDIR = _s('MEDIA_TMP_UPLOAD_SUBDIR', 'u') MEDIA_TEST_UPLOAD_PATH = _s('MEDIA_TEST_UPLOAD_PATH', 'testing') # prefix of url to use for media uploaded to file storage MEDIA_URL_PREFIX = '%s%s' % (_s('MEDIA_URL'), MEDIA_UPLOAD_PATH) # name of thumbnail directory THUMBNAIL_DIRECTORY = _s('THUMBNAIL_DIRECTORY', 'thumbs') # max image height and width MAX_IMAGE_HEIGHT = _s('MAX_IMAGE_HEIGHT', 400) MAX_IMAGE_WIDTH = _s('MAX_IMAGE_WIDTH', 600)
Test classes based on Django TestCase * created: 2013-07-21 Kevin Chan <*****@*****.**> * updated: 2015-02-22 kchan """ from __future__ import (absolute_import, unicode_literals) import unittest from garage import get_setting as _s from garage.test.utils import msg # set verbosity to > 2 to output diagnostics and messages in tests VERBOSITY = _s('TEST_VERBOSITY', 0) class SimpleTestCase(unittest.TestCase): """ Test case based on Python unittest TestCase. """ # verbose output verbosity = VERBOSITY def _msg(self, *args, **kwargs): """ Utility method to print out verbose test and debug messages. * print output only if verbosity level is above 2. """ if self.verbosity > 2:
* updated: 2013-10-27 kchan """ from django.utils import unittest from django.test import TestCase from django.test.client import Client from django.test.client import RequestFactory from garage import get_setting as _s from helpers.test.utils import ( msg, create_test_users, get_field_error, ) VERBOSITY = _s('TEST_VERBOSITY', 0) class SimpleTestCase(unittest.TestCase): """ Test case based on Python unittest TestCase. """ # verbose output verbosity = VERBOSITY def _msg(self, *args, **kwargs): """ Utility method to print out verbose test and debug messages. * print output only if verbosity level is above 2. """ if self.verbosity > 2: