Lesson metadata on side.
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Thu, 31 Jan 2013 12:44:01 +0000 (13:44 +0100)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Thu, 31 Jan 2013 12:44:01 +0000 (13:44 +0100)
catalogue/migrations/0005_auto__add_field_lesson_dc.py [new file with mode: 0644]
catalogue/models.py
catalogue/templates/catalogue/lesson_detail.html
catalogue/templates/catalogue/snippets/lesson_nav.html [new file with mode: 0755]
catalogue/templatetags/catalogue_tags.py

diff --git a/catalogue/migrations/0005_auto__add_field_lesson_dc.py b/catalogue/migrations/0005_auto__add_field_lesson_dc.py
new file mode 100644 (file)
index 0000000..ce7705f
--- /dev/null
@@ -0,0 +1,69 @@
+# -*- 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 'Lesson.dc'
+        db.add_column('catalogue_lesson', 'dc',
+                      self.gf('jsonfield.fields.JSONField')(default='{}'),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Lesson.dc'
+        db.delete_column('catalogue_lesson', 'dc')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'object_name': 'Attachment'},
+            'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'depth': ('django.db.models.fields.IntegerField', [], {}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
index fadb718..03606c0 100644 (file)
@@ -1,7 +1,10 @@
 from django.core.files import File
+from django.core.urlresolvers import reverse
 from django.db import models
+from jsonfield import JSONField
 from curriculum.models import Level
 
+
 class Section(models.Model):
     title = models.CharField(max_length=255, unique=True)
     slug = models.SlugField(unique=True)
@@ -13,6 +16,16 @@ class Section(models.Model):
     def __unicode__(self):
         return self.title
 
+    def get_absolute_url(self):
+        return "%s#%s" % (reverse("catalogue_lessons"), self.slug)
+
+    def syntetic_lesson(self):
+        try:
+            return self.lesson_set.filter(depth=0)[0]
+        except IndexError:
+            return None
+
+
 class Lesson(models.Model):
     section = models.ForeignKey(Section)
     level = models.ForeignKey(Level)
@@ -20,6 +33,7 @@ class Lesson(models.Model):
     slug = models.SlugField(unique=True)
     depth = models.IntegerField()
     order = models.IntegerField()
+    dc = JSONField(default='{}')
 
     xml_file = models.FileField(upload_to="catalogue/lesson/xml",
         null=True, blank=True) # FIXME: slug in paths
@@ -70,17 +84,42 @@ class Lesson(models.Model):
         lesson.section = Section.objects.all()[0]
         lesson.order = 1
         lesson.depth = 1
+        lesson.populate_dc()
         lesson.save()
         lesson.build_html()
+        lesson.build_package()
+        lesson.build_package(student=True)
         return lesson
 
+    def populate_dc(self):
+        from librarian.parser import WLDocument
+        wldoc = WLDocument.from_file(self.xml_file.path)
+        self.dc = wldoc.book_info.to_dict()
+        self.save()
+
     def build_html(self):
         from librarian.parser import WLDocument
         wldoc = WLDocument.from_file(self.xml_file.path)
         html = wldoc.as_html()
         self.html_file.save("%s.html" % self.slug,
-            File(open(html.get_filename())), save=False)
-        self.save()
+            File(open(html.get_filename())))
+
+    def build_package(self, student=False):
+        from StringIO import StringIO
+        import zipfile
+        from django.core.files.base import ContentFile
+        buff = StringIO()
+        with zipfile.ZipFile(buff, 'w', zipfile.ZIP_STORED) as zipf:
+            zipf.write(self.xml_file.path, "pliki-zrodlowe/%s.xml" % self.slug)
+            pdf = self.student_pdf if student else self.pdf
+            if pdf:
+                zipf.write(self.xml_file.path, 
+                    "%s%s.pdf" % (self.slug, "_student" if student else ""))
+        fieldname = "student_package" if student else "package"
+        getattr(self, fieldname).save(
+            "%s%s.zip" % (self.slug, "_student" if student else ""),
+            ContentFile(buff.getvalue()))
+
 
 class Attachment(models.Model):
     lesson = models.ForeignKey(Lesson)
index 81ca932..2fbf7b2 100755 (executable)
@@ -1,5 +1,6 @@
 {% extends "base.html" %}
 {% load url from future %}
+{% load lesson_nav person_list from catalogue_tags %}
 
 {% block title %}{{ object }}{% endblock %}
 
         <p>Ta lekcja jest częścią działu
         <strong>{{ object.section }}</strong>.
         Dostępna jest również
-        <strong><a href="">lekcja syntetyczna</a></strong>
+        <strong><a href="{{ object.section.syntetic_lesson.get_absolute_url }}">lekcja syntetyczna</a></strong>
         dla tego działu.
         </p>
         {% endif %}
         <p>Czas trwania: 45 minut.</p>
     </section>
-    <section class="box-button"><a href="" class="dl-button">Pobierz całą lekcję</a></section>
-    <section><a href="" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
+
+    {% if object.package %}
+        <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
+    {% endif %}
+    {% if object.student_package %}
+        <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
+    {% endif %}
+
     <section class="section">
-        <h1>Korzystanie z informacji</h1>
+        {% lesson_nav object %}
     </section>
+
+    <section class="section-minor">
+        <p>Autor: {{ object.dc.authors|person_list }}</p>
+        <p>Licencja: <a href="{{ object.dc.license }}">{{ object.dc.license_description }}</a>.</p>
+    </section>
+
+    <section class="section-minor">
+        <ul class="link-list">
+            <li><a href="{{ object.xml_file.url }}">źródłowy plik XML</a></li>
+            <li><a href="">lekcja na Platformie Redakcyjnej</a></li>
+        </ul>
+    </section>
+
+    <section class="section-minor">
+        <p>{{ object.dc.description }}</p>
+    </section>
+
 </aside>
 
 <div id="main-bar">
diff --git a/catalogue/templates/catalogue/snippets/lesson_nav.html b/catalogue/templates/catalogue/snippets/lesson_nav.html
new file mode 100755 (executable)
index 0000000..742004f
--- /dev/null
@@ -0,0 +1,20 @@
+{% load url from future %}
+<h1>
+{% if root %}
+    <a href="{{ root.get_absolute_url }}">{{ root }}</a>
+{% else %}
+    <a href="{% url 'catalogue_lessons' %}">Wszystkie działy</a>
+{% endif %}
+</h1>
+
+<ul>
+{% for item in siblings %}
+    <li>
+    {% if item == lesson %}
+        <strong>{{ item }}</strong>
+    {% else %}
+        <a href="{{ item.get_absolute_url }}">{{ item }}</a>
+    {% endif %}
+    </li>
+{% endfor %}
+</ul>
index 23a4066..5c96e32 100755 (executable)
@@ -1,6 +1,6 @@
 from django import template
 from django.utils.datastructures import SortedDict
-from ..models import Section
+from ..models import Lesson, Section
 
 register = template.Library()
 
@@ -34,6 +34,25 @@ def section_box(section):
         "lessons": lessons,
     }
 
+@register.inclusion_tag("catalogue/snippets/lesson_nav.html")
+def lesson_nav(lesson):
+    if lesson.depth == 1:
+        root = lesson.section
+        siblings = root.lesson_set.filter(depth=1)
+    else:
+        root = None
+        siblings = Lesson.objects.filter(depth=0)
+    return {
+        "lesson": lesson,
+        "root": root,
+        "siblings": siblings,
+    }
+
+@register.filter
+def person_list(persons):
+    from librarian.dcparser import Person
+    return u", ".join(Person.from_text(p).readable() for p in persons)
+
 
 # FIXME: Move to fnpdjango
 import feedparser