from django.contrib import admin
-from .models import Section, Lesson
+from .models import Attachment, Section, Lesson
-admin.site.register(Section)
-admin.site.register(Lesson)
+class AttachmentInline(admin.TabularInline):
+ model = Attachment
+class LessonAdmin(admin.ModelAdmin):
+ inlines = [AttachmentInline]
+admin.site.register(Section)
+admin.site.register(Lesson, LessonAdmin)
from django.core.management.color import color_style
from django.core.files import File
+from librarian import IOFile
from catalogue.models import Lesson
#from search import Index
def import_book(self, file_path, options):
verbose = options.get('verbose')
- with open(file_path) as f:
- lesson = Lesson.publish(f)
+ iofile = IOFile.from_filename(file_path)
+ basename, ext = file_path.rsplit('.', 1)
+ if os.path.isdir(basename):
+ for att_name in os.listdir(basename):
+ iofile.attachments[att_name] = IOFile.from_filename(
+ os.path.join(basename, att_name))
+ lesson = Lesson.publish(iofile)
def handle(self, *directories, **options):
from django.db import transaction
--- /dev/null
+# -*- 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 'Attachment.slug'
+ db.add_column('catalogue_attachment', 'slug',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=255),
+ keep_default=False)
+
+ # Adding field 'Attachment.ext'
+ db.add_column('catalogue_attachment', 'ext',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=15),
+ keep_default=False)
+
+ # Adding unique constraint on 'Attachment', fields ['ext', 'lesson', 'slug']
+ db.create_unique('catalogue_attachment', ['ext', 'lesson_id', 'slug'])
+
+
+ def backwards(self, orm):
+ # Removing unique constraint on 'Attachment', fields ['ext', 'lesson', 'slug']
+ db.delete_unique('catalogue_attachment', ['ext', 'lesson_id', 'slug'])
+
+ # Deleting field 'Attachment.slug'
+ db.delete_column('catalogue_attachment', 'slug')
+
+ # Deleting field 'Attachment.ext'
+ db.delete_column('catalogue_attachment', 'ext')
+
+
+ models = {
+ 'catalogue.attachment': {
+ 'Meta': {'unique_together': "(['lesson', 'slug', 'ext'],)", 'object_name': 'Attachment'},
+ 'ext': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
+ 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+ },
+ 'catalogue.lesson': {
+ 'Meta': {'ordering': "['section', 'level', 'depth', 'order']", 'object_name': 'Lesson'},
+ 'dc': ('jsonfield.fields.JSONField', [], {'default': "'{}'"}),
+ 'depth': ('django.db.models.fields.IntegerField', [], {}),
+ 'html_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Section']"}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'student_package': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'xml_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+ },
+ 'catalogue.part': {
+ 'Meta': {'object_name': 'Part'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'lesson': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['catalogue.Lesson']"}),
+ 'pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'student_pdf': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'})
+ },
+ 'catalogue.section': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'title': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'})
+ },
+ 'curriculum.level': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ }
+ }
+
+ complete_apps = ['catalogue']
\ No newline at end of file
def publish(cls, infile):
from librarian.parser import WLDocument
from django.core.files.base import ContentFile
- # infile should be IOFile, now it's a regular file
- xml = infile.read()
+ xml = infile.get_string()
wldoc = WLDocument.from_string(xml)
slug = wldoc.book_info.url.slug
except cls.DoesNotExist:
lesson = cls(slug=slug)
+ lesson.attachment_set.all().delete()
+ for att_name, att_file in infile.attachments.items():
+ try:
+ slug, ext = att_name.rsplit('.', 1)
+ except ValueError:
+ slug, ext = att_name, ''
+ attachment = lesson.attachment_set.create(slug=slug, ext=ext)
+ attachment.file.save(att_name, ContentFile(att_file.get_string()))
+
# Save XML file
lesson.xml_file.save('%s.xml' % slug, ContentFile(xml), save=False)
lesson.title = wldoc.book_info.title
- #book.extra_info = wldoc.book_info.to_dict()
- # FIXME:
- #lesson.level = Level.objects.get(slug=wldoc.book_info.audience)
- lesson.level = Level.objects.get(name=wldoc.book_info.audience)
+ lesson.level = Level.objects.get(slug=wldoc.book_info.audience)
# TODO: no xml data?
lesson.section = Section.objects.all()[0]
lesson.order = 1
class Attachment(models.Model):
+ slug = models.CharField(max_length=255)
+ ext = models.CharField(max_length=15)
lesson = models.ForeignKey(Lesson)
file = models.FileField(upload_to="catalogue/attachment")
+ class Meta:
+ ordering = ['slug', 'ext']
+ unique_together = ['lesson', 'slug', 'ext']
+
+ def __unicode__(self):
+ return "%s.%s" % (self.slug, self.ext)
+
class Part(models.Model):
lesson = models.ForeignKey(Lesson)
{% extends "base.html" %}
{% load url from future %}
{% load lesson_nav person_list from catalogue_tags %}
+{% load find_competence url_for_level from curriculum_tags %}
+
{% block title %}{{ object }}{% endblock %}
</ul>
</section>
+ {% if object.dc.competences %}
+ <section class="section-minor">
+ <ul class="link-list">
+ {% for comp_text in object.dc.competences %}
+ {% with comp_text|find_competence as competence %}
+ {% if competence %}
+ <li><a href="{{ competence|url_for_level:object.level }}">
+ {{ competence }}</a></li>
+ {% else %}
+ {{ comp_text }}
+ {% endif %}
+ {% endwith %}
+ {% endfor %}
+ </ul>
+ </section>
+ {% endif %}
+
<section class="section-minor">
<p>{{ object.dc.description }}</p>
</section>
class LevelAdmin(admin.ModelAdmin):
model = Level
- list_display = ['name', 'slug', 'order']
+ list_display = ['name', 'group', 'slug', 'order']
class SectionAdmin(admin.ModelAdmin):
model = Section
--- /dev/null
+# -*- 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.group'
+ db.add_column('curriculum_level', 'group',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=255),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'Level.group'
+ db.delete_column('curriculum_level', 'group')
+
+
+ models = {
+ 'curriculum.competence': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ },
+ 'curriculum.competencelevel': {
+ 'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+ 'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+ },
+ 'curriculum.level': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+ 'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ },
+ 'curriculum.section': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ }
+ }
+
+ complete_apps = ['curriculum']
\ No newline at end of file
--- /dev/null
+# -*- 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):
+
+ # Changing field 'Level.slug'
+ db.alter_column('curriculum_level', 'slug', self.gf('django.db.models.fields.CharField')(max_length=255))
+ # Removing index on 'Level', fields ['slug']
+ db.delete_index('curriculum_level', ['slug'])
+
+
+ def backwards(self, orm):
+ # Adding index on 'Level', fields ['slug']
+ db.create_index('curriculum_level', ['slug'])
+
+
+ # Changing field 'Level.slug'
+ db.alter_column('curriculum_level', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=50))
+
+ models = {
+ 'curriculum.competence': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Competence'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'section': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Section']"}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ },
+ 'curriculum.competencelevel': {
+ 'Meta': {'ordering': "['competence', 'level']", 'object_name': 'CompetenceLevel'},
+ 'competence': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Competence']"}),
+ 'description': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['curriculum.Level']"})
+ },
+ 'curriculum.level': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Level'},
+ 'group': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'})
+ },
+ 'curriculum.section': {
+ 'Meta': {'ordering': "['order']", 'object_name': 'Section'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'order': ('django.db.models.fields.IntegerField', [], {}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ }
+ }
+
+ complete_apps = ['curriculum']
\ No newline at end of file
+from django.core.urlresolvers import reverse
from django.db import models
from django.utils.translation import ugettext_lazy as _
def __unicode__(self):
return self.name
+ def get_absolute_url(self):
+ return "%s?c=%d" % (reverse("curriculum"), self.pk)
+
def for_level(self, level):
return self.competencelevel_set.get(level=level)
+ @classmethod
+ def from_text(cls, text):
+ name = text.rsplit(u'\u2013', 1)[-1].strip()
+ return cls.objects.get(name__iexact=name)
+
class Level(models.Model):
+ group = models.CharField(_('group'), max_length=255)
name = models.CharField(_('name'), max_length=255)
- slug = models.SlugField(_('slug'))
+ slug = models.CharField(_('slug'), max_length=255)
order = models.IntegerField(_('order'))
class Meta:
verbose_name_plural = _('competences on levels')
def __unicode__(self):
- return "%s/%s" % (self.competence, self.level)
+ return u"%s/%s" % (self.competence, self.level)
+
+ def get_absolute_url(self):
+ return "%s?c=%d&level=%s&d=1" % (reverse("curriculum"), self.competence.pk, self.level.slug)
--- /dev/null
+.curriculum-form {
+ border: 1px solid #ddd;
+ padding: 1em;
+ border-radius: 0.688em;
+ background: #ADAEAF;
+ color: white; }
+ .curriculum-form h2 {
+ margin: 0; }
+ .curriculum-form h2 a {
+ display: block;
+ color: white; }
+ .curriculum-form h2 a span {
+ display: none; }
+ .curriculum-form strong {
+ display: inline-block;
+ vertical-align: top;
+ width: 12em; }
+ .curriculum-form .curriculum-levels {
+ display: inline-block;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ width: 40em;
+ vertical-align: top; }
+ .curriculum-form .curriculum-levels li {
+ display: inline-block;
+ width: 13em; }
+ .curriculum-form .curriculum-section-toggler {
+ display: none; }
--- /dev/null
+$(function() {
+ if (curriculum_hide_form) {
+ $('.curriculum-form form').hide();
+ $('.curriculum-form h2 a span').show();
+ }
+ $('.curriculum-form h2 a').click(function() {
+ $('.curriculum-form form').toggle('fast');
+ $('span', this).toggle();
+ });
+
+ /* show togglers */
+ $('.curriculum-section-toggler').show();
+
+ $('.curriculum-section').each(function() {
+ var category = this;
+
+ /* set up togglers */
+ $('.curriculum-section-toggler', this).click(function() {
+ $('ul', category).toggle('fast');
+ });
+
+ /* set up section checkboxes */
+ $('.s', category).change(function() {
+ if ($(this).attr('checked')) {
+ $('ul input', category).attr('checked', 'checked');
+ }
+ else {
+ $('ul input', category).removeAttr('checked');
+ }
+ });
+
+ /* unset section checkbox on unselect single competence */
+ $('ul input', category).change(function() {
+ if (!$(this).attr('checked')) {
+ $('.s', category).removeAttr('checked', 'checked');
+ }
+ });
+
+ /* hide unused section details on start */
+ if ($('.s', category).attr('checked') || !$('ul input[checked]', category).length)
+ $('ul', category).hide();
+ });
+});
--- /dev/null
+$px: 0.0625em;
+
+.curriculum-form {
+ border: 1px solid #ddd;
+ padding: 1em;
+ border-radius: 11*$px;
+ background: #ADAEAF;
+ color: white;
+
+ h2 {
+ margin: 0;
+ a {
+ display: block;
+ color: white;
+ span {display: none;}
+ }
+ }
+
+ strong {
+ display: inline-block;
+ vertical-align: top;
+ width: 12em;
+ }
+
+ .curriculum-levels {
+ display: inline-block;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ width: 40em;
+ vertical-align: top;
+
+ li {
+ display: inline-block;
+ width: 13em;
+ }
+ }
+
+ .curriculum-section-toggler {
+ display: none;
+ }
+
+ .categories {
+
+ }
+
+}
{% block body %}
<h1>Katalog kompetencji medialnych i informacyjnych</h1>
+<div class="curriculum-form">
+<h2><a>Przeglądaj kompetencje <span>(rozwiń)</span></a></h2>
<form>
+
<h3>Poziom edukacyjny:</h3>
{% if errors.level %}<p class="error">{{ errors.level }}</p>{% endif %}
-<strong>edukacja formalna:</strong>
-<ul>
-{% for lev in levels %}
+{% for lev_group, levels in levels.items %}
+ <strong>{{ lev_group }}</strong>
+ <ul class="curriculum-levels">
+ {% for lev in levels %}
<li><label><input type="radio" name="level" value="{{ lev.slug }}"
{% if lev == level %}checked="checked"{% endif %} />
{{ lev }}</label></li>
+ {% endfor %}
+ </ul>
{% endfor %}
-</ul>
-<strong>edukacja ustawiczna:</strong>
<h3>Kategorie kompetencji:</h3>
{% if errors.competences %}<p class="error">{{ errors.competences }}</p>{% endif %}
-<ul>
+<ul class="curriculum-sections">
{% for section in sections %}
- <li>
- <label><input type="checkbox" name="s" value="{{ section.pk }}"
+ <li class="curriculum-section">
+ <label><input type="checkbox" class="s" name="s" value="{{ section.pk }}"
{% if section.pk in sect_ids %}checked="checked"{% endif %} /> {{ section }}</label>
- <span class="curriculum-section-toggler" >(rozwiń)</span>
- <ul>
+ <a class="curriculum-section-toggler">(rozwiń)</a>
+ <ul class="competences">
{% for competence in section.competence_set.all %}
- <li><label><input type="checkbox" name="c" value="{{ competence.pk }}"
+ <li class="competence"><label><input class="c" type="checkbox" name="c" value="{{ competence.pk }}"
{% if competence.pk in comp_ids %}checked="checked"{% endif %} />
{{ competence }}</label></li>
{% endfor %}
</ul>
<button>Pokaż</button>
</form>
+</div>
{% if chosen_competences %}
+<h2>Wybrane kompetencje – {{ level }}</h2>
+
{% for section, competences in chosen_competences.items %}
<h3>{{ section }}</h3>
{% for competence in competences %}
{% endif %}
-{% endblock %}
\ No newline at end of file
+
+{% if request.GET.d %}
+<script type="text/javascript">
+ var curriculum_hide_form = true;
+</script>
+{% endif %}
+{% endblock %}
--- /dev/null
+from django import template
+from ..models import Competence
+
+register = template.Library()
+
+
+@register.filter
+def find_competence(text):
+ try:
+ return Competence.from_text(text)
+ except:
+ return None
+
+@register.filter
+def url_for_level(comp, level):
+ try:
+ return comp.for_level(level).get_absolute_url()
+ except:
+ return comp.get_absolute_url()
+
def get_context_data(self, **kwargs):
context = super(CompetencesView, self).get_context_data(**kwargs)
- context['levels'] = Level.objects.all()
+
+ context['levels'] = SortedDict()
+ for level in Level.objects.all():
+ context['levels'].setdefault(level.group, []).append(level)
+
context['sections'] = Section.objects.all()
errors = {}
'catalogue/css/lesson.scss',
'catalogue/css/exercise.scss',
'catalogue/css/section_list.scss',
+ 'curriculum/curriculum.scss',
),
'output_filename': 'compressed/base.css',
},
'catalogue/js/edumed.js',
'catalogue/js/carousel.js',
'sponsors/js/sponsors.js',
+ 'curriculum/curriculum.js',
),
'output_filename': 'compressed/base.js',
},