From: Radek Czajka Date: Wed, 8 Aug 2012 13:27:54 +0000 (+0200) Subject: submit form X-Git-Url: https://git.mdrn.pl/prawokultury.git/commitdiff_plain/891a1e056e6066b28e000df16d69b21946338a57?ds=sidebyside;hp=-c submit form --- 891a1e056e6066b28e000df16d69b21946338a57 diff --git a/migdal/forms.py b/migdal/forms.py new file mode 100755 index 0000000..5a9d5d0 --- /dev/null +++ b/migdal/forms.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# This file is part of PrawoKultury, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. +# +from django import forms +from django.utils.translation import ugettext_lazy as _, get_language +from migdal.models import Entry +from migdal.settings import TYPE_SUBMIT +from slughifi import slughifi +from django.core.mail import mail_managers +from django import template + + +def get_submit_form(*args, **kwargs): + lang = get_language() + + class SubmitForm(forms.ModelForm): + class Meta: + model = Entry + fields = ['title_%s' % lang, 'lead_%s' % lang, + 'author', 'author_email', 'categories'] + required = ['title_%s' % lang] + + def __init__(self, *args, **kwargs): + super(SubmitForm, self).__init__(*args, **kwargs) + self.fields['title_%s' % lang].required = True + self.fields['lead_%s' % lang].required = True + + def clean(self): + data = super(SubmitForm, self).clean() + data['type'] = TYPE_SUBMIT + orig_slug = slughifi(data.get('title_%s' % lang, '')) + slug = orig_slug + number = 2 + while Entry.objects.filter(**{'slug_%s' % lang: slug}).exists(): + slug = "%s-%s" % (orig_slug, number) + number += 1 + data['slug_%s' % lang] = slug + self.cleaned_data = data + return data + + def save(self, *args, **kwargs): + entry = super(SubmitForm, self).save(commit=False) + # Something's wrong with markup fields, they choke on None here. + for f in 'lead_en', 'lead_pl', 'body_en', 'body_pl': + if getattr(entry, f) is None: + setattr(entry, f, '') + for f in 'slug_%s' % lang, 'type': + setattr(entry, f, self.cleaned_data[f]) + entry.save() + entry = super(SubmitForm, self).save(*args, **kwargs) + mail_managers(u"Nowy wpis", + template.loader.get_template( + 'migdal/mail/manager_new_entry.txt').render( + template.Context({'object': entry}))) + + return SubmitForm(*args, **kwargs) \ No newline at end of file diff --git a/migdal/helpers.py b/migdal/helpers.py index 4fec03a..1fdbdd4 100644 --- a/migdal/helpers.py +++ b/migdal/helpers.py @@ -12,6 +12,7 @@ from django.utils.translation import get_language, string_concat class EntryType(namedtuple('EntryType', 'db slug commentable on_main')): + __slots__ = () def __unicode__(self): return unicode(self.slug) diff --git a/migdal/locale/pl/LC_MESSAGES/django.mo b/migdal/locale/pl/LC_MESSAGES/django.mo index 52cedd2..b461c96 100644 Binary files a/migdal/locale/pl/LC_MESSAGES/django.mo and b/migdal/locale/pl/LC_MESSAGES/django.mo differ diff --git a/migdal/locale/pl/LC_MESSAGES/django.po b/migdal/locale/pl/LC_MESSAGES/django.po index 1055e0e..c737385 100644 --- a/migdal/locale/pl/LC_MESSAGES/django.po +++ b/migdal/locale/pl/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: django-migdal 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-08-07 17:28+0200\n" -"PO-Revision-Date: 2012-08-07 17:31+0100\n" +"POT-Creation-Date: 2012-08-08 15:23+0200\n" +"PO-Revision-Date: 2012-08-08 15:26+0100\n" "Last-Translator: Radek Czajka \n" "Language-Team: FNP \n" "Language: Polish\n" @@ -27,7 +27,7 @@ msgid "latest" msgstr "ostatnie" #: feeds.py:30 -#: models.py:48 +#: models.py:46 msgid "entries" msgstr "wpisy" @@ -40,66 +40,73 @@ msgid "category" msgstr "kategoria" #: models.py:16 -#: urls.py:32 -#: urls.py:34 +#: urls.py:35 +#: urls.py:37 msgid "categories" msgstr "kategorie" -#: models.py:40 +#: models.py:37 msgid "author" msgstr "autor" -#: models.py:41 +#: models.py:38 msgid "author email" msgstr "e-mail autora" -#: models.py:42 +#: models.py:39 +msgid "Used only to display gravatar and send notifications." +msgstr "Używany tylko do wyświetlenia gravatara i wysyłania powiadomień." + +#: models.py:40 msgid "image" msgstr "obrazek" -#: models.py:43 +#: models.py:41 msgid "promoted" msgstr "promowane" -#: models.py:47 +#: models.py:45 msgid "entry" msgstr "wpis" -#: models.py:72 -#: models.py:78 -msgid "title" -msgstr "tytuł" - -#: models.py:73 -#: models.py:79 -msgid "lead" -msgstr "lead" - -#: models.py:80 +#: models.py:68 msgid "needed" msgstr "potrzebne" -#: models.py:81 +#: models.py:69 msgid "Unneeded" msgstr "Niepotrzebne" -#: models.py:81 +#: models.py:69 msgid "Needed" msgstr "Potrzebne" -#: models.py:81 +#: models.py:69 msgid "Done" msgstr "Ukończone" -#: models.py:86 +#: models.py:75 +msgid "title" +msgstr "tytuł" + +#: models.py:76 +msgid "lead" +msgstr "lead" + +#: models.py:77 +#: models.py:79 +msgid "Use Textile syntax." +msgstr "Włączona składnia Textile." + +#: models.py:78 msgid "body" msgstr "treść" -#: models.py:87 +#: models.py:80 msgid "published" msgstr "opublikowane" -#: models.py:93 +#: models.py:85 msgid "file" msgstr "plik" @@ -115,6 +122,15 @@ msgstr "publikacje" msgid "info" msgstr "info" +#: urls.py:32 +#: urls.py:33 +msgid "submit" +msgstr "wyslij" + +#: urls.py:33 +msgid "thanks" +msgstr "dzieki" + #: templates/comments/migdal/entry/preview.html:19 msgid "Please correct the error below" msgid_plural "Please correct the errors below" @@ -154,6 +170,10 @@ msgstr "Kategoria" msgid "Latest news" msgstr "Ostatnie newsy" +#: templates/migdal/entry/entry_list.html:21 +msgid "Submit a new story." +msgstr "Przyślij nowego newsa." + #: templates/migdal/entry/entry_short.html:10 msgid "read more" msgstr "czytaj więcej" @@ -166,3 +186,21 @@ msgstr[0] "%(c)s komentarz" msgstr[1] "%(c)s komentarze" msgstr[2] "%(c)s komentarzy" +#: templates/migdal/entry/submit.html:7 +msgid "Submit new story" +msgstr "Przyślij nowego newsa." + +#: templates/migdal/entry/submit_thanks.html:7 +msgid "Thanks for submitting" +msgstr "Dziękujemy za zgłoszenie" + +#: templates/migdal/entry/submit_thanks.html:9 +msgid "" +"\n" +"Thank you for submitting this new story, it's waiting for moderation.\n" +"If you provided an email, we'll inform you about changes in it's status\n" +"and comments.\n" +msgstr "" +"\n" +"Dziękujemy za przysłanie nowego newsa, teraz czeka on na moderację.Jeśli podano adres e-mail, będziemy Cię informowali o zmianach statusui komentarzach\n" + diff --git a/migdal/migrations/0002_auto__chg_field_entry_slug_pl__chg_field_entry_title_pl__chg_field_ent.py b/migdal/migrations/0002_auto__chg_field_entry_slug_pl__chg_field_entry_title_pl__chg_field_ent.py new file mode 100644 index 0000000..1caced4 --- /dev/null +++ b/migdal/migrations/0002_auto__chg_field_entry_slug_pl__chg_field_entry_title_pl__chg_field_ent.py @@ -0,0 +1,79 @@ +# -*- 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): + + # Changing field 'Entry.slug_pl' + db.alter_column('migdal_entry', 'slug_pl', self.gf('django.db.models.fields.SlugField')(max_length=50, unique=True, null=True)) + + # Changing field 'Entry.title_pl' + db.alter_column('migdal_entry', 'title_pl', self.gf('django.db.models.fields.CharField')(max_length=255, null=True)) + + # Changing field 'Entry.lead_pl' + db.alter_column('migdal_entry', 'lead_pl', self.gf('markupfield.fields.MarkupField')(null=True, rendered_field=True)) + + def backwards(self, orm): + + # Changing field 'Entry.slug_pl' + db.alter_column('migdal_entry', 'slug_pl', self.gf('django.db.models.fields.SlugField')(default='', max_length=50, unique=True)) + + # Changing field 'Entry.title_pl' + db.alter_column('migdal_entry', 'title_pl', self.gf('django.db.models.fields.CharField')(default='', max_length=255)) + + # Changing field 'Entry.lead_pl' + db.alter_column('migdal_entry', 'lead_pl', self.gf('markupfield.fields.MarkupField')(default='', rendered_field=True)) + + models = { + 'migdal.attachment': { + 'Meta': {'object_name': 'Attachment'}, + 'entry': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['migdal.Entry']"}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'migdal.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slug_en': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'slug_pl': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}), + 'title_en': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64', 'db_index': 'True'}), + 'title_pl': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64', 'db_index': 'True'}) + }, + 'migdal.entry': { + 'Meta': {'ordering': "['-date']", 'object_name': 'Entry'}, + '_body_en_rendered': ('django.db.models.fields.TextField', [], {}), + '_body_pl_rendered': ('django.db.models.fields.TextField', [], {}), + '_lead_en_rendered': ('django.db.models.fields.TextField', [], {}), + '_lead_pl_rendered': ('django.db.models.fields.TextField', [], {}), + 'author': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'author_email': ('django.db.models.fields.EmailField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'body_en': ('markupfield.fields.MarkupField', [], {'null': 'True', 'rendered_field': 'True', 'blank': 'True'}), + 'body_en_markup_type': ('django.db.models.fields.CharField', [], {'default': "'textile_pl'", 'max_length': '30', 'blank': 'True'}), + 'body_pl': ('markupfield.fields.MarkupField', [], {'null': 'True', 'rendered_field': 'True', 'blank': 'True'}), + 'body_pl_markup_type': ('django.db.models.fields.CharField', [], {'default': "'textile_pl'", 'max_length': '30', 'blank': 'True'}), + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['migdal.Category']", 'null': 'True', 'blank': 'True'}), + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'lead_en': ('markupfield.fields.MarkupField', [], {'null': 'True', 'rendered_field': 'True', 'blank': 'True'}), + 'lead_en_markup_type': ('django.db.models.fields.CharField', [], {'default': "'textile_pl'", 'max_length': '30', 'blank': 'True'}), + 'lead_pl': ('markupfield.fields.MarkupField', [], {'null': 'True', 'rendered_field': 'True', 'blank': 'True'}), + 'lead_pl_markup_type': ('django.db.models.fields.CharField', [], {'default': "'textile_pl'", 'max_length': '30', 'blank': 'True'}), + 'needed_en': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1', 'db_index': 'True'}), + 'promo': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'published_en': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'published_pl': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'slug_en': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'slug_pl': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'title_en': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'title_pl': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'}) + } + } + + complete_apps = ['migdal'] \ No newline at end of file diff --git a/migdal/models.py b/migdal/models.py index d735ba6..90a2d3c 100644 --- a/migdal/models.py +++ b/migdal/models.py @@ -30,15 +30,13 @@ add_translatable(Category, { class Entry(models.Model): - #type = models.CharField(max_length=16, - # choices=((t.db, t.slug) for t in settings.TYPES), - # db_index=True) type = models.CharField(max_length=16, choices=((t.db, t.slug) for t in settings.TYPES), db_index=True) date = models.DateTimeField(auto_now_add=True, db_index=True) author = models.CharField(_('author'), max_length=128) - author_email = models.EmailField(_('author email'), max_length=128, null=True, blank=True) + author_email = models.EmailField(_('author email'), max_length=128, null=True, blank=True, + help_text=_('Used only to display gravatar and send notifications.')) image = models.ImageField(_('image'), upload_to='entry/image/', null=True, blank=True) promo = models.BooleanField(_('promoted'), default=False) categories = models.ManyToManyField(Category, null=True, blank=True) @@ -66,29 +64,23 @@ class Entry(models.Model): def get_type(self): return dict(settings.TYPES_DICT)[self.type] - -add_translatable(Entry, languages=settings.OBLIGATORY_LANGUAGES, fields={ - 'slug': models.SlugField(unique=True, db_index=True), - 'title': models.CharField(_('title'), max_length=255), - 'lead': MarkupField(_('lead'), markup_type='textile_pl'), -}) - add_translatable(Entry, languages=settings.OPTIONAL_LANGUAGES, fields={ - 'slug': models.SlugField(unique=True, db_index=True, null=True, blank=True), - 'title': models.CharField(_('title'), max_length=255, null=True, blank=True), - 'lead': MarkupField(_('lead'), markup_type='textile_pl', null=True, blank=True), 'needed': models.CharField(_('needed'), max_length=1, db_index=True, choices=( ('n', _('Unneeded')), ('w', _('Needed')), ('y', _('Done'))), default='n'), }) add_translatable(Entry, { - 'body': MarkupField(_('body'), markup_type='textile_pl', null=True, blank=True), + 'slug': models.SlugField(unique=True, db_index=True, null=True, blank=True), + 'title': models.CharField(_('title'), max_length=255, null=True, blank=True), + 'lead': MarkupField(_('lead'), markup_type='textile_pl', null=True, blank=True, + help_text=_('Use Textile syntax.')), + 'body': MarkupField(_('body'), markup_type='textile_pl', null=True, blank=True, + help_text=_('Use Textile syntax.')), 'published': models.BooleanField(_('published'), default=False), }) - class Attachment(models.Model): file = models.FileField(_('file'), upload_to='entry/attach/') entry = models.ForeignKey(Entry) diff --git a/migdal/settings.py b/migdal/settings.py index 4331c07..3d5bd01 100644 --- a/migdal/settings.py +++ b/migdal/settings.py @@ -22,7 +22,8 @@ TYPES = app_setting('MIGDAL_TYPES', ( )) TYPES_DICT = dict((t.db, t) for t in TYPES) TYPES_ON_MAIN = tuple(t.db for t in TYPES if t.on_main) -# FIXME: if only news is on_main, `news/` should either throw 404 or redirect to main +TYPE_SUBMIT = 'news' + LANGUAGES = app_setting('MIGDAL_LANGUAGES', settings.LANGUAGES) LANGUAGE_CODE = app_setting('MIGDAL_LANGUAGE_CODE', settings.LANGUAGE_CODE) diff --git a/migdal/templates/django_comments_xtd/email_followup_comment.html b/migdal/templates/django_comments_xtd/email_followup_comment.html new file mode 100644 index 0000000..1987906 --- /dev/null +++ b/migdal/templates/django_comments_xtd/email_followup_comment.html @@ -0,0 +1,24 @@ +{% load i18n %} +

{{ user_name }},

+ +

Pojawił się nowy komentarz w wątku z Twoim udziałem.

+

(There is a new comment following up yours.)

+ +

+{% if content_object.published_pl %}{% language 'pl' %} + „{{ content_object.title }}” +{% endlanguage %}{% endif %} +{% if content_object.published_en %}{% language 'en' %} +
+ “{{ content_object.title}}

+{% endlanguage %}{% endif %} +

+ +

{{ comment.name }}, {{ comment.submit_date|date:"SHORT_DATE_FORMAT" }}:

+
+{{ comment.comment }} +
+ +

--
+{{ site }} +

diff --git a/migdal/templates/django_comments_xtd/email_followup_comment.txt b/migdal/templates/django_comments_xtd/email_followup_comment.txt index 7d9df1d..a1ca8f1 100755 --- a/migdal/templates/django_comments_xtd/email_followup_comment.txt +++ b/migdal/templates/django_comments_xtd/email_followup_comment.txt @@ -1 +1,18 @@ -POWIADOMIENIE \ No newline at end of file +{% load i18n %}{{ user_name }}, + +Pojawił się nowy komentarz w wątku z Twoim udziałem. +(There is a new comment following up yours.) + +{% if content_object.published_pl %}{% language 'pl' %}Polska wersja: „{{ content_object.title }}” + http://{{ site.domain }}{{ content_object.get_absolute_url }}{% endlanguage %}{% endif %} +{% if content_object.published_en %}{% language 'en' %}English version: “{{ content_object.title }}” + http://{{ site.domain }}{{ content_object.get_absolute_url }}{% endlanguage %}{% endif %} + + +{{ comment.name }}, {{ comment.submit_date|date:"SHORT_DATE_FORMAT" }}: +-------- +{{ comment.comment }} + + +-- +{{ site }} diff --git a/migdal/templates/migdal/entry/entry_begin.html b/migdal/templates/migdal/entry/entry_begin.html index fbec320..351148e 100755 --- a/migdal/templates/migdal/entry/entry_begin.html +++ b/migdal/templates/migdal/entry/entry_begin.html @@ -1,3 +1,4 @@ +{% load i18n %} {% load gravatar %} @@ -6,6 +7,20 @@
{{ object.date }} {{ object.author }} + +{% if request.LANGUAGE_CODE == 'pl' %} + {% if object.published_en %} + {% language 'en' %} + English version + {% endlanguage %} + {% endif %} +{% elif object.published_pl %} + {% language 'pl' %} + polska wersja + {% endlanguage %} +{% endif %} + + {% for category in object.categories.all %} {{ category }} {% endfor %} diff --git a/migdal/templates/migdal/entry/entry_detail.html b/migdal/templates/migdal/entry/entry_detail.html index 6ef926a..9812a59 100755 --- a/migdal/templates/migdal/entry/entry_detail.html +++ b/migdal/templates/migdal/entry/entry_detail.html @@ -12,7 +12,7 @@ {% if entry.get_type.commentable %} {% render_comment_list for entry %} - {% render_comment_form for entry %} + {% entry_comment_form entry %} {% endif %}
diff --git a/migdal/templates/migdal/entry/entry_list.html b/migdal/templates/migdal/entry/entry_list.html index d68673b..9f3ec41 100755 --- a/migdal/templates/migdal/entry/entry_list.html +++ b/migdal/templates/migdal/entry/entry_list.html @@ -17,6 +17,10 @@ {% endif %} +{% if submit %} + {% trans "Submit a new story." %} +{% endif %} + {% for object in object_list %} {% entry_short object %} {% endfor %} diff --git a/migdal/templates/migdal/entry/info/entry_begin.html b/migdal/templates/migdal/entry/info/entry_begin.html index 7544b6f..256a38d 100755 --- a/migdal/templates/migdal/entry/info/entry_begin.html +++ b/migdal/templates/migdal/entry/info/entry_begin.html @@ -1,4 +1,21 @@

{{ object.title }}

+ +
+{% if request.LANGUAGE_CODE == 'pl' %} + {% if object.published_en %} + {% language 'en' %} + English version + {% endlanguage %} + {% endif %} +{% elif object.published_pl %} + {{ request.LANGUAGE_CODE }} + {% language 'pl' %} + polska wersja + {% endlanguage %} +{% endif %} +
+ + {% if object.image %} {% endif %} diff --git a/migdal/templates/migdal/entry/submit.html b/migdal/templates/migdal/entry/submit.html new file mode 100755 index 0000000..14906ba --- /dev/null +++ b/migdal/templates/migdal/entry/submit.html @@ -0,0 +1,19 @@ +{% extends "base.html" %} +{% load url from future %} +{% load i18n %} + +{% block "body" %} + +

{% trans "Submit new story" %}

+ + +
+ {% csrf_token %} + + {{ submit_form.as_table }} + +
+
+ + +{% endblock %} \ No newline at end of file diff --git a/migdal/templates/migdal/entry/submit_thanks.html b/migdal/templates/migdal/entry/submit_thanks.html new file mode 100755 index 0000000..48a55d1 --- /dev/null +++ b/migdal/templates/migdal/entry/submit_thanks.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} +{% load url from future %} +{% load i18n %} + +{% block "body" %} + +

{% trans "Thanks for submitting" %}

+ +{% blocktrans %} +Thank you for submitting this new story, it's waiting for moderation. +If you provided an email, we'll inform you about changes in it's status +and comments. +{% endblocktrans %} + + + +{% endblock %} \ No newline at end of file diff --git a/migdal/templates/migdal/mail/manager_new_entry.txt b/migdal/templates/migdal/mail/manager_new_entry.txt new file mode 100755 index 0000000..59703e2 --- /dev/null +++ b/migdal/templates/migdal/mail/manager_new_entry.txt @@ -0,0 +1,14 @@ +{% load url from future %}W serwisie pojawił się nowy wpis. +http://localhost:8000{% url 'admin:migdal_entry_change' object.pk %} + +Autor: {{ object.author|default_if_none:"" }} +E-mail: {{ object.author_email|default_if_none:"" }} +Tytuł [pl]: {{ object.title_pl|default_if_none:"" }} +Tytuł [en]: {{ object.title_en|default_if_none:"" }} +Kategorie: {{ object.categories.all|join:", " }} + +--- +{{ object.lead_pl.raw }} +--- +{{ object.lead_en.raw }} +--- \ No newline at end of file diff --git a/migdal/templatetags/migdal_tags.py b/migdal/templatetags/migdal_tags.py index b9722b6..5578c5d 100644 --- a/migdal/templatetags/migdal_tags.py +++ b/migdal/templatetags/migdal_tags.py @@ -3,29 +3,30 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # from django_comments_xtd.models import XtdComment +from django.contrib import comments from django import template from migdal.models import Category register = template.Library() -@register.simple_tag -def entry_begin(entry): +@register.simple_tag(takes_context=True) +def entry_begin(context, entry): t = template.loader.select_template(( 'migdal/entry/%s/entry_begin.html' % entry.type, 'migdal/entry/entry_begin.html', )) - context = {'object': entry} + context.update({'object': entry}) return t.render(template.Context(context)) -@register.simple_tag -def entry_short(entry): +@register.simple_tag(takes_context=True) +def entry_short(context, entry): t = template.loader.select_template(( 'migdal/entry/%s/entry_short.html' % entry.type, 'migdal/entry/entry_short.html', )) - context = {'object': entry} + context.update({'object': entry}) return t.render(template.Context(context)) @@ -39,3 +40,11 @@ def categories(context): def last_comments(limit=10): return {'object_list': XtdComment.objects.filter(is_public=True, is_removed=False).order_by('-submit_date')[:limit]} + + +@register.inclusion_tag(['comments/form.html']) +def entry_comment_form(entry): + return { + 'form': comments.get_form()(entry), + 'next': entry.get_absolute_url(), + } \ No newline at end of file diff --git a/migdal/urls.py b/migdal/urls.py index b600cef..dec95bd 100644 --- a/migdal/urls.py +++ b/migdal/urls.py @@ -28,6 +28,9 @@ urlpatterns = i18n_patterns('', # main page url(r'^$', 'migdal.views.entry_list', name='migdal_main'), url(r'^rss.xml$', feeds.EntriesFeed(), name='migdal_main_feed'), + # submit new entry + url(string_concat(r'^', _('submit'), r'/$'), 'migdal.views.submit', name='migdal_submit'), + url(string_concat(r'^', _('submit'), r'/', _('thanks'), r'$'), 'migdal.views.submit_thanks', name='migdal_submit_thanks'), # category url(string_concat(r'^', _('categories'), r'/(?P[^/]*)/$'), 'migdal.views.entry_list', name='migdal_category'), diff --git a/migdal/views.py b/migdal/views.py index d705d34..42a2a39 100644 --- a/migdal/views.py +++ b/migdal/views.py @@ -2,33 +2,39 @@ # This file is part of PrawoKultury, licensed under GNU Affero GPLv3 or later. # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # -from django.shortcuts import get_object_or_404, render +from django.shortcuts import get_object_or_404, render, redirect from migdal import api +from migdal.forms import get_submit_form from migdal.models import Category, Entry -from migdal.settings import TYPES_DICT +from migdal.settings import TYPES_DICT, TYPES_ON_MAIN, TYPE_SUBMIT def entry_list(request, type_db=None, category_slug=None): lang = request.LANGUAGE_CODE templates = ["migdal/entry/entry_list.html"] - if category_slug: - category = get_object_or_404(Category, **{'slug_%s' % lang: category_slug}) - else: - category = None if type_db: + if TYPES_ON_MAIN == (type_db,): + return redirect('migdal_main') entry_type = TYPES_DICT[type_db] - # TODO: if it's the only on main, redirect to main templates = ["migdal/entry/%s/entry_list.html" % type_db] + templates + submit = type_db == TYPE_SUBMIT else: + submit = TYPES_ON_MAIN == (TYPE_SUBMIT,) entry_type = None + if category_slug: + category = get_object_or_404(Category, **{'slug_%s' % lang: category_slug}) + else: + category = None + object_list = api.entry_list(entry_type=entry_type, category=category) return render(request, templates, { 'object_list': object_list, 'category': category, 'entry_type': entry_type, + 'submit': submit, }) @@ -42,3 +48,20 @@ def entry(request, type_db, slug): if type_db is not None: templates = ["migdal/entry/%s/entry_detail.html" % type_db] + templates return render(request, templates, {'entry': entry}) + + +def submit(request): + if request.method == 'POST': + submit_form = get_submit_form(request.POST) + if submit_form.is_valid(): + submit_form.save() + return redirect('migdal_submit_thanks') + else: + submit_form = get_submit_form() + + return render(request, 'migdal/entry/submit.html', { + 'submit_form': submit_form, + }) + +def submit_thanks(request): + return render(request, "migdal/entry/submit_thanks.html") \ No newline at end of file diff --git a/slughifi.py b/slughifi.py new file mode 100644 index 0000000..fe5c9e3 --- /dev/null +++ b/slughifi.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +import re +from types import UnicodeType + +from django.template.defaultfilters import slugify + +# default unicode character mapping ( you may not see some chars, leave as is ) +char_map = {u'À': 'A', u'Á': 'A', u'Â': 'A', u'Ã': 'A', u'Ä': 'Ae', u'Å': 'A', u'Æ': 'A', u'Ā': 'A', u'Ą': 'A', u'Ă': 'A', u'Ç': 'C', u'Ć': 'C', u'Č': 'C', u'Ĉ': 'C', u'Ċ': 'C', u'Ď': 'D', u'Đ': 'D', u'È': 'E', u'É': 'E', u'Ê': 'E', u'Ë': 'E', u'Ē': 'E', u'Ę': 'E', u'Ě': 'E', u'Ĕ': 'E', u'Ė': 'E', u'Ĝ': 'G', u'Ğ': 'G', u'Ġ': 'G', u'Ģ': 'G', u'Ĥ': 'H', u'Ħ': 'H', u'Ì': 'I', u'Í': 'I', u'Î': 'I', u'Ï': 'I', u'Ī': 'I', u'Ĩ': 'I', u'Ĭ': 'I', u'Į': 'I', u'İ': 'I', u'IJ': 'IJ', u'Ĵ': 'J', u'Ķ': 'K', u'Ľ': 'K', u'Ĺ': 'K', u'Ļ': 'K', u'Ŀ': 'K', u'Ł': 'L', u'Ñ': 'N', u'Ń': 'N', u'Ň': 'N', u'Ņ': 'N', u'Ŋ': 'N', u'Ò': 'O', u'Ó': 'O', u'Ô': 'O', u'Õ': 'O', u'Ö': 'Oe', u'Ø': 'O', u'Ō': 'O', u'Ő': 'O', u'Ŏ': 'O', u'Œ': 'OE', u'Ŕ': 'R', u'Ř': 'R', u'Ŗ': 'R', u'Ś': 'S', u'Ş': 'S', u'Ŝ': 'S', u'Ș': 'S', u'Š': 'S', u'Ť': 'T', u'Ţ': 'T', u'Ŧ': 'T', u'Ț': 'T', u'Ù': 'U', u'Ú': 'U', u'Û': 'U', u'Ü': 'Ue', u'Ū': 'U', u'Ů': 'U', u'Ű': 'U', u'Ŭ': 'U', u'Ũ': 'U', u'Ų': 'U', u'Ŵ': 'W', u'Ŷ': 'Y', u'Ÿ': 'Y', u'Ý': 'Y', u'Ź': 'Z', u'Ż': 'Z', u'Ž': 'Z', u'à': 'a', u'á': 'a', u'â': 'a', u'ã': 'a', u'ä': 'ae', u'ā': 'a', u'ą': 'a', u'ă': 'a', u'å': 'a', u'æ': 'ae', u'ç': 'c', u'ć': 'c', u'č': 'c', u'ĉ': 'c', u'ċ': 'c', u'ď': 'd', u'đ': 'd', u'è': 'e', u'é': 'e', u'ê': 'e', u'ë': 'e', u'ē': 'e', u'ę': 'e', u'ě': 'e', u'ĕ': 'e', u'ė': 'e', u'ƒ': 'f', u'ĝ': 'g', u'ğ': 'g', u'ġ': 'g', u'ģ': 'g', u'ĥ': 'h', u'ħ': 'h', u'ì': 'i', u'í': 'i', u'î': 'i', u'ï': 'i', u'ī': 'i', u'ĩ': 'i', u'ĭ': 'i', u'į': 'i', u'ı': 'i', u'ij': 'ij', u'ĵ': 'j', u'ķ': 'k', u'ĸ': 'k', u'ł': 'l', u'ľ': 'l', u'ĺ': 'l', u'ļ': 'l', u'ŀ': 'l', u'ñ': 'n', u'ń': 'n', u'ň': 'n', u'ņ': 'n', u'ʼn': 'n', u'ŋ': 'n', u'ò': 'o', u'ó': 'o', u'ô': 'o', u'õ': 'o', u'ö': 'oe', u'ø': 'o', u'ō': 'o', u'ő': 'o', u'ŏ': 'o', u'œ': 'oe', u'ŕ': 'r', u'ř': 'r', u'ŗ': 'r', u'ś': 's', u'š': 's', u'ť': 't', u'ù': 'u', u'ú': 'u', u'û': 'u', u'ü': 'ue', u'ū': 'u', u'ů': 'u', u'ű': 'u', u'ŭ': 'u', u'ũ': 'u', u'ų': 'u', u'ŵ': 'w', u'ÿ': 'y', u'ý': 'y', u'ŷ': 'y', u'ż': 'z', u'ź': 'z', u'ž': 'z', u'ß': 'ss', u'ſ': 'ss', u'Α': 'A', u'Ά': 'A', u'Ἀ': 'A', u'Ἁ': 'A', u'Ἂ': 'A', u'Ἃ': 'A', u'Ἄ': 'A', u'Ἅ': 'A', u'Ἆ': 'A', u'Ἇ': 'A', u'ᾈ': 'A', u'ᾉ': 'A', u'ᾊ': 'A', u'ᾋ': 'A', u'ᾌ': 'A', u'ᾍ': 'A', u'ᾎ': 'A', u'ᾏ': 'A', u'Ᾰ': 'A', u'Ᾱ': 'A', u'Ὰ': 'A', u'Ά': 'A', u'ᾼ': 'A', u'Β': 'B', u'Γ': 'G', u'Δ': 'D', u'Ε': 'E', u'Έ': 'E', u'Ἐ': 'E', u'Ἑ': 'E', u'Ἒ': 'E', u'Ἓ': 'E', u'Ἔ': 'E', u'Ἕ': 'E', u'Έ': 'E', u'Ὲ': 'E', u'Ζ': 'Z', u'Η': 'I', u'Ή': 'I', u'Ἠ': 'I', u'Ἡ': 'I', u'Ἢ': 'I', u'Ἣ': 'I', u'Ἤ': 'I', u'Ἥ': 'I', u'Ἦ': 'I', u'Ἧ': 'I', u'ᾘ': 'I', u'ᾙ': 'I', u'ᾚ': 'I', u'ᾛ': 'I', u'ᾜ': 'I', u'ᾝ': 'I', u'ᾞ': 'I', u'ᾟ': 'I', u'Ὴ': 'I', u'Ή': 'I', u'ῌ': 'I', u'Θ': 'TH', u'Ι': 'I', u'Ί': 'I', u'Ϊ': 'I', u'Ἰ': 'I', u'Ἱ': 'I', u'Ἲ': 'I', u'Ἳ': 'I', u'Ἴ': 'I', u'Ἵ': 'I', u'Ἶ': 'I', u'Ἷ': 'I', u'Ῐ': 'I', u'Ῑ': 'I', u'Ὶ': 'I', u'Ί': 'I', u'Κ': 'K', u'Λ': 'L', u'Μ': 'M', u'Ν': 'N', u'Ξ': 'KS', u'Ο': 'O', u'Ό': 'O', u'Ὀ': 'O', u'Ὁ': 'O', u'Ὂ': 'O', u'Ὃ': 'O', u'Ὄ': 'O', u'Ὅ': 'O', u'Ὸ': 'O', u'Ό': 'O', u'Π': 'P', u'Ρ': 'R', u'Ῥ': 'R', u'Σ': 'S', u'Τ': 'T', u'Υ': 'Y', u'Ύ': 'Y', u'Ϋ': 'Y', u'Ὑ': 'Y', u'Ὓ': 'Y', u'Ὕ': 'Y', u'Ὗ': 'Y', u'Ῠ': 'Y', u'Ῡ': 'Y', u'Ὺ': 'Y', u'Ύ': 'Y', u'Φ': 'F', u'Χ': 'X', u'Ψ': 'PS', u'Ω': 'O', u'Ώ': 'O', u'Ὠ': 'O', u'Ὡ': 'O', u'Ὢ': 'O', u'Ὣ': 'O', u'Ὤ': 'O', u'Ὥ': 'O', u'Ὦ': 'O', u'Ὧ': 'O', u'ᾨ': 'O', u'ᾩ': 'O', u'ᾪ': 'O', u'ᾫ': 'O', u'ᾬ': 'O', u'ᾭ': 'O', u'ᾮ': 'O', u'ᾯ': 'O', u'Ὼ': 'O', u'Ώ': 'O', u'ῼ': 'O', u'α': 'a', u'ά': 'a', u'ἀ': 'a', u'ἁ': 'a', u'ἂ': 'a', u'ἃ': 'a', u'ἄ': 'a', u'ἅ': 'a', u'ἆ': 'a', u'ἇ': 'a', u'ᾀ': 'a', u'ᾁ': 'a', u'ᾂ': 'a', u'ᾃ': 'a', u'ᾄ': 'a', u'ᾅ': 'a', u'ᾆ': 'a', u'ᾇ': 'a', u'ὰ': 'a', u'ά': 'a', u'ᾰ': 'a', u'ᾱ': 'a', u'ᾲ': 'a', u'ᾳ': 'a', u'ᾴ': 'a', u'ᾶ': 'a', u'ᾷ': 'a', u'β': 'b', u'γ': 'g', u'δ': 'd', u'ε': 'e', u'έ': 'e', u'ἐ': 'e', u'ἑ': 'e', u'ἒ': 'e', u'ἓ': 'e', u'ἔ': 'e', u'ἕ': 'e', u'ὲ': 'e', u'έ': 'e', u'ζ': 'z', u'η': 'i', u'ή': 'i', u'ἠ': 'i', u'ἡ': 'i', u'ἢ': 'i', u'ἣ': 'i', u'ἤ': 'i', u'ἥ': 'i', u'ἦ': 'i', u'ἧ': 'i', u'ᾐ': 'i', u'ᾑ': 'i', u'ᾒ': 'i', u'ᾓ': 'i', u'ᾔ': 'i', u'ᾕ': 'i', u'ᾖ': 'i', u'ᾗ': 'i', u'ὴ': 'i', u'ή': 'i', u'ῂ': 'i', u'ῃ': 'i', u'ῄ': 'i', u'ῆ': 'i', u'ῇ': 'i', u'θ': 'th', u'ι': 'i', u'ί': 'i', u'ϊ': 'i', u'ΐ': 'i', u'ἰ': 'i', u'ἱ': 'i', u'ἲ': 'i', u'ἳ': 'i', u'ἴ': 'i', u'ἵ': 'i', u'ἶ': 'i', u'ἷ': 'i', u'ὶ': 'i', u'ί': 'i', u'ῐ': 'i', u'ῑ': 'i', u'ῒ': 'i', u'ΐ': 'i', u'ῖ': 'i', u'ῗ': 'i', u'κ': 'k', u'λ': 'l', u'μ': 'm', u'ν': 'n', u'ξ': 'ks', u'ο': 'o', u'ό': 'o', u'ὀ': 'o', u'ὁ': 'o', u'ὂ': 'o', u'ὃ': 'o', u'ὄ': 'o', u'ὅ': 'o', u'ὸ': 'o', u'ό': 'o', u'π': 'p', u'ρ': 'r', u'ῤ': 'r', u'ῥ': 'r', u'σ': 's', u'ς': 's', u'τ': 't', u'υ': 'y', u'ύ': 'y', u'ϋ': 'y', u'ΰ': 'y', u'ὐ': 'y', u'ὑ': 'y', u'ὒ': 'y', u'ὓ': 'y', u'ὔ': 'y', u'ὕ': 'y', u'ὖ': 'y', u'ὗ': 'y', u'ὺ': 'y', u'ύ': 'y', u'ῠ': 'y', u'ῡ': 'y', u'ῢ': 'y', u'ΰ': 'y', u'ῦ': 'y', u'ῧ': 'y', u'φ': 'f', u'χ': 'x', u'ψ': 'ps', u'ω': 'o', u'ώ': 'o', u'ὠ': 'o', u'ὡ': 'o', u'ὢ': 'o', u'ὣ': 'o', u'ὤ': 'o', u'ὥ': 'o', u'ὦ': 'o', u'ὧ': 'o', u'ᾠ': 'o', u'ᾡ': 'o', u'ᾢ': 'o', u'ᾣ': 'o', u'ᾤ': 'o', u'ᾥ': 'o', u'ᾦ': 'o', u'ᾧ': 'o', u'ὼ': 'o', u'ώ': 'o', u'ῲ': 'o', u'ῳ': 'o', u'ῴ': 'o', u'ῶ': 'o', u'ῷ': 'o', u'¨': '', u'΅': '', u'᾿': '', u'῾': '', u'῍': '', u'῝': '', u'῎': '', u'῞': '', u'῏': '', u'῟': '', u'῀': '', u'῁': '', u'΄': '', u'΅': '', u'`': '', u'῭': '', u'ͺ': '', u'᾽': '', u'А': 'A', u'Б': 'B', u'В': 'V', u'Г': 'G', u'Д': 'D', u'Е': 'E', u'Ё': 'E', u'Ж': 'ZH', u'З': 'Z', u'И': 'I', u'Й': 'I', u'К': 'K', u'Л': 'L', u'М': 'M', u'Н': 'N', u'О': 'O', u'П': 'P', u'Р': 'R', u'С': 'S', u'Т': 'T', u'У': 'U', u'Ф': 'F', u'Х': 'KH', u'Ц': 'TS', u'Ч': 'CH', u'Ш': 'SH', u'Щ': 'SHCH', u'Ы': 'Y', u'Э': 'E', u'Ю': 'YU', u'Я': 'YA', u'а': 'A', u'б': 'B', u'в': 'V', u'г': 'G', u'д': 'D', u'е': 'E', u'ё': 'E', u'ж': 'ZH', u'з': 'Z', u'и': 'I', u'й': 'I', u'к': 'K', u'л': 'L', u'м': 'M', u'н': 'N', u'о': 'O', u'п': 'P', u'р': 'R', u'с': 'S', u'т': 'T', u'у': 'U', u'ф': 'F', u'х': 'KH', u'ц': 'TS', u'ч': 'CH', u'ш': 'SH', u'щ': 'SHCH', u'ы': 'Y', u'э': 'E', u'ю': 'YU', u'я': 'YA', u'Ъ': '', u'ъ': '', u'Ь': '', u'ь': '', u'ð': 'd', u'Ð': 'D', u'þ': 'th', u'Þ': 'TH', + u'ა': 'a', u'ბ': 'b', u'გ': 'g', u'დ': 'd', u'ე': 'e', u'ვ': 'v', u'ზ': 'z', u'თ': 't', u'ი': 'i', u'კ': 'k', u'ლ': 'l', u'მ': 'm', u'ნ': 'n', u'ო': 'o', u'პ': 'p', u'ჟ': 'zh', u'რ': 'r', u'ს': 's', u'ტ': 't', u'უ': 'u', u'ფ': 'p', u'ქ': 'k', u'ღ': 'gh', u'ყ': 'q', u'შ': 'sh', u'ჩ': 'ch', u'ც': 'ts', u'ძ': 'dz', u'წ': 'ts', u'ჭ': 'ch', u'ხ': 'kh', u'ჯ': 'j', u'ჰ': 'h' } + +def replace_char(m): + char = m.group() + if char_map.has_key(char): + return char_map[char] + else: + return char + +def slughifi(value, do_slugify=True, overwrite_char_map={}): + """ + High Fidelity slugify - slughifi.py, v 0.1 + + Examples : + + >>> text = 'C\'est déjà l\'été.' + + >>> slughifi(text) + 'cest-deja-lete' + + >>> slughifi(text, overwrite_char_map={u'\'': '-',}) + 'c-est-deja-l-ete' + + >>> slughifi(text, do_slugify=False) + "C'est deja l'ete." + + # Normal slugify removes accented characters + >>> slugify(text) + 'cest-dj-lt' + + """ + + # unicodification + if type(value) != UnicodeType: + value = unicode(value, 'utf-8', 'ignore') + + # overwrite chararcter mapping + char_map.update(overwrite_char_map) + + # try to replace chars + value = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value) + + # apply django default slugify + if do_slugify: + value = slugify(value) + + return value.encode('ascii', 'ignore') +