Merge branch 'opraf'
Conflicts: mamweb/settings_common.py
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						|  | @ -20,3 +20,6 @@ | |||
| 
 | ||||
| # secrets | ||||
| /django.secret | ||||
| 
 | ||||
| # vim tmp files | ||||
| *~ | ||||
|  |  | |||
							
								
								
									
										14
									
								
								korektury/TODO
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,14 @@ | |||
| - korektura potrebuje reakci | ||||
| + komentáře fixně na username | ||||
|   - používat skutečné jméno? | ||||
| - vyžádat pozornost autora obsahu | ||||
| - zvednout upload limit na 5MB | ||||
| - sbalit a rozbalit korekturu | ||||
| - nápověda | ||||
| - nahrávání jiných věcí než PDF - kontrolovat? | ||||
| - stylování | ||||
| - vylepšení hlavičky | ||||
|   - seznam PDF, homepage M&M, admin, wiki | ||||
| - seznam PDF - co zobrazovat? | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										0
									
								
								korektury/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										16
									
								
								korektury/admin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,16 @@ | |||
| from django.contrib import admin | ||||
| from reversion.admin import VersionAdmin | ||||
| from korektury.models import KorekturovanePDF | ||||
| 
 | ||||
| # Register your models here. | ||||
| class KorekturovanePDFAdmin(VersionAdmin): | ||||
|      readonly_fields = ['cas', 'stran'] | ||||
|      fieldsets = [ | ||||
|          (None,              {'fields': ['pdf', 'cas', 'stran', 'nazev', 'komentar']}), | ||||
| #         (u'PDF',       {'fields': ['pdf']}), | ||||
|          ] | ||||
|      list_display = ['pdf', 'cas', 'stran'] | ||||
|      list_filter = [] | ||||
|      search_fields = [] | ||||
|   | ||||
| admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin) | ||||
							
								
								
									
										13
									
								
								korektury/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -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) | ||||
| 
 | ||||
							
								
								
									
										63
									
								
								korektury/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -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,), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										39
									
								
								korektury/migrations/0002_auto_20151202_2351.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,39 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django.utils.timezone | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('korektury', '0001_initial'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.CreateModel( | ||||
|             name='Komentar', | ||||
|             fields=[ | ||||
|                 ('id', models.AutoField(serialize=False, primary_key=True)), | ||||
|                 ('cas', models.DateTimeField(default=django.utils.timezone.now, 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': 'komentare', | ||||
|                 'verbose_name': 'Koment\xe1\u0159 k oprav\u011b', | ||||
|                 'verbose_name_plural': 'Koment\xe1\u0159e k oprav\u011b', | ||||
|             }, | ||||
|             bases=(models.Model,), | ||||
|         ), | ||||
|         migrations.RemoveField( | ||||
|             model_name='opravakomentar', | ||||
|             name='oprava', | ||||
|         ), | ||||
|         migrations.DeleteModel( | ||||
|             name='OpravaKomentar', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										27
									
								
								korektury/migrations/0003_auto_20151204_1855.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,27 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| import django.utils.timezone | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('korektury', '0002_auto_20151202_2351'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='korekturovanepdf', | ||||
|             name='cas', | ||||
|             field=models.DateTimeField(default=django.utils.timezone.now, help_text=b'\xc4\x8cas vlo\xc5\xbeen\xc3\xad PDF', verbose_name='\u010das vlo\u017een\xed PDF'), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='korekturovanepdf', | ||||
|             name='stran', | ||||
|             field=models.IntegerField(default=0, help_text=b'Po\xc4\x8det stran PDF', verbose_name='po\u010det stran'), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										26
									
								
								korektury/migrations/0004_auto_20151204_2240.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,26 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('korektury', '0003_auto_20151204_1855'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='korekturovanepdf', | ||||
|             name='komentar', | ||||
|             field=models.TextField(help_text=b'Koment\xc3\xa1\xc5\x99 ke korekturovan\xc3\xa9mu PDF (nap\xc5\x99. na co se zam\xc4\x9b\xc5\x99it)', verbose_name='koment\xe1\u0159 k PDF', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name='korekturovanepdf', | ||||
|             name='nazev', | ||||
|             field=models.TextField(help_text=b'N\xc3\xa1zev (nap\xc5\x99. 22.1 verze 4) korekturovan\xc3\xa9ho PDF', verbose_name='n\xe1zev PDF', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										32
									
								
								korektury/migrations/0005_auto_20151204_2244.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,32 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('korektury', '0004_auto_20151204_2240'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='komentar', | ||||
|             name='autor', | ||||
|             field=models.CharField(help_text=b'Autor koment\xc3\xa1\xc5\x99e', max_length=20, verbose_name='autor koment\xe1\u0159e', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='korekturovanepdf', | ||||
|             name='nazev', | ||||
|             field=models.CharField(help_text=b'N\xc3\xa1zev (nap\xc5\x99. 22.1 verze 4) korekturovan\xc3\xa9ho PDF', max_length=50, verbose_name='n\xe1zev PDF', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|         migrations.AlterField( | ||||
|             model_name='oprava', | ||||
|             name='autor', | ||||
|             field=models.CharField(help_text=b'Autor opravy', max_length=20, verbose_name='autor opravy', blank=True), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										20
									
								
								korektury/migrations/0006_oprava_pdf.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,20 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('korektury', '0005_auto_20151204_2244'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='oprava', | ||||
|             name='pdf', | ||||
|             field=models.ForeignKey(default=-1, to='korektury.KorekturovanePDF'), | ||||
|             preserve_default=True, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										0
									
								
								korektury/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										176
									
								
								korektury/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,176 @@ | |||
| # -*- 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 django.core.exceptions import ObjectDoesNotExist | ||||
| from imagekit.models import ImageSpecField, ProcessedImageField | ||||
| from imagekit.processors import ResizeToFit, Transpose | ||||
| 
 | ||||
| import os | ||||
| import subprocess | ||||
| 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', '').replace(":","_") | ||||
|     fname = "%s_%s" % ( | ||||
|         timezone.now().strftime('%Y-%m-%d-%H_%M'), | ||||
|         clean) | ||||
|     return os.path.join(settings.KOREKTURY_PDF_DIR, 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) | ||||
| 
 | ||||
|     cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF') | ||||
| 
 | ||||
|     nazev = models.CharField(u'název PDF',blank = True,max_length=50, help_text='Název (např. 22.1 verze 4) korekturovaného PDF') | ||||
| 
 | ||||
|     komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)') | ||||
| 
 | ||||
|     pdf = models.FileField(u'PDF', upload_to = generate_filename) | ||||
| 
 | ||||
|     stran = models.IntegerField(u'počet stran', help_text = 'Počet stran PDF', default = 0) | ||||
|     STATUS_PRIDAVANI = 'pridavani' | ||||
|     STATUS_ZANASENI = 'zanaseni' | ||||
|     STATUS_ZASTARALE = 'zastarale' | ||||
|     STATUS_CHOICES = ( | ||||
|             (STATUS_PRIDAVANI, u'Přidávání korektur'), | ||||
|             (STATUS_ZANASENI, u'Korektury jsou zanášeny'), | ||||
|             (STATUS_ZASTARALE, u'Stará verze, nekorigovat'), | ||||
|             ) | ||||
|     status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False, | ||||
|             default = STATUS_PRIDAVANI) | ||||
|   | ||||
|    | ||||
|     #TODO Nepovinný foreign key k číslu | ||||
| 
 | ||||
|     def save(self): | ||||
|         # Pokud se nezmenilo PDF, tak nepregenerovavej nahledy | ||||
|         try: | ||||
|             original = KorekturovanePDF.objects.get(pk=self.pk) | ||||
|             if original.pdf == self.pdf: | ||||
|                 super(KorekturovanePDF, self).save() | ||||
|                 return | ||||
|         except ObjectDoesNotExist: | ||||
|             pass | ||||
|         super(KorekturovanePDF, self).save() | ||||
|         print("\nSaving") | ||||
|         print(self.pdf.path) | ||||
|         print(self.pdf.url) | ||||
|         filename = os.path.split(self.pdf.file.name)[1].split(".")[0] | ||||
|         try: | ||||
|             os.listdir(settings.KOREKTURY_IMG_DIR) | ||||
|         except OSError: | ||||
|             os.mkdir(settings.KOREKTURY_IMG_DIR) | ||||
|         while True: | ||||
|             res = subprocess.call([ | ||||
|             "convert", | ||||
|             "-density","180x180", | ||||
|             "-geometry"," 1024x1448", | ||||
|             self.pdf.path+"[%d]"%self.stran, | ||||
|             os.path.join(settings.KOREKTURY_IMG_DIR, "%s-%d.png"%(filename,self.stran))]) | ||||
|             if res==1: | ||||
|                 break | ||||
|             self.stran +=1 | ||||
|         super(KorekturovanePDF, self).save() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @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, default=-1) | ||||
| 
 | ||||
|     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_NENI_CHYBA = 'neni_chyba' | ||||
|     STATUS_K_REAKCI = 'k_reakci' | ||||
|     STATUS_SMAZANO = 'smazano' | ||||
|     STATUS_CHOICES = ( | ||||
|             (STATUS_K_OPRAVE, u'K opravě'), | ||||
|             (STATUS_OPRAVENO, u'Opraveno'), | ||||
|             (STATUS_NENI_CHYBA, u'Není chyba'), | ||||
|             (STATUS_K_REAKCI, u'K reakci autora textu'), | ||||
|             (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.CharField(u'autor opravy',blank = True,max_length=20, 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 Komentar(models.Model): | ||||
|     class Meta: | ||||
|         db_table = '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',default=timezone.now,help_text = 'Čas zadání komentáře') | ||||
| 
 | ||||
|     oprava = models.ForeignKey(Oprava) | ||||
|     # TODO: Změnit na cizí klíč do orgů | ||||
|     autor = models.CharField(u'autor komentáře',blank = True,max_length=20, 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)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										46
									
								
								korektury/static/korektury/help.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,46 @@ | |||
| <html> | ||||
| <head> | ||||
| 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | ||||
| 	<title>Nápověda ke korigovátku</title> | ||||
| </head> | ||||
| <body> | ||||
| <h1> Nápověda ke korigovátku</h1> | ||||
| <p> Korigovátko slouží ke korigování PDF souborů. Umožňuje přidávat a komentovat | ||||
| korektury a označovat je jako zanesené / irelevantní. Rovněž umožňuje o PDF | ||||
| říci, že jsou právě zanášeny korektury nebo že je zastaralé. | ||||
| <h2> Použití </h2> | ||||
| <p> | ||||
| Kliknu do PDF tam, kam chci zadat korekturu, napíši text a kliknu na Oprav! | ||||
| (nebo Ctrl-Enter). | ||||
| Korektura se zobrazí na pravé straně červeně. Korektura nelze smazat ani | ||||
| upravit. | ||||
| </p><p> | ||||
| Pokud chci korekturu okomentovat, kliknu na ikonu <img src="imgs/comment.png"/>, | ||||
| napíši komentář a kliknu na Oprav! (nebo Ctrl-Enter). Komentář se zobrazí pod | ||||
| původní korekturou. | ||||
| </p> | ||||
| <h2> Tlačítka u korektury </h2> | ||||
| <ul> | ||||
| 	<li> <img src="imgs/delete.png"/> - smazat korekturu | ||||
| 	<li> <img src="imgs/check.png"/> - označt koreturu jako zanesenou | ||||
| 	<li> <img src="imgs/cross.png"/> - označit korekturu jako irelevantní | ||||
| 	(není to chyba, nebude zaneseno) | ||||
| 	<li> <img src="imgs/edit.png"/> - upravit text korektury | ||||
| 	<li> <img src="imgs/comment.png"/> - okomentovat korekturu | ||||
| </ul> | ||||
| <h2> Stavy </h2> | ||||
| <h3> Korektura </h3> | ||||
| <ul> | ||||
| 	<li> K opravě - zadaná, čeká na zanesení / zahození | ||||
| 	<li> Zanesená - zanesená v TeXu | ||||
| 	<li> Irelevantní - není to chyba, nebude zanesena | ||||
| 	<li> K reakci - vyžaduje reakci od autora <i>(zatím není | ||||
| 	implementováno)</i> | ||||
| </ul> | ||||
| <h3> PDF </h3> | ||||
| <ul> | ||||
| 	<li> Přidávání - probíhá přidávání korektur | ||||
| 	<li> Zanášení - probíhá zanášení korektur do TeXu | ||||
| 	<li> Zastaralé - PDF je zastaralé, nepřidávat nové korektury | ||||
| </ul> | ||||
| </body> | ||||
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/check.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 697 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/comment.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 726 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/cross.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 717 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/delete-gr.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 347 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/delete.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 500 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/edit-gr.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 973 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/edit.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/link.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.4 KiB | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/next-gr.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 881 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/next.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 557 B | 
							
								
								
									
										
											BIN
										
									
								
								korektury/static/korektury/imgs/undo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 617 B | 
							
								
								
									
										145
									
								
								korektury/static/korektury/opraf.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,145 @@ | |||
| body{background: #f3f3f3; color: black;} | ||||
| body.comitting { | ||||
|     background: yellow; | ||||
| } | ||||
| body.deprecated { | ||||
|     background: red; | ||||
| } | ||||
| 
 | ||||
| img{background:white;} | ||||
| 
 | ||||
| .pointer-hi,  | ||||
| .pointer,  | ||||
| .pointer-wontfix,  | ||||
| .pointer-wontfix-hi,  | ||||
| .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-wontfix-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); | ||||
| } | ||||
| .pointer-wontfix { | ||||
| 	border-color: #00F; /*IE*/ | ||||
| 	border-color: rgba(128, 128, 128, 0.2); | ||||
| } | ||||
| .pointer-wontfix-hi { | ||||
| 	border-color: #00F; /*IE*/ | ||||
| 	border-color: rgba(128, 128, 128, 1); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .box:hover, | ||||
| .box-done:hover, | ||||
| .box-wontfix:hover{ | ||||
| 	border-width:3px; | ||||
| 	margin: 0px; | ||||
| } | ||||
| .box, .box-done, .box-wontfix { | ||||
| 	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; | ||||
| } | ||||
| .box-wontfix { | ||||
| 	border-color: grey; | ||||
| } | ||||
| 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;	 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .box button, | ||||
| .box img, | ||||
| .box-done button, | ||||
| .box-done img, | ||||
| .box-wontfix button, | ||||
| .box-wontfix 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, | ||||
| .box-wontfix img:hover, | ||||
| .box-wontfix button:hover{ | ||||
| 	border: 1px solid black; | ||||
| } | ||||
| 
 | ||||
| .comment hr { | ||||
| 	height: 0px; | ||||
| } | ||||
| 
 | ||||
| .corr-header { | ||||
|     overflow: auto; | ||||
| } | ||||
| 
 | ||||
| .author { | ||||
|     font-weight: bold; | ||||
|     float: left; | ||||
|     margin-top: 3px; | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										256
									
								
								korektury/static/korektury/opraf.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,256 @@ | |||
| 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 body_class = document.body.className; | ||||
| 	switch(body_class){ | ||||
| 		case "comitting": | ||||
| 			if (!confirm("Právě jsou zanášeny korektury, opravdu chcete přidat novou?")) | ||||
| 				return; | ||||
| 			break; | ||||
| 		case "deprecated": | ||||
| 			if (!confirm("Toto PDF je již zastaralé, opravdu chcete vytvořit korekturu?")) | ||||
| 				return; | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	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' or 'comment' button pressed
 | ||||
| function box_edit(button, action) | ||||
| { | ||||
| 	var divbox = button.parentNode.parentNode.parentNode; | ||||
| 	var id = divbox.id; | ||||
| 	var divpointer = document.getElementById(divbox.id + '-pointer'); | ||||
| 
 | ||||
| 	var text; | ||||
| 	if (action == 'update') { | ||||
| 		var text_el = document.getElementById(divbox.id + '-text'); | ||||
| 		text = text_el.innerHTML.unescapeHTML(); | ||||
| 
 | ||||
| 	} else { | ||||
| 		text = ''; | ||||
| 	} | ||||
| 
 | ||||
| 	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, action); | ||||
| } | ||||
| 
 | ||||
| // show comment form when 'update-comment' button pressed
 | ||||
| function update_comment(button) | ||||
| { | ||||
| 	var divbox = button.parentNode.parentNode.parentNode.parentNode; | ||||
| 	var id = divbox.id; | ||||
| 	var divpointer = document.getElementById(divbox.id + '-pointer'); | ||||
| 	var dx = parseInt(divpointer.style.left); | ||||
| 	var dy = parseInt(divpointer.style.top); | ||||
| 
 | ||||
| 	var commentdiv = button.parentNode.parentNode.parentNode; | ||||
| 	var id = commentdiv.id.substring(1); | ||||
| 	var text = document.getElementById('kt' + id).innerHTML.unescapeHTML(); | ||||
| 
 | ||||
| 	return show_form(divbox.img_id, dx, dy, id, text, 'update-comment'); | ||||
| } | ||||
| 
 | ||||
| //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, stat) | ||||
| { | ||||
| 	var id = box.id; | ||||
| 	var pointer = document.getElementById(box.id + '-pointer'); | ||||
| 	switch (stat){ | ||||
| 		case 'done': | ||||
| 			pointer.className = 'pointer-done-hi'; | ||||
| 			break; | ||||
| 		case 'wontfix': | ||||
| 			pointer.className = 'pointer-wontfix-hi'; | ||||
| 			break; | ||||
| 		default: | ||||
| 			pointer.className = 'pointer-hi'; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| function box_onmouseout(box, stat) | ||||
| { | ||||
| 	var id = box.id; | ||||
| 	var pointer = document.getElementById(box.id + '-pointer'); | ||||
| 	switch (stat){ | ||||
| 		case 'done': | ||||
| 			pointer.className = 'pointer-done'; | ||||
| 			break; | ||||
| 		case 'wontfix': | ||||
| 			pointer.className = 'pointer-wontfix'; | ||||
| 			break; | ||||
| 		default: | ||||
| 			pointer.className = 'pointer'; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 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,'"')                                          | ||||
|         );                                                                      | ||||
| }; | ||||
| 
 | ||||
							
								
								
									
										1
									
								
								korektury/static/korektury/png/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1 @@ | |||
| * | ||||
							
								
								
									
										1
									
								
								korektury/static/korektury/tmp/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1 @@ | |||
| * | ||||
							
								
								
									
										185
									
								
								korektury/templates/korektury/opraf.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,185 @@ | |||
| <html> | ||||
| <head> | ||||
| 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | ||||
| 	<link rel="stylesheet" type="text/css" media="screen, projection" href="/static/korektury/opraf.css" /> | ||||
| 	<script src="/static/korektury/opraf.js"></script> | ||||
| 	<title>Korektury {{pdf.nazev}}</title> | ||||
| </head> | ||||
| <body {% if pdf.status = 'zanaseni'%} class="comitting" {% elif pdf.status = 'zastarale' %} class="deprecated" {% endif %}>  | ||||
| 	<h1>Korektury {{pdf.nazev}}</h1> | ||||
| 	{% if pdf.status = 'zanaseni' %} <h2> Probíhá zanášení korektur, zvažte, zda chcete přidávat nové </h2> {% endif %} | ||||
| 	{% if pdf.status = 'zastarale' %} <h2> Toto PDF je již zastaralé, nepřidávejte nové korektury </h2> {% endif %} | ||||
| 	<i>{{pdf.komentar}}</i> | ||||
| 	<br> | ||||
| 	<i>Klikni na chybu, napiš komentář</i>  | | ||||
| 	<a href="/korektury">ls</a> | | ||||
| 	<a href="/static/korektury/help.html">help</a> |          | | ||||
| 	<a href="https://mam.mff.cuni.cz/">hlavní stránka</a> | | ||||
| 	<a href="https://mam.mff.cuni.cz/wiki">wiki</a> | | ||||
| 	<hr/> | ||||
| 
 | ||||
| 	<div id="commform-div"> | ||||
| 		<!-- Pridat korekturu / komentar !--> | ||||
| 		<form action='' onsubmit='save_scroll(this)' id="commform" method="POST"> | ||||
| 			{% csrf_token %} | ||||
| 			<input size="8" name="au" value="{{user.username}}"/> | ||||
| 			<input type=submit value="Oprav!"/> | ||||
| 			<button type="button" onclick="close_commform()">Zavřít</button> | ||||
| 	  		<br/> | ||||
| 	  		<textarea onkeypress="textarea_onkey(event);" id="commform-text" cols=40 rows=10 name="txt"></textarea> | ||||
| 	  		<br/> | ||||
| 	  		<input type="hidden" size="3" name="pdf" value='{{pdf.id}}'/> | ||||
| 	  		<input type="hidden" size="3" id="commform-x" name="x"/> | ||||
| 	  		<input type="hidden" size="3" id="commform-y" name="y"/> | ||||
| 	  		<input type="hidden" size="3" id="commform-img-id" name="img-id"/> | ||||
| 	  		<input type="hidden" size="3" id="commform-id" name="id"/> | ||||
| 	  		<input type="hidden" size="3" id="commform-action" name="action"/> | ||||
| 	  		<input type="hidden" size="3" id="commform-action" name="scroll"/> | ||||
| 		</form> | ||||
| 		<!-- /Pridat korekturu / komentar !--> | ||||
| 	</div> | ||||
| 
 | ||||
| 	{% for i in img_indexes %} | ||||
| 	<div class='imgdiv'> | ||||
| 		<img width='1021' height='1448'  | ||||
| 			onclick='img_click(this,event)' id='img-{{i}}'  | ||||
| 			src='/media/korektury/img/{{img_name}}-{{i}}.png'/> | ||||
| 	</div> | ||||
| 	<hr/> | ||||
| 	{% endfor %} | ||||
| 
 | ||||
| 	<!-- Smazat vsechny komentare !--> | ||||
| 	<form method="post"> | ||||
| 		{% csrf_token %} | ||||
| 		<input type='hidden' name='action' value='delall'/> | ||||
| 		<input type='submit' value='Smazat všechny komentáře'/> | ||||
| 		<input type='hidden' name='pdf' value='{{pdf.id}}'/> | ||||
| 		<input type='checkbox' name='yes'/> Souhlasím se smazáním všech kometářů | ||||
| 	</form> | ||||
| 	<!-- /Smazat vsechny komentare !--> | ||||
| 	<hr/> | ||||
| 	<h4>Změnit stav PDF:</h4> | ||||
| 	<i>Aktuální: {{pdf.status}}</i> | ||||
| 	<br> | ||||
| 	<!-- Zmenit stav PDF !--> | ||||
| 	<form method="post"> | ||||
| 		{% csrf_token %} | ||||
| 		<input type='hidden' name='action' value='set-state'/> | ||||
| 		<input type='hidden' name='pdf' value='{{pdf.id}}'/> | ||||
| 		<input type="radio" name="state" value="adding" {% if pdf.status = 'pridavani' %} checked {% endif %}>Přidávání korektur | ||||
| 		<br> | ||||
| 		<input type="radio" name="state" value="comitting" {% if pdf.status = 'zanaseni' %} checked {% endif %}>Zanášení korektur | ||||
| 		<br> | ||||
| 		<input type="radio" name="state" value="deprecated" {%	if pdf.status = 'zastarale' %} checked {% endif %}>Zastaralé, nekorigovat | ||||
| 		<br> | ||||
| 		<input type='submit' value='Změnit stav PDF'/> | ||||
| 	</form> | ||||
| 	 | ||||
| 	<!-- /Zmenit stav PDF !--> | ||||
| 	<hr/> | ||||
| 	<p> | ||||
| 	Děkujeme opravovatelům: {% for autor,pocet in zasluhy.items %} {{autor}}({{pocet}}) {% endfor %}</p> | ||||
| 	<hr> | ||||
| 
 | ||||
| 	{% for o in opravy %} | ||||
| 	<div onclick='img_click(this,event)' | ||||
| 		id='op{{o.id}}-pointer' | ||||
| 		class='pointer{%if o.status = 'opraveno' %}-done{% elif o.status = 'neni_chyba' %}-wontfix{% endif %}'> | ||||
| 	</div> | ||||
| 	<div name='op{{o.id}}' id='op{{o.id}}'  | ||||
| 	    class='box{%if o.status = 'opraveno' %}-done{% elif o.status = 'neni_chyba' %}-wontfix{% endif %}'  | ||||
| 	    onmouseover='box_onmouseover(this,{% if o.status = 'opraveno' %}"done"{% elif o.status = 'neni_chyba' %}"wontfix"{%else%}""{% endif %})'  | ||||
| 	    onmouseout='box_onmouseout(this,{% if o.status = 'opraveno' %}"done"{% elif o.status = 'neni_chyba' %}"wontfix"{%else%}""{% endif %})'>  | ||||
| 
 | ||||
|     	<div class='corr-header'>  | ||||
| 			<div class='author' id='op{{o.id}}-autor'>{{o.autor}}</div> | ||||
| 			<div class='float-right'> | ||||
| 				<!-- Existujici korektura !--> | ||||
| 	  			<form  action='' onsubmit='save_scroll(this)' method='POST'> | ||||
| 	   				{% csrf_token %} | ||||
| 	   				<input type='hidden' name="au" value="{{o.autor}}"/> | ||||
| 	   				<input type='hidden' name='pdf' value='{{pdf.id}}'> | ||||
| 	   				<input type='hidden' name='id' value='{{o.id}}'> | ||||
| 	   				<input type='hidden' name='scroll'> | ||||
| 	   				 | ||||
| 					{% if o.komentare %} | ||||
| 	   				<button name='action' value='del' type='button' | ||||
|             			title="Opravu nelze smazat – už ji někdo okomentoval"> | ||||
| 		   				<img src="/static/korektury/imgs/delete-gr.png"/> | ||||
| 	   				</button> | ||||
| 					{% else %} | ||||
| 					<button type='submit' name='action' value='del' title='Smaž opravu'> | ||||
| 						<img src="/static/korektury/imgs/delete.png"/> | ||||
| 					</button> | ||||
| 					{% endif %} | ||||
| 					    | ||||
| 					{% if o.status = 'opraveno' or o.status = 'neni_chyba'  %} | ||||
| 					<button type='submit' name='action' value='undone' title='Označ jako neopravené'> | ||||
| 						<img src="/static/korektury/imgs/undo.png"/> | ||||
| 					</button> | ||||
| 					{% else %} | ||||
| 					<button type='submit' name='action' value='done' title='Označ jako opravené'> | ||||
| 						<img src="/static/korektury/imgs/check.png"/> | ||||
| 					</button> | ||||
| 					<button type='submit' name='action' value='wontfix' title='Označ jako irelevantní '> | ||||
| 						<img src="/static/korektury/imgs/cross.png"/> | ||||
| 					</button> | ||||
| 					{% endif %} | ||||
| 				</form> | ||||
| 				<!-- /Existujici korektura !--> | ||||
| 						 | ||||
| 				{% if o.komentare %} | ||||
| 				<button type='button' title="Korekturu nelze upravit – už ji někdo okomentoval"> | ||||
| 					<img src="/static/korektury/imgs/edit-gr.png"/> | ||||
| 				</button> | ||||
| 				{% else %} | ||||
| 				<button type='button' onclick='box_edit(this,"update");' title='Oprav opravu'> | ||||
| 					<img src="/static/korektury/imgs/edit.png"/> | ||||
| 				</button> | ||||
| 				{% endif %} | ||||
| 				<button type='button' onclick='box_edit(this, "comment");' title='Komentovat'> | ||||
| 					<img src="/static/korektury/imgs/comment.png"/> | ||||
| 				</button> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 		<div id='op{{o.id}}-text'>{{o.text}}</div> | ||||
| 
 | ||||
| 		{% for k in o.komentare %} | ||||
|     	<hr> | ||||
| 		<div class='comment' id='k{{k.id}}'> | ||||
|     		<div class='corr-header'> | ||||
|         		<div class='author'>{{k.autor}}</div> | ||||
|             	<div class="float-right"> | ||||
| 					<!-- Komentar !--> | ||||
|                     <form  action='' onsubmit='save_scroll(this)' method='POST'> | ||||
| 						{% csrf_token %} | ||||
|                     	<input type='hidden' name='pdf' value='{{pdf.id}}'> | ||||
| 						<input type='hidden' name='id' value='{{k.id}}'> | ||||
|                     	<input type='hidden' name='scroll'> | ||||
|                     	<button type='submit' name='action' value='del-comment' title='Smaž komentář' | ||||
|                       		onclick='return confirm("Opravdu smazat komentář?")'> | ||||
| 						  	<img src="/static/korektury/imgs/delete.png"/> | ||||
| 					 	</button> | ||||
|                     </form> | ||||
| 					<!-- /Komentar !--> | ||||
| 					<button type='button' onclick='update_comment(this);' title='Uprav komentář'> | ||||
| 						<img src="/static/korektury/imgs/edit.png"/> | ||||
| 					</button> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 			<div id='kt{{k.id}}'>{{k.text}}</div> | ||||
| 		</div> | ||||
| 		{% endfor %}  | ||||
| 	</div>	 | ||||
| 	{% endfor %} | ||||
| 
 | ||||
| 	<script> | ||||
| 	{% for s in opravy_strany %} | ||||
| 		place_comments_one_div("img-{{s.strana}}", [{% for o in s.op_id %}["op{{o.id}}",{{o.x}},{{o.y}}],{% endfor %}[]]); | ||||
| 	{% endfor %} | ||||
| 	{% if scroll %} | ||||
| 		window.scrollTo(0,{{scroll}}); | ||||
| 	{% endif %} | ||||
| 	</script> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										20
									
								
								korektury/templates/korektury/seznam.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,20 @@ | |||
| {% extends "base.html" %} | ||||
| 
 | ||||
| {% block content %} | ||||
| 
 | ||||
| <h1> | ||||
| {% block nadpis1a %} | ||||
|   Korektury | ||||
| {% endblock nadpis1a %} | ||||
| </h1> | ||||
| 
 | ||||
| <ul> | ||||
|   {% for pdf in object_list  %} | ||||
| 	  <li> <b>{{ pdf.nazev }}</b> <i>{{pdf.komentar}}</i> <a href="/korektury/{{pdf.id}}">{{pdf.pdf.url}}</a> </li> | ||||
|   {% empty %} | ||||
|     <li> Nejsou žádné dokumenty ke korekturování. | ||||
|   {% endfor %} | ||||
| </ul> | ||||
| 
 | ||||
| 
 | ||||
| {% endblock content %} | ||||
							
								
								
									
										3
									
								
								korektury/tests.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,3 @@ | |||
| from django.test import TestCase | ||||
| 
 | ||||
| # Create your tests here. | ||||
							
								
								
									
										9
									
								
								korektury/urls.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,9 @@ | |||
| from django.conf.urls import *  # NOQA | ||||
| from django.conf.urls import patterns, url | ||||
| from django.contrib.auth.decorators import permission_required | ||||
| from . import views | ||||
| 
 | ||||
| urlpatterns = patterns('', | ||||
|     url(r'^korektury$',permission_required('is_staff')(views.KorekturyListView.as_view()),name='korektury-list'), | ||||
|     url(r'^korektury/(?P<pdf>\d+)$', permission_required('is_staff')(views.KorekturyView.as_view()), name='korektury'), | ||||
| ) | ||||
							
								
								
									
										163
									
								
								korektury/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						|  | @ -0,0 +1,163 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from django.shortcuts import render | ||||
| from django.shortcuts import get_object_or_404, render | ||||
| from django.http import HttpResponseRedirect | ||||
| from django.http import HttpResponse | ||||
| from django.core.urlresolvers import reverse | ||||
| from django.views import generic | ||||
| from django.utils.translation import ugettext as _ | ||||
| from django.http import Http404 | ||||
| from django.http import HttpResponseRedirect | ||||
| 
 | ||||
| from .models import Oprava,Komentar,KorekturovanePDF | ||||
| from .forms import OpravaForm | ||||
| 
 | ||||
| from datetime import timedelta, date, datetime | ||||
| from itertools import groupby | ||||
| import tempfile | ||||
| import subprocess | ||||
| import shutil | ||||
| import os | ||||
| from django.conf import settings | ||||
| import unicodedata | ||||
| 
 | ||||
| 
 | ||||
| class KorekturyListView(generic.ListView): | ||||
|     model = KorekturovanePDF | ||||
|     template_name = 'korektury/seznam.html' | ||||
| 
 | ||||
| ### Korektury | ||||
| class KorekturyView(generic.TemplateView): | ||||
|     model = Oprava | ||||
|     template_name = 'korektury/opraf.html' | ||||
|     form_class = OpravaForm | ||||
| 
 | ||||
|     def post(self, request, *args, **kwargs): | ||||
|         form = self.form_class(request.POST) | ||||
|         q = request.POST | ||||
|         scroll = q.get('scroll') | ||||
|         autor = q.get('au') | ||||
|         print "autor:" + str(autor) | ||||
|         if not autor: | ||||
|             autor = 'anonym' | ||||
|         if not scroll: | ||||
|             scroll = 0 | ||||
| 
 | ||||
| 
 | ||||
|         action = q.get('action') | ||||
|         if (action == u''):  # Přidej | ||||
|             x = int(q.get('x')) | ||||
|             y = int(q.get('y')) | ||||
|             text = q.get('txt') | ||||
|             strana = int(q.get('img-id')[4:]) | ||||
|             pdf = KorekturovanePDF.objects.filter(id=q.get('pdf')).first() | ||||
| 
 | ||||
|             op = Oprava(x=x,y=y, autor=autor, text=text, strana=strana,pdf = pdf) | ||||
|             op.save() | ||||
|         elif (action == u'del'): | ||||
|             id = int(q.get('id')) | ||||
|             op = Oprava.objects.filter(id=id).first() | ||||
|             op.delete() | ||||
|         elif (action == u'update'): | ||||
|             id = int(q.get('id')) | ||||
|             op = Oprava.objects.filter(id=id).first() | ||||
|             text = q.get('txt') | ||||
|             op.autor = autor | ||||
|             op.text = text | ||||
|             op.save() | ||||
|         elif (action == u'undone'): | ||||
|             id = int(q.get('id')) | ||||
|             op = Oprava.objects.filter(id=id).first() | ||||
|             op.status = op.STATUS_K_OPRAVE | ||||
|             op.save() | ||||
|         elif (action == u'done'): | ||||
|             id = int(q.get('id')) | ||||
|             op = Oprava.objects.filter(id=id).first() | ||||
|             op.status = op.STATUS_OPRAVENO | ||||
|             op.save() | ||||
|         elif (action == u'wontfix'): | ||||
|             id = int(q.get('id')) | ||||
|             op = Oprava.objects.filter(id=id).first() | ||||
|             op.status = op.STATUS_NENI_CHYBA | ||||
|             op.save() | ||||
|         elif (action == u'comment'): | ||||
|             id = int(q.get('id')) | ||||
|             op = Oprava.objects.filter(id=id).first() | ||||
|             text = q.get('txt') | ||||
|             kom = Komentar(oprava=op,autor=autor,text=text) | ||||
|             kom.save() | ||||
|         elif (action == u'update-comment'): | ||||
|             id = int(q.get('id')) | ||||
|             kom = Komentar.objects.filter(id=id).first() | ||||
|             text = q.get('txt') | ||||
|             kom.text = text | ||||
|             kom.autor = autor | ||||
|             kom.save() | ||||
|         elif (action == u'del-comment'): | ||||
|             id = int(q.get('id')) | ||||
|             kom = Komentar.objects.filter(id=id).first() | ||||
|             kom.delete() | ||||
|         elif (action == u'delall'): | ||||
|             pdf = KorekturovanePDF.objects.filter(id=q.get('pdf')) | ||||
|             checked = q.get('yes') | ||||
|             if checked: | ||||
|                 opravy = Oprava.objects.filter(pdf=pdf) | ||||
|                 komentare = Komentar.objects.filter(oprava=opravy) | ||||
|                 opravy.delete() | ||||
|                 komentare.delete() | ||||
|         elif (action == u'set-state'): | ||||
|             pdf = KorekturovanePDF.objects.get(id=q.get('pdf')) | ||||
|             if (q.get('state') == u'adding'): | ||||
|                 pdf.status = pdf.STATUS_PRIDAVANI | ||||
|             elif (q.get('state') == u'comitting'): | ||||
|                 pdf.status = pdf.STATUS_ZANASENI | ||||
|             elif (q.get('state') == u'deprecated'): | ||||
|                 pdf.status = pdf.STATUS_ZASTARALE | ||||
|             pdf.save() | ||||
|              | ||||
| 
 | ||||
|              | ||||
| 
 | ||||
| #        return HttpResponse(u'Keys: %s '%(q.iteitems())) | ||||
| #        return HttpResponse(u'Oprav: %d, akce: %s'%( | ||||
| #            len(Oprava.objects.all()),action)) | ||||
|   | ||||
| #        return HttpResponseRedirect(reverse('korektury')+"?scroll=%s"%(scroll)) | ||||
|         context = self.get_context_data() | ||||
|         context['scroll'] = scroll | ||||
|         context['autor'] = autor | ||||
|         return render(request, 'korektury/opraf.html',context) | ||||
| #        return HttpResponse(u'Oprav: %d,x: %d y: %d, autor: %s, text: %s, strana: %d'%( | ||||
| #            len(Oprava.objects.all()),x,y,autor,text,strana)) | ||||
|     def get_context_data(self, **kwargs): | ||||
|         context = super(KorekturyView,self).get_context_data(**kwargs) | ||||
|         pdf = KorekturovanePDF.objects.filter(id=self.kwargs['pdf']).first() | ||||
|         context['pdf'] = pdf | ||||
|         context['img_name'] = os.path.split(pdf.pdf.path)[1].split('.')[0] | ||||
|         context['img_path'] = settings.KOREKTURY_IMG_DIR | ||||
|         context['img_indexes'] = range(pdf.stran)  | ||||
|         context['form_oprava'] = OpravaForm() | ||||
|         opravy = Oprava.objects.filter(pdf=self.kwargs['pdf']) | ||||
|         zasluhy = {} | ||||
|         for o in opravy: | ||||
|             if o.autor in zasluhy: | ||||
|                 zasluhy[o.autor]+=1 | ||||
|             else: | ||||
|                 zasluhy[o.autor]=1 | ||||
|             o.komentare = o.komentar_set.all() | ||||
|             for k in o.komentare: | ||||
|                 if k.autor in zasluhy: | ||||
|                     zasluhy[k.autor]+=1 | ||||
|                 else:  | ||||
|                     zasluhy[k.autor]=1 | ||||
| 
 | ||||
|         strany = opravy.values('strana') | ||||
|         opravy_na_stranu = [{'strana':s['strana'],'op_id':opravy.filter(strana=s['strana'])} for s in strany] | ||||
|         context['opravy_strany'] = opravy_na_stranu | ||||
|          | ||||
|         context['opravy'] = opravy | ||||
|         context['zasluhy'] = zasluhy | ||||
|         return context | ||||
|     def form_valid(self,form): | ||||
|         return super(KorekturyView,self).form_valid(form) | ||||
| 
 | ||||
|  | @ -42,6 +42,9 @@ STATICFILES_FINDERS = ( | |||
|     'django.contrib.staticfiles.finders.FileSystemFinder', | ||||
| ) | ||||
| 
 | ||||
| # Where redirect for login required services | ||||
| LOGIN_URL = '/admin/login' | ||||
| 
 | ||||
| # Modules configuration | ||||
| 
 | ||||
| AUTHENTICATION_BACKENDS = ( | ||||
|  | @ -117,6 +120,7 @@ INSTALLED_APPS = ( | |||
|     'mamweb', | ||||
|     'seminar', | ||||
|     'galerie', | ||||
|     'korektury', | ||||
| 
 | ||||
|     # Admin upravy: | ||||
| 
 | ||||
|  | @ -236,3 +240,5 @@ LOGGING = { | |||
| # MaM specific | ||||
| 
 | ||||
| SEMINAR_RESENI_DIR = os.path.join(BASE_DIR, 'media', 'reseni') | ||||
| KOREKTURY_PDF_DIR = os.path.join(BASE_DIR, 'media', 'korektury','pdf') | ||||
| KOREKTURY_IMG_DIR = os.path.join(BASE_DIR, 'media', 'korektury','img') | ||||
|  |  | |||
|  | @ -35,6 +35,13 @@ DATABASES = { | |||
|         'NAME': os.path.join(BASE_DIR, 'db-local.sqlite3'), | ||||
|     } | ||||
| } | ||||
| #DATABASES = { | ||||
| #    'default': { | ||||
| #        'ENGINE': 'django.db.backends.postgresql_psycopg2', | ||||
| #        'NAME': 'mam_local', | ||||
| #        'USER': 'mam', | ||||
| #    }, | ||||
| #} | ||||
| 
 | ||||
| # LOGGING | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,6 +14,9 @@ urlpatterns = patterns('', | |||
| 
 | ||||
|     # Seminarova aplikace (ma vlastni podadresare) | ||||
|     url(r'^', include('seminar.urls')), | ||||
|      | ||||
|     # Korekturovaci aplikace (ma vlastni podadresare) | ||||
|     url(r'^', include('korektury.urls')), | ||||
| 
 | ||||
|     # Comments (interni i verejne) | ||||
|     url(r'^comments_dj/', include('django_comments.urls')), | ||||
|  |  | |||
 Bc. Petr Pecha
						Bc. Petr Pecha