diff --git a/locale/ja/LC_MESSAGES/django.mo b/locale/ja/LC_MESSAGES/django.mo index 8da8da19..da19639a 100644 Binary files a/locale/ja/LC_MESSAGES/django.mo and b/locale/ja/LC_MESSAGES/django.mo differ diff --git a/locale/ja/LC_MESSAGES/django.po b/locale/ja/LC_MESSAGES/django.po index 2c04f174..0ba24c11 100644 --- a/locale/ja/LC_MESSAGES/django.po +++ b/locale/ja/LC_MESSAGES/django.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: pyconjp-website\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-05-18 22:24+0900\n" +"POT-Creation-Date: 2017-08-16 16:37+0900\n" "PO-Revision-Date: 2016-07-02 16:13+0000\n" "Last-Translator: Ian Lewis \n" "Language-Team: Japanese (http://www.transifex.com/projects/p/pyconjp-website/" @@ -1912,9 +1912,33 @@ msgstr "" msgid "Message sent" msgstr "" +#: pyconjp/forms.py:11 pyconjp/templates/proposals/_proposal_fields.html:115 +msgid "video" +msgstr "動画" + +#: pyconjp/forms.py:14 +msgid "url field for video" +msgstr "動画のURLを入力してください" + +#: pyconjp/forms.py:17 pyconjp/templates/proposals/_proposal_fields.html:118 +msgid "slide" +msgstr "スライド" + +#: pyconjp/forms.py:20 +msgid "url field for slide" +msgstr "スライドのURLを入力してください" + +#: pyconjp/forms.py:23 pyconjp/templates/proposals/_proposal_fields.html:121 +msgid "code" +msgstr "ソースコード" + +#: pyconjp/forms.py:26 +msgid "url field for code" +msgstr "ソースコードのURLを入力してください" + #: pyconjp/models.py:11 msgid "Video" -msgstr "ビデオ" +msgstr "動画" #: pyconjp/models.py:12 msgid "Slide" diff --git a/pycon/proposals/views.py b/pycon/proposals/views.py index 4149e6a0..04c1a68f 100644 --- a/pycon/proposals/views.py +++ b/pycon/proposals/views.py @@ -22,6 +22,8 @@ from symposion.proposals.forms import AddSpeakerForm, SupportingDocumentCreateForm from pycon.models import PyConProposal +from pyconjp.models import PresentationResource + def get_form(name): dot = name.rindex('.') @@ -74,6 +76,13 @@ def proposal_submit_kind(request, kind_slug): proposal.speaker = speaker_profile proposal.save() form.save_m2m() + for resource_type in ['video', 'slide', 'code']: + if form.cleaned_data[resource_type]: + resource = PresentationResource() + resource.proposal_base_id = proposal.proposalbase_ptr_id + resource.type = resource_type + resource.url = form.cleaned_data[resource_type] + resource.save() messages.success(request, "Proposal submitted.") if "add-speakers" in request.POST: return redirect("proposal_speaker_manage", proposal.pk) @@ -177,6 +186,12 @@ def proposal_edit(request, pk): queryset = ProposalBase.objects.select_related("speaker") proposal = get_object_or_404(queryset, pk=pk) proposal = ProposalBase.objects.get_subclass(pk=proposal.pk) + for resource_type in ['video', 'slide', 'code']: + resource_query = PresentationResource.objects.filter(proposal_base_id=proposal.id, type=resource_type) + url = '' + if resource_query.__len__(): + url = resource_query[0].url + setattr(proposal, resource_type, url) if request.user != proposal.speaker.user: raise Http404() @@ -209,10 +224,29 @@ def proposal_edit(request, pk): [user.email], "proposal_updated", context=ctx ) + for resource_type in ['video', 'slide', 'code']: + if form.cleaned_data[resource_type]: + resource = PresentationResource.objects.get( + proposal_base_id=proposal.proposalbase_ptr_id, + type=resource_type + ) + if not resource: + resource = PresentationResource() + resource.proposal_base_id = proposal.proposalbase_ptr_id + resource.type = resource_type + resource.url = form.cleaned_data[resource_type] + resource.save() + else: + resource = PresentationResource.objects.get( + proposal_base_id=proposal.proposalbase_ptr_id, + type=resource_type + ) + if resource: + resource.delete() messages.success(request, "Proposal updated.") return redirect("proposal_detail", proposal.pk) else: - form = form_class(instance=proposal) + form = form_class(instance=proposal, initial={'code': proposal.code, 'video': proposal.video, 'slide': proposal.slide}) return render(request, "proposals/proposal_edit.html", { "proposal": proposal, @@ -225,6 +259,11 @@ def proposal_detail(request, pk): queryset = ProposalBase.objects.select_related("speaker", "speaker__user") proposal = get_object_or_404(queryset, pk=pk) proposal = ProposalBase.objects.get_subclass(pk=proposal.pk) + resource = {} + for resource_type in ['video', 'slide', 'code']: + resource_query = PresentationResource.objects.filter(proposal_base_id=proposal.id, type=resource_type) + if resource_query.__len__(): + resource[resource_type] = resource_query[0].url if request.user not in [p.user for p in proposal.speakers()]: raise Http404() @@ -269,6 +308,7 @@ def proposal_detail(request, pk): return render(request, "proposals/proposal_detail.html", { "proposal": proposal, + "resource": resource, "message_form": message_form }) diff --git a/pyconjp/forms.py b/pyconjp/forms.py index f7ab19da..68cc3a34 100644 --- a/pyconjp/forms.py +++ b/pyconjp/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.utils.translation import gettext as _ from markedit.widgets import MarkEdit from pycon.models import PyConTalkProposal @@ -6,6 +7,24 @@ class PyConJPTalkProposalForm(PyConProposalForm): + video = forms.URLField( + label=_('video'), + required=False, + widget=forms.TextInput(attrs={'class': 'fullwidth-input'}), + help_text=_('url field for video'), + ) + slide = forms.URLField( + label=_('slide'), + required=False, + widget=forms.TextInput(attrs={'class': 'fullwidth-input'}), + help_text=_('url field for slide'), + ) + code = forms.URLField( + label=_('code'), + required=False, + widget=forms.TextInput(attrs={'class': 'fullwidth-input'}), + help_text=_('url field for code'), + ) class Meta: model = PyConTalkProposal @@ -23,6 +42,9 @@ class Meta: "additional_notes", "additional_requirements", "recording_release", + "video", + "slide", + "code", ] widgets = { "title": forms.TextInput(attrs={'class': 'fullwidth-input'}), diff --git a/pyconjp/migrations/0003_initial.py b/pyconjp/migrations/0003_initial.py new file mode 100644 index 00000000..8d976149 --- /dev/null +++ b/pyconjp/migrations/0003_initial.py @@ -0,0 +1,149 @@ +# -*- 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 'PresentationResource' + db.create_table(u'pyconjp_presentationresource', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('proposal_base', self.gf('django.db.models.fields.related.ForeignKey')(related_name='presentation_resources', to=orm['proposals.ProposalBase'])), + ('url', self.gf('django.db.models.fields.CharField')(max_length=1024)), + ('type', self.gf('django.db.models.fields.CharField')(max_length=16)), + ('label', self.gf('django.db.models.fields.CharField')(default='', max_length=16, blank=True)), + )) + db.send_create_signal(u'pyconjp', ['PresentationResource']) + + + def backwards(self, orm): + # Deleting model 'PresentationResource' + db.delete_table(u'pyconjp_presentationresource') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'conference.conference': { + 'Meta': {'object_name': 'Conference'}, + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'timezone': ('timezones.fields.TimeZoneField', [], {'default': "'Asia/Tokyo'", 'max_length': '100', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'conference.section': { + 'Meta': {'object_name': 'Section'}, + 'conference': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['conference.Conference']"}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'proposals.additionalspeaker': { + 'Meta': {'unique_together': "(('speaker', 'proposalbase'),)", 'object_name': 'AdditionalSpeaker', 'db_table': "'proposals_proposalbase_additional_speakers'"}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'proposalbase': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['proposals.ProposalBase']"}), + 'speaker': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['speakers.Speaker']"}), + 'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}) + }, + u'proposals.proposalbase': { + 'Meta': {'object_name': 'ProposalBase'}, + 'abstract': ('django.db.models.fields.TextField', [], {}), + 'additional_notes': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'additional_speakers': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['speakers.Speaker']", 'symmetrical': 'False', 'through': u"orm['proposals.AdditionalSpeaker']", 'blank': 'True'}), + 'cancelled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'max_length': '200'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['proposals.ProposalKind']"}), + 'language': ('django.db.models.fields.CharField', [], {'default': "'ja'", 'max_length': '2'}), + 'speaker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposals'", 'to': u"orm['speakers.Speaker']"}), + 'submitted': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'proposals.proposalkind': { + 'Meta': {'object_name': 'ProposalKind'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proposal_kinds'", 'to': u"orm['conference.Section']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}) + }, + u'pyconjp.presentationresource': { + 'Meta': {'object_name': 'PresentationResource'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'label': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'proposal_base': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'presentation_resources'", 'to': u"orm['proposals.ProposalBase']"}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}) + }, + u'speakers.speaker': { + 'Meta': {'object_name': 'Speaker'}, + 'admission': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}), + 'annotation': ('django.db.models.fields.TextField', [], {}), + 'biography': ('django.db.models.fields.TextField', [], {}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'facebook_username': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}), + 'github_username': ('django.db.models.fields.CharField', [], {'max_length': '39', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'invite_email': ('django.db.models.fields.CharField', [], {'max_length': '200', 'unique': 'True', 'null': 'True', 'db_index': 'True'}), + 'invite_token': ('django.db.models.fields.CharField', [], {'max_length': '40', 'db_index': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'photo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'blank': 'True'}), + 'sessions_preference': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'twitter_username': ('django.db.models.fields.CharField', [], {'max_length': '15', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'speaker_profile'", 'unique': 'True', 'null': 'True', 'to': u"orm['auth.User']"}) + }, + u'taggit.tag': { + 'Meta': {'object_name': 'Tag'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}) + }, + u'taggit.taggeditem': { + 'Meta': {'object_name': 'TaggedItem'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_tagged_items'", 'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "u'taggit_taggeditem_items'", 'to': u"orm['taggit.Tag']"}) + } + } + + complete_apps = ['pyconjp'] \ No newline at end of file diff --git a/pyconjp/models.py b/pyconjp/models.py index 94341426..801abdec 100644 --- a/pyconjp/models.py +++ b/pyconjp/models.py @@ -10,6 +10,7 @@ class PresentationResource(models.Model): PRESENTATION_RESOURCE_TYPE = ( ('video', _('Video')), ('slide', _('Slide')), + ('code', _('Code')), ) proposal_base = models.ForeignKey(ProposalBase, related_name="presentation_resources") diff --git a/pyconjp/templates/proposals/_proposal_fields.html b/pyconjp/templates/proposals/_proposal_fields.html index f22b67b3..2b195116 100644 --- a/pyconjp/templates/proposals/_proposal_fields.html +++ b/pyconjp/templates/proposals/_proposal_fields.html @@ -111,4 +111,13 @@ {% trans "No supporting documents attached to this proposal." %} {% endif %} + +
{% trans "video" %}
+
{{ resource.video }} 
+ +
{% trans "slide" %}
+
{{ resource.slide }} 
+ +
{% trans "code" %}
+
{{ resource.code }}