+
+
+def customizations_hash(customizations):
+ customizations.sort()
+ return hash(tuple(customizations))
+
+
+def get_customized_pdf_path(book, customizations):
+ """
+ Returns a MEDIA_ROOT relative path for a customized pdf. The name will contain a hash of customization options.
+ """
+ h = customizations_hash(customizations)
+ return 'book/%s/%s-custom-%s.pdf' % (book.slug, book.slug, h)
+
+
+def clear_custom_pdf(book):
+ """
+ Returns a list of paths to generated customized pdf of a book
+ """
+ from waiter.utils import clear_cache
+ clear_cache('book/%s' % book.slug)
+
+
+class AppSettings(object):
+ """Allows specyfying custom settings for an app, with default values.
+
+ Just subclass, set some properties and instantiate with a prefix.
+ Getting a SETTING from an instance will check for prefix_SETTING
+ in project settings if set, else take the default. The value will be
+ then filtered through _more_SETTING method, if there is one.
+
+ """
+ def __init__(self, prefix):
+ self._prefix = prefix
+
+ def __getattribute__(self, name):
+ if name.startswith('_'):
+ return object.__getattribute__(self, name)
+ value = getattr(settings,
+ "%s_%s" % (self._prefix, name),
+ object.__getattribute__(self, name))
+ more = "_more_%s" % name
+ if hasattr(self, more):
+ value = getattr(self, more)(value)
+ return value
+
+
+def trim_query_log(trim_to=25):
+ """
+connection.queries includes all SQL statements -- INSERTs, UPDATES, SELECTs, etc. Each time your app hits the database, the query will be recorded.
+This can sometimes occupy lots of memory, so trim it here a bit.
+ """
+ if settings.DEBUG:
+ from django.db import connection
+ connection.queries = trim_to > 0 \
+ and connection.queries[-trim_to:] \
+ or []
+
+
+def delete_from_cache_by_language(cache, key_template):
+ cache.delete_many([key_template % lc for lc, ln in settings.LANGUAGES])