Added lesson-curriculum relation.
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Fri, 8 Feb 2013 14:13:32 +0000 (15:13 +0100)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Fri, 8 Feb 2013 14:13:32 +0000 (15:13 +0100)
15 files changed:
catalogue/migrations/0010_auto.py [new file with mode: 0644]
catalogue/models.py
catalogue/static/catalogue/css/section_list.css
catalogue/static/catalogue/css/section_list.scss
catalogue/templates/catalogue/section_list.html
catalogue/templates/catalogue/snippets/chosen_topics.html [deleted file]
catalogue/templatetags/catalogue_tags.py
curriculum/fixtures/curriculum.json
curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py [new file with mode: 0644]
curriculum/models.py
curriculum/templates/curriculum/snippets/course_box.html [new file with mode: 0755]
curriculum/templates/curriculum/snippets/course_boxes.html [new file with mode: 0755]
curriculum/templates/curriculum/snippets/course_boxes_toc.html [new file with mode: 0755]
curriculum/templatetags/curriculum_tags.py
edumed/templates/home.html

diff --git a/catalogue/migrations/0010_auto.py b/catalogue/migrations/0010_auto.py
new file mode 100644 (file)
index 0000000..73602ca
--- /dev/null
@@ -0,0 +1,83 @@
+# -*- 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 M2M table for field curriculum_courses on 'Lesson'
+        db.create_table('catalogue_lesson_curriculum_courses', (
+            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+            ('lesson', models.ForeignKey(orm['catalogue.lesson'], null=False)),
+            ('curriculumcourse', models.ForeignKey(orm['curriculum.curriculumcourse'], null=False))
+        ))
+        db.create_unique('catalogue_lesson_curriculum_courses', ['lesson_id', 'curriculumcourse_id'])
+
+
+    def backwards(self, orm):
+        # Removing M2M table for field curriculum_courses on 'Lesson'
+        db.delete_table('catalogue_lesson_curriculum_courses')
+
+
+    models = {
+        'catalogue.attachment': {
+            'Meta': {'ordering': "['slug', 'ext']", 'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+            'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+            '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']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['curriculum.CurriculumCourse']", 'symmetrical': 'False'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            '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', [], {'db_index': 'True'}),
+            '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']", 'null': 'True', 'blank': 'True'}),
+            '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'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            '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'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'object_name': 'CurriculumCourse'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            '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.CharField', [], {'max_length': '255'})
+        }
+    }
+
+    complete_apps = ['catalogue']
\ No newline at end of file
index f1c5377..46d026c 100644 (file)
@@ -2,7 +2,7 @@ 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
+from curriculum.models import Level, Curriculum, CurriculumCourse
 
 
 class Section(models.Model):
@@ -71,6 +71,7 @@ class Lesson(models.Model):
     type = models.CharField(max_length=15, db_index=True)
     order = models.IntegerField(db_index=True)
     dc = JSONField(default='{}')
+    curriculum_courses = models.ManyToManyField(CurriculumCourse)
 
     xml_file = models.FileField(upload_to="catalogue/lesson/xml",
         null=True, blank=True) # FIXME: slug in paths
@@ -128,8 +129,6 @@ class Lesson(models.Model):
         lesson.level = Level.objects.get(slug=wldoc.book_info.audience)
         lesson.order = 0
         lesson.populate_dc()
-        lesson.type = lesson.dc["type"]
-        lesson.save()
         lesson.build_html()
         lesson.build_package()
         lesson.build_package(student=True)
@@ -139,8 +138,19 @@ class Lesson(models.Model):
         from librarian.parser import WLDocument
         wldoc = WLDocument.from_file(self.xml_file.path)
         self.dc = wldoc.book_info.to_dict()
+        self.type = self.dc["type"]
         self.save()
 
+        courses = set()
+        for identifier in wldoc.book_info.curriculum:
+            try:
+                curr = Curriculum.objects.get(identifier=identifier)
+            except Curriculum.DoesNotExist:
+                pass
+            else:
+                courses.add(curr.course)
+        self.curriculum_courses = courses
+
     def build_html(self):
         from librarian.parser import WLDocument
         wldoc = WLDocument.from_file(self.xml_file.path)
index 99046a0..1b6749a 100644 (file)
     .section-level-liceum .section-type-course a {
       color: #fff; }
 
+.course-boxes h1 {
+  color: #363a3e; }
+.course-boxes .section-level {
+  background: white;
+  border: 1px solid #777; }
+  .course-boxes .section-level a, .course-boxes .section-level a:hover {
+    color: #363a3e; }
+  .course-boxes .section-level .section-type-course {
+    background: white;
+    bborder-left: 1px solid #363a3e; }
+
 .section-links {
   float: right; }
 
 h2.section-header {
   margin: 0; }
+
+.section-list-toc {
+  display: inline-block;
+  vertical-align: top;
+  width: 18.75em; }
index ecab3c8..535ebb4 100755 (executable)
@@ -66,6 +66,24 @@ $px: 0.0625em;
 }
 
 
+.course-boxes {
+    h1 {
+        color: #363a3e;
+    }
+    .section-level {
+        background: white;
+        border: 1px solid #777;
+        a, a:hover {
+            color: #363a3e;
+        }
+        .section-type-course {
+            background: white;
+            bborder-left: 1px solid #363a3e;
+        }
+    }
+}
+
+
 .section-links {
     float: right;
 }
@@ -73,3 +91,10 @@ $px: 0.0625em;
 h2.section-header {
     margin: 0;
 }
+
+
+.section-list-toc {
+    display: inline-block;
+    vertical-align: top;
+    width: 300*$px;
+}
index 0113684..6317688 100755 (executable)
@@ -1,5 +1,6 @@
 {% extends "base.html" %}
 {% load catalogue_tags %}
+{% load course_boxes course_boxes_toc from curriculum_tags %}
 
 {% block title %}Lekcje{% endblock %}
 
 </aside>
 
 <div id="main-bar">
-    <a name="top"></a><h2>Tematy</h2>
+    <div class="section-list-toc">
+    <h2>Tematy<a name="top"></a></h2>
     <ul class="link-list">
     {% for object in object_list %}
         <li><a href="#{{ object.slug }}">{{ object }}</a></li>
     {% endfor %}
     </ul>
+    </div>
+    <div class="section-list-toc">
+    <h2>Przedmioty</h2>
+    <ul class="link-list">
+        {% course_boxes_toc %}
+    </ul>
+    </div>
     
     {% for object in object_list %}
         <div class="section-links">
 
         {% section_box object %}
     {% endfor %}
+
+    <div class="course-boxes">
+    <h2>Lekcje wybrane na poszczególne przedmioty:</h2>
+    {% course_boxes %}
+    </div>
+
 </div>
 
 
diff --git a/catalogue/templates/catalogue/snippets/chosen_topics.html b/catalogue/templates/catalogue/snippets/chosen_topics.html
deleted file mode 100755 (executable)
index fe9ff43..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<ul class="link-list">
-    <li><a href="">język polski</a></li>
-    <li><a href="">informatykę</a></li>
-    <li><a href="">wiedzę o społeczeństwie</a></li>
-    <li><a href="">muzykę</a></li>
-</ul>
index 80b1a0c..09113d9 100755 (executable)
@@ -17,11 +17,6 @@ def catalogue_section_buttons():
         "object_list": Section.objects.all()
     }
 
-@register.inclusion_tag("catalogue/snippets/chosen_topics.html")
-def catalogue_chosen_topics():
-    return {
-    }
-
 @register.inclusion_tag("catalogue/snippets/section_box.html")
 def section_box(section):
     lessons = SortedDict()
index 286018d..dc62f07 100644 (file)
@@ -17,7 +17,8 @@
         "pk": 1,
         "model": "curriculum.curriculumcourse",
         "fields": {
-            "slug": "POLSKI",
+            "accusative": "j\u0119zyk polski",
+            "slug": "polski",
             "title": "J\u0119zyk polski"
         }
     },
@@ -25,7 +26,8 @@
         "pk": 2,
         "model": "curriculum.curriculumcourse",
         "fields": {
-            "slug": "PLASTYKA",
+            "accusative": "plastyk\u0119",
+            "slug": "plastyka",
             "title": "Plastyka"
         }
     },
@@ -33,7 +35,8 @@
         "pk": 3,
         "model": "curriculum.curriculumcourse",
         "fields": {
-            "slug": "WOS",
+            "accusative": "wiedz\u0119 o spo\u0142ecze\u0144stwie",
+            "slug": "wos",
             "title": "Wiedza o spo\u0142ecze\u0144stwie"
         }
     },
@@ -41,7 +44,8 @@
         "pk": 4,
         "model": "curriculum.curriculumcourse",
         "fields": {
-            "slug": "INFORMATYKA",
+            "accusative": "informatyk\u0119",
+            "slug": "informatyka",
             "title": "Informatyka"
         }
     },
@@ -49,7 +53,8 @@
         "pk": 5,
         "model": "curriculum.curriculumcourse",
         "fields": {
-            "slug": "ETYKA",
+            "accusative": "etyk\u0119",
+            "slug": "etyka",
             "title": "Etyka"
         }
     },
diff --git a/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py b/curriculum/migrations/0005_auto__add_field_curriculumcourse_accusative.py
new file mode 100644 (file)
index 0000000..0708f44
--- /dev/null
@@ -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):
+        # Adding field 'CurriculumCourse.accusative'
+        db.add_column('curriculum_curriculumcourse', 'accusative',
+                      self.gf('django.db.models.fields.CharField')(default='', max_length=255),
+                      keep_default=False)
+
+        if not db.dry_run:
+            orm.CurriculumCourse.objects.all().update(accusative=models.F('title'))
+
+
+    def backwards(self, orm):
+        # Deleting field 'CurriculumCourse.accusative'
+        db.delete_column('curriculum_curriculumcourse', 'accusative')
+
+
+    models = {
+        'curriculum.competence': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+        },
+        'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumCourse']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'identifier': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        'curriculum.curriculumcourse': {
+            'Meta': {'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            '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.CharField', [], {'max_length': '255'})
+        },
+        'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            '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 = ['curriculum']
index 14c916f..e34e5ab 100644 (file)
@@ -87,11 +87,13 @@ class CurriculumLevel(models.Model):
 
 class CurriculumCourse(models.Model):
     title = models.CharField(max_length=255)
+    accusative = models.CharField(max_length=255)
     slug = models.CharField(max_length=255, db_index=True)
 
     class Meta:
         verbose_name = _("curriculum course")
         verbose_name_plural = _("curriculum courses")
+        ordering = ['slug']
 
     def __unicode__(self):
         return self.title
@@ -122,9 +124,13 @@ class Curriculum(models.Model):
         assert m is not None, "Curriculum identifier doesn't match template."
         level, created = CurriculumLevel.objects.get_or_create(
                                        title=m.group('level'))
+        def_title = m.group('course').title()
         course, created = CurriculumCourse.objects.get_or_create(
-                                        slug=m.group('course'),
-                                        defaults={'title': m.group('course').title()})
+                                        slug=m.group('course').lower(),
+                                        defaults={
+                                            'title': def_title,
+                                            'accusative': def_title,
+                                        })
         type_ = m.group('type')
         if m.group('roz'):
             title += " (zakres rozszerzony)"
diff --git a/curriculum/templates/curriculum/snippets/course_box.html b/curriculum/templates/curriculum/snippets/course_box.html
new file mode 100755 (executable)
index 0000000..b00c71a
--- /dev/null
@@ -0,0 +1,33 @@
+{% for level, types in lessons.items %}
+{% if level.slug == "liceum" %}
+    <p>Poziom zaawansowany
+        <span class="section-links"><a href="#top">wróć do spisu treści</a></span>
+    </p>
+{% endif %}
+<section class="section-level section-level-{{ level.slug }}">
+    {% spaceless %}
+    {% for lesson_type, lesson_list in types.items %}
+        <section class="section-type section-type-{{ lesson_type }}">
+            {% if lesson_type == 'synthetic' %}
+                <h1>Lekcje syntetyczne</h1>
+            {% else %}
+                <h1>Lekcje z pełnych kursów</h1>
+            {% endif %}
+            {% if lesson_list %}
+            <ul class="section-lessons link-list">
+                {% for lesson in lesson_list %}
+                    <li class="section-lesson">
+                        <a href="{{ lesson.get_absolute_url }}">{{ lesson }}{% if lesson_type == 'synthetic' %}
+                            <br/>(przegląd całego tematu „{{ lesson.section }}” w 45 minut)
+                        {% endif %}</a>
+                    </li>
+                {% endfor %}
+            </ul>
+            {% else %}
+                <p>(W przygotowaniu)</p>
+            {% endif %}
+        </section>
+    {% endfor %}
+    {% endspaceless %}
+</section>
+{% endfor %}
diff --git a/curriculum/templates/curriculum/snippets/course_boxes.html b/curriculum/templates/curriculum/snippets/course_boxes.html
new file mode 100755 (executable)
index 0000000..3b3c41b
--- /dev/null
@@ -0,0 +1,8 @@
+{% load course_box from curriculum_tags %}
+{% for course in object_list %}
+    <div class="section-links">
+        <a href="#top">wróć do spisu treści</a>
+    </div>
+    <h3>{{ course }}<a name="{{ course.slug }}" class="permalink"></a></h3>
+    {% course_box course %}
+{% endfor %}
diff --git a/curriculum/templates/curriculum/snippets/course_boxes_toc.html b/curriculum/templates/curriculum/snippets/course_boxes_toc.html
new file mode 100755 (executable)
index 0000000..cb52cdc
--- /dev/null
@@ -0,0 +1,12 @@
+{% load url from future %}
+
+{% url "catalogue_lessons" as lessons_url %}
+{% for course in object_list %}
+<li><a href="{{ lessons_url }}#{{ course.slug }}">
+    {% if accusative %}
+        {{ course.accusative }}
+    {% else %}
+        {{ course }}
+    {% endif %}
+</a></li>
+{% endfor %}
index 00959ee..f772485 100755 (executable)
@@ -1,6 +1,6 @@
 from django import template
 from django.utils.datastructures import SortedDict
-from ..models import Competence, Curriculum
+from ..models import Competence, Curriculum, CurriculumCourse
 
 register = template.Library()
 
@@ -45,3 +45,30 @@ def url_for_level(comp, level):
     except:
         return comp.get_absolute_url()
 
+
+@register.inclusion_tag("curriculum/snippets/course_box.html")
+def course_box(course):
+    lessons = SortedDict()
+    for lesson in course.lesson_set.all():
+        if lesson.level not in lessons:
+            newdict = SortedDict()
+            newdict['synthetic'] = []
+            newdict['course'] = []
+            lessons[lesson.level] = newdict
+        if lesson.type not in lessons[lesson.level]:
+            lessons[lesson.level][lesson.type] = []
+        lessons[lesson.level][lesson.type].append(lesson)
+    return {
+        "lessons": lessons,
+    }
+
+@register.inclusion_tag("curriculum/snippets/course_boxes.html")
+def course_boxes():
+    return {'object_list': CurriculumCourse.objects.all()}
+
+@register.inclusion_tag("curriculum/snippets/course_boxes_toc.html")
+def course_boxes_toc(accusative=False):
+    return {
+        'object_list': CurriculumCourse.objects.all(),
+        'accusative': accusative,
+    }
index 8ec229f..7be0b3e 100755 (executable)
@@ -1,5 +1,6 @@
 {% extends "base.html" %}
 {% load catalogue_tags %}
+{% load course_boxes_toc from curriculum_tags %}
 
 {% block full_title %}Edukacja medialna{% endblock %}
 
@@ -29,7 +30,9 @@ w trzech wierszach?</p>
 
 <section id="main-chosen">
 <h1>Wybrane tematy na:</h1>
-{% catalogue_chosen_topics %}
+<ul class="link-list">
+{% course_boxes_toc 1 %}
+</ul>
 </section>
 
 <section id="main-tools">