From 548d9fe735b1c4f04c296f01a3bf73149f627005 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 10 Jan 2013 13:23:46 +0100 Subject: [PATCH] some work on questions --- prawokultury/settings.d/30-apps.py | 1 + prawokultury/urls.py | 1 + questions/__init__.py | 0 questions/admin.py | 22 +++++++ questions/forms.py | 8 +++ questions/migrations/0001_initial.py | 54 ++++++++++++++++ questions/migrations/__init__.py | 0 questions/models.py | 61 +++++++++++++++++++ .../templates/questions/answered_mail.txt | 19 ++++++ .../templates/questions/question_detail.html | 11 ++++ .../templates/questions/question_form.html | 18 ++++++ .../templates/questions/question_list.html | 18 ++++++ .../templates/questions/question_thanks.html | 9 +++ questions/urls.py | 29 +++++++++ questions/views.py | 13 ++++ requirements.txt | 4 +- 16 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 questions/__init__.py create mode 100755 questions/admin.py create mode 100755 questions/forms.py create mode 100644 questions/migrations/0001_initial.py create mode 100644 questions/migrations/__init__.py create mode 100644 questions/models.py create mode 100755 questions/templates/questions/answered_mail.txt create mode 100755 questions/templates/questions/question_detail.html create mode 100755 questions/templates/questions/question_form.html create mode 100755 questions/templates/questions/question_list.html create mode 100755 questions/templates/questions/question_thanks.html create mode 100755 questions/urls.py create mode 100644 questions/views.py diff --git a/prawokultury/settings.d/30-apps.py b/prawokultury/settings.d/30-apps.py index 0eb98e1..4ae5e23 100644 --- a/prawokultury/settings.d/30-apps.py +++ b/prawokultury/settings.d/30-apps.py @@ -4,6 +4,7 @@ INSTALLED_APPS = ( 'menu', 'events', 'migdal', + 'questions', 'gravatar', 'south', diff --git a/prawokultury/urls.py b/prawokultury/urls.py index 1e2683b..761afeb 100644 --- a/prawokultury/urls.py +++ b/prawokultury/urls.py @@ -30,6 +30,7 @@ if 'django_cas' in settings.INSTALLED_APPS: urlpatterns += i18n_patterns('', url(string_concat(r'^', _('events'), r'/'), include('events.urls')), url(r'^comments/', include('django_comments_xtd.urls')), + url(r'^prawnik/', include('questions.urls')), ) + migdal_urlpatterns if settings.DEBUG: diff --git a/questions/__init__.py b/questions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/questions/admin.py b/questions/admin.py new file mode 100755 index 0000000..d8676dc --- /dev/null +++ b/questions/admin.py @@ -0,0 +1,22 @@ +from django.contrib import admin +from .models import Question + +class QuestionAdmin(admin.ModelAdmin): + model = Question + list_filter = ('approved', 'answered', 'published') + list_display = ('question', 'email', 'created_at', 'approved', 'answered', 'published') + date_hierarchy = 'created_at' + fields = ( + ('email', 'created_at'), + 'question', + 'approved', + 'edited_question', + 'answer', + ('answered', 'answered_at'), + ('published', 'published_at'), + + ) + readonly_fields = ['created_at', 'answered_at', 'published_at'] + + +admin.site.register(Question, QuestionAdmin) diff --git a/questions/forms.py b/questions/forms.py new file mode 100755 index 0000000..3a80db1 --- /dev/null +++ b/questions/forms.py @@ -0,0 +1,8 @@ +from django.forms import ModelForm +from .models import Question + +class QuestionForm(ModelForm): + class Meta: + model = Question + fields = ['email', 'question'] + # TODO: honeypot! diff --git a/questions/migrations/0001_initial.py b/questions/migrations/0001_initial.py new file mode 100644 index 0000000..09ce67c --- /dev/null +++ b/questions/migrations/0001_initial.py @@ -0,0 +1,54 @@ +# -*- 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 model 'Question' + db.create_table('questions_question', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True)), + ('question', self.gf('django.db.models.fields.TextField')(db_index=True)), + ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('approved', self.gf('django.db.models.fields.BooleanField')(default=False)), + ('edited_question', self.gf('django.db.models.fields.TextField')(db_index=True, null=True, blank=True)), + ('answer', self.gf('markupfield.fields.MarkupField')(rendered_field=True, blank=True)), + ('answered', self.gf('django.db.models.fields.BooleanField')(default=False, db_index=True)), + ('answer_markup_type', self.gf('django.db.models.fields.CharField')(default='textile_pl', max_length=30, blank=True)), + ('answered_at', self.gf('django.db.models.fields.DateTimeField')(db_index=True, null=True, blank=True)), + ('_answer_rendered', self.gf('django.db.models.fields.TextField')()), + ('published', self.gf('django.db.models.fields.BooleanField')(default=False, db_index=True)), + ('published_at', self.gf('django.db.models.fields.DateTimeField')(db_index=True, null=True, blank=True)), + )) + db.send_create_signal('questions', ['Question']) + + + def backwards(self, orm): + # Deleting model 'Question' + db.delete_table('questions_question') + + + models = { + 'questions.question': { + 'Meta': {'ordering': "['-created_at']", 'object_name': 'Question'}, + '_answer_rendered': ('django.db.models.fields.TextField', [], {}), + 'answer': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True', 'blank': 'True'}), + 'answer_markup_type': ('django.db.models.fields.CharField', [], {'default': "'textile_pl'", 'max_length': '30', 'blank': 'True'}), + 'answered': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'answered_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'edited_question': ('django.db.models.fields.TextField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'published': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'published_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}), + 'question': ('django.db.models.fields.TextField', [], {'db_index': 'True'}) + } + } + + complete_apps = ['questions'] \ No newline at end of file diff --git a/questions/migrations/__init__.py b/questions/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/questions/models.py b/questions/models.py new file mode 100644 index 0000000..47dc697 --- /dev/null +++ b/questions/models.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 +from datetime import datetime +from django.contrib.sites.models import Site +from django.core.mail import EmailMultiAlternatives +from django.db import models +from django.template import loader, Context +from django.utils.translation import ugettext_lazy as _ +from markupfield.fields import MarkupField + +class Question(models.Model): + email = models.EmailField(_('contact e-mail'), null=True, blank=True) + question = models.TextField(_('question'), db_index=True) + created_at = models.DateTimeField(_('created at'), auto_now_add=True) + approved = models.BooleanField(_('approved'), default=False) + edited_question = models.TextField(_('edited question'), db_index=True, null=True, blank=True, + help_text=_("Leave empty if question doesn't need editing.")) + answer = MarkupField(_('answer'), markup_type='textile_pl', blank=True, + help_text=_('Use Textile syntax.')) + answered = models.BooleanField(_('answered'), db_index=True, default=False, + help_text=_('Check to send the answer to user.')) + answered_at = models.DateTimeField(_('answered at'), null=True, blank=True, db_index=True) + published = models.BooleanField(_('published'), db_index=True, default=False, + help_text=_('Check to display answered question on site.')) + published_at = models.DateTimeField(_('published at'), null=True, blank=True, db_index=True) + + class Meta: + ordering = ['-created_at'] + + def __unicode__(self): + return self.edited_question or self.question + + @models.permalink + def get_absolute_url(self): + return ('questions_question', (self.pk,)) + + def notify_author(self): + if not self.email: + return + site = Site.objects.get_current() + context = Context({ + 'question': self, + 'site': site, + }) + text_content = loader.get_template('questions/answered_mail.txt' + ).render(context) + html_content = loader.get_template('questions/answered_mail.html' + ).render(context) + msg = EmailMultiAlternatives( + u'Odpowiedź na Twoje pytanie w serwisie %s.' % site.domain, + text_content, settings.SERVER_EMAIL, [self.email]) + msg.attach_alternative(html_content, "text/html") + msg.send() + + def save(self, *args, **kwargs): + now = datetime.now() + if self.answered and not self.answered_at: + self.notify_author() + self.answered_at = now + if self.published and not self.published_at: + self.published_at = now + super(Question, self).save(*args, **kwargs) diff --git a/questions/templates/questions/answered_mail.txt b/questions/templates/questions/answered_mail.txt new file mode 100755 index 0000000..57ed289 --- /dev/null +++ b/questions/templates/questions/answered_mail.txt @@ -0,0 +1,19 @@ +{% load i18n %}{% language 'pl' %}{{ question.created_at }} zadałeś/zadałaś pytanie: + +{{ question.question|safe }} + + +Odpowiedź: + +{{ question.answer.raw|safe }} + +{% if question.published %} +Pytanie wraz z odpowiedzią można znaleźć na stronie: +http://{{ site.domain }}{{ question.get_absolute_url }} +{% endif %} + +Dziękujemy! + +-- +{{ site }} +{% endlanguage %} \ No newline at end of file diff --git a/questions/templates/questions/question_detail.html b/questions/templates/questions/question_detail.html new file mode 100755 index 0000000..be19018 --- /dev/null +++ b/questions/templates/questions/question_detail.html @@ -0,0 +1,11 @@ +{% extends "base.html" %} + +{% block "titleextra" %}{{ question }} :: {% endblock %} +{% block "body" %} +

{{ question }}

+ +{{ question.answer }} + +

Wróć do listy pytań.

+ +{% endblock %} \ No newline at end of file diff --git a/questions/templates/questions/question_form.html b/questions/templates/questions/question_form.html new file mode 100755 index 0000000..d712219 --- /dev/null +++ b/questions/templates/questions/question_form.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block "titleextra" %}Pierwsza pomoc w prawie autorskim: pytanie do prawnika :: {% endblock %} +{% block "body" %} +

Pierwsza pomoc w prawie autorskim: pytanie do prawnika

+ + + +
+{% csrf_token %} + + {{ form.as_table }} + +
+
+ + +{% endblock %} \ No newline at end of file diff --git a/questions/templates/questions/question_list.html b/questions/templates/questions/question_list.html new file mode 100755 index 0000000..9432850 --- /dev/null +++ b/questions/templates/questions/question_list.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{% load url from future %} + +{% block "titleextra" %}Pierwsza pomoc w prawie autorskim :: {% endblock %} +{% block "body" %} +

Pierwsza pomoc w prawie autorskim

+ +

Jeśli rozwiązania Twojego problemu nie ma na tej stronie, +zajrzyj do naszego podręcznika. Jeśli i to nie pomoże, +zadaj pytanie naszemu prawnikowi.

+ + + +{% endblock %} \ No newline at end of file diff --git a/questions/templates/questions/question_thanks.html b/questions/templates/questions/question_thanks.html new file mode 100755 index 0000000..b137678 --- /dev/null +++ b/questions/templates/questions/question_thanks.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} + +{% block "titleextra" %}Dziękujemy za przesłanie pytania :: {% endblock %} +{% block "body" %} +

Dziękujemy za przesłanie pytania

+ +??? + +{% endblock %} \ No newline at end of file diff --git a/questions/urls.py b/questions/urls.py new file mode 100755 index 0000000..9930956 --- /dev/null +++ b/questions/urls.py @@ -0,0 +1,29 @@ +# -*- 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.conf.urls import patterns, url +from django.views.generic import DetailView, ListView, TemplateView +from .models import Question +from .views import QuestionFormView + +urlpatterns = patterns('', + url(r'^$', + ListView.as_view(queryset=Question.objects.filter(published=True + ).order_by('-published_at')), + name="questions" + ), + url(r'^(?P\d+)/$', + DetailView.as_view(model=Question), + name="questions_question"), + url(r'^pytanie/$', + QuestionFormView.as_view(), + name="questions_form", + ), + url(r'^pytanie/dziekujemy/$', + TemplateView.as_view( + template_name="questions/question_thanks.html", + ), + name="questions_thanks" + ), +) diff --git a/questions/views.py b/questions/views.py new file mode 100644 index 0000000..1c918c8 --- /dev/null +++ b/questions/views.py @@ -0,0 +1,13 @@ +from django.core.urlresolvers import reverse_lazy +from django.views.generic.edit import FormView +from .forms import QuestionForm + + +class QuestionFormView(FormView): + form_class = QuestionForm + template_name = "questions/question_form.html" + success_url = reverse_lazy("questions_thanks") + + def form_valid(self, form): + form.save() + return super(QuestionFormView, self).form_valid(form) diff --git a/requirements.txt b/requirements.txt index 64674fb..9a4bc1a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,5 @@ +-i http://pypi.nowoczesnapolska.org.pl/simple + Django>=1.4,<1.5 #django_cas -e hg+https://bitbucket.org/cpcc/django-cas@197f156ee943#egg=django_cas @@ -6,8 +8,8 @@ PIL sorl-thumbnail>=11.09,<12 django-pagination --e git+git://github.com/fnp/fnpdjango.git@9a5b05c52311da4f726fec29d8be7d173f695352#egg=fnpdjango -e git+git://github.com/fnp/django-migdal.git@a3983327291548497d9bdd3db5976b895675b25e#egg=django-migdal +fnpdjango>=0.1.3,<0.2 textile django-markupfield -- 2.20.1