diff --git a/.gitignore b/.gitignore index aefe158b..6b8b5c02 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ # secrets /django.secret + +# vim tmp files +*~ diff --git a/korektury/forms.py b/korektury/forms.py new file mode 100644 index 00000000..676d6b3a --- /dev/null +++ b/korektury/forms.py @@ -0,0 +1,13 @@ +from django import forms + +class OpravaForm(forms.Form): + text = forms.CharField(max_length=256) + autor = forms.CharField(max_length=20) + x = forms.IntegerField() + y = forms.IntegerField() + scroll = forms.CharField(max_length=256) + pdf = forms.CharField(max_length=256) + img_id = forms.CharField(max_length=256) + id = forms.CharField(max_length=256) + action = forms.CharField(max_length=256) + diff --git a/korektury/migrations/0001_initial.py b/korektury/migrations/0001_initial.py new file mode 100644 index 00000000..22643689 --- /dev/null +++ b/korektury/migrations/0001_initial.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import korektury.models + + +class Migration(migrations.Migration): + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='KorekturovanePDF', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('pdf', models.FileField(upload_to=korektury.models.generate_filename, verbose_name='pdf')), + ], + options={ + 'db_table': 'korekturovane_cislo', + 'verbose_name': 'PDF k oprav\xe1m', + 'verbose_name_plural': 'PDF k oprav\xe1m', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='Oprava', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('strana', models.IntegerField(help_text=b'Strana s opravou (od 0)', verbose_name='strana s opravou')), + ('x', models.IntegerField(verbose_name='x-ov\xe1 sou\u0159adnice bugu')), + ('y', models.IntegerField(verbose_name='y-ov\xe1 sou\u0159adnice bugu')), + ('status', models.CharField(default=b'k_oprave', max_length=16, verbose_name='stav opravy', choices=[(b'k_oprave', 'K oprav\u011b'), (b'opraveno', 'Opraveno'), (b'smazano', 'Smaz\xe1no')])), + ('autor', models.TextField(help_text=b'Autor opravy', verbose_name='autor opravy', blank=True)), + ('text', models.TextField(help_text=b'Text opravy', verbose_name='text opravy', blank=True)), + ], + options={ + 'ordering': ['y', 'x'], + 'db_table': 'opravy', + 'verbose_name': 'Oprava', + 'verbose_name_plural': 'Opravy', + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='OpravaKomentar', + fields=[ + ('id', models.AutoField(serialize=False, primary_key=True)), + ('cas', models.DateTimeField(help_text=b'\xc4\x8cas zad\xc3\xa1n\xc3\xad koment\xc3\xa1\xc5\x99e', verbose_name='\u010das koment\xe1\u0159e')), + ('autor', models.TextField(help_text=b'Autor koment\xc3\xa1\xc5\x99e', verbose_name='autor koment\xe1\u0159e', blank=True)), + ('text', models.TextField(help_text=b'Text koment\xc3\xa1\xc5\x99e', verbose_name='text koment\xe1\u0159e', blank=True)), + ('oprava', models.ForeignKey(to='korektury.Oprava')), + ], + options={ + 'ordering': ['cas'], + 'db_table': 'opravy_komentare', + 'verbose_name': 'Koment\xe1\u0159 k oprav\u011b', + 'verbose_name_plural': 'Koment\xe1\u0159e k oprav\u011b', + }, + bases=(models.Model,), + ), + ] diff --git a/korektury/models.py b/korektury/models.py index 71a83623..d5ea8203 100644 --- a/korektury/models.py +++ b/korektury/models.py @@ -1,3 +1,123 @@ +# -*- coding: utf-8 -*- +import os +import random from django.db import models +from django.contrib import auth +from django.utils import timezone +from django.conf import settings +from django.utils.encoding import python_2_unicode_compatible +from django.utils.encoding import force_unicode +from django.utils.text import slugify +from django.core.urlresolvers import reverse +from django.core.cache import cache +from imagekit.models import ImageSpecField, ProcessedImageField +from imagekit.processors import ResizeToFit, Transpose + +from PIL import Image +import os +from cStringIO import StringIO +from django.core.files.base import ContentFile + +from django_countries.fields import CountryField +from solo.models import SingletonModel +from taggit.managers import TaggableManager + +import reversion + +# PrilohaReseni method +def generate_filename(self, filename): + clean = filename.replace('/','-').replace('\0', '') + datedir = timezone.now().strftime('%Y-%m') + fname = "%s_%s" % ( + timezone.now().strftime('%Y-%m-%d-%H:%M'), + clean) + return os.path.join(settings.SEMINAR_RESENI_DIR, datedir, fname) + + +#@reversion.register(ignore_duplicate_revision=True) +#@python_2_unicode_compatible +class KorekturovanePDF(models.Model): + class Meta: + db_table = 'korekturovane_cislo' + verbose_name = u'PDF k opravám' + verbose_name_plural = u'PDF k opravám' + + #Interní ID + id = models.AutoField(primary_key = True) + + pdf = models.FileField(u'pdf', upload_to = generate_filename) + + #TODO Nepovinný foreign key k číslu + + + +@reversion.register(ignore_duplicate_revision=True) +@python_2_unicode_compatible +class Oprava(models.Model): + class Meta: + db_table = 'opravy' + verbose_name = u'Oprava' + verbose_name_plural = u'Opravy' + ordering = ['y','x'] + + #Interní ID + id = models.AutoField(primary_key = True) + + #pdf = models.ForeignKey(KorekturovanePDF) + + strana = models.IntegerField(u'strana s opravou', help_text='Strana s opravou (od 0)') + + x = models.IntegerField(u'x-ová souřadnice bugu') + y = models.IntegerField(u'y-ová souřadnice bugu') + + STATUS_K_OPRAVE = 'k_oprave' + STATUS_OPRAVENO = 'opraveno' + STATUS_SMAZANO = 'smazano' + STATUS_CHOICES = ( + (STATUS_K_OPRAVE, u'K opravě'), + (STATUS_OPRAVENO, u'Opraveno'), + (STATUS_SMAZANO, u'Smazáno'), + ) + status = models.CharField(u'stav opravy',max_length=16, choices=STATUS_CHOICES, blank=False, + default = STATUS_K_OPRAVE) + + + # TODO: Změnit na cizí klíč do orgů + autor = models.TextField(u'autor opravy',blank = True, help_text='Autor opravy') + + text = models.TextField(u'text opravy',blank = True, help_text='Text opravy') + +# def __init__(self,dictionary): +# for k,v in dictionary.items(): +# setattr(self,k,v) + + def __str__(self): + return force_unicode(u'%s od %s: %s',self.status,self.autor,self.text) + + + +@reversion.register(ignore_duplicate_revision=True) +@python_2_unicode_compatible +class OpravaKomentar(models.Model): + class Meta: + db_table = 'opravy_komentare' + verbose_name = u'Komentář k opravě' + verbose_name_plural = u'Komentáře k opravě' + ordering = ['cas'] + + #Interní ID + id = models.AutoField(primary_key = True) + + cas = models.DateTimeField(u'čas komentáře',help_text = 'Čas zadání komentáře') + + oprava = models.ForeignKey(Oprava) + # TODO: Změnit na cizí klíč do orgů + autor = models.TextField(u'autor komentáře',blank = True, help_text='Autor komentáře') + + text = models.TextField(u'text komentáře',blank = True, help_text='Text komentáře') + + def __str__(self): + return force_unicode(u'%s od %s: %s',self.cas,self.autor,self.text) + + -# Create your models here. diff --git a/korektury/static/korektury/imgs/check.png b/korektury/static/korektury/imgs/check.png new file mode 100644 index 00000000..c4d5504e Binary files /dev/null and b/korektury/static/korektury/imgs/check.png differ diff --git a/korektury/static/korektury/imgs/delete.png b/korektury/static/korektury/imgs/delete.png new file mode 100644 index 00000000..f3add6aa Binary files /dev/null and b/korektury/static/korektury/imgs/delete.png differ diff --git a/korektury/static/korektury/imgs/edit.png b/korektury/static/korektury/imgs/edit.png new file mode 100644 index 00000000..95cabe7d Binary files /dev/null and b/korektury/static/korektury/imgs/edit.png differ diff --git a/korektury/static/korektury/imgs/link.png b/korektury/static/korektury/imgs/link.png new file mode 100644 index 00000000..cfa343c7 Binary files /dev/null and b/korektury/static/korektury/imgs/link.png differ diff --git a/korektury/static/korektury/imgs/next-gr.png b/korektury/static/korektury/imgs/next-gr.png new file mode 100644 index 00000000..885c2cd7 Binary files /dev/null and b/korektury/static/korektury/imgs/next-gr.png differ diff --git a/korektury/static/korektury/imgs/next.png b/korektury/static/korektury/imgs/next.png new file mode 100644 index 00000000..e8b15f66 Binary files /dev/null and b/korektury/static/korektury/imgs/next.png differ diff --git a/korektury/static/korektury/imgs/undo.png b/korektury/static/korektury/imgs/undo.png new file mode 100644 index 00000000..973b5939 Binary files /dev/null and b/korektury/static/korektury/imgs/undo.png differ diff --git a/korektury/static/korektury/opraf.css b/korektury/static/korektury/opraf.css new file mode 100644 index 00000000..d385932c --- /dev/null +++ b/korektury/static/korektury/opraf.css @@ -0,0 +1,105 @@ +.pointer-hi, +.pointer, +.pointer-done, +.pointer-done-hi { + position:absolute; + /*border-bottom-left-radius: 10px; */ + border-left: 2px solid yellow; + border-bottom: 2px solid yellow; +} + +.pointer-done-hi, +.pointer-hi { + border-width: 3px; +} + +.pointer { + border-color: #F00; /*IE*/ + border-color: rgba(255, 0, 0, 0.35); +} +.pointer-hi { + border-color: #F00; /*IE*/ + border-color: rgba(255, 0, 0, 1); +} +.pointer-done { + border-color: #00F; /*IE*/ + border-color: rgba(0, 0, 255, 0.2); +} +.pointer-done-hi { + border-color: #00F; /*IE*/ + border-color: rgba(0, 0, 255, 1); +} + + +.box:hover, .box-done:hover { + border-width:3px; + margin: 0px; +} +.box, .box-done { + margin: 1px; + background-color: white; + width:300px; + /*position:absolute;*/ + padding: 3px; + border: 2px solid black; + border-radius: 10px; +} +.box { + border-color: red; +} +.box-done { + border-color: blue; +} +form { + display:inline; +} + +.float-right{ + float:right; +} + +.imgdiv { + position:relative; + left:0px; + top:0px; +} +#commform-div { + display: none; + position: absolute; + background-color: white; + border: 1px solid; + padding: 3px; + /* + width: 310; + height: 220; + */ + z-index: 10; + border: 4px solid red; + border-radius: 10px; + background-color: white; +} +.close-button{ + background-color: yellow; +} + +body { + background-color: #b0b0ff; +} + + + +.box button, +.box img, +.box-done button, +.box-done img { + border: 1px solid white; + background-color:transparent; + margin:0; + padding: 1px; +} +.box button:hover, +.box img:hover, +.box-done img:hover, +.box-done button:hover { + border: 1px solid black; +} diff --git a/korektury/static/korektury/opraf.js b/korektury/static/korektury/opraf.js new file mode 100644 index 00000000..60764ca1 --- /dev/null +++ b/korektury/static/korektury/opraf.js @@ -0,0 +1,213 @@ +function place_comments_one_div(img_id, comments) +{ + var img = document.getElementById(img_id); + if( img == null ) { + return; + } + var par = img.parentNode; + var w = img.clientWidth; + var h = img.clientHeight; + var w_skip = 10; + var h_skip = 5; + var pointer_min_h = 30; + + var bott_max = 0; + var comments_sorted = comments.sort(function (a,b) { + return a[2] - b[2]; + //pokus o hezci kladeni poiteru, ale nic moc + if( a[3] < b[3] ) { + return (a[2] + pointer_min_h)- b[2]; + } else { + return (a[2] - pointer_min_h)- b[2]; + } + + }); + //console.log("w:" + w); + for (c in comments_sorted) { + var id = comments_sorted[c][0]; + var x = comments_sorted[c][1]; + var y = comments_sorted[c][2]; + + var el = document.getElementById(id); + var elp = document.getElementById(id + "-pointer"); + + if( el == null || elp == null ) { + continue; + } + + par.appendChild(elp); + par.appendChild(el); + + var delta_y = (y > bott_max) ? 0: bott_max - y + h_skip; + + elp.style.left = x; + elp.style.top = y ; + elp.style.width = w - x + w_skip; + elp.style.height = pointer_min_h + delta_y; + elp.img_id = img_id; + el.img_id = img_id; + + el.style.position = 'absolute'; + el.style.left = w + w_skip; + el.style.top = y + delta_y; + + var bott = el.offsetTop + el.offsetHeight; + bott_max = ( bott_max > bott ) ? bott_max : bott; + + //console.log( "par.w:" + par.style.width); + + } + if( par.offsetHeight < bott_max ) { + //par.style.height = bott_max; + //alert("preteklo to:"+ par.offsetHeight +",mx:" + bott_max ); + par.style.height = bott_max; + + } +} + +// ctrl-enter submits form +function textarea_onkey(ev) +{ + //console.log("ev:" + ev.keyCode + "," + ev.ctrlKey); + if( (ev.keyCode == 13 || ev.keyCode == 10 ) && ev.ctrlKey ) { + var form = document.getElementById('commform'); + if( form ) { + save_scroll(form); + //form.action =''; + form.submit(); + } + return true; + } + return false; +} + +//hide comment form +function close_commform() { + + var formdiv = document.getElementById('commform-div'); + if( formdiv == null ) { + alert("form null"); + return true; + } + formdiv.style.display = 'none'; + return false; +} + +// show comment form, when clicked to image +function img_click(element, ev) { + + var dx, dy; + var par = element.parentNode; + if( ev.pageX != null ) { + dx = ev.pageX - par.offsetLeft; + dy = ev.pageY - par.offsetTop; + } else { //IE + dx = ev.offsetX; + dy = ev.offsetY; + } + var img_id = element.id; + if( element.img_id != null ) { + // click was to '-pointer' + img_id = element.img_id; + } + return show_form(img_id, dx, dy, '', '', '', ''); +} + +// show comment form, when 'edit' button pressed +function box_edit(button) +{ + var divbox = button.parentNode.parentNode.parentNode; + var id = divbox.id; + //alert("id: " + id); + var divpointer = document.getElementById(divbox.id + '-pointer'); + var text_el = document.getElementById(divbox.id + '-text'); + var text = text_el.innerHTML.unescapeHTML(); + + var dx = parseInt(divpointer.style.left); + var dy = parseInt(divpointer.style.top); + //alert('not yet 2:' + text + text_el); // + divpointer.style.top "x" + divpo ); + id = id.substring(2); + return show_form(divbox.img_id, dx, dy, id, text, 'update'); + +} + +//fill up comment form and show him +function show_form(img_id, dx, dy, id, text, action) { + var form = document.getElementById('commform'); + var formdiv = document.getElementById('commform-div'); + var textarea = document.getElementById('commform-text'); + var inputX = document.getElementById('commform-x'); + var inputY = document.getElementById('commform-y'); + var inputImgId = document.getElementById('commform-img-id'); + var inputId = document.getElementById('commform-id'); + var inputAction = document.getElementById('commform-action'); + var img = document.getElementById(img_id); + + if( formdiv == null || textarea == null ) { + alert("form null"); + return 1; + } + + //form.action = "#" + img_id; + + // set hidden values + inputX.value = dx; + inputY.value = dy; + inputImgId.value = img_id; + inputId.value = id; + inputAction.value = action; + textarea.value = text; + + //textarea.value = "dxy:"+ dx + "x" + dy + "\n" + 'id:' + img_id; + + // show form + formdiv.style.display = 'block'; + formdiv.style.left = dx; + formdiv.style.top = dy; + + img.parentNode.appendChild(formdiv); + + textarea.focus(); + + return true; + +} + +function box_onmouseover(box, done) +{ + var id = box.id; + var pointer = document.getElementById(box.id + '-pointer'); + pointer.className = done ? 'pointer-done-hi' : 'pointer-hi'; + //console.log('mouseout'); + +} + +function box_onmouseout(box, done) +{ + var id = box.id; + var pointer = document.getElementById(box.id + '-pointer'); + pointer.className = done ? 'pointer-done' : 'pointer'; + + //console.log('mousein'); +} + +function save_scroll(form) +{ + //alert('save_scroll:' + document.body.scrollTop); + form.scroll.value = document.body.scrollTop; + //alert('save_scroll:' + form.scroll.value); + + + return true; +} + + +String.prototype.unescapeHTML = function () { + return( + this.replace(/&/g,'&'). + replace(/>/g,'>'). + replace(/</g,'<'). + replace(/"/g,'"') + ); +}; + diff --git a/korektury/static/korektury/png/.gitignore b/korektury/static/korektury/png/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/korektury/static/korektury/png/.gitignore @@ -0,0 +1 @@ +* diff --git a/korektury/static/korektury/tmp/.gitignore b/korektury/static/korektury/tmp/.gitignore new file mode 100644 index 00000000..72e8ffc0 --- /dev/null +++ b/korektury/static/korektury/tmp/.gitignore @@ -0,0 +1 @@ +* diff --git a/korektury/templates/korektury/opraf.html b/korektury/templates/korektury/opraf.html new file mode 100644 index 00000000..75d80b7f --- /dev/null +++ b/korektury/templates/korektury/opraf.html @@ -0,0 +1,97 @@ + +
+ + + +