Status update emails.
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Fri, 12 Jul 2013 15:03:59 +0000 (17:03 +0200)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Fri, 12 Jul 2013 15:03:59 +0000 (17:03 +0200)
19 files changed:
apps/funding/forms.py
apps/funding/locale/pl/LC_MESSAGES/django.mo
apps/funding/locale/pl/LC_MESSAGES/django.po
apps/funding/migrations/0015_auto__add_field_funding_notifications__add_field_funding_notify_key.py [new file with mode: 0644]
apps/funding/models.py
apps/funding/templates/funding/disable_notifications.html [new file with mode: 0755]
apps/funding/templates/funding/email.txt [deleted file]
apps/funding/templates/funding/email/base.txt [new file with mode: 0755]
apps/funding/templates/funding/email/end.txt [new file with mode: 0755]
apps/funding/templates/funding/email/near.txt [new file with mode: 0755]
apps/funding/templates/funding/email/published.txt [new file with mode: 0755]
apps/funding/templates/funding/email/thanks.txt [new file with mode: 0644]
apps/funding/templates/funding/no_thanks.html [changed mode: 0755->0644]
apps/funding/templates/funding/offer_detail.html [changed mode: 0755->0644]
apps/funding/templates/funding/offer_list.html [changed mode: 0755->0644]
apps/funding/templates/funding/thanks.html [changed mode: 0755->0644]
apps/funding/templates/funding/wlfund.html [changed mode: 0755->0644]
apps/funding/urls.py
apps/funding/views.py

index dc0e623..bb155b9 100644 (file)
@@ -14,8 +14,9 @@ class FundingForm(forms.Form):
     name = forms.CharField(label=_("Name"), required=False,
         help_text=_("Optional name for public list of contributors"))
     email = forms.EmailField(label=_("Contact e-mail"),
     name = forms.CharField(label=_("Name"), required=False,
         help_text=_("Optional name for public list of contributors"))
     email = forms.EmailField(label=_("Contact e-mail"),
-        help_text=_("We'll use it to contact you about your perks and fundraiser status and payment updates.<br/> "
-            "Won't be publicised."), required=False)
+        help_text=_("We'll use it to contact you about the <strong>details needed for your perks</strong>,<br/>"
+            "and to send you updates about your payment and the fundraiser status (which you can always turn off).<br/>"
+            "Your e-mail won't be publicised."), required=False)
 
     def __init__(self, offer, *args, **kwargs):
         self.offer = offer
 
     def __init__(self, offer, *args, **kwargs):
         self.offer = offer
index a2ca35f..15638ce 100644 (file)
Binary files a/apps/funding/locale/pl/LC_MESSAGES/django.mo and b/apps/funding/locale/pl/LC_MESSAGES/django.mo differ
index 7168719..07a2ced 100644 (file)
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-06-26 15:26+0200\n"
-"PO-Revision-Date: 2013-06-26 15:32+0100\n"
+"POT-Creation-Date: 2013-07-12 17:00+0200\n"
+"PO-Revision-Date: 2013-07-12 17:01+0100\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "MIME-Version: 1.0\n"
 "Last-Translator: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -36,181 +36,189 @@ msgstr "E-mail kontaktowy"
 
 #: forms.py:17
 msgid ""
 
 #: forms.py:17
 msgid ""
-"We'll use it to contact you about your perks and fundraiser status and "
-"payment updates.<br/> Won't be publicised."
+"We'll use it to contact you about the <strong>details needed for your perks</"
+"strong>,<br/>and to send you updates about your payment and the fundraiser "
+"status (which you can always turn off).<br/>Your e-mail won't be publicised."
 msgstr ""
 msgstr ""
-"Użyjemy go do kontaktu w sprawie prezentów i informacji o zmianach statusu "
-"zbiórki i kolejnych akcjach.<br/>Nie będzie publikowany."
+"Użyjemy go do kontaktu w sprawie <strong>danych potrzebnych do realizacji "
+"prezentów</strong>,<br/>i informowania Cię o zmianach statusu płatności i "
+"zbiórki (z czego zawsze możesz zrezygnować).<br/>Twój adres e-mail nie "
+"będzie upubliczniony."
 
 
-#: forms.py:28
+#: forms.py:32
 #, python-format
 msgid "The minimum amount is %(amount)s PLN."
 msgstr "Minimalna kwota wpłaty to %(amount)s zł."
 
 #, python-format
 msgid "The minimum amount is %(amount)s PLN."
 msgstr "Minimalna kwota wpłaty to %(amount)s zł."
 
-#: forms.py:34
+#: forms.py:38
 msgid "This offer is out of date."
 msgstr "Ta zbiórka jest już nieaktywna."
 
 msgid "This offer is out of date."
 msgstr "Ta zbiórka jest już nieaktywna."
 
-#: models.py:19
+#: models.py:22
 msgid "author"
 msgstr "autor"
 
 msgid "author"
 msgstr "autor"
 
-#: models.py:20
+#: models.py:23
 msgid "title"
 msgstr "tytuł"
 
 msgid "title"
 msgstr "tytuł"
 
-#: models.py:21
+#: models.py:24
 msgid "slug"
 msgstr "slug"
 
 msgid "slug"
 msgstr "slug"
 
-#: models.py:22
+#: models.py:25
 msgid "description"
 msgstr "opis"
 
 msgid "description"
 msgstr "opis"
 
-#: models.py:23
+#: models.py:26
 msgid "target"
 msgstr "kwota docelowa"
 
 msgid "target"
 msgstr "kwota docelowa"
 
-#: models.py:24
+#: models.py:27
 msgid "start"
 msgstr "początek"
 
 msgid "start"
 msgstr "początek"
 
-#: models.py:25
+#: models.py:28
 msgid "end"
 msgstr "koniec"
 
 msgid "end"
 msgstr "koniec"
 
-#: models.py:26
+#: models.py:29
 msgid "due"
 msgstr "data publikacji"
 
 msgid "due"
 msgstr "data publikacji"
 
-#: models.py:27
+#: models.py:30
 msgid "When will it be published if the money is raised."
 msgstr "Kiedy książka zostanie opublikowana, jeśli uda się zebrać pieniądze."
 
 msgid "When will it be published if the money is raised."
 msgstr "Kiedy książka zostanie opublikowana, jeśli uda się zebrać pieniądze."
 
-#: models.py:28
+#: models.py:31
 msgid "redakcja URL"
 msgstr "URL na Redakcji"
 
 msgid "redakcja URL"
 msgstr "URL na Redakcji"
 
-#: models.py:30
+#: models.py:33
 msgid "Published book."
 msgstr "Opublikowana książka."
 
 msgid "Published book."
 msgstr "Opublikowana książka."
 
-#: models.py:31
+#: models.py:34
 msgid "Cover"
 msgstr "Okładka"
 
 msgid "Cover"
 msgstr "Okładka"
 
-#: models.py:32
+#: models.py:35
 msgid "Poll"
 msgstr "Ankieta"
 
 msgid "Poll"
 msgstr "Ankieta"
 
-#: models.py:36
+#: models.py:39
 msgid "Cover preview"
 msgstr "Podgląd okładki"
 
 msgid "Cover preview"
 msgstr "Podgląd okładki"
 
-#: models.py:40 models.py:114 models.py:135
+#: models.py:43 models.py:168 models.py:189
 msgid "offer"
 msgstr "zbiórka"
 
 msgid "offer"
 msgstr "zbiórka"
 
-#: models.py:41
+#: models.py:44
 msgid "offers"
 msgstr "zbiórki"
 
 msgid "offers"
 msgstr "zbiórki"
 
-#: models.py:115
+#: models.py:128
+msgid "The fundraiser has ended!"
+msgstr "Zbiórka dobiegła końca!"
+
+#: models.py:141
+msgid "The fundraiser will end soon!"
+msgstr "Zbiórka niedługo się zakończy!"
+
+#: models.py:153
+msgid "The book you helped fund has been published."
+msgstr "Książka, którą pomogłeś/-aś ufundować, została opublikowana."
+
+#: models.py:169
 msgid "price"
 msgstr "cena"
 
 msgid "price"
 msgstr "cena"
 
-#: models.py:116 models.py:136
+#: models.py:170 models.py:190
 msgid "name"
 msgstr "nazwa"
 
 msgid "name"
 msgstr "nazwa"
 
-#: models.py:117
+#: models.py:171
 msgid "long name"
 msgstr "długa nazwa"
 
 msgid "long name"
 msgstr "długa nazwa"
 
-#: models.py:118
+#: models.py:172
 msgid "end date"
 msgstr "data końcowa"
 
 msgid "end date"
 msgstr "data końcowa"
 
-#: models.py:121
+#: models.py:175
 msgid "perk"
 msgstr "prezent"
 
 msgid "perk"
 msgstr "prezent"
 
-#: models.py:122 models.py:140
+#: models.py:176 models.py:194
 msgid "perks"
 msgstr "prezenty"
 
 msgid "perks"
 msgstr "prezenty"
 
-#: models.py:137
+#: models.py:191
 msgid "email"
 msgstr "e-mail"
 
 msgid "email"
 msgstr "e-mail"
 
-#: models.py:138 models.py:168
+#: models.py:192 models.py:268
 msgid "amount"
 msgstr "kwota"
 
 msgid "amount"
 msgstr "kwota"
 
-#: models.py:139
+#: models.py:193
 msgid "payed at"
 msgstr "data wpłaty"
 
 msgid "payed at"
 msgstr "data wpłaty"
 
-#: models.py:151
+#: models.py:196
+msgid "notifications"
+msgstr "powiadomienia"
+
+#: models.py:200
 msgid "funding"
 msgstr "wpłata"
 
 msgid "funding"
 msgstr "wpłata"
 
-#: models.py:152
+#: models.py:201
 msgid "fundings"
 msgstr "wpłaty"
 
 msgid "fundings"
 msgstr "wpłaty"
 
-#: models.py:169
+#: models.py:269
 msgid "when"
 msgstr "kiedy"
 
 msgid "when"
 msgstr "kiedy"
 
-#: models.py:172
+#: models.py:272
 msgid "money spent on a book"
 msgstr "pieniądze wydane na książkę"
 
 msgid "money spent on a book"
 msgstr "pieniądze wydane na książkę"
 
-#: models.py:173
+#: models.py:273
 msgid "money spent on books"
 msgstr "pieniądze wydane na książki"
 
 msgid "money spent on books"
 msgstr "pieniądze wydane na książki"
 
-#: models.py:203 templates/funding/thanks.html:6
+#: models.py:299 templates/funding/thanks.html:6
 #: templates/funding/thanks.html.py:13
 msgid "Thank you for your support!"
 msgstr "Dziękujemy za Twoje wsparcie!"
 
 #: templates/funding/thanks.html.py:13
 msgid "Thank you for your support!"
 msgstr "Dziękujemy za Twoje wsparcie!"
 
-#: templates/funding/email.txt:3
-msgid "Hi"
-msgstr "Cześć"
-
-#: templates/funding/email.txt:5
-msgid ""
-"Thank you for your support - thanks to you we will set another book free."
-msgstr "Dziękujemy za wsparcie - dzięki Tobie uwolnimy kolejną książkę."
+#: templates/funding/disable_notifications.html:5
+#: templates/funding/no_thanks.html:5 templates/funding/no_thanks.html.py:9
+msgid "Payment failed"
+msgstr "Płatność nie doszła do skutku"
 
 
-#: templates/funding/email.txt:7
-msgid "The book will be supplemented with your name as a donor."
-msgstr ""
-"Twoje imię i nazwisko lub pseudonim zostaną dodane do listy darczyńców przy "
-"opublikowanej książce."
+#: templates/funding/disable_notifications.html:9
+#: templates/funding/disable_notifications.html:16
+msgid "Disable notifications"
+msgstr "Wyłącz powiadomienia"
 
 
-#: templates/funding/email.txt:9
-msgid ""
-"We will contact you to keep you informed about your perks,\n"
-"status changes to this fundraiser and the incoming ones that we plan to "
-"launch."
-msgstr ""
-"Skontaktujemy się Tobą w sprawie prezentów i informacji o zmianach statusu "
-"zbiórki oraz kolejnych akcjach."
+#: templates/funding/disable_notifications.html:14
+#, python-format
+msgid "Are you sure you want to disable notifications for address %(e)s?"
+msgstr "Czy na pewno chcesz wyłączyć powiadomienia dla adresu %(e)s?"
 
 
-#: templates/funding/email.txt:12
-msgid ""
-"Cheers,\n"
-"Wolne Lektury team"
-msgstr ""
-"Pozdrawiamy,\n"
-"zespół Wolnych Lektur"
+#: templates/funding/disable_notifications.html:21
+#, python-format
+msgid "Notifications for address %(e)s have been successfully disabled."
+msgstr "Powiadomienia dla adresu %(e)s zostały wyłączone."
 
 
-#: templates/funding/no_thanks.html:5 templates/funding/no_thanks.html.py:9
-msgid "Payment failed"
-msgstr "Płatność nie doszła do skutku"
+#: templates/funding/disable_notifications.html:27
+#, python-format
+msgid "Return to the <a href=\"%(current)s\">current fundraiser</a>."
+msgstr "Wróć do <a href=\"%(current)s\">aktualnej zbiórki</a>."
 
 #: templates/funding/no_thanks.html:12
 msgid "You're support has not been processed successfully."
 
 #: templates/funding/no_thanks.html:12
 msgid "You're support has not been processed successfully."
@@ -240,27 +248,27 @@ msgstr "Dowiedz się więcej"
 msgid "Support the publication"
 msgstr "Wesprzyj publikację"
 
 msgid "Support the publication"
 msgstr "Wesprzyj publikację"
 
-#: templates/funding/offer_detail.html:51
+#: templates/funding/offer_detail.html:50
 msgid "Donate!"
 msgstr "Wpłać!"
 
 msgid "Donate!"
 msgstr "Wpłać!"
 
-#: templates/funding/offer_detail.html:59 templates/funding/thanks.html:35
+#: templates/funding/offer_detail.html:58 templates/funding/thanks.html:35
 msgid "Tell your friends!"
 msgstr "Powiedz swoim znajomym!"
 
 msgid "Tell your friends!"
 msgstr "Powiedz swoim znajomym!"
 
-#: templates/funding/offer_detail.html:60
+#: templates/funding/offer_detail.html:59
 msgid "Support Wolne Lektury!"
 msgstr "Wesprzyj Wolne Lektury!"
 
 msgid "Support Wolne Lektury!"
 msgstr "Wesprzyj Wolne Lektury!"
 
-#: templates/funding/offer_detail.html:63
+#: templates/funding/offer_detail.html:62
 msgid "See all fundraisers."
 msgstr "Zobacz wszystkie zbiórki."
 
 msgid "See all fundraisers."
 msgstr "Zobacz wszystkie zbiórki."
 
-#: templates/funding/offer_detail.html:68
+#: templates/funding/offer_detail.html:67
 msgid "Supporters"
 msgstr "Wpłaty"
 
 msgid "Supporters"
 msgstr "Wpłaty"
 
-#: templates/funding/offer_detail.html:82
+#: templates/funding/offer_detail.html:81
 msgid "Anonymous"
 msgstr "Anonim"
 
 msgid "Anonymous"
 msgstr "Anonim"
 
@@ -357,6 +365,151 @@ msgstr "Pieniądze przeznaczone na opublikowanie książki"
 msgid "Money remaining from the fundraiser for"
 msgstr "Pieniądze pozostałe ze zbiórki na"
 
 msgid "Money remaining from the fundraiser for"
 msgstr "Pieniądze pozostałe ze zbiórki na"
 
+#: templates/funding/email/base.txt:1
+msgid "Hi"
+msgstr "Cześć"
+
+#: templates/funding/email/base.txt:4
+msgid ""
+"Cheers,\n"
+"Wolne Lektury team"
+msgstr ""
+"Pozdrawiamy,\n"
+"zespół Wolnych Lektur"
+
+#: templates/funding/email/base.txt:8
+msgid "If you don't want to receive any more updates, please visit this page:"
+msgstr "Jeśli nie chcesz otrzymywać kolejnych powiadomień, odwiedź tę stronę:"
+
+#: templates/funding/email/end.txt:6
+msgid ""
+"we succesfully collected the full amount needed\n"
+"for the book you contributed to:"
+msgstr "udało nam się zebrać pełną kwotę na książkę, którą wsparłeś/-aś:"
+
+#: templates/funding/email/end.txt:12
+msgid ""
+"We will now digitize it, develop and publish it in the library,\n"
+"in various formats, free for everyone."
+msgstr ""
+"Teraz ją zdigitalizujemy, opracujemy i bezpłatnie udostępnimy w bibliotece w "
+"wielu formatach."
+
+#: templates/funding/email/end.txt:15
+msgid ""
+"Your name will be included on the list of contributors, irrespectively\n"
+"of the amount of your contribution."
+msgstr ""
+"Zostaniesz umieszczony/-a na liście darczyńców, niezależnie od wysokości "
+"wpłaty."
+
+#: templates/funding/email/end.txt:18
+msgid ""
+"We will contact you again about details needed\n"
+"to deliver your perks."
+msgstr "Skontaktujemy się z Tobą w sprawie prezentów, które wybrałeś/-aś."
+
+#: templates/funding/email/end.txt:21
+#, python-format
+msgid ""
+"All of the money remaining after this fundraiser (%(x)s PLN)\n"
+"will be spent on liberating other books still waiting for publication."
+msgstr ""
+"Wszystkie dodatkowe pieniądze pozostałe z tej zbiórki (%(x)s PLN)\n"
+"zostaną przeznaczone na uwolnienie innych książek czekających na publikację."
+
+#: templates/funding/email/end.txt:23 templates/funding/email/end.txt.py:34
+msgid "You can see how we're spending these funds on this page:"
+msgstr "Możesz zobaczyć, jak wydajemy te środki, na tej stronie:"
+
+#: templates/funding/email/end.txt:26
+msgid ""
+"unfortunately, we were unable to collect the full amount needed\n"
+"for the book you contributed to:"
+msgstr ""
+"niestety, nie udało nam się zebrać pełnej kwoty na książkę, którą wsparłeś/-"
+"aś:"
+
+#: templates/funding/email/end.txt:32
+#, python-format
+msgid ""
+"All of the money we collected in this fundraiser (%(x)s PLN)\n"
+"will be spent on liberating other books still waiting for publication."
+msgstr ""
+"Wszystkie pieniądze z tej zbiórki (%(x)s PLN)\n"
+"zostaną przeznaczone na uwolnienie innych książek czekających na publikację."
+
+#: templates/funding/email/end.txt:37 templates/funding/email/published.txt:12
+msgid ""
+"If you'd like to help liberate another book, or invite your friends\n"
+"to do so, we're currently raising money for:"
+msgstr ""
+"Jeśli chcesz pomóc uwolnić kolejną książkę, albo zachęcić do tegoswoich "
+"znajomych, to aktualnie zbieramy na:"
+
+#: templates/funding/email/near.txt:5
+#, python-format
+msgid "there's only %(d)s day left until the end of the fundraiser for:\n"
+msgid_plural ""
+"There're only %(d)s days left until the end of the fundraiser for:\n"
+msgstr[0] "został jeden dzień do końca zbiórki na:\n"
+msgstr[1] "zostały %(d)s dni do końca zbiórki na:\n"
+msgstr[2] "zostało %(d)s dni do końca zbiórki na:\n"
+
+#: templates/funding/email/near.txt:10
+#, python-format
+msgid "We managed to collect %(x)s PLN so far."
+msgstr "Dotąd udało nam się zebrać %(x)s PLN."
+
+#: templates/funding/email/near.txt:12
+msgid ""
+"The fundraiser is a success already, but the more money\n"
+"we collect, the more other books we'll publish."
+msgstr ""
+"Zbiórka już osiągnęła sukces, ale im więcej pieniędzy\n"
+"zbierzemy, tym więcej opublikujemy książek."
+
+#: templates/funding/email/near.txt:14
+#, python-format
+msgid "We still need %(x)s PLN more."
+msgstr "Nadal potrzebujemy %(x)s PLN."
+
+#: templates/funding/email/near.txt:16
+msgid "There's still time to let your friends know about the fundraiser!"
+msgstr "Jest jeszcze czas, by poinformować o zbiórce Twoich znajomych!"
+
+#: templates/funding/email/published.txt:4
+msgid "we have just published the book you contributed to:"
+msgstr "właśnie opublikowaliśmy książkę, którą wsparłeś/-aś:"
+
+#: templates/funding/email/published.txt:9
+msgid ""
+"Thanks to you, it is now available for free,\n"
+"in various formats, to everyone."
+msgstr ""
+"Dzięki Tobie jest teraz dostępna bezpłatnie\n"
+"dla wszystkich w wielu formatach."
+
+#: templates/funding/email/thanks.txt:6
+msgid ""
+"Thank you for your support - thanks to you we will set another book free."
+msgstr "Dziękujemy za wsparcie - dzięki Tobie uwolnimy kolejną książkę."
+
+#: templates/funding/email/thanks.txt:8
+msgid "The book will be supplemented with your name as a donor."
+msgstr ""
+"Twoje imię i nazwisko lub pseudonim zostaną dodane do listy darczyńców przy "
+"opublikowanej książce."
+
+#: templates/funding/email/thanks.txt:14
+msgid ""
+"We will contact you to keep you informed about\n"
+"status changes to this fundraiser and the upcoming ones that we plan\n"
+"to launch."
+msgstr ""
+"Będziemy Cię informować o zmienach statusu tej zbiórki\n"
+"i o kolejnych, które planujemy rozpocząć."
+
 #: templates/funding/snippets/any_remaining.html:4
 #, python-format
 msgid ""
 #: templates/funding/snippets/any_remaining.html:4
 #, python-format
 msgid ""
diff --git a/apps/funding/migrations/0015_auto__add_field_funding_notifications__add_field_funding_notify_key.py b/apps/funding/migrations/0015_auto__add_field_funding_notifications__add_field_funding_notify_key.py
new file mode 100644 (file)
index 0000000..dd9a41e
--- /dev/null
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'Funding.notifications'
+        db.add_column(u'funding_funding', 'notifications',
+                      self.gf('django.db.models.fields.BooleanField')(default=True, db_index=True),
+                      keep_default=False)
+
+        # Adding field 'Funding.notify_key'
+        db.add_column(u'funding_funding', 'notify_key',
+                      self.gf('django.db.models.fields.CharField')(default='x', max_length=32),
+                      keep_default=False)
+
+        # Adding index on 'Funding', fields ['email']
+        db.create_index(u'funding_funding', ['email'])
+
+
+    def backwards(self, orm):
+        # Removing index on 'Funding', fields ['email']
+        db.delete_index(u'funding_funding', ['email'])
+
+        # Deleting field 'Funding.notifications'
+        db.delete_column(u'funding_funding', 'notifications')
+
+        # Deleting field 'Funding.notify_key'
+        db.delete_column(u'funding_funding', 'notify_key')
+
+
+    models = {
+        'catalogue.book': {
+            'Meta': {'ordering': "('sort_key',)", 'object_name': 'Book'},
+            '_related_info': ('jsonfield.fields.JSONField', [], {'null': 'True', 'blank': 'True'}),
+            'changed_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'common_slug': ('django.db.models.fields.SlugField', [], {'max_length': '120'}),
+            'cover': ('catalogue.fields.EbookField', [], {'max_length': '100', 'null': 'True', 'format_name': "'cover'", 'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'epub_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'epub'", 'blank': 'True'}),
+            'extra_info': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'fb2_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'fb2'", 'blank': 'True'}),
+            'gazeta_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            'html_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'html'", 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'default': "'pol'", 'max_length': '3', 'db_index': 'True'}),
+            'mobi_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'mobi'", 'blank': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['catalogue.Book']"}),
+            'parent_number': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'pdf_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'pdf'", 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '120'}),
+            'sort_key': ('django.db.models.fields.CharField', [], {'max_length': '120', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '120'}),
+            'txt_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'txt'", 'blank': 'True'}),
+            'wiki_link': ('django.db.models.fields.CharField', [], {'max_length': '240', 'blank': 'True'}),
+            'xml_file': ('catalogue.fields.EbookField', [], {'default': "''", 'max_length': '100', 'format_name': "'xml'", 'blank': 'True'})
+        },
+        u'funding.funding': {
+            'Meta': {'ordering': "['-payed_at']", 'object_name': 'Funding'},
+            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
+            'email': ('django.db.models.fields.EmailField', [], {'db_index': 'True', 'max_length': '75', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language_code': ('django.db.models.fields.CharField', [], {'max_length': '2', 'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '127', 'blank': 'True'}),
+            'notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+            'notify_key': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+            'offer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['funding.Offer']"}),
+            'payed_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+            'perks': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['funding.Perk']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'funding.offer': {
+            'Meta': {'ordering': "['-end']", 'object_name': 'Offer'},
+            'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Book']", 'null': 'True', 'blank': 'True'}),
+            'cover': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'due': ('django.db.models.fields.DateField', [], {}),
+            'end': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['polls.Poll']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
+            'redakcja_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
+            'start': ('django.db.models.fields.DateField', [], {'db_index': 'True'}),
+            'target': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'funding.perk': {
+            'Meta': {'ordering': "['-price']", 'object_name': 'Perk'},
+            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'long_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'offer': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['funding.Offer']", 'null': 'True', 'blank': 'True'}),
+            'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'})
+        },
+        u'funding.spent': {
+            'Meta': {'ordering': "['-timestamp']", 'object_name': 'Spent'},
+            'amount': ('django.db.models.fields.DecimalField', [], {'max_digits': '10', 'decimal_places': '2'}),
+            'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Book']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'timestamp': ('django.db.models.fields.DateField', [], {})
+        },
+        u'polls.poll': {
+            'Meta': {'object_name': 'Poll'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'open': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'question': ('django.db.models.fields.TextField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['funding']
\ No newline at end of file
index 8c3312e..ac652b1 100644 (file)
@@ -3,15 +3,18 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from datetime import date, datetime
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from datetime import date, datetime
+from urllib import urlencode
 from django.core.urlresolvers import reverse
 from django.core.mail import send_mail
 from django.conf import settings
 from django.template.loader import render_to_string
 from django.db import models
 from django.core.urlresolvers import reverse
 from django.core.mail import send_mail
 from django.conf import settings
 from django.template.loader import render_to_string
 from django.db import models
-from django.utils.translation import ugettext_lazy as _, ugettext as __, override
+from django.utils.translation import ugettext_lazy as _, ugettext, override
 import getpaid
 from catalogue.models import Book
 import getpaid
 from catalogue.models import Book
+from catalogue.utils import get_random_hash
 from polls.models import Poll
 from polls.models import Poll
+from django.contrib.sites.models import Site
 
 
 class Offer(models.Model):
 
 
 class Offer(models.Model):
@@ -47,6 +50,15 @@ class Offer(models.Model):
     def get_absolute_url(self):
         return reverse('funding_offer', args=[self.slug])
 
     def get_absolute_url(self):
         return reverse('funding_offer', args=[self.slug])
 
+    def save(self, *args, **kw):
+        published_now = (self.book_id is not None and 
+            self.pk is not None and
+            type(self).objects.values('book').get(pk=self.pk)['book'] != self.book_id)
+        retval = super(Offer, self).save(*args, **kw)
+        if published_now:
+            self.notify_published()
+        return retval
+
     def is_current(self):
         return self.start <= date.today() <= self.end
 
     def is_current(self):
         return self.start <= date.today() <= self.end
 
@@ -104,6 +116,48 @@ class Offer(models.Model):
         """ The money gathered. """
         return self.funding_payed().aggregate(s=models.Sum('amount'))['s'] or 0
 
         """ The money gathered. """
         return self.funding_payed().aggregate(s=models.Sum('amount'))['s'] or 0
 
+    def notify_all(self, subject, template_name, extra_context=None):
+        Funding.notify_funders(
+            subject, template_name, extra_context,
+            query_filter=models.Q(offer=self)
+        )
+
+    def notify_end(self):
+        assert not self.is_current()
+        self.notify_all(
+            _('The fundraiser has ended!'),
+            'funding/email/end.txt', {
+                'offer': self,
+                'is_win': self.is_win(),
+                'remaining': self.remaining(),
+                'current': self.current(),
+            })
+
+    def notify_near(self):
+        assert self.is_current()
+        sum_ = self.sum()
+        need = self.target - sum_
+        self.notify_all(
+            _('The fundraiser will end soon!'),
+            'funding/email/near.txt', {
+                'days': (self.end - date.today()).days + 1,
+                'offer': self,
+                'is_win': self.is_win(),
+                'sum': sum_,
+                'need': need,
+            })
+
+    def notify_published(self):
+        assert self.book is not None
+        self.notify_all(
+            _('The book you helped fund has been published.'),
+            'funding/email/published.txt', {
+                'offer': self,
+                'book': self.book,
+                'author': ", ".join(a[0] for a in self.book.related_info()['tags']['author']),
+                'current': self.current(),
+            })
+
 
 class Perk(models.Model):
     """ A perk offer.
 
 class Perk(models.Model):
     """ A perk offer.
@@ -134,30 +188,76 @@ class Funding(models.Model):
     """
     offer = models.ForeignKey(Offer, verbose_name=_('offer'))
     name = models.CharField(_('name'), max_length=127, blank=True)
     """
     offer = models.ForeignKey(Offer, verbose_name=_('offer'))
     name = models.CharField(_('name'), max_length=127, blank=True)
-    email = models.EmailField(_('email'), blank=True)
+    email = models.EmailField(_('email'), blank=True, db_index=True)
     amount = models.DecimalField(_('amount'), decimal_places=2, max_digits=10)
     payed_at = models.DateTimeField(_('payed at'), null=True, blank=True, db_index=True)
     perks = models.ManyToManyField(Perk, verbose_name=_('perks'), blank=True)
     language_code = models.CharField(max_length = 2, null = True, blank = True)
     amount = models.DecimalField(_('amount'), decimal_places=2, max_digits=10)
     payed_at = models.DateTimeField(_('payed at'), null=True, blank=True, db_index=True)
     perks = models.ManyToManyField(Perk, verbose_name=_('perks'), blank=True)
     language_code = models.CharField(max_length = 2, null = True, blank = True)
+    notifications = models.BooleanField(_('notifications'), default=True, db_index=True)
+    notify_key = models.CharField(max_length=32)
 
 
-    # Any additional info needed for perks?
+    class Meta:
+        verbose_name = _('funding')
+        verbose_name_plural = _('fundings')
+        ordering = ['-payed_at']
 
     @classmethod
     def payed(cls):
         """ QuerySet for all completed payments. """
         return cls.objects.exclude(payed_at=None)
 
 
     @classmethod
     def payed(cls):
         """ QuerySet for all completed payments. """
         return cls.objects.exclude(payed_at=None)
 
-    class Meta:
-        verbose_name = _('funding')
-        verbose_name_plural = _('fundings')
-        ordering = ['-payed_at']
-
     def __unicode__(self):
         return unicode(self.offer)
 
     def get_absolute_url(self):
         return reverse('funding_funding', args=[self.pk])
 
     def __unicode__(self):
         return unicode(self.offer)
 
     def get_absolute_url(self):
         return reverse('funding_funding', args=[self.pk])
 
+    def get_disable_notifications_url(self):
+        return "%s?%s" % (reverse("funding_disable_notifications"),
+            urlencode({
+                'email': self.email,
+                'key': self.notify_key,
+            }))
+
+    def save(self, *args, **kwargs):
+        if self.email and not self.notify_key:
+            self.notify_key = get_random_hash(self.email)
+        return super(Funding, self).save(*args, **kwargs)
+
+    @classmethod
+    def notify_funders(cls, subject, template_name, extra_context=None,
+                query_filter=None, payed_only=True):
+        funders = cls.objects.exclude(email="").filter(notifications=True)
+        if payed_only:
+            funders = funders.exclude(payed_at=None)
+        if query_filter is not None:
+            funders = funders.filter(query_filter)
+        emails = set()
+        for funder in funders:
+            if funder.email in emails:
+                continue
+            emails.add(funder.email)
+            funder.notify(subject, template_name, extra_context)
+
+    def notify(self, subject, template_name, extra_context=None):
+        context = {
+            'funding': self,
+            'site': Site.objects.get_current(),
+        }
+        context.update(extra_context)
+        with override(self.language_code or 'pl'):
+            send_mail(subject,
+                render_to_string(template_name, context),
+                getattr(settings, 'CONTACT_EMAIL', 'wolnelektury@nowoczesnapolska.org.pl'),
+                [self.email],
+                fail_silently=False
+            )
+
+    def disable_notifications(self):
+        """Disables all notifications for this e-mail address."""
+        type(self).objects.filter(email=self.email).update(notifications=False)
+
+
 # Register the Funding model with django-getpaid for payments.
 getpaid.register_to_payment(Funding, unique=False, related_name='payment')
 
 # Register the Funding model with django-getpaid for payments.
 getpaid.register_to_payment(Funding, unique=False, related_name='payment')
 
@@ -195,15 +295,8 @@ def payment_status_changed_listener(sender, instance, old_status, new_status, **
         instance.order.payed_at = datetime.now()
         instance.order.save()
         if instance.order.email:
         instance.order.payed_at = datetime.now()
         instance.order.save()
         if instance.order.email:
-            send_thank_you_email(instance.order.name, instance.order.email, instance.order.language_code)
+            instance.order.notify(
+                _('Thank you for your support!'),
+                'funding/email/thanks.txt'
+            )
 getpaid.signals.payment_status_changed.connect(payment_status_changed_listener)
 getpaid.signals.payment_status_changed.connect(payment_status_changed_listener)
-
-def send_thank_you_email(name, address, language_code):
-    with override(language_code or 'pl'):
-        send_mail(_('Thank you for your support!'), 
-                render_to_string('funding/email.txt', dict(name = name)),
-                getattr(settings, 'CONTACT_EMAIL', 'wolnelektury@nowoczesnapolska.org.pl'),
-                [address],
-                fail_silently=False
-                )
diff --git a/apps/funding/templates/funding/disable_notifications.html b/apps/funding/templates/funding/disable_notifications.html
new file mode 100755 (executable)
index 0000000..9123310
--- /dev/null
@@ -0,0 +1,34 @@
+{% extends "base.html" %}
+{% load i18n %}
+{% load fnp_share %}
+
+{% block titleextra %}{% trans "Payment failed" %}{% endblock %}
+
+{% block body %}
+
+<h1>{% trans "Disable notifications" %}</h1>
+<div class="white-box normal-text">
+
+{% if view.object.notifications %}
+
+<p>{% blocktrans with e=view.object.email %}Are you sure you want to disable notifications for address {{e}}?{% endblocktrans %}</p>
+<form method="post" action="">
+    <button>{% trans "Disable notifications" %}</button>
+</form>
+
+{% else %}
+
+<p>{% blocktrans with e=view.object.email %}Notifications for address {{e}} have been successfully disabled.{% endblocktrans %}</p>
+
+{% endif %}
+
+{% url 'funding_current' as current %}
+<p>
+{% blocktrans with current=current %}Return to the <a href="{{current}}">current fundraiser</a>.{% endblocktrans %}
+</p>
+
+
+</div>
+
+
+{% endblock %}
diff --git a/apps/funding/templates/funding/email.txt b/apps/funding/templates/funding/email.txt
deleted file mode 100644 (file)
index e548767..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{% load i18n %}
-
-{% trans 'Hi' %}{% if name %} {{name}}{% endif %},
-
-{% trans 'Thank you for your support - thanks to you we will set another book free.' %}{% if name %}
-
-{% trans 'The book will be supplemented with your name as a donor.' %}{% endif %} 
-
-{% blocktrans %}We will contact you to keep you informed about your perks,
-status changes to this fundraiser and the incoming ones that we plan to launch.{% endblocktrans %}
-
-{% blocktrans %}Cheers,
-Wolne Lektury team{% endblocktrans %}
diff --git a/apps/funding/templates/funding/email/base.txt b/apps/funding/templates/funding/email/base.txt
new file mode 100755 (executable)
index 0000000..1129549
--- /dev/null
@@ -0,0 +1,10 @@
+{% autoescape off %}{% load i18n %}{% trans 'Hi' %}{% if funding.name %} {{ funding.name }}{% endif %},
+{% block body %}
+{% endblock %}
+{% blocktrans %}Cheers,
+Wolne Lektury team{% endblocktrans %}
+
+-- 
+{% blocktrans %}If you don't want to receive any more updates, please visit this page:{% endblocktrans %}
+http://{{site.domain}}{{ funding.get_disable_notifications_url }}
+{% endautoescape %}
diff --git a/apps/funding/templates/funding/email/end.txt b/apps/funding/templates/funding/email/end.txt
new file mode 100755 (executable)
index 0000000..3f054e2
--- /dev/null
@@ -0,0 +1,42 @@
+{% extends "funding/email/base.txt" %}
+{% load i18n %}
+
+
+{% block body %}{% if is_win %}
+{% blocktrans %}we succesfully collected the full amount needed
+for the book you contributed to:{% endblocktrans %}
+
+  {{ offer.author }} – {{ offer.title }}
+  http://{{ site.domain }}{{ offer.get_absolute_url }}
+
+{% blocktrans %}We will now digitize it, develop and publish it in the library,
+in various formats, free for everyone.{% endblocktrans %}
+{% if funding.name %}
+{% blocktrans %}Your name will be included on the list of contributors, irrespectively
+of the amount of your contribution.{% endblocktrans %}
+{% endif %}{# funding.name #}{% if funding.perks.exists %}
+{% blocktrans %}We will contact you again about details needed
+to deliver your perks.{% endblocktrans %}
+{% endif %}{# funding.perks.exists #}{% if remaining %}
+{% blocktrans with r=remaining %}All of the money remaining after this fundraiser ({{ x }} PLN)
+will be spent on liberating other books still waiting for publication.{% endblocktrans %}
+{% blocktrans %}You can see how we're spending these funds on this page:{% endblocktrans %}
+http://{{ site.domain }}{% url 'funding_wlfund' %}
+{% endif %}{# remaining #}{% else %}{# !is_win #}
+{% blocktrans %}unfortunately, we were unable to collect the full amount needed
+for the book you contributed to:{% endblocktrans %}
+
+  {{ offer.author }} – {{ offer.title }}
+  http://{{ site.domain }}{{ offer.get_absolute_url }}
+{% if remaining %}
+{% blocktrans with x=remaining %}All of the money we collected in this fundraiser ({{ x }} PLN)
+will be spent on liberating other books still waiting for publication.{% endblocktrans %}
+{% blocktrans %}You can see how we're spending these funds on this page:{% endblocktrans %}
+http://{{ site.domain }}{% url 'funding_wlfund' %}
+{% endif %}{# remaining #}{% endif %}{# is_win #}{% if current %}
+{% blocktrans %}If you'd like to help liberate another book, or invite your friends
+to do so, we're currently raising money for:{% endblocktrans %}
+
+  {{ current.author }} – {{ current.title }}
+  http://{{ site.domain }}{% url 'funding_current' %}
+{% endif %}{% endblock %}
diff --git a/apps/funding/templates/funding/email/near.txt b/apps/funding/templates/funding/email/near.txt
new file mode 100755 (executable)
index 0000000..47537c1
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "funding/email/base.txt" %}
+{% load i18n %}
+
+{% block body %}
+{% blocktrans count days as d %}there's only {{ d }} day left until the end of the fundraiser for:
+{% plural %}There're only {{ d }} days left until the end of the fundraiser for:
+{% endblocktrans %}
+  {{ offer.author }} – {{ offer.title }}
+
+{% blocktrans with x=sum %}We managed to collect {{x}} PLN so far.{% endblocktrans %}
+{% if is_win %}
+{% blocktrans %}The fundraiser is a success already, but the more money
+we collect, the more other books we'll publish.{% endblocktrans %}
+{% else %}{% blocktrans with x=need %}We still need {{ x }} PLN more.{% endblocktrans %}
+{% endif %}
+{% trans "There's still time to let your friends know about the fundraiser!" %}
+http://{{ site.domain }}{% url 'funding_current' %}
+{% endblock %}
diff --git a/apps/funding/templates/funding/email/published.txt b/apps/funding/templates/funding/email/published.txt
new file mode 100755 (executable)
index 0000000..672efa2
--- /dev/null
@@ -0,0 +1,17 @@
+{% extends "funding/email/base.txt" %}
+{% load i18n %}
+{% block body %}
+{% blocktrans %}we have just published the book you contributed to:{% endblocktrans %}
+
+  {{ author }} – {{ offer.book.title }}
+  http://{{ site.domain }}{{ offer.book.get_absolute_url }}
+
+{% blocktrans %}Thanks to you, it is now available for free,
+in various formats, to everyone.{% endblocktrans %}
+{% if current %}
+{% blocktrans %}If you'd like to help liberate another book, or invite your friends
+to do so, we're currently raising money for:{% endblocktrans %}
+
+  {{ current.author }} – {{ current.title }}
+  http://{{ site.domain }}{% url 'funding_current' %}
+{% endif %}{% endblock %}
diff --git a/apps/funding/templates/funding/email/thanks.txt b/apps/funding/templates/funding/email/thanks.txt
new file mode 100644 (file)
index 0000000..f1bb085
--- /dev/null
@@ -0,0 +1,17 @@
+{% extends "funding/email/base.txt" %}
+{% load i18n %}
+
+
+{% block body %}
+{% trans 'Thank you for your support - thanks to you we will set another book free.' %}{% if funding.name %}
+
+{% trans 'The book will be supplemented with your name as a donor.' %}{% endif %} 
+{% if funding.perks.exists %}
+Skontaktujemy się z Tobą jeszcze w sprawie Twoich prezentów
+({% for perk in funding.perks.all %}{{ perk.name }}{% if not forloop.first %}, {% endif %}{% endfor %}).
+{% endif %}{# funding.perks.exists #}
+
+{% blocktrans %}We will contact you to keep you informed about
+status changes to this fundraiser and the upcoming ones that we plan
+to launch.{% endblocktrans %}
+{% endblock %}
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index c5631b0..aef4d28
@@ -43,7 +43,6 @@
         <div class="normal-text">
             <h3>{% trans "Support the publication" %}</h3>
             <form action="" method="post">
         <div class="normal-text">
             <h3>{% trans "Support the publication" %}</h3>
             <form action="" method="post">
-                {% csrf_token %}
                 <table>
                 {{ form.as_table }}
                 <tr><td></td><td>
                 <table>
                 {{ form.as_table }}
                 <tr><td></td><td>
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
index e92704d..f05bc1d 100644 (file)
@@ -6,7 +6,7 @@ from django.conf.urls import patterns, url, include
 
 from .models import Offer
 from .views import (WLFundView, OfferDetailView, OfferListView,
 
 from .models import Offer
 from .views import (WLFundView, OfferDetailView, OfferListView,
-                ThanksView, NoThanksView, CurrentView)
+                ThanksView, NoThanksView, CurrentView, DisableNotifications)
 
 
 urlpatterns = patterns('',
 
 
 urlpatterns = patterns('',
@@ -19,6 +19,8 @@ urlpatterns = patterns('',
     
     url(r'^dziekujemy/$', ThanksView.as_view(), name='funding_thanks'),
     url(r'^niepowodzenie/$', NoThanksView.as_view(), name='funding_nothanks'),
     
     url(r'^dziekujemy/$', ThanksView.as_view(), name='funding_thanks'),
     url(r'^niepowodzenie/$', NoThanksView.as_view(), name='funding_nothanks'),
+
+    url(r'^wylacz_email/$', DisableNotifications.as_view(), name='funding_disable_notifications'),
     
     url(r'^getpaid/', include('getpaid.urls')),
 )
     
     url(r'^getpaid/', include('getpaid.urls')),
 )
index bf2a073..581a64e 100644 (file)
@@ -8,6 +8,7 @@ from django.conf import settings
 from django.core.urlresolvers import reverse
 from django.http import Http404
 from django.shortcuts import redirect, get_object_or_404
 from django.core.urlresolvers import reverse
 from django.http import Http404
 from django.shortcuts import redirect, get_object_or_404
+from django.views.decorators.csrf import csrf_exempt
 from django.views.generic import TemplateView, FormView, DetailView, ListView
 import getpaid.backends.payu
 from getpaid.models import Payment
 from django.views.generic import TemplateView, FormView, DetailView, ListView
 import getpaid.backends.payu
 from getpaid.models import Payment
@@ -76,6 +77,7 @@ class OfferDetailView(FormView):
     template_name = "funding/offer_detail.html"
     backend = 'getpaid.backends.payu'
 
     template_name = "funding/offer_detail.html"
     backend = 'getpaid.backends.payu'
 
+    @csrf_exempt
     def dispatch(self, request, slug=None):
         if getattr(self, 'object', None) is None:
             if slug:
     def dispatch(self, request, slug=None):
         if getattr(self, 'object', None) is None:
             if slug:
@@ -109,6 +111,7 @@ class OfferDetailView(FormView):
 
 
 class CurrentView(OfferDetailView):
 
 
 class CurrentView(OfferDetailView):
+    @csrf_exempt
     def dispatch(self, request, slug=None):
         self.object = Offer.current()
         if self.object is None:
     def dispatch(self, request, slug=None):
         self.object = Offer.current()
         if self.object is None:
@@ -136,5 +139,20 @@ class ThanksView(TemplateView):
         ctx['funding_no_show_current'] = True
         return ctx
 
         ctx['funding_no_show_current'] = True
         return ctx
 
+
 class NoThanksView(TemplateView):
     template_name = "funding/no_thanks.html"
 class NoThanksView(TemplateView):
     template_name = "funding/no_thanks.html"
+
+
+class DisableNotifications(TemplateView):
+    template_name = "funding/disable_notifications.html"
+
+    @csrf_exempt
+    def dispatch(self, request):
+        self.object = get_object_or_404(Funding, 
+            email=request.GET.get('email'), notify_key=request.GET.get('key'))
+        return super(DisableNotifications, self).dispatch(request)
+
+    def post(self, *args, **kwargs):
+        self.object.disable_notifications()
+        return redirect(self.request.get_full_path())