fixes
[wolnelektury.git] / src / wolnelektury / utils.py
1 # This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
3 #
4 import codecs
5 import csv
6 from functools import wraps
7 from io import BytesIO
8 import os
9 import re
10
11 from django.conf import settings
12 from django.contrib import admin
13 from django.core.cache import cache
14 from django.core.mail import send_mail
15 from django.template.loader import render_to_string
16 from django.utils.translation import get_language
17 from django.conf import settings
18 from django.utils.safestring import mark_safe
19
20
21 def utc_for_js(dt):
22     return dt.strftime('%Y/%m/%d %H:%M:%S UTC')
23
24
25 def makedirs(path):
26     if not os.path.isdir(path):
27         os.makedirs(path)
28
29
30 def send_noreply_mail(subject, message, recipient_list, **kwargs):
31     send_mail(
32         '[WolneLektury] ' + subject,
33         message + "\n\n-- \nWiadomość wysłana automatycznie. Prosimy nie odpowiadać.",
34         'no-reply@wolnelektury.pl', recipient_list, **kwargs)
35
36
37 # source: https://docs.python.org/2/library/csv.html#examples
38 class UnicodeCSVWriter(object):
39     """
40     A CSV writer which will write rows to CSV file "f",
41     which is encoded in the given encoding.
42     """
43
44     def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
45         # Redirect output to a queue
46         self.queue = BytesIO()
47         self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
48         self.stream = f
49         self.encoder = codecs.getincrementalencoder(encoding)()
50
51     def writerow(self, row):
52         self.writer.writerow([s.encode("utf-8") for s in row])
53         # Fetch UTF-8 output from the queue ...
54         data = self.queue.getvalue()
55         data = data.decode("utf-8")
56         # ... and reencode it into the target encoding
57         data = self.encoder.encode(data)
58         # write to the target stream
59         self.stream.write(data)
60         # empty queue
61         self.queue.truncate(0)
62
63     def writerows(self, rows):
64         for row in rows:
65             self.writerow(row)
66
67
68 # the original re.escape messes with unicode
69 def re_escape(s):
70     return re.sub(r"[(){}\[\].*?|^$\\+-]", r"\\\g<0>", s)
71
72
73 def get_cached_render_key(instance, property_name, language=None):
74     if language is None:
75         language = get_language()
76     return 'cached_render:%s.%s:%s:%s' % (
77             type(instance).__name__,
78             property_name,
79             instance.pk,
80             language
81         )
82
83
84 def cached_render(template_name, timeout=24 * 60 * 60):
85     def decorator(method):
86         @wraps(method)
87         def wrapper(self):
88             key = get_cached_render_key(self, method.__name__)
89             content = cache.get(key)
90             if content is None:
91                 context = method(self)
92                 content = render_to_string(template_name, context)
93                 cache.set(key, str(content), timeout=timeout)
94             else:
95                 content = mark_safe(content)
96             return content
97         return wrapper
98     return decorator
99
100
101 def clear_cached_renders(bound_method):
102     for lc, ln in settings.LANGUAGES:
103         cache.delete(
104             get_cached_render_key(
105                 bound_method.__self__,
106                 bound_method.__name__,
107                 lc
108             )
109         )
110
111
112 class YesNoFilter(admin.SimpleListFilter):
113     def lookups(self, request, model_admin):
114         return (
115             ('yes', 'Tak'),
116             ('no', 'Nie'),
117         )
118
119     def queryset(self, request, queryset):
120         if self.value() == 'yes':
121             return queryset.filter(self.q)
122         elif self.value() == 'no':
123             return queryset.exclude(self.q)
124
125
126 def is_ajax(request):
127     return request.headers.get('x-requested-with') == 'XMLHttpRequest'