Prepared for SP 4-6.
authorRadek Czajka <radekczajka@nowoczesnapolska.org.pl>
Fri, 31 Jan 2014 11:57:43 +0000 (12:57 +0100)
committerRadek Czajka <radekczajka@nowoczesnapolska.org.pl>
Fri, 31 Jan 2014 11:58:42 +0000 (12:58 +0100)
- Main and lesson list pages overhaul.
- Lessons now inform about internet requirements and publisher.
- PDF support for <obraz> (by sorl.thumnail with ImageMagick)
- Add summary and picture for Sections, description for Lesson.
- Level slug and meta dc:audience value can be different.
- Per-level lesson packages instead of global ones.
- Lesson packages are now rebuilt after import.
- Add option for allowing incomplete sections on import.
- Django 1.6, `django-piwik` replaces `piwik`.

57 files changed:
catalogue/management/commands/importlessons.py
catalogue/management/commands/repackage.py
catalogue/migrations/0014_auto__add_field_section_summary.py [new file with mode: 0644]
catalogue/migrations/0015_auto__add_field_lesson_description.py [new file with mode: 0644]
catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py [new file with mode: 0644]
catalogue/models.py
catalogue/publish.py
catalogue/static/catalogue/css/carousel.css
catalogue/static/catalogue/css/carousel.scss
catalogue/static/catalogue/css/layout.css
catalogue/static/catalogue/css/layout.scss
catalogue/static/catalogue/css/lesson.css
catalogue/static/catalogue/css/lesson.scss
catalogue/static/catalogue/css/section_list.css
catalogue/static/catalogue/css/section_list.scss
catalogue/static/catalogue/js/carousel.js
catalogue/static/catalogue/js/lesson-list.js [new file with mode: 0644]
catalogue/static/catalogue/js/lesson.js
catalogue/templates/catalogue/lesson/appendix/lesson_detail.html
catalogue/templates/catalogue/lesson/box-icons.html [new file with mode: 0644]
catalogue/templates/catalogue/lesson/course/lesson_detail.html
catalogue/templates/catalogue/lesson/lesson_detail.html
catalogue/templates/catalogue/lesson/project/lesson_detail.html
catalogue/templates/catalogue/lesson/synthetic/lesson_detail.html
catalogue/templates/catalogue/lesson_list.html [new file with mode: 0755]
catalogue/templates/catalogue/section_list.html [deleted file]
catalogue/templates/catalogue/snippets/carousel.html
catalogue/templates/catalogue/snippets/lesson_nav.html
catalogue/templates/catalogue/snippets/lesson_or_stub.html [new file with mode: 0644]
catalogue/templates/catalogue/snippets/level_box.html [new file with mode: 0755]
catalogue/templates/catalogue/snippets/levels_main.html [new file with mode: 0644]
catalogue/templates/catalogue/snippets/section_box.html [deleted file]
catalogue/templates/catalogue/snippets/section_buttons.html [deleted file]
catalogue/templatetags/catalogue_tags.py
catalogue/urls.py
catalogue/views.py
contact/forms.py
curriculum/migrations/0010_auto__add_field_level_meta_name.py [new file with mode: 0644]
curriculum/migrations/0011_meta_name.py [new file with mode: 0644]
curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py [new file with mode: 0644]
curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py [new file with mode: 0644]
curriculum/models.py
curriculum/templates/curriculum/snippets/course_boxes_toc.html
curriculum/templatetags/curriculum_tags.py
edumed/settings.d/30-apps.py
edumed/settings.d/40-middleware.py
edumed/settings.d/50-contrib.py
edumed/settings.d/50-static.py
edumed/settings.d/60-custom.py
edumed/static/css/main.css
edumed/static/css/main.scss
edumed/static/img/icons/internet_black.png [new file with mode: 0644]
edumed/static/img/icons/nointernet_black.png [new file with mode: 0644]
edumed/templates/base_super.html
edumed/templates/home.html
edumed/views.py
requirements.txt

index 4e7a38c..83bf68b 100755 (executable)
@@ -23,15 +23,17 @@ class Command(BaseCommand):
             help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
         make_option('-a', '--attachments', dest='attachments', metavar="PATH", default='materialy',
             help='Attachments dir path.'),
             help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
         make_option('-a', '--attachments', dest='attachments', metavar="PATH", default='materialy',
             help='Attachments dir path.'),
+        make_option('--ignore-incomplete', action='store_true', dest='ignore_incomplete', default=False,
+            help='Attachments dir path.'),
     )
     help = 'Imports lessons from the specified directories.'
     args = 'directory [directory ...]'
 
     )
     help = 'Imports lessons from the specified directories.'
     args = 'directory [directory ...]'
 
-    def import_book(self, file_path, options, attachments):
+    def import_book(self, file_path, options, attachments, ignore_incomplete=False):
         verbose = options.get('verbose')
         iofile = IOFile.from_filename(os.path.join(self.curdir, file_path))
         iofile.attachments = attachments
         verbose = options.get('verbose')
         iofile = IOFile.from_filename(os.path.join(self.curdir, file_path))
         iofile.attachments = attachments
-        lesson = Lesson.publish(iofile)
+        return Lesson.publish(iofile, ignore_incomplete)
 
     @staticmethod
     def all_attachments(path):
 
     @staticmethod
     def all_attachments(path):
@@ -52,8 +54,9 @@ class Command(BaseCommand):
 
 
     def handle(self, *directories, **options):
 
 
     def handle(self, *directories, **options):
-        from django.db import transaction
+        from django.db import connection, transaction
 
 
+        levels = set()
         self.style = color_style()
         
         verbose = options.get('verbose')
         self.style = color_style()
         
         verbose = options.get('verbose')
@@ -61,9 +64,14 @@ class Command(BaseCommand):
 
 
         # Start transaction management.
 
 
         # Start transaction management.
-        transaction.commit_unless_managed()
-        transaction.enter_transaction_management()
-        transaction.managed(True)
+        # SQLite will choke on generating thumbnails 
+        use_transaction = not connection.features.autocommits_when_autocommit_is_off
+        if use_transaction:
+            transaction.commit_unless_managed()
+            transaction.enter_transaction_management()
+            transaction.managed(True)
+        else:
+            print 'WARNING: Not using transaction management.'
 
         files_imported = 0
         files_skipped = 0
 
         files_imported = 0
         files_skipped = 0
@@ -79,6 +87,7 @@ class Command(BaseCommand):
                 # files queue
                 files = sorted(os.listdir(abs_dir))
                 postponed = {}
                 # files queue
                 files = sorted(os.listdir(abs_dir))
                 postponed = {}
+                ignore_incomplete = set()
                 while files:
                     file_name = files.pop(0)
                     file_path = os.path.join(abs_dir, file_name)
                 while files:
                     file_name = files.pop(0)
                     file_path = os.path.join(abs_dir, file_name)
@@ -96,9 +105,8 @@ class Command(BaseCommand):
 
                     # Import book files
                     try:
 
                     # Import book files
                     try:
-                        self.import_book(file_path, options, attachments)
-                        files_imported += 1
-                        transaction.commit()
+                        lesson = self.import_book(file_path, options, attachments,
+                                    ignore_incomplete=file_name in ignore_incomplete)
                     except Section.IncompleteError, e:
                         if file_name not in postponed or postponed[file_name] < files_imported:
                             # Push it back into the queue, maybe the missing lessons will show up.
                     except Section.IncompleteError, e:
                         if file_name not in postponed or postponed[file_name] < files_imported:
                             # Push it back into the queue, maybe the missing lessons will show up.
@@ -106,6 +114,10 @@ class Command(BaseCommand):
                                 print self.style.NOTICE('Waiting for missing lessons.')
                             files.append(file_name)
                             postponed[file_name] = files_imported
                                 print self.style.NOTICE('Waiting for missing lessons.')
                             files.append(file_name)
                             postponed[file_name] = files_imported
+                        elif options['ignore_incomplete'] and file_name not in ignore_incomplete:
+                            files.append(file_name)
+                            ignore_incomplete.add(file_name)
+                            postponed[file_name] = files_imported
                         else:
                             # We're in a loop, nothing's being imported - some lesson is really missing.
                             raise e
                         else:
                             # We're in a loop, nothing's being imported - some lesson is really missing.
                             raise e
@@ -113,6 +125,22 @@ class Command(BaseCommand):
                         import traceback
                         traceback.print_exc()
                         files_skipped += 1
                         import traceback
                         traceback.print_exc()
                         files_skipped += 1
+                    else:
+                        files_imported += 1
+                        if use_transaction:
+                            transaction.commit()
+                        if hasattr(lesson, 'level'):
+                            levels.add(lesson.level)
+                    finally:
+                        if verbose > 0:
+                            print
+
+
+        if levels:
+            print "Rebuilding level packages:"
+            for level in levels:
+                print level.name
+                level.build_packages()
 
         # Print results
         print
 
         # Print results
         print
@@ -120,5 +148,6 @@ class Command(BaseCommand):
             files_imported, files_skipped, files_imported + files_skipped)
         print
 
             files_imported, files_skipped, files_imported + files_skipped)
         print
 
-        transaction.commit()
-        transaction.leave_transaction_management()
+        if use_transaction:
+            transaction.commit()
+            transaction.leave_transaction_management()
index 3946e82..f3ae5e8 100755 (executable)
@@ -2,61 +2,15 @@
 # This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of EduMed, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-import os
 from optparse import make_option
 from optparse import make_option
-from django.conf import settings
 from django.core.management.base import BaseCommand
 from django.core.management.base import BaseCommand
-from catalogue.models import Section
-import zipfile
 
 
 class Command(BaseCommand):
 
 
 class Command(BaseCommand):
-    option_list = BaseCommand.option_list + (
-        make_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
-            help='Verbosity level; 0=minimal output, 1=normal output, 2=all output'),
-    )
     help = 'Rebuilds downloadable packages.'
 
     help = 'Rebuilds downloadable packages.'
 
-    def build_package(self, zippath, student, verbose):
-        with open(zippath, 'w') as outf:
-            zipf = zipfile.ZipFile(outf, 'w', zipfile.ZIP_STORED)
-            
-            for si, section in enumerate(Section.objects.all()):
-                li = 1
-                li_adv = 1
-                for lesson in section.lesson_set.all():
-                    advanced = lesson.level.slug == "liceum"
-                    section_dir = "%d_%s%s" % (
-                        si + 1, section.slug,
-                        " (zaawansowane)" if advanced else "")
-                    if lesson.type == 'course':
-                        if advanced:
-                            ind = li_adv
-                            li_adv += 1
-                        else:
-                            ind = li
-                            li += 1
-                        prefix = "%s/%02d_%s/" % (
-                                section_dir, ind, lesson.slug,
-                            )
-                    elif lesson.type == 'synthetic':
-                        prefix = "%s/%s (synteza)/" % (
-                                section_dir, lesson.slug)
-                    elif lesson.type == 'project':
-                        prefix = "%s/%s (projekt)/" % (
-                                section_dir, lesson.slug)
-                    else:
-                        prefix = "%s/%s/" % (
-                                section_dir, lesson.slug)
-                    lesson.add_to_zip(zipf, student, prefix)
-            zipf.close()
-
     def handle(self, **options):
     def handle(self, **options):
-        verbose = options.get('verbose')
+        from curriculum.models import Level
 
 
-        self.build_package(
-            os.path.join(settings.MEDIA_ROOT, settings.CATALOGUE_PACKAGE), 
-            False, verbose)
-        self.build_package(
-            os.path.join(settings.MEDIA_ROOT, settings.CATALOGUE_PACKAGE_STUDENT),
-            True, verbose)
+        for level in Level.objects.all():
+            level.build_packages()
diff --git a/catalogue/migrations/0014_auto__add_field_section_summary.py b/catalogue/migrations/0014_auto__add_field_section_summary.py
new file mode 100644 (file)
index 0000000..7805ec7
--- /dev/null
@@ -0,0 +1,94 @@
+# -*- 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 'Section.summary'
+        db.add_column(u'catalogue_section', 'summary',
+                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.summary'
+        db.delete_column(u'catalogue_section', 'summary')
+
+
+    models = {
+        u'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'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', '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': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", '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'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", '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
diff --git a/catalogue/migrations/0015_auto__add_field_lesson_description.py b/catalogue/migrations/0015_auto__add_field_lesson_description.py
new file mode 100644 (file)
index 0000000..6d7dd5d
--- /dev/null
@@ -0,0 +1,95 @@
+# -*- 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.description'
+        db.add_column(u'catalogue_lesson', 'description',
+                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Lesson.description'
+        db.delete_column(u'catalogue_lesson', 'description')
+
+
+    models = {
+        u'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'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', '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': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", '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'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", '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
diff --git a/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py b/catalogue/migrations/0016_auto__add_field_section_pic__add_field_section_pic_attribution__add_fi.py
new file mode 100644 (file)
index 0000000..6be3fcf
--- /dev/null
@@ -0,0 +1,114 @@
+# -*- 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 'Section.pic'
+        db.add_column(u'catalogue_section', 'pic',
+                      self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Section.pic_attribution'
+        db.add_column(u'catalogue_section', 'pic_attribution',
+                      self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Section.pic_src'
+        db.add_column(u'catalogue_section', 'pic_src',
+                      self.gf('django.db.models.fields.URLField')(max_length=200, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Section.pic'
+        db.delete_column(u'catalogue_section', 'pic')
+
+        # Deleting field 'Section.pic_attribution'
+        db.delete_column(u'catalogue_section', 'pic_attribution')
+
+        # Deleting field 'Section.pic_src'
+        db.delete_column(u'catalogue_section', 'pic_src')
+
+
+    models = {
+        u'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'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Lesson']"}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'catalogue.lesson': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'Lesson'},
+            'curriculum_courses': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['curriculum.CurriculumCourse']", 'symmetrical': 'False', 'blank': 'True'}),
+            'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '255', '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': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'catalogue.lessonstub': {
+            'Meta': {'ordering': "['section', 'level', 'order']", 'object_name': 'LessonStub'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"}),
+            'order': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['catalogue.Section']", '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'})
+        },
+        u'catalogue.part': {
+            'Meta': {'object_name': 'Part'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': u"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'})
+        },
+        u'catalogue.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'pic': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'pic_attribution': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'pic_src': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '255'}),
+            'summary': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", '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 239f60c..4af4810 100644 (file)
@@ -1,8 +1,11 @@
+# -*- coding: utf-8
 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, Curriculum, CurriculumCourse
 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, Curriculum, CurriculumCourse
+import logging
+
 
 
 class Section(models.Model):
 
 
 class Section(models.Model):
@@ -14,6 +17,12 @@ class Section(models.Model):
     image = models.ImageField(upload_to="catalogue/section/image",
         null=True, blank=True)
 
     image = models.ImageField(upload_to="catalogue/section/image",
         null=True, blank=True)
 
+    pic = models.ImageField(upload_to="catalogue/section/pic", null=True, blank=True)
+    pic_attribution = models.CharField(max_length=255, null=True, blank=True)
+    pic_src = models.URLField(null=True, blank=True)
+    
+    summary = models.TextField(blank=True, null=True)
+
     class Meta:
         ordering = ['order']
 
     class Meta:
         ordering = ['order']
 
@@ -24,20 +33,22 @@ class Section(models.Model):
         return self.title
 
     def get_absolute_url(self):
         return self.title
 
     def get_absolute_url(self):
-        return "%s#%s" % (reverse("catalogue_lessons"), self.slug)
+        return "%s#gimnazjum_%s" % (reverse("catalogue_lessons"), self.slug)
 
     @classmethod
 
     @classmethod
-    def publish(cls, infile):
+    def publish(cls, infile, ignore_incomplete=False):
         from librarian.parser import WLDocument
         from django.core.files.base import ContentFile
         xml = infile.get_string()
         wldoc = WLDocument.from_string(xml)
 
         from librarian.parser import WLDocument
         from django.core.files.base import ContentFile
         xml = infile.get_string()
         wldoc = WLDocument.from_string(xml)
 
-        try:
-            lessons = [Lesson.objects.get(slug=part.slug)
-                        for part in wldoc.book_info.parts]
-        except Lesson.DoesNotExist, e:
-            raise cls.IncompleteError(part.slug)
+        lessons = []
+        for part in wldoc.book_info.parts:
+            try:
+                lessons.append(Lesson.objects.get(slug=part.slug))
+            except Lesson.DoesNotExist, e:
+                if not ignore_incomplete:
+                    raise cls.IncompleteError(part.slug)
 
         slug = wldoc.book_info.url.slug
         try:
 
         slug = wldoc.book_info.url.slug
         try:
@@ -74,6 +85,7 @@ class Lesson(models.Model):
     order = models.IntegerField(db_index=True)
     dc = JSONField(default='{}')
     curriculum_courses = models.ManyToManyField(CurriculumCourse, blank=True)
     order = models.IntegerField(db_index=True)
     dc = JSONField(default='{}')
     curriculum_courses = models.ManyToManyField(CurriculumCourse, blank=True)
+    description = models.TextField(null=True, blank=True)
 
     xml_file = models.FileField(upload_to="catalogue/lesson/xml",
         null=True, blank=True, max_length=255)
 
     xml_file = models.FileField(upload_to="catalogue/lesson/xml",
         null=True, blank=True, max_length=255)
@@ -99,7 +111,7 @@ class Lesson(models.Model):
         return ('catalogue_lesson', [self.slug])
 
     @classmethod
         return ('catalogue_lesson', [self.slug])
 
     @classmethod
-    def publish(cls, infile):
+    def publish(cls, infile, ignore_incomplete=False):
         from librarian.parser import WLDocument
         from django.core.files.base import ContentFile
         xml = infile.get_string()
         from librarian.parser import WLDocument
         from django.core.files.base import ContentFile
         xml = infile.get_string()
@@ -107,8 +119,8 @@ class Lesson(models.Model):
 
         # Check if not section metadata block.
         if wldoc.book_info.parts:
 
         # Check if not section metadata block.
         if wldoc.book_info.parts:
-            return Section.publish(infile)
-        
+            return Section.publish(infile, ignore_incomplete=ignore_incomplete)
+
         slug = wldoc.book_info.url.slug
         try:
             lesson = cls.objects.get(slug=slug)
         slug = wldoc.book_info.url.slug
         try:
             lesson = cls.objects.get(slug=slug)
@@ -120,13 +132,14 @@ class Lesson(models.Model):
         lesson.xml_file.save('%s.xml' % slug, ContentFile(xml), save=False)
         lesson.title = wldoc.book_info.title
 
         lesson.xml_file.save('%s.xml' % slug, ContentFile(xml), save=False)
         lesson.title = wldoc.book_info.title
 
-        lesson.level = Level.objects.get(slug=wldoc.book_info.audience)
+        lesson.level = Level.objects.get(meta_name=wldoc.book_info.audience)
         lesson.populate_dc()
         lesson.populate_dc()
+        lesson.populate_description(wldoc=wldoc)
         lesson.build_html(infile=infile)
         lesson.build_html(infile=infile)
-        lesson.build_pdf(infile=infile)
+        lesson.build_pdf()
         lesson.build_package()
         if lesson.type != 'project':
         lesson.build_package()
         if lesson.type != 'project':
-            lesson.build_pdf(student=True, infile=infile)
+            lesson.build_pdf(student=True)
             lesson.build_package(student=True)
         return lesson
 
             lesson.build_package(student=True)
         return lesson
 
@@ -135,18 +148,34 @@ class Lesson(models.Model):
         wldoc = WLDocument.from_file(self.xml_file.path)
         self.dc = wldoc.book_info.to_dict()
         self.type = self.dc["type"]
         wldoc = WLDocument.from_file(self.xml_file.path)
         self.dc = wldoc.book_info.to_dict()
         self.type = self.dc["type"]
+        assert self.type in ('appendix', 'course', 'synthetic', 'project'), \
+            u"Unknown lesson type: %s" % self.type
         self.save()
 
         courses = set()
         for identifier in wldoc.book_info.curriculum:
         self.save()
 
         courses = set()
         for identifier in wldoc.book_info.curriculum:
+            identifier = (identifier or "").replace(' ', '')
+            if not identifier: continue
             try:
             try:
-                curr = Curriculum.objects.get(identifier=identifier)
+                curr = Curriculum.objects.get(identifier__iexact=identifier)
             except Curriculum.DoesNotExist:
             except Curriculum.DoesNotExist:
+                logging.warn('Unknown curriculum course %s in lesson %s' % (identifier, self.slug))
                 pass
             else:
                 courses.add(curr.course)
         self.curriculum_courses = courses
 
                 pass
             else:
                 courses.add(curr.course)
         self.curriculum_courses = courses
 
+    def populate_description(self, wldoc=None, infile=None):
+        if wldoc is None:
+            wldoc = self.wldocument(infile)
+        for nagl in wldoc.edoc.findall('.//naglowek_rozdzial'):
+            if (nagl.text or '').strip() == u'Pomysł na lekcję':
+                from lxml import etree
+                self.description = etree.tostring(nagl.getnext(),
+                        method='text', encoding='unicode').strip()
+                self.save()
+                return
+
     def wldocument(self, infile=None):
         from librarian import IOFile
         from librarian.parser import WLDocument
     def wldocument(self, infile=None):
         from librarian import IOFile
         from librarian.parser import WLDocument
@@ -166,9 +195,11 @@ class Lesson(models.Model):
         self.html_file.save("%s.html" % self.slug,
             File(open(html.get_filename())))
 
         self.html_file.save("%s.html" % self.slug,
             File(open(html.get_filename())))
 
-    def build_pdf(self, student=False, infile=None):
+    def build_pdf(self, student=False):
         from .publish import PdfFormat
         from .publish import PdfFormat
-        wldoc = self.wldocument(infile)
+        # PDF uses document with attachments already saved as media,
+        # otherwise sorl.thumbnail complains about SuspiciousOperations.
+        wldoc = self.wldocument()
         if student:
             pdf = PdfFormat(wldoc).build()
             self.student_pdf.save("%s.pdf" % self.slug,
         if student:
             pdf = PdfFormat(wldoc).build()
             self.student_pdf.save("%s.pdf" % self.slug,
@@ -230,6 +261,9 @@ class Lesson(models.Model):
         except IndexError:
             return None
 
         except IndexError:
             return None
 
+    def requires_internet(self):
+        return 'internet' in self.dc.get('requires', [])
+
 
 class Attachment(models.Model):
     slug = models.CharField(max_length=255)
 
 class Attachment(models.Model):
     slug = models.CharField(max_length=255)
@@ -265,3 +299,10 @@ class LessonStub(models.Model):
 
     def __unicode__(self):
         return self.title
 
     def __unicode__(self):
         return self.title
+
+    @property
+    def slug(self):
+        return ''
+
+    def add_to_zip(self, *args, **kwargs):
+        pass
index 9f79dae..cca25de 100755 (executable)
@@ -1,13 +1,56 @@
 # -*- coding: utf-8
 from django.core.files.base import ContentFile
 from django.core.files import File
 # -*- coding: utf-8
 from django.core.files.base import ContentFile
 from django.core.files import File
+from django.core.urlresolvers import reverse
 from librarian import DocProvider, IOFile
 from librarian.pyhtml import EduModuleFormat
 from librarian.pypdf import EduModulePDFFormat
 from .models import Lesson, Attachment
 from librarian import DocProvider, IOFile
 from librarian.pyhtml import EduModuleFormat
 from librarian.pypdf import EduModulePDFFormat
 from .models import Lesson, Attachment
+from fnpdjango.utils.text.slughifi import slughifi
+
+
+# TODO: Using sorl.thumbnail for now,
+# but this should be done in Librarian,
+# directly using convert or PIL as a fallback.
+def get_image(src_img_path, width=None,
+        default_width=1600, formats=('PNG', 'JPEG', 'GIF')):
+    """ Returns an object with `url` and `storage` attributes,
+        or None if using the original image is OK.
+    """
+    
+    from PIL import Image
+    from sorl.thumbnail import get_thumbnail
+    
+    # Does it need converting?
+    # Yes, if width is given explicitly.
+    convert = width is not None
+    if not convert:
+        # Looks like it doesn't need converting.
+        # But let's try opening it and checking its type.
+        try:
+            simg = Image.open(src_img_path)
+        except IOError:
+            # It doesn't look like image,
+            # but maybe it's convertable to one.
+            convert = True
+        else:
+            if simg.format not in formats:
+                # It's an image, but it's in some weird format.
+                convert = True
+                width = simg.size[0]
+
+    if convert:
+        if width is None:
+            width = default_width
+        return get_thumbnail(src_img_path, '%sx%s' % (width, 10*width))
+    else:
+        return None
 
 
 class HtmlFormat(EduModuleFormat):
 
 
 class HtmlFormat(EduModuleFormat):
+    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
+    DEFAULT_IMAGE_WIDTH = 1600
+
     def find_attachment(self, slug, fmt):
         lesson_slug = self.wldoc.book_info.url.slug
         try:
     def find_attachment(self, slug, fmt):
         lesson_slug = self.wldoc.book_info.url.slug
         try:
@@ -34,35 +77,45 @@ class HtmlFormat(EduModuleFormat):
         return self.find_attachment(slug, fmt).file.url
 
     def url_for_image(self, slug, fmt, width=None):
         return self.find_attachment(slug, fmt).file.url
 
     def url_for_image(self, slug, fmt, width=None):
-        if width is None:
-            return self.url_for_material(slug, fmt)
-
-        lesson_slug = self.wldoc.book_info.url.slug
-        th_slug = "thumb/%s__th%d" % (slug, width)
         try:
         try:
-            # If already saved, use it.
-            att = Attachment.objects.get(lesson__slug=lesson_slug,
-                                         slug=th_slug, ext=fmt)
-        except Attachment.DoesNotExist, e:
-            from PIL import Image
-            from StringIO import StringIO
-            # Find full image, create thumbnail, save.
-            src_att = self.find_attachment(slug, fmt)
-            simg = Image.open(src_att.file.path)
-            size = (width, simg.size[1]*width/simg.size[0])
-            simg = simg.resize(size, Image.ANTIALIAS)
-
-            tempfile = StringIO()
-            img_format = "JPEG" if fmt.upper() == "JPG" else fmt
-            simg.save(tempfile, format=img_format)
-            att_name = "%s.%s" % (th_slug, fmt)
-            lesson = Lesson.objects.get(slug=lesson_slug)
-            att = lesson.attachment_set.create(slug=th_slug, ext=fmt)
-            att.file.save(att_name, ContentFile(tempfile.getvalue()))
-        return att.file.url
+            src_img = self.find_attachment(slug, fmt).file
+        except self.MaterialNotFound:
+            return ''
+        img = get_image(src_img.path, width,
+            self.DEFAULT_IMAGE_WIDTH, self.IMAGE_FORMATS)
+        return (img or src_img).url
+
+    def text_to_anchor(self, text):
+        return slughifi(text)
+
+    def get_forma_url(self, forma):
+        return '%s#%s' % (
+            reverse('catalogue_lesson', args=['metody']),
+            self.text_to_anchor(forma)
+        )
+
+    def get_help_url(self, naglowek):
+        return '%s%s#%s' % (
+            '//edukacjamedialna.edu.pl',
+            reverse('info', args=['jak-korzystac/']),
+            self.naglowek_to_anchor(naglowek)
+        )
+
 
 class PdfFormat(EduModulePDFFormat):
 
 class PdfFormat(EduModulePDFFormat):
-    pass
+    IMAGE_FORMATS = ('PNG', 'JPEG', 'GIF')
+    DEFAULT_IMAGE_WIDTH = 1600
+
+    def get_image(self, name):
+        src_img = super(PdfFormat, self).get_image(name)
+        img = get_image(src_img.get_filename(),
+                default_width=self.DEFAULT_IMAGE_WIDTH,
+                formats=self.IMAGE_FORMATS
+            )
+        if img:
+            return IOFile.from_filename(img.storage.path(img))
+        else:
+            return src_img
 
 
 class OrmDocProvider(DocProvider):
 
 
 class OrmDocProvider(DocProvider):
index 968e8d1..a7f365c 100644 (file)
@@ -2,12 +2,12 @@
   float: left;
   position: relative;
   width: 43.75em;
   float: left;
   position: relative;
   width: 43.75em;
-  height: 14.688em;
+  height: 14.6875em;
   overflow: hidden;
   overflow: hidden;
-  border-radius: 0.938em; }
+  border-radius: 0.9375em; }
   #catalogue-carousel #catalogue-carousel-links {
     width: 28.75em;
   #catalogue-carousel #catalogue-carousel-links {
     width: 28.75em;
-    height: 14.688em;
+    height: 14.6875em;
     list-style: none;
     margin: 0;
     padding: 0; }
     list-style: none;
     margin: 0;
     padding: 0; }
       left: 0;
       height: 100%;
       background-size: 100% 100%;
       left: 0;
       height: 100%;
       background-size: 100% 100%;
-      border-top-left-radius: 0.938em 6.38%;
-      border-bottom-left-radius: 0.938em 6.38%; }
-      #catalogue-carousel #catalogue-carousel-links li a {
+      border-top-left-radius: 0.9375em 6.38%;
+      border-bottom-left-radius: 0.9375em 6.38%;
+      z-index: 100;
+      background-color: #888; }
+      #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link {
         display: block;
         overflow: hidden;
         width: 28.75em;
         height: 100%;
         background: url(/static/catalogue/img/carousel-left.png) 100% 0 no-repeat;
         background-size: 4.375em 100%; }
         display: block;
         overflow: hidden;
         width: 28.75em;
         height: 100%;
         background: url(/static/catalogue/img/carousel-left.png) 100% 0 no-repeat;
         background-size: 4.375em 100%; }
-        #catalogue-carousel #catalogue-carousel-links li a .catalogue-carousel-note {
+        #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note {
           position: relative;
           height: 100%;
           color: white;
           position: relative;
           height: 100%;
           color: white;
-          margin-top: 12em; }
-          #catalogue-carousel #catalogue-carousel-links li a .catalogue-carousel-note p:before {
+          margin-top: 8.5em; }
+          #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div:before {
             content: " ";
             display: block;
             position: absolute;
             content: " ";
             display: block;
             position: absolute;
             z-index: -1;
             background-color: black;
             opacity: 0.6; }
             z-index: -1;
             background-color: black;
             opacity: 0.6; }
-          #catalogue-carousel #catalogue-carousel-links li a .catalogue-carousel-note p {
-            margin: 0; }
-            #catalogue-carousel #catalogue-carousel-links li a .catalogue-carousel-note p em {
-              margin: 0 .2em 0 .5em;
-              font-style: normal;
-              font-size: 1.5em; }
-            #catalogue-carousel #catalogue-carousel-links li a .catalogue-carousel-note p strong {
-              margin-left: .5em;
-              font-size: 2em; }
-      #catalogue-carousel #catalogue-carousel-links li a:active {
+          #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p {
+            padding: .4em 3em 0 .5em; }
+            #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p strong {
+              font-size: 1.2em;
+              display: block; }
+            #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link .catalogue-carousel-note div p .more {
+              position: absolute;
+              right: 4em;
+              top: 4.5em; }
+      #catalogue-carousel #catalogue-carousel-links li a.catalogue-carousel-link:active {
         outline: none; }
         outline: none; }
+      #catalogue-carousel #catalogue-carousel-links li .attribution {
+        text-align: right;
+        font-size: .75em;
+        position: absolute;
+        right: 5em;
+        top: .1em;
+        color: white;
+        font-weight: bold;
+        text-shadow: 0 0 5px #000; }
   #catalogue-carousel #catalogue-carousel-switcher {
     margin: 0;
   #catalogue-carousel #catalogue-carousel-switcher {
     margin: 0;
-    padding: 3.125em 0 0 3.625em;
+    padding: 1.25em 0 0 3.625em;
     width: 11.375em;
     width: 11.375em;
-    height: 11.563em;
+    height: 13.4375em;
     position: absolute;
     right: 0;
     top: 0;
     list-style: none;
     position: absolute;
     right: 0;
     top: 0;
     list-style: none;
-    border-radius: 0 0.938em 0.938em 0;
+    border-radius: 0 0.9375em 0.9375em 0;
     background-color: #ed7831;
     background-image: url(/static/catalogue/img/carousel-right.png);
     background-position: 0 0;
     background-repeat: no-repeat;
     background-color: #ed7831;
     background-image: url(/static/catalogue/img/carousel-right.png);
     background-position: 0 0;
     background-repeat: no-repeat;
-    background-size: auto 14.688em;
+    background-size: auto 14.6875em;
     /* right part of mask as background */ }
     #catalogue-carousel #catalogue-carousel-switcher li {
     /* right part of mask as background */ }
     #catalogue-carousel #catalogue-carousel-switcher li {
-      margin-bottom: .9em; }
+      margin-bottom: .5em;
+      font-size: .85em;
+      line-height: 1em; }
       #catalogue-carousel #catalogue-carousel-switcher li a {
         text-transform: uppercase;
       #catalogue-carousel #catalogue-carousel-switcher li a {
         text-transform: uppercase;
-        color: #363a3e;
-        font-size: .9em;
-        font-weight: bold; }
+        color: #363a3e; }
       #catalogue-carousel #catalogue-carousel-switcher li a:before {
         vertical-align: top;
         margin-right: 1.5em; }
       #catalogue-carousel #catalogue-carousel-switcher li a:before {
         vertical-align: top;
         margin-right: 1.5em; }
index 079ec3a..bc2041d 100755 (executable)
@@ -27,8 +27,10 @@ $ciemny: #363a3e;
             background-size: 100% 100%;
             border-top-left-radius: 15*$px 6.38%;
             border-bottom-left-radius: 15*$px 6.38%;
             background-size: 100% 100%;
             border-top-left-radius: 15*$px 6.38%;
             border-bottom-left-radius: 15*$px 6.38%;
+            z-index: 100;
+            background-color: #888;
 
 
-            a {
+            a.catalogue-carousel-link {
                 display: block;
                 overflow: hidden;
                 width: 460*$px;
                 display: block;
                 overflow: hidden;
                 width: 460*$px;
@@ -40,44 +42,58 @@ $ciemny: #363a3e;
                     position: relative;
                     height: 100%;
                     color: white;
                     position: relative;
                     height: 100%;
                     color: white;
-                    margin-top: 12em;
-
-                    p:before {
-                        content: " ";
-                        display: block;
-                        position: absolute;
-                        height: 100%;
-                        width: 100%;
-                        z-index: -1;
-                        background-color: black;
-                        opacity: 0.6;
-                    }
+                    margin-top: 8.5em;
 
 
-                    p {
-                        margin: 0;
-                        em {
-                            margin: 0 .2em 0 .5em;
-                            font-style: normal;
-                            font-size: 1.5em;
+                    div {
+                        &:before {
+                            content: " ";
+                            display: block;
+                            position: absolute;
+                            height: 100%;
+                            width: 100%;
+                            z-index: -1;
+                            background-color: black;
+                            opacity: 0.6;
                         }
                         }
-                        strong {
-                            margin-left: .5em;
-                            font-size: 2em;
+
+                        p {
+                            padding: .4em 3em 0 .5em;
+
+                            strong {
+                                font-size: 1.2em;
+                                display: block;
+                            }
+
+                            .more {
+                                position: absolute;
+                                right: 4em;
+                                top: 4.5em;
+                            }
                         }
                         }
-                        
                     }
                 }
             }
                     }
                 }
             }
-            a:active {
+            a.catalogue-carousel-link:active {
                 outline: none;
             }
                 outline: none;
             }
+            .attribution {
+                text-align: right;
+                font-size: .75em;
+                position: absolute;
+                right: 5em;
+                top: .1em;
+                color: white;
+                font-weight: bold;
+                text-shadow: 0 0 5px #000;
+            }
+
         }
     }
     #catalogue-carousel-switcher {
         margin: 0;
         }
     }
     #catalogue-carousel-switcher {
         margin: 0;
-        padding: 50*$px 0 0 58*$px;
+        padding: 20*$px 0 0 58*$px;
         width: 240*$px - 58*$px;
         width: 240*$px - 58*$px;
-        height: 235*$px - 50*$px;
+        height: 235*$px - 20*$px;
         position: absolute;
         right: 0;
         top: 0;
         position: absolute;
         right: 0;
         top: 0;
@@ -92,13 +108,13 @@ $ciemny: #363a3e;
         /* right part of mask as background */
 
         li {
         /* right part of mask as background */
 
         li {
-            margin-bottom: .9em;
+            margin-bottom: .5em;
+            font-size: .85em;
+            line-height: 1em;
 
             a {
                 text-transform: uppercase;
                 color: $ciemny;
 
             a {
                 text-transform: uppercase;
                 color: $ciemny;
-                font-size: .9em;
-                font-weight: bold;
             }
             a:before {
                 vertical-align: top;
             }
             a:before {
                 vertical-align: top;
index 09ff5af..acf699d 100644 (file)
@@ -1,4 +1,25 @@
 @charset "UTF-8";
 @charset "UTF-8";
+.box-button {
+  background-color: #ed7831;
+  border-radius: 0.9375em; }
+  .box-button .dl-button {
+    color: white;
+    padding: 1.0625em 0.75em 1.0625em 0.75em; }
+
+.dl-button {
+  color: #363a3e;
+  display: block;
+  font-weight: bold;
+  text-align: center;
+  text-transform: uppercase;
+  font-size: .9em; }
+
+.dl-button:after {
+  content: " ↓"; }
+
+#main-bar section.button {
+  margin-bottom: 1.0625em; }
+
 #sidebar {
   position: absolute;
   right: 0;
 #sidebar {
   position: absolute;
   right: 0;
   width: 13.75em;
   color: #363a3e; }
   #sidebar section {
   width: 13.75em;
   color: #363a3e; }
   #sidebar section {
-    margin-bottom: 1.063em; }
+    margin-bottom: 1.0625em; }
     #sidebar section h1 {
       margin: 0; }
     #sidebar section h1.realisation {
       font-weight: normal; }
     #sidebar section h1 {
       margin: 0; }
     #sidebar section h1.realisation {
       font-weight: normal; }
-  #sidebar .box {
-    background-color: #d4d6d8;
-    border-radius: 0.938em;
-    padding: 1.063em 0.75em 1.063em 0.75em; }
-    #sidebar .box h1 {
-      font-size: 1em;
-      text-transform: uppercase; }
-  #sidebar .box-button {
-    background-color: #ed7831;
-    border-radius: 0.938em; }
-    #sidebar .box-button .dl-button {
-      color: white;
-      padding: 1.063em 0.75em 1.063em 0.75em; }
-  #sidebar .dl-button {
-    color: #363a3e;
-    display: block;
-    font-weight: bold;
-    text-align: center;
-    text-transform: uppercase;
-    font-size: .9em; }
-  #sidebar .dl-button:after {
-    content: " ↓"; }
   #sidebar .section {
     border-top: 1px solid #c9ccce;
   #sidebar .section {
     border-top: 1px solid #c9ccce;
-    padding-top: 1.063em; }
+    padding-top: 1.0625em; }
   #sidebar .section-minor {
     border-top: 1px solid #c9ccce;
   #sidebar .section-minor {
     border-top: 1px solid #c9ccce;
-    padding-top: 1.063em; }
+    padding-top: 1.0625em; }
     #sidebar .section-minor h1 {
       font-weight: normal;
       font-size: 1em; }
     #sidebar .section-minor h1 {
       font-weight: normal;
       font-size: 1em; }
     font-size: .8em;
     color: #888;
     border-top: 1px solid #c9ccce;
     font-size: .8em;
     color: #888;
     border-top: 1px solid #c9ccce;
-    padding-top: 1.063em; }
+    padding-top: 1.0625em; }
     #sidebar .section-micro h1 {
       font-weight: normal;
       font-size: 1em; }
     #sidebar .section-micro .link-list a {
       color: #888; }
     #sidebar .section-micro h1 {
       font-weight: normal;
       font-size: 1em; }
     #sidebar .section-micro .link-list a {
       color: #888; }
+  #sidebar section:first-child {
+    border-top: 0;
+    padding-top: 0; }
 
 #main-bar {
   width: 40em; }
   #main-bar .top-link {
     float: right; }
 
 #main-bar {
   width: 40em; }
   #main-bar .top-link {
     float: right; }
+  #main-bar .box {
+    background-color: #d4d6d8;
+    border-radius: 0.9375em;
+    padding: 1.0625em; }
+    #main-bar .box h1 {
+      font-size: 1em;
+      text-transform: uppercase; }
+    #main-bar .box p {
+      margin: 0; }
+    #main-bar .box .box-icon {
+      margin: -.2em 0 -.2em 1em;
+      float: right;
+      text-align: center; }
 
 .lesson-footer {
   clear: both;
 
 .lesson-footer {
   clear: both;
index 7bea63a..230e4aa 100755 (executable)
@@ -1,6 +1,30 @@
 $px: .0625em;
 $new_black: #363a3e;
 
 $px: .0625em;
 $new_black: #363a3e;
 
+.box-button {
+    background-color: #ed7831;
+    border-radius: 15*$px;
+    .dl-button {
+        color: white;
+        padding: 17*$px 12*$px 17*$px 12*$px;
+    }
+}
+.dl-button {
+    color: $new_black;
+    display: block;
+    font-weight: bold;
+    text-align: center;
+    text-transform: uppercase;
+    font-size: .9em;
+}
+.dl-button:after {
+    content: " ↓";
+}
+
+#main-bar section.button {
+    margin-bottom: 17*$px;
+}
+
 #sidebar {
     position: absolute;
     right: 0;
 #sidebar {
     position: absolute;
     right: 0;
@@ -18,34 +42,6 @@ $new_black: #363a3e;
         }
     }
 
         }
     }
 
-    .box {
-        background-color: #d4d6d8;
-        border-radius: 15*$px;
-        padding: 17*$px 12*$px 17*$px 12*$px;
-        h1 {
-            font-size: 1em;
-            text-transform: uppercase;
-        }
-    }
-    .box-button {
-        background-color: #ed7831;
-        border-radius: 15*$px;
-        .dl-button {
-            color: white;
-            padding: 17*$px 12*$px 17*$px 12*$px;
-        }
-    }
-    .dl-button {
-        color: $new_black;
-        display: block;
-        font-weight: bold;
-        text-align: center;
-        text-transform: uppercase;
-        font-size: .9em;
-    }
-    .dl-button:after {
-        content: " ↓";
-    }
     .section {
         border-top: 1px solid #c9ccce;
         padding-top: 17*$px;
     .section {
         border-top: 1px solid #c9ccce;
         padding-top: 17*$px;
@@ -71,6 +67,10 @@ $new_black: #363a3e;
             color: #888;
         }
     }
             color: #888;
         }
     }
+    section:first-child {
+        border-top: 0;
+        padding-top: 0;
+    }
 }
 #main-bar {
     width: 640*$px;
 }
 #main-bar {
     width: 640*$px;
@@ -78,6 +78,24 @@ $new_black: #363a3e;
     .top-link {
         float:right;
     }
     .top-link {
         float:right;
     }
+
+    .box {
+        background-color: #d4d6d8;
+        border-radius: 15*$px;
+        padding: 17*$px;
+        h1 {
+            font-size: 1em;
+            text-transform: uppercase;
+        }
+        p {
+            margin: 0;
+        }
+        .box-icon {
+            margin: -.2em 0 -.2em 1em;
+            float: right;
+            text-align: center;
+        }
+    }
 }
 
 .lesson-footer {
 }
 
 .lesson-footer {
index b51e7f3..c8e73c4 100644 (file)
@@ -207,15 +207,15 @@ em.person {
     font-size: 2em; }
   .activity .info {
     float: right;
     font-size: 2em; }
   .activity .info {
     float: right;
-    width: 8.438em; }
+    width: 8.4375em; }
     .activity .info .infobox {
       padding: 1em 0;
       border-top: 1px solid #c9ccce; }
       .activity .info .infobox h1 {
         text-transform: uppercase;
         font-weight: bold;
     .activity .info .infobox {
       padding: 1em 0;
       border-top: 1px solid #c9ccce; }
       .activity .info .infobox h1 {
         text-transform: uppercase;
         font-weight: bold;
-        margin: 0 0 0.5em -2.188em;
-        padding-left: 2.188em;
+        margin: 0 0 0.5em -2.1875em;
+        padding-left: 2.1875em;
         line-height: 24px;
         font-size: 1em; }
       .activity .info .infobox p {
         line-height: 24px;
         font-size: 1em; }
       .activity .info .infobox p {
@@ -246,3 +246,9 @@ em.person {
 
 #book-text .top-link {
   margin-top: 1em; }
 
 #book-text .top-link {
   margin-top: 1em; }
+
+.help {
+  font-size: .7em;
+  padding: 0 .5em;
+  color: #888;
+  vertical-align: super; }
index b200002..d98f1a3 100755 (executable)
@@ -318,3 +318,10 @@ em.person {
 #book-text .top-link {
     margin-top: 1em;
 }
 #book-text .top-link {
     margin-top: 1em;
 }
+
+.help {
+    font-size: .7em;
+    padding: 0 .5em;
+    color: #888;
+    vertical-align: super;
+}
index 15c44ca..1a45397 100644 (file)
@@ -1,84 +1,54 @@
-.section-level {
-  width: 40em;
-  border-radius: 0.9375em;
-  margin: 1em 0;
-  overflow: hidden; }
-  .section-level a:hover {
-    text-decoration: underline; }
-
-.sections-row {
-  display: table; }
-
-.section-type {
-  display: table-cell;
-  vertical-align: top;
-  padding: 1.25em; }
-  .section-type h1 {
+#level-chooser-place {
+  min-height: 4em;
+  margin-top: 2em; }
+  #level-chooser-place ul#level-chooser {
+    margin: 0;
+    padding: 1em 0 1em 8.75em;
+    background-color: white;
+    width: 31.25em;
+    z-index: 300;
+    position: relative;
     text-transform: uppercase;
     text-transform: uppercase;
-    margin: 0 0 1em 0;
-    font-size: 1em; }
-  .section-type img {
-    float: left;
-    margin-right: 1em;
-    margin-bottom: 1em;
-    border: 0.375em solid white; }
-
-.section-type-synthetic {
-  width: 18.75em; }
-
-.section-type-course {
-  width: 16.25em; }
-
-.section-type-project {
-  width: 37.5em; }
-
-.section-level-gimnazjum {
-  background: #f4ae83;
-  color: #67584f; }
-  .section-level-gimnazjum a, .section-level-gimnazjum a:hover {
-    color: #67584f; }
-  .section-level-gimnazjum .section-type-course {
-    background: #ed7831;
-    color: #fff; }
-    .section-level-gimnazjum .section-type-course a {
-      color: #fff; }
-  .section-level-gimnazjum .section-type-project {
-    background-color: #f8cdb2; }
-
-.section-level-liceum {
-  background: #44b69f;
-  color: #363a3e; }
-  .section-level-liceum a, .section-level-liceum a:hover {
-    color: #363a3e; }
-  .section-level-liceum .section-type-course {
-    background: #16a487;
-    color: #fff; }
-    .section-level-liceum .section-type-course a {
-      color: #fff; }
-  .section-level-liceum .section-type-project {
-    background-color: #9fdbcf; }
-
-.course-boxes h1 {
-  color: #363a3e; }
-.course-boxes .section-level {
-  background: white;
-  border: 1px solid #777777; }
-  .course-boxes .section-level a, .course-boxes .section-level a:hover {
-    color: #363a3e; }
-  .course-boxes .section-level .section-type {
-    background: white; }
-.course-boxes .section-type-synthetic {
-  width: 16.25em; }
-.course-boxes .section-type-course {
-  width: 18.75em; }
-
-.section-links {
-  float: right; }
-
-h2.section-header {
-  margin: 0; }
-
-.section-list-toc {
-  display: inline-block;
-  vertical-align: top;
-  width: 18.75em; }
+    text-align: right; }
+    #level-chooser-place ul#level-chooser .home {
+      display: none;
+      position: absolute;
+      top: .5em;
+      left: 0; }
+      #level-chooser-place ul#level-chooser .home a {
+        background: none;
+        padding: 0; }
+        #level-chooser-place ul#level-chooser .home a img {
+          width: 6.25em; }
+    #level-chooser-place ul#level-chooser.fixed {
+      position: fixed;
+      top: 0;
+      border-bottom: 1px solid #c9ccce; }
+      #level-chooser-place ul#level-chooser.fixed .home {
+        display: block; }
+    #level-chooser-place ul#level-chooser li {
+      display: inline-block;
+      list-style: none; }
+      #level-chooser-place ul#level-chooser li a {
+        padding: .5em 1em;
+        border-radius: 0.3125em;
+        background: #eee; }
+        #level-chooser-place ul#level-chooser li a.active {
+          color: white;
+          background: #ED7831; }
+
+.level .link-list {
+  margin-left: 1em; }
+.level .level-toc {
+  overflow: hidden;
+  /* Because we're changing bg color lower. */ }
+  .level .level-toc.fixed {
+    position: fixed; }
+  .level .level-toc .link-list {
+    margin-left: 1em; }
+    .level .level-toc .link-list li {
+      margin-bottom: 0; }
+      .level .level-toc .link-list li.curriculumcourses {
+        margin: 10px -17px -17px;
+        padding: 10px 16px 16px;
+        background-color: #eee; }
index a9a1305..192e5b6 100755 (executable)
 $px: 0.0625em;
 
 $px: 0.0625em;
 
-.section-level {
-    width: 640*$px;
-    border-radius: 15*$px;
-    margin: 1em 0;
-    overflow: hidden;
-
-    a:hover {
-        text-decoration: underline;
-    }
-}
-
-.sections-row {
-    display: table;
-}
-
-.section-type {
-    display: table-cell;
-    vertical-align: top;
-    padding: 20*$px;
-
-    h1 {
+#level-chooser-place {
+    min-height: 4em;
+    margin-top: 2em;
+
+    ul#level-chooser {
+        margin: 0;
+        padding: 1em 0 1em 140*$px;
+        background-color: white;
+        width: 500*$px;
+        z-index: 300;
+        position: relative;
         text-transform: uppercase;
         text-transform: uppercase;
-        margin: 0 0 1em 0;
-        font-size: 1em;
-    }
-
-    img {
-        float: left;
-        margin-right: 16*$px;
-        margin-bottom: 16*$px;
-        border: 6*$px solid white;
-    }
-}
-.section-type-synthetic {
-    width: 340*$px - 2 * 20*$px;
-}
-.section-type-course {
-    width: 300*$px - 2 * 20*$px;
-}
-
-.section-type-project {
-    width: 640*$px - 2 * 20*$px;
-}
+        text-align: right;
+
+        .home {
+            display: none;
+            position: absolute;
+            top: .5em;
+            left: 0;
+
+            a {
+                background: none;
+                padding: 0;
+                img {
+                    width: 100*$px;
+                }
+            }
+        }
 
 
-.section-level-gimnazjum {
-    background: #f4ae83;
-    color: #67584f;
-    a, a:hover {
-        color: #67584f;
-    }
+        &.fixed {
+            position: fixed;
+            top: 0;
+            border-bottom: 1px solid #c9ccce;
 
 
-    .section-type-synthetic {
-    }
-    .section-type-course {
-        background: #ed7831;
-        color: #fff;
-        a {
-            color: #fff;
+            .home {
+                display: block;
+            }
         }
         }
-    }
-    .section-type-project {
-        background-color: lighten(#f4ae83, 10);
-    }
-}
 
 
+        li {
+            display: inline-block;
+            list-style: none;
 
 
-.section-level-liceum {
-    background: #44b69f;
-    color: #363a3e;
-    a, a:hover {
-        color: #363a3e;
-    }
+            a {
+                padding: .5em 1em;
+                border-radius: 5*$px;
+                background: #eee;
 
 
-    .section-type-synthetic {
-    }
-    .section-type-course {
-        background: #16a487;
-        color: #fff;
-        a {
-            color: #fff;
+                &.active {
+                    color: white;
+                    background: #ED7831;
+                }
+            }
         }
     }
         }
     }
-    .section-type-project {
-        background-color: lighten(#44b69f, 25);
-    }
 }
 
 }
 
-
-.course-boxes {
-    h1 {
-        color: #363a3e;
-    }
-    .section-level {
-        background: white;
-        border: 1px solid #777;
-        a, a:hover {
-            color: #363a3e;
-        }
-        .section-type {
-            background: white;
-        }
-    }
-    .section-type-synthetic {
-        width: 300*$px - 2 * 20*$px;
-    }
-    .section-type-course {
-        width: 340*$px - 2 * 20*$px;
+.level {
+    .link-list {
+        margin-left: 1em;
     }
     }
-}
 
 
+    .level-toc {
+        overflow: hidden; /* Because we're changing bg color lower. */
 
 
-.section-links {
-    float: right;
-}
+        &.fixed {
+            position: fixed;
+        }
 
 
-h2.section-header {
-    margin: 0;
-}
+        .link-list {
+            margin-left: 1em;
 
 
+            li {
+                margin-bottom: 0;
 
 
-.section-list-toc {
-    display: inline-block;
-    vertical-align: top;
-    width: 300*$px;
+                &.curriculumcourses {
+                    margin: 10px -17px -17px;
+                    padding: 10px 16px 16px;
+                    background-color: #eee;
+                }
+            }
+        }
+    }
 }
 }
index b7e5021..b2484be 100755 (executable)
@@ -2,31 +2,26 @@
 $(function() {
 
 
 $(function() {
 
 
-$.fn.cycle.transitions.rgrowY = function($cont, $slides, opts) {
-       opts.before.push(function(curr, next, opts) {
-               $.fn.cycle.commonReset(curr,next,opts,true,false,true);
-               opts.cssBefore.top = this.cycleH/2;
-               opts.animIn.top = 0;
-               opts.animIn.height = this.cycleH;
-               opts.animOut.top = this.cycleH/2;
-        opts.animOut.height = 0;
-       });
-       opts.cssBefore.height = 0;
-       opts.cssBefore.left = 0;
-};
-
 $("#catalogue-carousel-links").each(function() {
 $("#catalogue-carousel-links").each(function() {
-    $(this).cycle({
-        fx: 'rgrowY',
-        sync:false,
-        easeIn: 'easeInQuad',
-        easeOut: 'easeOutQuad',
+    $slides = $(this); 
+
+    $slides.cycle({
+        fx: 'fade',
         speed: 1000,
         speed: 1000,
+        timeout: 5000,
         pager: '#catalogue-carousel-switcher',
         pager: '#catalogue-carousel-switcher',
-        pagerAnchorBuilder: function(){},
+        pagerAnchorBuilder: function() {},
     });
     });
+
+    $("#catalogue-carousel-switcher li").each(function(i, e) {
+        $("a", e).click(function(ev) {
+            ev.preventDefault();
+            $slides.cycle(i);
+        });
+    });
+
 });
 
 
 });
 });
 
 
 });
-})($);
+})(jQuery);
diff --git a/catalogue/static/catalogue/js/lesson-list.js b/catalogue/static/catalogue/js/lesson-list.js
new file mode 100644 (file)
index 0000000..62bbb65
--- /dev/null
@@ -0,0 +1,60 @@
+(function($){
+$(function() {
+
+
+function scrollTo(thing) {
+    $('html, body').scrollTop($(thing).offset().top - $('#level-chooser').outerHeight());
+}
+
+function updateView() {
+    var scrolltop = $(window).scrollTop();
+
+    $('#level-chooser-place').each(function(i, el){
+        if (scrolltop > $(el).offset().top) {
+            $("#level-chooser").addClass("fixed");
+        }
+        else {
+            $("#level-chooser").removeClass("fixed");
+        }
+    });
+
+    $('.level-toc').each(function(i, el) {
+        var $sect = $($(el).parent());
+        var menu_top = $('#level-chooser').outerHeight();
+        var menu_scrolltop = scrolltop + menu_top;
+
+        if (menu_scrolltop + 2 >= $sect.offset().top && 
+                menu_scrolltop < $sect.offset().top + $sect.outerHeight()) {
+            $(el).addClass("fixed").css("top", Math.min(
+                menu_top, 
+                - scrolltop + $sect.offset().top + $sect.outerHeight() - $(el).outerHeight()
+            ));
+            $("#level-chooser a[href='#" + $sect.attr('id') + "']").addClass('active');
+        }
+        else {
+            $(el).removeClass("fixed");
+            $("#level-chooser a[href='#" + $sect.attr('id') + "']").removeClass('active');
+        }
+    });
+}
+
+
+
+$("#level-chooser a, .level-toc a").click(function(ev) {
+    ev.preventDefault();
+    scrollTo($(this).attr('href'));
+});
+
+
+
+
+
+updateView();
+$(document).scroll(updateView);
+if (window.location.hash) {
+    scrollTo(window.location.hash);
+}
+
+
+});
+})(jQuery);
index 6b22a83..080eb45 100755 (executable)
@@ -2,7 +2,10 @@
 $(function() {
 
 
 $(function() {
 
 
-$('a.image').colorbox();
+$('a.image').colorbox({
+    maxWidth: '100%',
+    maxHeight: '100%',
+});
 
 
 });
 
 
 });
index 7dce3c9..98b6e3b 100755 (executable)
@@ -1,22 +1,9 @@
 {% extends "catalogue/lesson/lesson_detail.html" %}
 
 {% extends "catalogue/lesson/lesson_detail.html" %}
 
-{% block sidebar-top %}
-
-<section class="box">
-    <h1 class="realisation">Zebrane dla wszystkich tematów</h1>
-    
-    <p>To jest materiał wspólny dla wszystkich lekcji
-    edukacji medialnej{% if object.level.slug = "liceum" %}
-        (na poziomie zaawansowanym)
-    {% endif %}. 
-    Zobacz też
-    <strong><a href="{% url 'catalogue_lessons' %}">pełny kurs</a></strong>
-    z podziałem na poszczególne tematy.
-    </p>
-</section>
-
+{% block lesson-info %}
 {% endblock %}
 
 {% endblock %}
 
+
 {% block suggest-link %}
 <a href="{% url 'contact_form' 'sugestie' %}?temat={{ object.title|urlencode }}">
     Zgłoś swoją uwagę na temat tej strony.
 {% block suggest-link %}
 <a href="{% url 'contact_form' 'sugestie' %}?temat={{ object.title|urlencode }}">
     Zgłoś swoją uwagę na temat tej strony.
diff --git a/catalogue/templates/catalogue/lesson/box-icons.html b/catalogue/templates/catalogue/lesson/box-icons.html
new file mode 100644 (file)
index 0000000..2963698
--- /dev/null
@@ -0,0 +1,18 @@
+{% load static from staticfiles %}
+{% if object.requires_internet %}
+<div class="box-icon"><img src="{% static 'img/icons/internet_black.png' %}"
+        title="Wymaga dostępu do Internetu"
+        alt="Wymaga dostępu do Internetu"
+    ><br>Internet</div>
+{% else %}
+<div class="box-icon"><img src="{% static 'img/icons/nointernet_black.png' %}"
+        title="Nie wymaga dostępu do Internetu"
+        alt="Nie wymaga dostępu do Internetu"
+        ><br>Bez Internetu</div>
+{% endif %}
+{% if publisher %}
+<div class="box-icon"><img src="{{ publisher.logo.url }}"
+        title="{{ publisher.name }}"
+        alt="{{ publisher.name }}"
+    ></div>
+{% endif %}
index cadc580..28f6504 100755 (executable)
@@ -1,24 +1,25 @@
 {% extends "catalogue/lesson/lesson_detail.html" %}
 {% extends "catalogue/lesson/lesson_detail.html" %}
+{% load static from staticfiles %}
 
 
-{% block sidebar-top %}
-
+{% block lesson-info %}
 <section class="box">
 <section class="box">
-    <h1 class="realisation">Realizacja i czas lekcji</h1>
+    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
+
+    {% include "catalogue/lesson/box-icons.html" %}
+
     <p>Ta lekcja jest częścią tematu
     <p>Ta lekcja jest częścią tematu
-    <a href="{{ object.section.get_absolute_url }}"><strong>{{ object.section }}</strong></a>{% if object.level.slug = "liceum" %}
-        (na poziomie zaawansowanym)
-    {% endif %}.
-    {% with object.get_syntetic as synth %}
-    {% if synth %}
-    Dostępna jest również
-    <strong><a href="{{ object.get_syntetic.get_absolute_url }}">lekcja syntetyczna</a></strong>
-    dla tego tematu.
-    {% endif %}
-    {% endwith %}
+    <a href="{{ object.section.get_absolute_url }}"><strong>{{ object.section }}</strong></a>
+    na poziomie {{ object.level|lower }}.
     </p>
     </p>
-    <p>Czas trwania: 45 minut.</p>
+    <div style="clear: right"></div>
 </section>
 
 </section>
 
+{% endblock %}
+
+
+{% block sidebar-top %}
+<div class="buttons" style="padding-bottom: 1em; border-bottom: 1px solid red;">
+
 {% if object.package %}
     <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
 {% endif %}
 {% if object.package %}
     <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
 {% endif %}
@@ -26,5 +27,5 @@
     <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
 {% endif %}
 
     <section><a href="{{ object.student_package.url }}" class="dl-button">Pobierz lekcję w wersji dla ucznia</a></section>
 {% endif %}
 
-
+</div>
 {% endblock %}
 {% endblock %}
index f08b5b8..362df10 100755 (executable)
 </aside>
 
 <div id="main-bar">
 </aside>
 
 <div id="main-bar">
+
+{% block lesson-info %}
+{% endblock %}
+
 {{ object.html_file.read|safe }}
 
 
 {{ object.html_file.read|safe }}
 
 
index 88e4a34..0c6d217 100755 (executable)
@@ -1,18 +1,25 @@
 {% extends "catalogue/lesson/lesson_detail.html" %}
 
 {% extends "catalogue/lesson/lesson_detail.html" %}
 
-{% block sidebar-top %}
-
+{% block lesson-info %}
 <section class="box">
 <section class="box">
-    <h1 class="realisation">Projekt</h1>
-    <p>To jest <a href="{% url 'info' 'metoda-projektowa' %}">projekt</a> w ramach tematu
-    <strong>{{ object.section }}</strong></a>{% if object.level.slug = "liceum" %}
-        (na poziomie zaawansowanym)
-    {% endif %}.
-    Dostępny jest również
-    <strong><a href="{% url 'catalogue_lessons' %}#{{ object.section.slug }}">pełny kurs</a></strong>
-    tego tematu.
+    {% if publisher %}
+    <div class="box-icon"><img src="{{ publisher.logo.url }}"
+            title="{{ publisher.name }}"
+            alt="{{ publisher.name }}"
+        ></div>
+    {% endif %}
+
+    <p>To jest <a href="{% url 'info' 'metoda-projektowa' %}">projekt</a> 
+    na poziomie
+    <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_pelny">{{ object.level|lower }}</a>.
     </p>
 </section>
     </p>
 </section>
+{% endblock %}
+
+
+
+{% block sidebar-top %}
+
 
 {% if object.package %}
     <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz cały projekt</a></section>
 
 {% if object.package %}
     <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz cały projekt</a></section>
index c7d04c8..df60c9f 100755 (executable)
@@ -1,19 +1,19 @@
 {% extends "catalogue/lesson/lesson_detail.html" %}
 
 {% extends "catalogue/lesson/lesson_detail.html" %}
 
-{% block sidebar-top %}
-
+{% block lesson-info %}
 <section class="box">
 <section class="box">
-    <h1 class="realisation">Realizacja i czas lekcji</h1>
-    <p>Ta lekcja jest syntezą tematu
-    <strong>{{ object.section }}</strong></a>{% if object.level.slug = "liceum" %}
-        (na poziomie zaawansowanym)
-    {% endif %}.
-    Dostępny jest również
-    <strong><a href="{% url 'catalogue_lessons' %}#{{ object.section.slug }}">pełny kurs</a></strong>
-    tego tematu.
+    <div class="box-icon"><img src="/static/img/icons/activity-time.png"><br>45m</div>
+
+    {% include "catalogue/lesson/box-icons.html" %}
+
+    <p>Ta lekcja jest częścią skróconego kursu na poziomie {{ object.level|lower }}.
+        Zobacz też <a href="{% url 'catalogue_lessons' %}#{{ object.level.slug }}_pelny">pełny kurs</a>.
     </p>
     </p>
-    <p>Czas trwania: 45 minut.</p>
+    <div style="clear: right"></div>
 </section>
 </section>
+{% endblock %}
+
+{% block sidebar-top %}
 
 {% if object.package %}
     <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
 
 {% if object.package %}
     <section class="box-button"><a href="{{ object.package.url }}" class="dl-button">Pobierz całą lekcję</a></section>
diff --git a/catalogue/templates/catalogue/lesson_list.html b/catalogue/templates/catalogue/lesson_list.html
new file mode 100755 (executable)
index 0000000..1578aa2
--- /dev/null
@@ -0,0 +1,46 @@
+{% extends "base.html" %}
+{% load catalogue_tags %}
+{% load static from staticfiles %}
+{% load course_boxes course_boxes_toc from curriculum_tags %}
+{% load chunk from chunks %}
+
+{% block title %}Lekcje{% endblock %}
+
+{% block body %}
+    <h1>Lekcje</h1>
+
+<aside id="sidebar">
+    <section class="section-minor">
+        <h1>Zebrane dla wszystkich tematów</h1>
+        <ul class="link-list">
+            {% for lesson in appendix %}
+                <li><a href="{{ lesson.get_absolute_url }}">{{ lesson }}</a></li>
+            {% endfor %}
+            <li><a href="{% url 'info' 'infografiki' %}">Infografiki</a></li>
+        </ul>
+    </section>
+</aside>
+
+<div id="main-bar">
+    <div class="box">
+    {% chunk 'levels_disclaimer' %}
+    </div>
+
+    <div id="level-chooser-place">
+        <ul id="level-chooser">
+            <li class="home"><a href="#body"><img src="{% static 'img/logo.png' %}" /></a></li>
+            {% for object in object_list %}
+                <li><a href="#{{ object.slug }}">{{ object }}</a></li>
+            {% endfor %}
+        </ul>
+    </div>
+
+
+
+    {% for level in object_list %}
+        {% level_box level %}
+    {% endfor %}
+</div>
+
+
+{% endblock %}
diff --git a/catalogue/templates/catalogue/section_list.html b/catalogue/templates/catalogue/section_list.html
deleted file mode 100755 (executable)
index 9f48c4f..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-{% extends "base.html" %}
-{% load catalogue_tags %}
-{% load course_boxes course_boxes_toc from curriculum_tags %}
-
-{% block title %}Lekcje{% endblock %}
-
-{% block body %}
-    <h1>Lekcje</h1>
-
-<aside id="sidebar">
-    <section class="box">
-        <h1 class="realisation">Realizacja i czas lekcji</h1>
-        <p>Każdy dział można zrealizować w formie lekcji syntetycznej
-        dającej przegląd danego zagadnienia, bądź w formie pełnego kursu.
-        </p>
-        <p>Czas trwania: 45 minut</p>
-    </section>
-    <section class="box-button"><a href="{{ package_url }}" class="dl-button">Pobierz wszystkie lekcje</a></section>
-    <section><a href="{{ package_student_url }}" class="dl-button">Pobierz wszystkie lekcje w&nbsp;wersji dla ucznia</a></section>
-    <section class="section-minor">
-        <h1>Zebrane dla wszystkich tematów</h1>
-        <ul class="link-list">
-            {% for lesson in appendix %}
-                <li><a href="{{ lesson.get_absolute_url }}">{{ lesson }}</a></li>
-            {% endfor %}
-            <li><a href="{% url 'info' 'infografiki' %}">Infografiki</a></li>
-        </ul>
-    </section>
-</aside>
-
-<div id="main-bar">
-    <div class="section-list-toc">
-    <h2 id='top'>Tematy</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">
-            <a href="#top">wróć do spisu treści</a>
-        </div>
-        <h2 id='{{ object.slug }}' class="section-header">{{ object }}</h2>
-
-        {% section_box object %}
-    {% endfor %}
-
-    <div class="course-boxes">
-    <h2>Lekcje wybrane na poszczególne przedmioty:</h2>
-    {% course_boxes %}
-    </div>
-
-</div>
-
-
-{% endblock %}
index c482556..bb31eae 100755 (executable)
@@ -1,21 +1,27 @@
-{% load static %}
-
-{% url "info" "jak-korzystac/" as jak %}
+{% load thumbnail %}
+{% url 'catalogue_lessons' as lessons %}
 <section id="catalogue-carousel">
     <ul id="catalogue-carousel-links">
 <section id="catalogue-carousel">
     <ul id="catalogue-carousel-links">
-        <li style="background-image: url({% static 'catalogue/img/carousel/katarzyna-wlodarczyk.jpg' %}); z-index: 100;">
-            <a href="{% url 'info' 'dobre-praktyki/' %}" class="catalogue-carousel-link">
+        {% for section in object_list %}
+        <li style="{% if section.pic %}{% thumbnail section.pic '460x235' crop='center' as th %}background-image: url('{{ th.url }}');{% endthumbnail %}{% endif %}">
+            <a href="{{ lessons }}#gimnazjum_{{ section.slug }}" class="catalogue-carousel-link">
                 <div class="catalogue-carousel-note">
                 <div class="catalogue-carousel-note">
-                    <p><strong>{{ lessons_count }}</strong> <em>{{ lessons_desc }}</em>
-                    - zobacz w działaniu</p>
+                    <div>
+                        <p>
+                        <strong>{{ section }}</strong>
+                        {{ section.summary }}
+                        <span class="more">zobacz &rarr;</span>
+                        </p>
+                    </div>
                 </div>
             </a>
                 </div>
             </a>
-        </li>
+            <a class="attribution" href="{{ section.pic_src }}">fot. {{ section.pic_attribution }}</a>
+        </li>    
+        {% endfor %}
     </ul>
     <ul id="catalogue-carousel-switcher">
     </ul>
     <ul id="catalogue-carousel-switcher">
-        <li><a href="{{ jak }}#wiedza-w-pigulce" class="knowledge">wiedza w pigułce</a></li>
-        <li><a href="{{ jak }}#zadania" class="activity">zadania</a></li>
-        <li><a href="{{ jak }}#scenariusze" class="lesson-plan">scenariusze</a></li>
-        <li><a href="{{ jak }}#slowniczek" class="reference">słowniczek</a></li>
+        {% for section in object_list %}
+            <li><a href="{{ section.get_absolute_url }}">{{ section }}</a></li>
+        {% endfor %}
     </ul>
 </section>
     </ul>
 </section>
index 4e36e22..d2bcf48 100755 (executable)
@@ -1,10 +1,10 @@
 <h1>
 {% if root %}
 <h1>
 {% if root %}
-    <a href="{{ root.get_absolute_url }}">{{ root }}</a>
+    <a href="{{ root.get_absolute_url }}">{{ root }}, <br>{{ lesson.level }}</a>
 {% elif lesson.type == 'synthetic' %}
 {% elif lesson.type == 'synthetic' %}
-    <a href="{% url 'catalogue_lessons' %}">Lekcje syntetyczne ze wszystkich tematów</a>
+    <a href="{% url 'catalogue_lessons' %}">Kurs skrócony, <br>{{ lesson.level }}</a>
 {% elif lesson.type == 'project' %}
 {% elif lesson.type == 'project' %}
-    <a href="{% url 'catalogue_lessons' %}">Projekty ze wszystkich tematów</a>
+    <a href="{% url 'catalogue_lessons' %}">Projekty, <br>{{ lesson.level }}</a>
 {% else %}
     <a href="{% url 'catalogue_lessons' %}">Inne</a>
 {% endif %}
 {% else %}
     <a href="{% url 'catalogue_lessons' %}">Inne</a>
 {% endif %}
     <li>
     {% if item == lesson %}
         <strong>{{ item }}</strong>
     <li>
     {% if item == lesson %}
         <strong>{{ item }}</strong>
-        {% if mark_level and item.level.slug == 'liceum' %} (poziom zaawansowany){% endif %}
     {% else %}
     {% else %}
-        <a href="{{ item.get_absolute_url }}">{{ item }}
-            {% if mark_level and item.level.slug == 'liceum' %} (poziom zaawansowany){% endif %}
-        </a>
+        <a href="{{ item.get_absolute_url }}">{{ item }}</a>
     {% endif %}
     </li>
 {% endfor %}
 </ul>
     {% endif %}
     </li>
 {% endfor %}
 </ul>
-
-{% if link_other_level %}
-{% with other=lesson.get_other_level %}
-    {% if other %}
-        <p>Ten temat jest dostępny również na 
-        <a href="{% url 'catalogue_lessons' %}#{{ lesson.section.slug }}_{{ other.slug }}">poziomie
-        {% if other.slug == 'liceum' %}zaawansowanym{% else %}podstawowym{% endif %}</a>.</p>
-    {% endif %}
-{% endwith %}
-{% endif %}
diff --git a/catalogue/templates/catalogue/snippets/lesson_or_stub.html b/catalogue/templates/catalogue/snippets/lesson_or_stub.html
new file mode 100644 (file)
index 0000000..5bb2614
--- /dev/null
@@ -0,0 +1,9 @@
+{% if lesson.slug %}
+    <a href="{{ lesson.get_absolute_url }}" title="{{ lesson.description }}">
+{% endif %}
+{{ lesson }}
+{% if lesson.slug %}
+    </a>
+{% else %}
+(w przygotowaniu)
+{% endif %}
diff --git a/catalogue/templates/catalogue/snippets/level_box.html b/catalogue/templates/catalogue/snippets/level_box.html
new file mode 100755 (executable)
index 0000000..bb2fa12
--- /dev/null
@@ -0,0 +1,142 @@
+<section id="{{ level.slug }}" class="level" style="margin-left: 20em">
+
+    <section class="box level-toc" style="float: left; margin-left: -20em; width: 15em;">
+        <strong><a href="#{{ level.slug }}">{{ level }}</a></strong>
+        <ul  class="link-list"  style="list-style: none; padding: 0; margin: 0;">
+            {% if lessons.synthetic %}
+            <li><a href="#{{ level.slug }}_skrocony">Skrócony kurs</a></li>
+            {% endif %}
+            {% if lessons.course %}
+            <li><a href="#{{ level.slug }}_pelny">Pełny kurs</a>
+                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
+                {% for section in lessons.course %}
+                        <li><a href="#{{ level.slug }}_{{ section.slug}}">{{ section }}</a></li>
+                {% endfor %}
+                </ul>
+            </li>
+            {% endif %}
+            {% if lessons.project %}
+            <li><a href="#{{ level.slug }}_projekt">Projekt</a></li>
+            {% endif %}
+            {% if lessons.appendix %}
+            <li><a href="#{{ level.slug }}_pozostale">Pozostałe materiały</a></li>
+            {% endif %}
+
+            {% if courses %}
+            <li class="curriculumcourses"><a href="#{{ level.slug }}_podstawa">Wg postawy programowej</a>
+                <ul style="list-style: none; padding: 0 0 0 1em; margin: 0;">
+                {% for course, lessons in courses %}
+                        <li><a href="#{{ level.slug }}_{{ course.slug}}">{{ course }}</a></li>
+                {% endfor %}
+                </ul>
+            </li>
+            {% endif %}
+        </ul>
+    </section>
+
+
+    <h1>{{ level }}</h1>
+
+    <section class="box-button button"><a href="{{ level.package.url }}" class="dl-button">Pobierz wszystkie lekcje</a></section>
+    <section class="button"><a href="{{ level.student_package.url }}" class="dl-button">Pobierz wszystkie lekcje w&nbsp;wersji dla ucznia</a></section>
+
+    {% if lessons.synthetic %}
+    <section id="{{ level.slug }}_skrocony">
+        <h1>Skrócony kurs</h1>
+
+        <p>Masz kilka godzin? Przeprowadź po jednej lekcji przeglądowej z każdego tematu.</p>
+
+        <ul class="link-list">
+            {% for lesson in lessons.synthetic %}
+                <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+            {% endfor %}
+        </ul>
+    </section>
+    {% endif %}
+
+
+    {% if lessons.course %}
+    <section id="{{ level.slug }}_pelny">
+        <h1>Pełny kurs</h1>
+
+        <p>Masz więcej czasu? Zrealizuj kompletny program edukacji medialnej.</p>
+
+        {% for section, s_lessons in lessons.course.items %}
+            <section id="{{ level.slug }}_{{ section.slug}}">
+                <h1>{{ section }}</h1>
+
+                <ul class="link-list">
+                    {% for lesson in s_lessons %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+        {% endfor %}
+
+    </section>
+    {% endif %}
+
+
+    {% if lessons.project %}
+    <section id="{{ level.slug }}_projekt">
+        <h1>Projekt</h1>
+
+        <p>Masz 4-6 tygodni? Zrealizuj jeden z projektów ze swoimi uczniami.</p>
+
+        <ul class="link-list">
+            {% for lesson in lessons.project %}
+                <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+            {% endfor %}
+        </ul>
+    </section>
+    {% endif %}
+
+
+    {% if courses %}
+    <section id="{{ level.slug }}_podstawa">
+        <h1>Wg podstawy programowej</h1>
+
+        {% for course, lessons in courses %}
+        <section id="{{ level.slug}}_{{ course.slug }}">
+            <h1>{{ course }}</h1>
+
+            {% if lessons.synthetic %}
+            <section>
+                <h1>Z kursu skróconego</h1>
+                <ul class="link-list">
+                    {% for lesson in lessons.synthetic %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+            {% endif %}
+
+            {% if lessons.course %}
+            <section>
+                <h1>Z kursu pełnego</h1>
+                <ul class="link-list">
+                    {% for lesson in lessons.course %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+            {% endif %}
+
+            {% if lessons.project %}
+            <section>
+                <h1>Projekt</h1>
+                <ul class="link-list">
+                    {% for lesson in lessons.project %}
+                        <li>{% include "catalogue/snippets/lesson_or_stub.html" %}</li>
+                    {% endfor %}
+                </ul>
+            </section>
+            {% endif %}
+
+        </section>
+        {% endfor %}
+        
+    </section>
+    {% endif %}
+
+</section>
diff --git a/catalogue/templates/catalogue/snippets/levels_main.html b/catalogue/templates/catalogue/snippets/levels_main.html
new file mode 100644 (file)
index 0000000..497a5c8
--- /dev/null
@@ -0,0 +1,19 @@
+{% load i18n %}
+<style type="text/css">
+#main-sections ul li {width: {{ section_width }}px;}
+#main-sections ul li a {width: {{ section_width|add:"-10" }}px;}
+.levelth {width: {{ section_width }}px;}
+</style>
+{% url 'catalogue_lessons' as les %}
+<ul class="section-buttons">
+{% for level in object_list %}
+<li class="box{{ level.pk }}">
+    <a href="{{ les }}#{{ level.slug }}">
+    <span class="in-box">
+    <span class="name">{{ level }}</span>
+    {{ level.length_synthetic }} lub {{ level.length_course }} godzin
+    </span>
+    </a>
+</li>
+{% endfor %}
+</ul>
diff --git a/catalogue/templates/catalogue/snippets/section_box.html b/catalogue/templates/catalogue/snippets/section_box.html
deleted file mode 100755 (executable)
index c505c04..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-{% load thumbnail %}
-{% for level, types in lessons.items %}
-{% if level.slug == "liceum" %}
-    <p><strong>{{section.title}}</strong>: poziom zaawansowany
-        <span class="section-links"><a href="#top">wróć do spisu treści</a></span>
-    </p>
-{% endif %}
-<section id="{{ section.slug }}_{{ level.slug }}" class="section-level section-level-{{ level.slug }}">
-    {% spaceless %}
-    <div class='sections-row'>
-    {% for lesson_type, lesson_list in types.items %}
-        {% if lesson_type == 'project' %}
-            </div><div class='sections-row'>
-        {% endif %}
-        <section class="section-type section-type-{{ lesson_type }}">
-            {% if lesson_type == 'synthetic' %}
-                {% if section.image %}
-                    {% thumbnail section.image "120x160" as im %}
-                        <a class="image" href="{{ section.image.url }}">
-                            <img src="{{ im.url }}" />
-                        </a>
-                    {% endthumbnail %}
-                {% endif %}
-                <h1>Lekcja syntetyczna</h1>
-            {% elif lesson_type == 'project' %}
-                <h1>Projekt</h1>
-            {% else %}
-                <h1>Pełny kurs</h1>
-            {% endif %}
-            {% if lesson_list %}
-            <ul class="section-lessons link-list">
-                {% for lesson in lesson_list %}
-                    <li class="section-lesson">
-                        {% if lesson.slug %}
-                            <a href="{{ lesson.get_absolute_url }}">{{ lesson }}{% if lesson_type == 'synthetic' %}
-                                <br/>(przegląd całego tematu w 45 minut)
-                            {% endif %}</a>
-                        {% else %}
-                            {{ lesson }} <em>(w&nbsp;przygotowaniu)</em>
-                        {% endif %}
-                    </li>
-                {% endfor %}
-            </ul>
-            {% else %}
-                <p>(W przygotowaniu)</p>
-            {% endif %}
-        </section>
-    {% endfor %}
-    </div>
-    {% endspaceless %}
-</section>
-{% endfor %}
diff --git a/catalogue/templates/catalogue/snippets/section_buttons.html b/catalogue/templates/catalogue/snippets/section_buttons.html
deleted file mode 100755 (executable)
index c7bb162..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<ul class="section-buttons">
-{% for object in object_list %}
-    {% url "catalogue_lessons" as lessons_url %}
-    <li class="box{{ object.order }}"><a href="{{ lessons_url }}#{{  object.slug }}"><span>{{ object }}</span></a></li>
-{% endfor %}
-</ul>
index a8d69e6..5166298 100755 (executable)
@@ -1,6 +1,8 @@
+from collections import defaultdict
 from django import template
 from django.utils.datastructures import SortedDict
 from ..models import Lesson, Section
 from django import template
 from django.utils.datastructures import SortedDict
 from ..models import Lesson, Section
+from curriculum.models import Level, CurriculumCourse
 from librarian.dcparser import WLURI, Person
 
 register = template.Library()
 from librarian.dcparser import WLURI, Person
 
 register = template.Library()
@@ -8,43 +10,58 @@ register = template.Library()
 
 @register.inclusion_tag("catalogue/snippets/carousel.html")
 def catalogue_carousel():
 
 @register.inclusion_tag("catalogue/snippets/carousel.html")
 def catalogue_carousel():
-    lessons_count = Lesson.objects.filter(type__in=('course', 'synthetic')).count()
-    if 1 < lessons_count % 10 < 5 and lessons_count / 10 % 10 != 1:
-        lessons_desc = u'kompletne lekcje'
-    else:
-        lessons_desc = u'kompletnych lekcji'
-    return locals()
-
-@register.inclusion_tag("catalogue/snippets/section_buttons.html")
-def catalogue_section_buttons():
     return {
         "object_list": Section.objects.all()
     }
 
     return {
         "object_list": Section.objects.all()
     }
 
-@register.inclusion_tag("catalogue/snippets/section_box.html")
-def section_box(section):
-    lessons = SortedDict()
+@register.inclusion_tag("catalogue/snippets/levels_main.html")
+def catalogue_levels_main():
+    object_list = Level.objects.exclude(lesson=None)
+    c = object_list.count()
+    return {
+        'object_list': object_list,
+        'section_width': (700 - 20 * (c - 1)) / c,
+    }
+
+
+@register.inclusion_tag("catalogue/snippets/level_box.html")
+def level_box(level):
+    lessons = dict(
+        synthetic = [],
+        course = SortedDict(),
+        project = [],
+    )
+    by_course = defaultdict(lambda: defaultdict(list))
+
     lesson_lists = [alist for alist in [
     lesson_lists = [alist for alist in [
-        list(section.lesson_set.all()),
-        list(section.lessonstub_set.all())
+        list(level.lesson_set.exclude(type='appendix').order_by('section__order')),
+        list(level.lessonstub_set.all())
     ] if alist]
     ] if alist]
+
     while lesson_lists:
         min_index, min_list = min(enumerate(lesson_lists), key=lambda x: x[1][0].order)
         lesson = min_list.pop(0)
         if not min_list:
             lesson_lists.pop(min_index)
 
     while lesson_lists:
         min_index, min_list = min(enumerate(lesson_lists), key=lambda x: x[1][0].order)
         lesson = min_list.pop(0)
         if not min_list:
             lesson_lists.pop(min_index)
 
-        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)
+        if lesson.type == 'course':
+            if lesson.section not in lessons['course']:
+                lessons['course'][lesson.section] = []
+            lessons['course'][lesson.section].append(lesson)
+        else:
+            lessons[lesson.type].append(lesson)
+
+        if hasattr(lesson, 'curriculum_courses'):
+            for course in lesson.curriculum_courses.all():
+                by_course[course][lesson.type].append(lesson)
+
+    courses = [(course, by_course[course]) for course in
+        CurriculumCourse.objects.filter(lesson__level=level).distinct()]
+
     return {
     return {
-        "section": section,
+        "level": level,
         "lessons": lessons,
         "lessons": lessons,
+        "courses": courses,
     }
 
 @register.inclusion_tag("catalogue/snippets/lesson_nav.html")
     }
 
 @register.inclusion_tag("catalogue/snippets/lesson_nav.html")
@@ -52,17 +69,16 @@ def lesson_nav(lesson):
     if lesson.type == 'course':
         root = lesson.section
         siblings = Lesson.objects.filter(type='course', level=lesson.level, section=root)
     if lesson.type == 'course':
         root = lesson.section
         siblings = Lesson.objects.filter(type='course', level=lesson.level, section=root)
-        mark_level = False
-        link_other_level = True
-    else:
+    elif lesson.type == 'appendix':
         root = None
         siblings = Lesson.objects.filter(type=lesson.type)
         root = None
         siblings = Lesson.objects.filter(type=lesson.type)
-        mark_level = link_other_level = lesson.type == 'course'
+    else:
+        root = None
+        siblings = Lesson.objects.filter(type=lesson.type, level=lesson.level)
     return {
         "lesson": lesson,
         "root": root,
         "siblings": siblings,
     return {
         "lesson": lesson,
         "root": root,
         "siblings": siblings,
-        "mark_level": mark_level
     }
 
 @register.inclusion_tag("catalogue/snippets/lesson_link.html")
     }
 
 @register.inclusion_tag("catalogue/snippets/lesson_link.html")
index 61e9e9a..3923f61 100755 (executable)
@@ -1,9 +1,9 @@
 from django.conf.urls import patterns, include, url
 from django.conf.urls import patterns, include, url
-from .views import SectionView, LessonView
+from .views import LessonListView, LessonView
 
 urlpatterns = patterns('',
     url(r'^$',
 
 urlpatterns = patterns('',
     url(r'^$',
-        SectionView.as_view(),
+        LessonListView.as_view(),
         name="catalogue_lessons"),
     url(r'^(?P<slug>[^/]+)/$',
         LessonView.as_view(),
         name="catalogue_lessons"),
     url(r'^(?P<slug>[^/]+)/$',
         LessonView.as_view(),
index 273bfa3..0ce7454 100644 (file)
@@ -2,16 +2,17 @@ import os.path
 from django.conf import settings
 from django.views.generic import DetailView, ListView
 from .models import Lesson, Section
 from django.conf import settings
 from django.views.generic import DetailView, ListView
 from .models import Lesson, Section
+from curriculum.models import Level
+from publishers.models import Publisher
 
 
 
 
-class SectionView(ListView):
-    model = Section
+class LessonListView(ListView):
+    queryset = Level.objects.exclude(lesson=None)
+    template_name = "catalogue/lesson_list.html"
 
     def get_context_data(self, **kwargs):
 
     def get_context_data(self, **kwargs):
-        context = super(SectionView, self).get_context_data(**kwargs)
+        context = super(LessonListView, self).get_context_data(**kwargs)
         context['appendix'] = Lesson.objects.filter(type='appendix')
         context['appendix'] = Lesson.objects.filter(type='appendix')
-        context['package_url'] = os.path.join(settings.MEDIA_URL, settings.CATALOGUE_PACKAGE)
-        context['package_student_url'] = os.path.join(settings.MEDIA_URL, settings.CATALOGUE_PACKAGE_STUDENT)
         return context
 
 
         return context
 
 
@@ -23,4 +24,12 @@ class LessonView(DetailView):
             'catalogue/lesson/%s/lesson_detail.html' % self.object.type,
             'catalogue/lesson/lesson_detail.html',
         ]
             'catalogue/lesson/%s/lesson_detail.html' % self.object.type,
             'catalogue/lesson/lesson_detail.html',
         ]
-        
+
+    def get_context_data(self, **kwargs):
+        context = super(LessonView, self).get_context_data(**kwargs)
+        try:
+            context['publisher'] = Publisher.objects.get(
+                name=context['object'].dc.get('publisher', '').strip())
+        except:
+            pass
+        return context
index 8fa0149..b975da3 100644 (file)
@@ -1,7 +1,7 @@
 from django.contrib.sites.models import Site
 from django.core.files.uploadedfile import UploadedFile
 from django.core.mail import send_mail, mail_managers
 from django.contrib.sites.models import Site
 from django.core.files.uploadedfile import UploadedFile
 from django.core.mail import send_mail, mail_managers
-from django.core.validators import email_re
+from django.core.validators import validate_email
 from django import forms
 from django.template.loader import render_to_string
 from django.template import RequestContext
 from django import forms
 from django.template.loader import render_to_string
 from django.template import RequestContext
@@ -78,7 +78,7 @@ class ContactForm(forms.Form):
         mail_managers(mail_managers_subject, mail_managers_body, 
             fail_silently=True)
 
         mail_managers(mail_managers_subject, mail_managers_body, 
             fail_silently=True)
 
-        if email_re.match(contact.contact):
+        if validate_email(contact.contact):
             mail_subject = render_to_string([
                     'contact/%s/mail_subject.txt' % self.form_tag,
                     'contact/mail_subject.txt', 
             mail_subject = render_to_string([
                     'contact/%s/mail_subject.txt' % self.form_tag,
                     'contact/mail_subject.txt', 
diff --git a/curriculum/migrations/0010_auto__add_field_level_meta_name.py b/curriculum/migrations/0010_auto__add_field_level_meta_name.py
new file mode 100644 (file)
index 0000000..24fc996
--- /dev/null
@@ -0,0 +1,82 @@
+# -*- 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 'Level.meta_name'
+        db.add_column(u'curriculum_level', 'meta_name',
+                      self.gf('django.db.models.fields.CharField')(default=' ', max_length=255),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Level.meta_name'
+        db.delete_column(u'curriculum_level', 'meta_name')
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'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': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0011_meta_name.py b/curriculum/migrations/0011_meta_name.py
new file mode 100644 (file)
index 0000000..0539ae7
--- /dev/null
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        "Write your forwards methods here."
+        orm.Level.objects.all().update(meta_name=models.F('slug'))
+
+    def backwards(self, orm):
+        "Write your backwards methods here."
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'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': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
+    symmetrical = True
diff --git a/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py b/curriculum/migrations/0012_auto__add_unique_level_meta_name__add_unique_level_slug.py
new file mode 100644 (file)
index 0000000..f9fa032
--- /dev/null
@@ -0,0 +1,86 @@
+# -*- 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 unique constraint on 'Level', fields ['meta_name']
+        db.create_unique(u'curriculum_level', ['meta_name'])
+
+        # Adding unique constraint on 'Level', fields ['slug']
+        db.create_unique(u'curriculum_level', ['slug'])
+
+
+    def backwards(self, orm):
+        # Removing unique constraint on 'Level', fields ['slug']
+        db.delete_unique(u'curriculum_level', ['slug'])
+
+        # Removing unique constraint on 'Level', fields ['meta_name']
+        db.delete_unique(u'curriculum_level', ['meta_name'])
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'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': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
diff --git a/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py b/curriculum/migrations/0013_auto__add_field_level_package__add_field_level_student_package.py
new file mode 100644 (file)
index 0000000..4e0ee70
--- /dev/null
@@ -0,0 +1,92 @@
+# -*- 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 'Level.package'
+        db.add_column(u'curriculum_level', 'package',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+        # Adding field 'Level.student_package'
+        db.add_column(u'curriculum_level', 'student_package',
+                      self.gf('django.db.models.fields.files.FileField')(max_length=255, null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'Level.package'
+        db.delete_column(u'curriculum_level', 'package')
+
+        # Deleting field 'Level.student_package'
+        db.delete_column(u'curriculum_level', 'student_package')
+
+
+    models = {
+        u'curriculum.competence': {
+            'Meta': {'ordering': "['section', 'order']", 'object_name': 'Competence'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'section': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Section']"}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        },
+        u'curriculum.competencelevel': {
+            'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+            'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Competence']"}),
+            'description_en': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            'description_pl': ('django.db.models.fields.TextField', [], {'default': "''"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.Level']"})
+        },
+        u'curriculum.curriculum': {
+            'Meta': {'object_name': 'Curriculum'},
+            'course': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['curriculum.CurriculumCourse']"}),
+            u'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': u"orm['curriculum.CurriculumLevel']"}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '16'})
+        },
+        u'curriculum.curriculumcourse': {
+            'Meta': {'ordering': "['slug']", 'object_name': 'CurriculumCourse'},
+            'accusative': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            u'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'})
+        },
+        u'curriculum.curriculumlevel': {
+            'Meta': {'object_name': 'CurriculumLevel'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '16', 'db_index': 'True'})
+        },
+        u'curriculum.level': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+            'group_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'group_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'meta_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+            'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'})
+        },
+        u'curriculum.section': {
+            'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name_en': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'name_pl': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+            'order': ('django.db.models.fields.IntegerField', [], {}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['curriculum']
\ No newline at end of file
index b53d2ca..b4d8ac4 100644 (file)
@@ -22,7 +22,7 @@ class Section(models.Model):
 
     def url_for_level(self, level):
         return "%s?s=%d&level=%s&d=1" % (reverse("curriculum"), self.pk, level.slug)
 
     def url_for_level(self, level):
         return "%s?s=%d&level=%s&d=1" % (reverse("curriculum"), self.pk, level.slug)
-        
+
 add_translatable(Section, {
     'name': models.CharField(_('name'), max_length=255, default = '')
 })
 add_translatable(Section, {
     'name': models.CharField(_('name'), max_length=255, default = '')
 })
@@ -66,8 +66,13 @@ add_translatable(Competence, {
 
 
 class Level(models.Model):
 
 
 class Level(models.Model):
-    slug = models.CharField(_('slug'), max_length=255)
+    slug = models.CharField(_('slug'), max_length=255, unique=True)
+    meta_name = models.CharField(_('meta name'), max_length=255, unique=True)
     order = models.IntegerField(_('order'))
     order = models.IntegerField(_('order'))
+    package = models.FileField(upload_to=lambda i, f: "curriculum/pack/edukacjamedialna_%s.zip" % i.slug,
+        null=True, blank=True, max_length=255)
+    student_package = models.FileField(upload_to=lambda i, f: "curriculum/pack/edukacjamedialna_%s_uczen.zip" % i.slug,
+        null=True, blank=True, max_length=255)
 
     class Meta:
         ordering = ['order']
 
     class Meta:
         ordering = ['order']
@@ -77,6 +82,48 @@ class Level(models.Model):
     def __unicode__(self):
         return self.name
 
     def __unicode__(self):
         return self.name
 
+    def length_course(self):
+        return self.lesson_set.filter(type='course').count()
+
+    def length_synthetic(self):
+        return self.lesson_set.filter(type='synthetic').count()
+
+    def build_package(self, student):
+        from StringIO import StringIO
+        import zipfile
+        from django.core.files.base import ContentFile
+        from catalogue.templatetags.catalogue_tags import section_box
+        from catalogue.models import Lesson
+
+        buff = StringIO()
+        zipf = zipfile.ZipFile(buff, 'w', zipfile.ZIP_STORED)
+
+        lessons = section_box(self)['lessons']
+        for i, lesson in enumerate(lessons['synthetic']):
+            prefix = 'Skrocony kurs/%d %s/' % (i, lesson.slug)
+            lesson.add_to_zip(zipf, student, prefix)
+        for c, (section, clessons) in enumerate(lessons['course'].items()):
+            for i, lesson in enumerate(clessons):
+                prefix = 'Pelny kurs/%d %s/%d %s/' % (c, section.slug, i, lesson.slug)
+                lesson.add_to_zip(zipf, student, prefix)
+        for i, lesson in enumerate(lessons['project']):
+            prefix = 'Kurs skrocony/%d %s/' % (i, lesson.slug)
+            lesson.add_to_zip(zipf, student, prefix)
+        # Add all appendix lessons, from all levels.
+        for lesson in Lesson.objects.exclude(type__in=('synthetic', 'course', 'project')):
+            prefix = '%s/' % lesson.slug
+            lesson.add_to_zip(zipf, student, prefix)
+        zipf.close()
+
+        fieldname = "student_package" if student else "package"
+        getattr(self, fieldname).save(None, ContentFile(buff.getvalue()))
+
+    def build_packages(self):
+        self.build_package(False)
+        self.build_package(True)
+
+
+
 add_translatable(Level, {
     'name': models.CharField(_('name'), max_length=255, default = ''),
     'group': models.CharField(_('group'), max_length=255, default = '')
 add_translatable(Level, {
     'name': models.CharField(_('name'), max_length=255, default = ''),
     'group': models.CharField(_('group'), max_length=255, default = '')
index db6d484..a2000b7 100755 (executable)
@@ -1,10 +1,14 @@
 {% url "catalogue_lessons" as lessons_url %}
 {% 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>
+{% for level, course_list in object_list %}
+<section class="levelth" style="float: left;">{{ level }}:
+<ul class="link-list">
+        {% for course in course_list %}
+            <li><a href="{{ lessons_url }}#{{ level.slug }}_{{ course.slug }}">
+            {% if accusative %}
+                {{ course.accusative }}{% else %}
+                {{ course|lower }}{% endif %}</a>{% if not forloop.last %}, {% else %}.{% endif %}
+                </li>
+        {% endfor %}
+</ul>
+</section>
 {% endfor %}
 {% endfor %}
index 986271c..4e02e04 100755 (executable)
@@ -1,6 +1,7 @@
 from django import template
 from django.utils.datastructures import SortedDict
 from ..models import Competence, Curriculum, CurriculumCourse
 from django import template
 from django.utils.datastructures import SortedDict
 from ..models import Competence, Curriculum, CurriculumCourse
+from catalogue.models import Lesson
 
 register = template.Library()
 
 
 register = template.Library()
 
@@ -19,7 +20,7 @@ def competence(texts, level):
 @register.inclusion_tag("curriculum/snippets/curriculum.html")
 def curriculum(identifiers):
     try:
 @register.inclusion_tag("curriculum/snippets/curriculum.html")
 def curriculum(identifiers):
     try:
-        currs = [Curriculum.objects.get(identifier=identifier)
+        currs = [Curriculum.objects.get(identifier__iexact=identifier.replace(' ', ''))
                     for identifier in identifiers]
     except Curriculum.DoesNotExist:
         return {'identifiers': identifiers}
                     for identifier in identifiers]
     except Curriculum.DoesNotExist:
         return {'identifiers': identifiers}
@@ -70,7 +71,18 @@ def course_boxes():
 
 @register.inclusion_tag("curriculum/snippets/course_boxes_toc.html")
 def course_boxes_toc(accusative=False):
 
 @register.inclusion_tag("curriculum/snippets/course_boxes_toc.html")
 def course_boxes_toc(accusative=False):
+    last = None, None
+    object_list = []
+    for l in Lesson.curriculum_courses.through.objects.all().order_by(
+            'lesson__level', 'curriculumcourse'):
+        level, course = l.lesson.level, l.curriculumcourse
+        if (level, course) == last:
+            continue
+        if level != last[0]:
+            object_list.append((level, []))
+        object_list[-1][1].append(course)
+        last = (level, course)
     return {
     return {
-        'object_list': CurriculumCourse.objects.all(),
+        'object_list': object_list,
         'accusative': accusative,
     }
         'accusative': accusative,
     }
index 7091ff1..ee80ab7 100644 (file)
@@ -3,12 +3,13 @@ INSTALLED_APPS = (
     'curriculum',
     'catalogue',
     'comment',
     'curriculum',
     'catalogue',
     'comment',
+    'publishers',
 
     'fnpdjango',
     'south',
     'pipeline',
     # Disable, if not using Piwik.
 
     'fnpdjango',
     'south',
     'pipeline',
     # Disable, if not using Piwik.
-    'piwik.django',
+    'piwik',
     # Disable, if not using CAS.
     'honeypot',
     'django_cas',
     # Disable, if not using CAS.
     'honeypot',
     'django_cas',
index 998b707..bb7401f 100644 (file)
@@ -15,8 +15,6 @@ MIDDLEWARE_CLASSES = tuple(x for x in (
             if "django_cas" in INSTALLED_APPS else None,
     'django.contrib.messages.middleware.MessageMiddleware'
             if "django.contrib.messages" in INSTALLED_APPS else None,
             if "django_cas" in INSTALLED_APPS else None,
     'django.contrib.messages.middleware.MessageMiddleware'
             if "django.contrib.messages" in INSTALLED_APPS else None,
-    'piwik.django.middleware.PiwikMiddleware'
-            if "piwik.django" in INSTALLED_APPS else None,
     # Uncomment the next line for simple clickjacking protection:
     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'pagination.middleware.PaginationMiddleware'
     # Uncomment the next line for simple clickjacking protection:
     # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
     'pagination.middleware.PaginationMiddleware'
index 64770e8..e5b3dee 100644 (file)
@@ -11,3 +11,6 @@ PYBB_ENABLE_ANONYMOUS_POST = False
 PYBB_DEFAULT_TITLE = u'Forum'
 PYBB_DEFAULT_TIME_ZONE = 1
 PYBB_PERMISSION_HANDLER = 'edumed.forum.ForumPermissionHandler'
 PYBB_DEFAULT_TITLE = u'Forum'
 PYBB_DEFAULT_TIME_ZONE = 1
 PYBB_PERMISSION_HANDLER = 'edumed.forum.ForumPermissionHandler'
+
+THUMBNAIL_ENGINE = 'sorl.thumbnail.engines.convert_engine.Engine'
+THUMBNAIL_CONVERT = 'convert -density 300 -background white -flatten -alpha off'
index 43dbb7c..7cdd26c 100644 (file)
@@ -39,8 +39,10 @@ PIPELINE_JS = {
             'catalogue/js/jquery.cycle.all.js',
             'jquery/colorbox/jquery.colorbox-min.js',
             'jquery/colorbox/jquery.colorbox-pl.js',
             'catalogue/js/jquery.cycle.all.js',
             'jquery/colorbox/jquery.colorbox-min.js',
             'jquery/colorbox/jquery.colorbox-pl.js',
+            'catalogue/js/carousel.js',
             'catalogue/js/edumed.js',
             'catalogue/js/lesson.js',
             'catalogue/js/edumed.js',
             'catalogue/js/lesson.js',
+            'catalogue/js/lesson-list.js',
             'sponsors/js/sponsors.js',
             'curriculum/curriculum.js',
             'js/formset.js',
             'sponsors/js/sponsors.js',
             'curriculum/curriculum.js',
             'js/formset.js',
index 758819b..869e6f4 100644 (file)
@@ -1,3 +1 @@
-CATALOGUE_PACKAGE = "catalogue/edukacjamedialna.zip"
-CATALOGUE_PACKAGE_STUDENT = "catalogue/edukacjamedialna_uczen.zip"
 CONTACT_FORMS_MODULE = 'edumed.contact_forms'
 CONTACT_FORMS_MODULE = 'edumed.contact_forms'
index 4fecbb1..ffb78d9 100644 (file)
@@ -1,10 +1,10 @@
 #main-promobox {
   float: right;
 #main-promobox {
   float: right;
-  border-radius: 0.938em;
+  border-radius: 0.9375em;
   background: #16a487;
   padding: 1.5em 1.25em;
   width: 11.25em;
   background: #16a487;
   padding: 1.5em 1.25em;
   width: 11.25em;
-  height: 11.688em; }
+  height: 11.6875em; }
   #main-promobox a {
     display: block; }
   #main-promobox h1 {
   #main-promobox a {
     display: block; }
   #main-promobox h1 {
   width: 43.75em; }
   #main-sections h1 {
     font-size: .9em;
   width: 43.75em; }
   #main-sections h1 {
     font-size: .9em;
-    margin: 0 0 0 1.6em;
+    margin: 0 0 0 1.25em;
     text-transform: uppercase; }
   #main-sections ul {
     text-transform: uppercase; }
   #main-sections ul {
-    margin: -0.188em 0 0 -1.25em;
+    margin: -0.1875em 0 0 -1.25em;
     padding: 0;
     list-style: none; }
     #main-sections ul li {
       margin-top: 1.25em;
       margin-left: 1.25em;
       float: left;
     padding: 0;
     list-style: none; }
     #main-sections ul li {
       margin-top: 1.25em;
       margin-left: 1.25em;
       float: left;
-      width: 10em;
       height: 5.625em;
       height: 5.625em;
-      border-radius: 0.938em; }
+      border-radius: 0.9375em; }
       #main-sections ul li a {
         color: white;
         text-transform: uppercase;
         display: block;
         height: 5em;
       #main-sections ul li a {
         color: white;
         text-transform: uppercase;
         display: block;
         height: 5em;
-        width: 9.375em;
         display: table;
         display: table;
-        padding: 0.313em; }
-        #main-sections ul li a span {
+        padding: 5px; }
+        #main-sections ul li a .in-box {
           font-size: .9em;
           height: 100%;
           width: 100%;
           font-size: .9em;
           height: 100%;
           width: 100%;
           border: 1px solid transparent;
           border-radius: 0.625em;
           padding-left: 1em; }
           border: 1px solid transparent;
           border-radius: 0.625em;
           padding-left: 1em; }
-      #main-sections ul li a:hover span {
+          #main-sections ul li a .in-box .name {
+            display: block;
+            font-size: 1.5em;
+            line-height: 1em;
+            margin-bottom: .2em; }
+      #main-sections ul li a:hover .in-box {
         border: 1px solid white; }
     #main-sections ul .box1 {
       background-color: #adaeaf; }
         border: 1px solid white; }
     #main-sections ul .box1 {
       background-color: #adaeaf; }
@@ -76,7 +79,7 @@
     #main-sections ul .box4 {
       background-color: #5e6165; }
     #main-sections ul .box5 {
     #main-sections ul .box4 {
       background-color: #5e6165; }
     #main-sections ul .box5 {
-      background-color: #16a487; }
+      background-color: #f8b323; }
     #main-sections ul .box6 {
       background-color: #363a3e; }
     #main-sections ul .box7 {
     #main-sections ul .box6 {
       background-color: #363a3e; }
     #main-sections ul .box7 {
     #main-sections ul .box8 {
       background-color: #ed7831; }
 
     #main-sections ul .box8 {
       background-color: #ed7831; }
 
-#main-chosen {
+#main-howto {
   float: right;
   margin-top: 1.2em;
   width: 13.75em; }
   float: right;
   margin-top: 1.2em;
   width: 13.75em; }
-  #main-chosen h1 {
+  #main-howto h1 {
     font-size: .9em;
     margin: 0 0 0 1.4em;
     text-transform: uppercase; }
     font-size: .9em;
     margin: 0 0 0 1.4em;
     text-transform: uppercase; }
-  #main-chosen ul {
-    margin: 1.063em 0 0 1.4em; }
-    #main-chosen ul li {
+  #main-howto ul {
+    margin: 1.0625em 0 1.0625em 1.4em; }
+    #main-howto ul li {
       font-size: .9em;
       text-transform: uppercase;
       line-height: 1.25em; }
       font-size: .9em;
       text-transform: uppercase;
       line-height: 1.25em; }
+    #main-howto ul a:before {
+      height: 1.25em; }
+    #main-howto ul .knowledge:before {
+      content: url(/static/img/icons/knowledge_dark.png); }
+    #main-howto ul .activity:before {
+      content: url(/static/img/icons/activity_dark.png); }
+    #main-howto ul .lesson-plan:before {
+      content: url(/static/img/icons/lesson-plan_dark.png); }
+    #main-howto ul .reference:before {
+      content: url(/static/img/icons/reference_dark.png); }
+    #main-howto ul .knowledge:hover:before {
+      content: url(/static/img/icons/knowledge_orange.png); }
+    #main-howto ul .activity:hover:before {
+      content: url(/static/img/icons/activity_orange.png); }
+    #main-howto ul .lesson-plan:hover:before {
+      content: url(/static/img/icons/lesson-plan_orange.png); }
+    #main-howto ul .reference:hover:before {
+      content: url(/static/img/icons/reference_orange.png); }
+  #main-howto p {
+    margin: 0 0 1.875em 1.4em; }
+
+#main-chosen {
+  clear: left;
+  float: left;
+  margin-top: 2em; }
+  #main-chosen h1 {
+    font-size: .9em;
+    margin: 0 0 1em 1.25em;
+    text-transform: uppercase; }
+  #main-chosen .levelth {
+    margin-left: 1.25em; }
 
 #main-tools {
   clear: both; }
 
 #main-tools {
   clear: both; }
index e956c81..54b2d35 100755 (executable)
@@ -48,7 +48,7 @@ $px: .0625em;
 
     h1 {
         font-size: .9em;
 
     h1 {
         font-size: .9em;
-        margin: 0 0 0 1.6em;
+        margin: 0 0 0 20*$px;
         text-transform: uppercase;
     }
 
         text-transform: uppercase;
     }
 
@@ -61,7 +61,6 @@ $px: .0625em;
             margin-top: 20*$px;
             margin-left: 20*$px;
             float: left;
             margin-top: 20*$px;
             margin-left: 20*$px;
             float: left;
-            width: 160*$px;
             height: 90*$px;
             border-radius: 15*$px;
 
             height: 90*$px;
             border-radius: 15*$px;
 
@@ -70,11 +69,10 @@ $px: .0625em;
                 text-transform: uppercase;
                 display: block;
                 height: 80*$px;
                 text-transform: uppercase;
                 display: block;
                 height: 80*$px;
-                width: 150*$px;
                 display: table;
                 display: table;
-                padding: 5*$px;
+                padding: 5px;
 
 
-                span {
+                .in-box {
                     font-size: .9em;
                     height: 100%;
                     width: 100%;
                     font-size: .9em;
                     height: 100%;
                     width: 100%;
@@ -83,9 +81,16 @@ $px: .0625em;
                     border: 1px solid transparent;
                     border-radius: 10*$px;
                     padding-left: 16*$px;
                     border: 1px solid transparent;
                     border-radius: 10*$px;
                     padding-left: 16*$px;
+
+                    .name {
+                        display: block;
+                        font-size: 1.5em;
+                        line-height: 1em;
+                        margin-bottom: .2em;
+                    }
                 }
             }
                 }
             }
-            a:hover span {
+            a:hover .in-box {
                 border: 1px solid white;
             }
         }
                 border: 1px solid white;
             }
         }
@@ -93,14 +98,15 @@ $px: .0625em;
         .box2 {background-color: #f8b323;}
         .box3 {background-color: #16a487;}
         .box4 {background-color: #5e6165;}
         .box2 {background-color: #f8b323;}
         .box3 {background-color: #16a487;}
         .box4 {background-color: #5e6165;}
-        .box5 {background-color: #16a487;}
+        // .box5 {background-color: #16a487;}
+        .box5 {background-color: #f8b323;}
         .box6 {background-color: #363a3e;}
         .box7 {background-color: #adaeaf;}
         .box8 {background-color: #ed7831;}
     }
 }
 
         .box6 {background-color: #363a3e;}
         .box7 {background-color: #adaeaf;}
         .box8 {background-color: #ed7831;}
     }
 }
 
-#main-chosen {
+#main-howto {
     float: right;
     margin-top: 1.2em;
     width: 220*$px;
     float: right;
     margin-top: 1.2em;
     width: 220*$px;
@@ -112,13 +118,45 @@ $px: .0625em;
     }
 
     ul {
     }
 
     ul {
-        margin: 17*$px 0 0 1.4em;;
+        margin: 17*$px 0 17*$px 1.4em;
 
         li {
             font-size: .9em;
             text-transform: uppercase;
             line-height: 1.25em;
         }
 
         li {
             font-size: .9em;
             text-transform: uppercase;
             line-height: 1.25em;
         }
+        a:before {
+            height: 20*$px;
+        }
+
+        .knowledge:before {content: url(/static/img/icons/knowledge_dark.png);}
+        .activity:before {content: url(/static/img/icons/activity_dark.png);}
+        .lesson-plan:before {content: url(/static/img/icons/lesson-plan_dark.png);}
+        .reference:before {content: url(/static/img/icons/reference_dark.png);}
+        .knowledge:hover:before {content: url(/static/img/icons/knowledge_orange.png);}
+        .activity:hover:before {content: url(/static/img/icons/activity_orange.png);}
+        .lesson-plan:hover:before {content: url(/static/img/icons/lesson-plan_orange.png);}
+        .reference:hover:before {content: url(/static/img/icons/reference_orange.png);}
+
+    }
+    p {
+        margin: 0 0 30*$px 1.4em;
+    }
+}
+
+#main-chosen {
+    clear: left;
+    float: left;
+    margin-top: 2em;
+
+    h1 {
+        font-size: .9em;
+        margin: 0 0 1em 20*$px;
+        text-transform: uppercase;
+    }
+
+    .levelth {
+        margin-left: 20*$px;
     }
 }
 
     }
 }
 
diff --git a/edumed/static/img/icons/internet_black.png b/edumed/static/img/icons/internet_black.png
new file mode 100644 (file)
index 0000000..538e60b
Binary files /dev/null and b/edumed/static/img/icons/internet_black.png differ
diff --git a/edumed/static/img/icons/nointernet_black.png b/edumed/static/img/icons/nointernet_black.png
new file mode 100644 (file)
index 0000000..9977783
Binary files /dev/null and b/edumed/static/img/icons/nointernet_black.png differ
index f4a3c27..9607254 100644 (file)
@@ -3,6 +3,7 @@
 {% load fnp_common fnp_share fnp_lang macros %}
 {% load compressed static %}
 {% load subdomainurls %}
 {% load fnp_common fnp_share fnp_lang macros %}
 {% load compressed static %}
 {% load subdomainurls %}
+{% load piwik_tags %}
 
 {% macro title %}{% block title %}{% endblock %}{% endmacro %}
 {% macro site_name %}Edukacja medialna{% endmacro %}
 
 {% macro title %}{% block title %}{% endblock %}{% endmacro %}
 {% macro site_name %}Edukacja medialna{% endmacro %}
@@ -98,6 +99,6 @@
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
     {% compressed_js 'base' %}
     {% block extra_script %}{% endblock %}
     <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
     {% compressed_js 'base' %}
     {% block extra_script %}{% endblock %}
-    {{ piwik_tag|safe }}
+    {% tracking_code %}
     </body>
 </html>
     </body>
 </html>
index 3a82a7b..ce81ed9 100755 (executable)
 
 <section id="main-sections">
 <h1>Lekcje:</h1>
 
 <section id="main-sections">
 <h1>Lekcje:</h1>
-{% catalogue_section_buttons %}
+{% catalogue_levels_main %}
 </section>
 
 </section>
 
-<section id="main-chosen">
-<h1>Wybrane tematy na:</h1>
+<section id="main-howto">
+<h1>Nasze lekcje to:</h1>
 <ul class="link-list">
 <ul class="link-list">
-{% course_boxes_toc 1 %}
+    <li><a class="knowledge" href="/info/jak-korzystac/#wiedza-w-pigulce">wiedza w pigułce</a></li>
+    <li><a class="activity" href="/info/jak-korzystac/#zadania">zadania</a></li>
+    <li><a class="lesson-plan" href="/info/jak-korzystac/#scenariusze">scenariusze</a></li>
+    <li><a class="reference" href="/info/jak-korzystac/#slowniczek">słowniczek</a></li>
 </ul>
 </ul>
+<p>Zobacz, <a href="{% url 'info' 'dobre-praktyki' %}">jak przeprowadzili je inni.</a></p>
+
+{# <iframe width="220" height="124" src="//www.youtube.com/embed/______?controls=2&amp;rel=0&amp;showinfo=0&amp;theme=light" frameborder="0" allowfullscreen></iframe> #}
+</section>
+
+<section id="main-chosen">
+<h1>Według podstawy programowej:</h1>
+{% course_boxes_toc %}
 </section>
 
 </section>
 
+
 <section id="main-tools">
 
 <section class="main-tools-box">
 <section id="main-tools">
 
 <section class="main-tools-box">
@@ -39,8 +51,6 @@
 <ul class="link-list">
     <li><a href="{% url 'contact_form' 'sugestie' %}">Zgłoś błąd lub sugestię</a></li>
     <li><a href="{% url 'info' 'jak-korzystac/' %}">Jak korzystać?</a></li>
 <ul class="link-list">
     <li><a href="{% url 'contact_form' 'sugestie' %}">Zgłoś błąd lub sugestię</a></li>
     <li><a href="{% url 'info' 'jak-korzystac/' %}">Jak korzystać?</a></li>
-    <li><a href="{{ package_url }}">Pobierz wszystkie lekcje</a></li>
-    <li><a href="{{ package_student_url }}">Pobierz wszystkie lekcje w&nbsp;wersji dla ucznia</a></li>
     <li><a href="{% url 'catalogue_lesson' 'slowniczek' %}">Słowniczek</a></li>
     <li><a href="{% url 'catalogue_lesson' 'metody' %}">Metody edukacyjne</a></li>
     {% if request.user.is_authenticated %}<li><a href="{% url 'pybb:index' %}">Forum</a></li>{% endif %}
     <li><a href="{% url 'catalogue_lesson' 'slowniczek' %}">Słowniczek</a></li>
     <li><a href="{% url 'catalogue_lesson' 'metody' %}">Metody edukacyjne</a></li>
     {% if request.user.is_authenticated %}<li><a href="{% url 'pybb:index' %}">Forum</a></li>{% endif %}
@@ -55,7 +65,3 @@
 
 {% endblock %}
 
 
 {% endblock %}
 
-
-{% block footer_extra %}
-    <p>Wykorzystano zdjęcie autorstwa Katarzyny Włodarczyk, udostępnione na wolnej licencji CC BY-SA.</p>
-{% endblock %}
index 5ac002b..712570d 100755 (executable)
@@ -10,13 +10,6 @@ from .forms import AvatarlessEditProfileForm
 class HomeView(TemplateView):
     template_name="home.html"
 
 class HomeView(TemplateView):
     template_name="home.html"
 
-    def get_context_data(self, **kwargs):
-        context = super(HomeView, self).get_context_data(**kwargs)
-        context['package_url'] = os.path.join(settings.MEDIA_URL, settings.CATALOGUE_PACKAGE)
-        context['package_student_url'] = os.path.join(settings.MEDIA_URL, settings.CATALOGUE_PACKAGE_STUDENT)
-        return context
-
-
 def mil_home_view(request):
     return flatpage(request, url = '/' if request.LANGUAGE_CODE == 'pl' else '/en/')
 
 def mil_home_view(request):
     return flatpage(request, url = '/' if request.LANGUAGE_CODE == 'pl' else '/en/')
 
index 530e990..eea64b5 100644 (file)
@@ -1,10 +1,10 @@
 -i http://pypi.nowoczesnapolska.org.pl/simple
 
 -i http://pypi.nowoczesnapolska.org.pl/simple
 
-Django>=1.5,<1.6
+Django>=1.6,<1.7
 South>=0.7.4
 django-pipeline>=1.2,<1.3
 python-memcached
 South>=0.7.4
 django-pipeline>=1.2,<1.3
 python-memcached
-piwik
+django-piwik
 #pyScss
 #git+git://github.com/Kronuz/pyScss.git@d8f4da23a3c87696a75b3830ed4ab49b75550a93#egg=pyScss
 #TODO: pyScss support, for now just install sass
 #pyScss
 #git+git://github.com/Kronuz/pyScss.git@d8f4da23a3c87696a75b3830ed4ab49b75550a93#egg=pyScss
 #TODO: pyScss support, for now just install sass