Browse Source

Add CKEditor +configure, first tests, test data generation

remotes/origin/feincms
Tomas Gavenciak 10 years ago
parent
commit
0b88b8022c
  1. 45
      mamweb/settings_common.py
  2. 1
      mamweb/urls.py
  3. 1
      requirements.txt
  4. 13
      seminar/admin.py
  5. 83
      seminar/management/commands/testdata.py
  6. 17
      seminar/models.py
  7. 80
      seminar/tests.py

45
mamweb/settings_common.py

@ -90,6 +90,7 @@ INSTALLED_APPS = (
'reversion', 'reversion',
'django_countries', 'django_countries',
'solo', 'solo',
'ckeditor',
# MaMweb # MaMweb
'mamweb', 'mamweb',
@ -97,9 +98,53 @@ INSTALLED_APPS = (
) )
DEBUG_TOOLBAR_CONFIG = {
'SHOW_COLLAPSED': True,
}
SUMMERNOTE_CONFIG = {
'iframe': False,
'airMode': False,
'attachment_require_authentication': True,
'width': '80%',
# 'height': '30em',
'toolbar': [
['style', ['style']],
['font', ['bold', 'italic', 'superscript', 'subscript', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link', 'picture', 'hr']],
['view', ['fullscreen', 'codeview']],
['help', ['help']],
]
}
CKEDITOR_UPLOAD_PATH = "uploads/"
CKEDITOR_IMAGE_BACKEND = 'pillow'
#CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'
CKEDITOR_CONFIGS = {
'default': {
'toolbar': [
['Source', 'ShowBlocks', '-', 'Maximize'],
['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'],
['NumberedList','BulletedList','-','Blockquote','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
['Link', 'Unlink', 'Anchor', '-', 'Image', 'Table', 'HorizontalRule'],
['Format'],
],
# 'toolbar': 'full',
'height': '40em',
'width': '100%',
'toolbarStartupExpanded': False
},
}
# MaM specific # MaM specific
SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni') SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni')

1
mamweb/urls.py

@ -7,6 +7,7 @@ from django.conf import settings
urlpatterns = i18n_patterns('', urlpatterns = i18n_patterns('',
url(r'^admin/', include(admin.site.urls)), # NOQA url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'^ckeditor/', include('ckeditor.urls')),
url(r'^', include('seminar.urls')), url(r'^', include('seminar.urls')),
) )

1
requirements.txt

@ -15,6 +15,7 @@ django-reversion==1.8.5
django-sekizai==0.8.1 django-sekizai==0.8.1
django-countries==3.2 django-countries==3.2
django-solo==1.1.0 django-solo==1.1.0
django-ckeditor==4.4.7
# debug tools/extensions # debug tools/extensions

13
seminar/admin.py

@ -1,7 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib import admin from django.contrib import admin
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni from django import forms
from solo.admin import SingletonModelAdmin from solo.admin import SingletonModelAdmin
from ckeditor.widgets import CKEditorWidget
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
### Nastaveni ### Nastaveni
@ -106,7 +109,15 @@ class ReseniInline(admin.StackedInline):
### Problem ### Problem
class ProblemAdminForm(forms.ModelForm):
text_problemu = forms.CharField(widget=CKEditorWidget())
text_problemu_org = forms.CharField(widget=CKEditorWidget())
class Meta:
model = Problem
exclude = []
class ProblemAdmin(admin.ModelAdmin): class ProblemAdmin(admin.ModelAdmin):
form = ProblemAdminForm
# readonly_fields = ['autor'] # readonly_fields = ['autor']
fieldsets = [ fieldsets = [
(None, {'fields': ['nazev', 'typ', 'stav', 'autor']}), (None, {'fields': ['nazev', 'typ', 'stav', 'autor']}),

83
seminar/management/commands/testdata.py

@ -8,6 +8,12 @@ from django.core.management.base import NoArgsCommand
from django.core.management import call_command from django.core.management import call_command
from django.conf import settings from django.conf import settings
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
from seminar.tests import create_test_data
import django.contrib.auth
User = django.contrib.auth.get_user_model()
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "Clear database and load testing data." help = "Clear database and load testing data."
@ -18,76 +24,13 @@ class Command(NoArgsCommand):
os.rename(dbfile, dbfile + '.old') os.rename(dbfile, dbfile + '.old')
self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old')) self.stderr.write('Stara databaze prejmenovana na "%s"' % (dbfile + '.old'))
call_command('migrate', noinput=True) call_command('migrate', noinput=True)
self.load_testing_data() self.stdout.write('Vytvarim uzivatele "admin" (heslo "admin") a pseudo-nahodna data ...')
create_test_data()
def load_testing_data(self): self.stdout.write('Vytvoreno %d uzivatelu, %d skol, %d resitelu, %d rocniku, %d cisel, %d problemu, %d reseni.' %
from seminar import models as sm (User.objects.count(), Skola.objects.count(), Resitel.objects.count(), Rocnik.objects.count(),
import django.contrib.auth Cislo.objects.count(), Problem.objects.count(), Reseni.objects.count()))
User = django.contrib.auth.get_user_model()
self.stderr.write('Vytvarim uzivatele "admin" (heslo "admin")')
# pevna pseudo-nahodnost
rnd = random.Random(x=42)
# users
admin = User.objects.create_superuser(username='admin', email='', password='admin')
self.stderr.write('Vytvarim pseudo-nahodna data')
orgs = []
for org in ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']:
o = User.objects.create_user(username=org, password=org)
o.first_name = org.capitalize()
o.save()
orgs.append(o)
# skoly
sm.Skola.objects.create(mesto = u'Praha', stat='CZ', psc='101 00', ulice=u'Krátká 5', nazev=u'První SŠ')
sm.Skola.objects.create(mesto = u'Praha', stat='CZ', psc='102 00', ulice=u'Dlouhá 5', nazev=u'Druhá SŠ')
sm.Skola.objects.create(mesto = u'Praha', stat='CZ', psc='103 00', ulice=u'Široká 3', nazev=u'Třetí SŠ')
sm.Skola.objects.create(mesto = u'Ostrava', stat='CZ', psc='700 00', ulice=u'Hluboká 42', nazev=u'Hutní gympl')
sm.Skola.objects.create(mesto = u'Humenné', stat='SK', psc='012 34', ulice=u'Pltká 1', nazev=u'Sredná škuola')
# resitele
for i in range(20):
skola = rnd.choice(sm.Skola.objects.all())
pohlavi = rnd.randint(0,1)
sm.Resitel.objects.create(skola = skola, datum_prihlaseni = datetime.date(rnd.randint(2002, 2014), rnd.randint(1,12), 1),
jmeno = u'Řešitel' if pohlavi else u'Řešitelka', prijmeni = 'Číslo-%s' % (i), rok_maturity = rnd.randint(2015, 2019),
stat = skola.stat, zasilat = sm.Resitel.ZASILAT_NIKAM, pohlavi_muz = pohlavi)
# rocniky
for ri in range(17, 22):
r = sm.Rocnik.objects.create(prvni_rok = 1993 + ri, rocnik = ri)
# cisla
cisel = rnd.randint(4, 6)
cs = {}
for ci in range(1, cisel + 1):
vydano = datetime.date(r.prvni_rok, ci + 6, 1)
deadline = datetime.date(r.prvni_rok, ci + 8, 1) if ci + 2 < cisel else None
c = sm.Cislo.objects.create(rocnik = r, cislo = str(ci), datum_vydani=vydano, datum_deadline=deadline)
cs[ci] = c
# problemy resene v ci
seq='#ABCDEFGHIJKLMNOPQRSTUVWXYZ'
if ci >= 3:
for pi in range(1, 4):
p = sm.Problem.objects.create(autor = rnd.choice(orgs), cislo_zadani=cs[ci-2], cislo_reseni=cs[ci],
opravovatel = rnd.choice(orgs), kod = str(pi), nazev = u'Dummy úloha %s-%s' % (seq[ci], seq[pi]),
stav = sm.Problem.STAV_ZADANY, typ = sm.Problem.TYP_ULOHA, body = rnd.randint(1, 5))
for resi in range(rnd.randint(0, 7)):
res = sm.Reseni.objects.create(problem = p, resitel = rnd.choice(sm.Resitel.objects.all()),
body = rnd.randint(0, p.body), cislo_body = cs[ci])
nastaveni = sm.Nastaveni.objects.create(aktualni_rocnik = sm.Rocnik.objects.last(),
aktualni_cislo = sm.Cislo.objects.last())
self.stderr.write('Vytvoreno %d uzivatelu, %d skol, %d resitelu, %d rocniku, %d cisel, %d problemu, %d reseni.' %
(User.objects.count(), sm.Skola.objects.count(), sm.Resitel.objects.count(), sm.Rocnik.objects.count(),
sm.Cislo.objects.count(), sm.Problem.objects.count(), sm.Reseni.objects.count()))

17
seminar/models.py

@ -13,6 +13,10 @@ from django.utils.encoding import force_unicode
from django_countries.fields import CountryField from django_countries.fields import CountryField
from solo.models import SingletonModel from solo.models import SingletonModel
from ckeditor.fields import RichTextField
from redactor.fields import RedactorField
# #
# Mělo by být částečně vytaženo z Aesopa # Mělo by být částečně vytaženo z Aesopa
# viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol. # viz https://ovvp.mff.cuni.cz/wiki/aesop/export-skol.
@ -155,6 +159,11 @@ class Rocnik(models.Model):
def __str__(self): def __str__(self):
return force_unicode(u'%s (%d/%d)' % (self.rocnik, self.prvni_rok, self.prvni_rok+1)) return force_unicode(u'%s (%d/%d)' % (self.rocnik, self.prvni_rok, self.prvni_rok+1))
def roman(self):
if self.rocnik.isdigit():
return force_unicode(roman(int(self.rocnik)))
else:
return force_unicode(self.rocnik)
@python_2_unicode_compatible @python_2_unicode_compatible
class Cislo(models.Model): class Cislo(models.Model):
@ -320,3 +329,11 @@ class Nastaveni(SingletonModel):
return u'Nastavení semináře' return u'Nastavení semináře'
def roman(num):
ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1)
nums = ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
res = ""
for i, n in zip(ints, nums):
res += n * (num // i)
num %= i
return res

80
seminar/tests.py

@ -1,3 +1,79 @@
from django.test import TestCase # -*- coding: utf-8 -*-
import datetime
import random
from unittest import TestCase
import django.contrib.auth
from django.db import transaction
from seminar.models import Skola, Resitel, Rocnik, Cislo, Problem, Reseni, PrilohaReseni, Nastaveni
User = django.contrib.auth.get_user_model()
@transaction.atomic
def create_test_data():
# pevna pseudo-nahodnost
rnd = random.Random(x=42)
# users
admin = User.objects.create_superuser(username='admin', email='', password='admin')
orgs = []
for org in ['anet', 'bara', 'cyril', 'david', 'eva', 'filip']:
o = User.objects.create_user(username=org, password=org)
o.first_name = org.capitalize()
o.save()
orgs.append(o)
# skoly
Skola.objects.create(mesto = u'Praha', stat='CZ', psc='101 00', ulice=u'Krátká 5', nazev=u'První SŠ')
Skola.objects.create(mesto = u'Praha', stat='CZ', psc='102 00', ulice=u'Dlouhá 5', nazev=u'Druhá SŠ')
Skola.objects.create(mesto = u'Praha', stat='CZ', psc='103 00', ulice=u'Široká 3', nazev=u'Třetí SŠ')
Skola.objects.create(mesto = u'Ostrava', stat='CZ', psc='700 00', ulice=u'Hluboká 42', nazev=u'Hutní gympl')
Skola.objects.create(mesto = u'Humenné', stat='SK', psc='012 34', ulice=u'Pltká 1', nazev=u'Sredná škuola')
# resitele
for i in range(20):
skola = rnd.choice(Skola.objects.all())
pohlavi = rnd.randint(0,1)
Resitel.objects.create(skola = skola, datum_prihlaseni = datetime.date(rnd.randint(2002, 2014), rnd.randint(1,12), 1),
jmeno = u'Řešitel' if pohlavi else u'Řešitelka', prijmeni = 'Číslo-%s' % (i), rok_maturity = rnd.randint(2015, 2019),
stat = skola.stat, zasilat = Resitel.ZASILAT_NIKAM, pohlavi_muz = pohlavi)
# rocniky
for ri in range(17, 22):
r = Rocnik.objects.create(prvni_rok = 1993 + ri, rocnik = ri)
# cisla
cisel = rnd.randint(4, 6)
cs = {}
for ci in range(1, cisel + 1):
vydano = datetime.date(r.prvni_rok, ci + 6, 1)
deadline = datetime.date(r.prvni_rok, ci + 8, 1) if ci + 2 < cisel else None
c = Cislo.objects.create(rocnik = r, cislo = str(ci), datum_vydani=vydano, datum_deadline=deadline)
cs[ci] = c
# problemy resene v ci
seq='#ABCDEFGHIJKLMNOPQRSTUVWXYZ'
if ci >= 3:
for pi in range(1, 4):
p = Problem.objects.create(autor = rnd.choice(orgs), cislo_zadani=cs[ci-2], cislo_reseni=cs[ci],
opravovatel = rnd.choice(orgs), kod = str(pi), nazev = u'Dummy úloha %s-%s' % (seq[ci], seq[pi]),
stav = Problem.STAV_ZADANY, typ = Problem.TYP_ULOHA, body = rnd.randint(1, 5))
for resi in range(rnd.randint(0, 7)):
res = Reseni.objects.create(problem = p, resitel = rnd.choice(Resitel.objects.all()),
body = rnd.randint(0, p.body), cislo_body = cs[ci])
nastaveni = Nastaveni.objects.create(aktualni_rocnik = Rocnik.objects.last(),
aktualni_cislo = Cislo.objects.last())
class SeminarTests(TestCase):
def setUp(self):
create_test_data()
def test_rocniky(self):
r19 = Rocnik.objects.get(rocnik=19)
self.assertEqual(r19.roman(), 'XIX')
# Create your tests here.

Loading…
Cancel
Save