RFC: Videjka a další bazmeky do galerií #99
					 16 changed files with 284 additions and 119 deletions
				
			
		|  | @ -1,4 +1,4 @@ | ||||||
| from galerie.models import Obrazek, Galerie | from galerie.models import Obrazek, Galerie, VZDY, ORG, NIKDY, UCASTNIK | ||||||
| from django.contrib import admin | from django.contrib import admin | ||||||
| from django.http import HttpResponseRedirect | from django.http import HttpResponseRedirect | ||||||
| from django import forms | from django import forms | ||||||
|  | @ -8,8 +8,9 @@ from django.db import models | ||||||
| 
 | 
 | ||||||
| def zverejnit_fotogalerii(modeladmin, request, queryset): | def zverejnit_fotogalerii(modeladmin, request, queryset): | ||||||
| 	'''zverejni vybranou fotogalerii i jeji vsechny podgalerie''' | 	'''zverejni vybranou fotogalerii i jeji vsechny podgalerie''' | ||||||
|  | 	queryset = queryset.filter(zobrazit=ORG) | ||||||
| 	for galerie in queryset: | 	for galerie in queryset: | ||||||
| 		galerie.zobrazit = 0 | 		galerie.zobrazit = VZDY | ||||||
| 		galerie.save() | 		galerie.save() | ||||||
| 		zverejnit_fotogalerii(modeladmin, request, | 		zverejnit_fotogalerii(modeladmin, request, | ||||||
| 				Galerie.objects.filter(galerie_up = galerie)) | 				Galerie.objects.filter(galerie_up = galerie)) | ||||||
|  | @ -18,8 +19,9 @@ def zverejnit_fotogalerii(modeladmin, request, queryset): | ||||||
| 
 | 
 | ||||||
| def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset): | def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset): | ||||||
| 	'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie''' | 	'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie''' | ||||||
|  | 	queryset = queryset.filter(zobrazit=VZDY) | ||||||
| 	for galerie in queryset: | 	for galerie in queryset: | ||||||
| 		galerie.zobrazit = 1 | 		galerie.zobrazit = ORG | ||||||
| 		galerie.save() | 		galerie.save() | ||||||
| 		prepnout_fotogalerii_do_org_rezimu(modeladmin, request, | 		prepnout_fotogalerii_do_org_rezimu(modeladmin, request, | ||||||
| 				Galerie.objects.filter(galerie_up = galerie)) | 				Galerie.objects.filter(galerie_up = galerie)) | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								galerie/migrations/0014_alter_galerie_zobrazit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								galerie/migrations/0014_alter_galerie_zobrazit.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | # Generated by Django 4.2.20 on 2025-04-23 18:37 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('galerie', '0013_post_split_soustredeni'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='galerie', | ||||||
|  |             name='zobrazit', | ||||||
|  |             field=models.IntegerField(choices=[(0, 'Vždy'), (1, 'Organizátorům'), (3, 'Účastníkům a orgům'), (2, 'Nikdy')], default=1, verbose_name='Zobrazit?'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
							
								
								
									
										19
									
								
								galerie/migrations/0015_alter_galerie_galerie_up.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								galerie/migrations/0015_alter_galerie_galerie_up.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | # Generated by Django 4.2.16 on 2025-04-30 18:53 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | import django.db.models.deletion | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('galerie', '0014_alter_galerie_zobrazit'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='galerie', | ||||||
|  |             name='galerie_up', | ||||||
|  |             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='galerie.galerie'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
							
								
								
									
										19
									
								
								galerie/migrations/0016_alter_obrazek_galerie.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								galerie/migrations/0016_alter_obrazek_galerie.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | # Generated by Django 4.2.16 on 2025-04-30 19:02 | ||||||
|  | 
 | ||||||
|  | from django.db import migrations, models | ||||||
|  | import django.db.models.deletion | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Migration(migrations.Migration): | ||||||
|  | 
 | ||||||
|  |     dependencies = [ | ||||||
|  |         ('galerie', '0015_alter_galerie_galerie_up'), | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  |     operations = [ | ||||||
|  |         migrations.AlterField( | ||||||
|  |             model_name='obrazek', | ||||||
|  |             name='galerie', | ||||||
|  |             field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='galerie.galerie'), | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | @ -10,9 +10,11 @@ from soustredeni.models import Soustredeni | ||||||
| VZDY=0 | VZDY=0 | ||||||
| ORG=1 | ORG=1 | ||||||
| NIKDY=2 | NIKDY=2 | ||||||
|  | UCASTNIK=3 | ||||||
| VIDITELNOST = ( | VIDITELNOST = ( | ||||||
| 	(VZDY, 'Vždy'), | 	(VZDY, 'Vždy'), | ||||||
| 	(ORG, 'Organizátorům'), | 	(ORG, 'Organizátorům'), | ||||||
|  | 	(UCASTNIK, 'Účastníkům a orgům'), | ||||||
| 	(NIKDY, 'Nikdy'), | 	(NIKDY, 'Nikdy'), | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -59,7 +61,7 @@ class Obrazek(models.Model): | ||||||
| 	# ~~Rádoby~~ vtipný popisek od orgů | 	# ~~Rádoby~~ vtipný popisek od orgů | ||||||
| 	popis = models.TextField('Popis', blank=True, null=True) | 	popis = models.TextField('Popis', blank=True, null=True) | ||||||
| 	datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True) | 	datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True) | ||||||
| 	galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.SET_NULL) | 	galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.CASCADE) | ||||||
| 	# Primární klíč k řazení pro overridování řazení podle názvu | 	# Primární klíč k řazení pro overridování řazení podle názvu | ||||||
| 	poradi = models.IntegerField('Pořadí', blank=True, null=True) | 	poradi = models.IntegerField('Pořadí', blank=True, null=True) | ||||||
| 
 | 
 | ||||||
|  | @ -98,7 +100,7 @@ class Galerie(models.Model): | ||||||
| 	titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL) | 	titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL) | ||||||
| 	zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST) | 	zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST) | ||||||
| 	galerie_up = models.ForeignKey('Galerie', blank = True, null = True, | 	galerie_up = models.ForeignKey('Galerie', blank = True, null = True, | ||||||
| 		on_delete=models.SET_NULL) | 		on_delete=models.PROTECT) | ||||||
| 	soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True, | 	soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True, | ||||||
| 		on_delete=models.PROTECT) | 		on_delete=models.PROTECT) | ||||||
| 	poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0) | 	poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0) | ||||||
|  | @ -108,25 +110,3 @@ class Galerie(models.Model): | ||||||
| 	class Meta: | 	class Meta: | ||||||
| 		verbose_name = 'Galerie' | 		verbose_name = 'Galerie' | ||||||
| 		verbose_name_plural = 'Galerie' | 		verbose_name_plural = 'Galerie' | ||||||
| 
 |  | ||||||
| 	#def link_na_preview(self): |  | ||||||
| 		#"""Odkaz na galerii, používá se v admin rozhranní. """ |  | ||||||
| 		#return '<a href="/fotogalerie/galerie/%s/">Preview</a>' % self.id |  | ||||||
| 	#link_na_preview.allow_tags = True |  | ||||||
| 	#link_na_preview.short_description = 'Zobrazit galerii' |  | ||||||
| # |  | ||||||
| 	#def je_publikovano(self): |  | ||||||
| 		#"""Vraci True, pokud je tato galerie publikovana. """  |  | ||||||
| 		#if self.zobrazit == VZDY: |  | ||||||
| 			#return True |  | ||||||
| 		#if self.zobrazit == PODLE_CLANKU: |  | ||||||
| 			#for clanek in self.clanek_set.all(): |  | ||||||
| 				#if clanek.je_publikovano(): |  | ||||||
| 					#return True |  | ||||||
| 		#return False |  | ||||||
| # |  | ||||||
| 	#@staticmethod |  | ||||||
| 	#def publikovane_galerie(): |  | ||||||
| 		#"""Vraci galerie, ktere uz maji byt publikovane.""" |  | ||||||
| 		#clanky = Blog.models.Clanek.publikovane_clanky() |  | ||||||
| 		#return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct() |  | ||||||
|  |  | ||||||
|  | @ -136,6 +136,11 @@ | ||||||
| 	top: 160px; | 	top: 160px; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .podgalerie_nahled.mam-org-only, .podgalerie_nahled.mam-resitel-only { | ||||||
|  | 	margin: 10px; | ||||||
|  | 	padding: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| /* Odkazy na předchozí a následující podgalerii */ | /* Odkazy na předchozí a následující podgalerii */ | ||||||
| .galerie_predchozi_nasledujici { | .galerie_predchozi_nasledujici { | ||||||
|  |  | ||||||
|  | @ -47,6 +47,7 @@ | ||||||
| 
 | 
 | ||||||
| {% block content %} | {% block content %} | ||||||
| 
 | 
 | ||||||
|  |   <div class="{% if obrazek.galerie.zobrazit == 1 or obrazek.galerie.zobrazit == 2 %}mam-org-only{% endif %}{% if obrazek.galerie.zobrazit == 3 %}mam-resitel-only{% endif %}"> | ||||||
| 
 | 
 | ||||||
|   <h2> |   <h2> | ||||||
|     {% for g in cesta %} |     {% for g in cesta %} | ||||||
|  | @ -85,7 +86,7 @@ | ||||||
| 
 | 
 | ||||||
|   {# Popisek fotky #} |   {# Popisek fotky #} | ||||||
|   <div class="popis"> |   <div class="popis"> | ||||||
|     {% if preview %} |     {% if upravy_popisku %} | ||||||
|     <form action=".#nahoru" method="post" id="komentarform"> |     <form action=".#nahoru" method="post" id="komentarform"> | ||||||
|       {% csrf_token %} |       {% csrf_token %} | ||||||
|       <table> |       <table> | ||||||
|  | @ -135,4 +136,6 @@ | ||||||
|       {% endif %} |       {% endif %} | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
|  | 
 | ||||||
|  |   </div> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
|  | @ -8,8 +8,11 @@ Galerie {{galerie.nazev}} | ||||||
| 
 | 
 | ||||||
| {% block content %} | {% block content %} | ||||||
| 
 | 
 | ||||||
|   {% if galerie.zobrazit > 0 %} |   {# FIXME: použít konstanty… #} | ||||||
|  |   {% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %} | ||||||
|     <div class="mam-org-only"> |     <div class="mam-org-only"> | ||||||
|  |   {% elif galerie.zobrazit == 3 %} | ||||||
|  |     <div class="mam-resitel-only"> | ||||||
|   {% endif %} |   {% endif %} | ||||||
| 
 | 
 | ||||||
|   <h2> |   <h2> | ||||||
|  | @ -47,34 +50,40 @@ Galerie {{galerie.nazev}} | ||||||
|     {% if podgalerie %} |     {% if podgalerie %} | ||||||
|       {% with 22 as max_delka_nazvu %} |       {% with 22 as max_delka_nazvu %} | ||||||
|       <div class="galerie_nahledy"> |       <div class="galerie_nahledy"> | ||||||
|       {% for galerie in podgalerie %} |       {% for pgalerie in podgalerie %} | ||||||
|         <a href="../{{galerie.pk}}" |           <a href="../{{pgalerie.pk}}" | ||||||
|           {% if galerie.nazev|length > max_delka_nazvu %} |             {% if pgalerie.nazev|length > max_delka_nazvu %} | ||||||
|             title="{{ galerie.nazev }}" |               title="{{ pgalerie.nazev }}" | ||||||
|           {% endif %} |  | ||||||
|          class="podgalerie_nahled"> |  | ||||||
|             {% if galerie.titulni_obrazek %} |  | ||||||
|               {% zmenseny_nahled galerie.titulni_obrazek.jako_bazmek %} |  | ||||||
|             {% endif %} |             {% endif %} | ||||||
|             <div class="nazev_galerie"> |            class="podgalerie_nahled {% if pgalerie.zobrazit == 1 or pgalerie.zobrazit == 2 %}mam-org-only{% endif %}{% if pgalerie.zobrazit == 3 %}mam-resitel-only{% endif %}"> | ||||||
|             {{ galerie|truncatechars:max_delka_nazvu }} |               {% if pgalerie.titulni_obrazek %} | ||||||
|  |                 {% zmenseny_nahled pgalerie.titulni_obrazek.jako_bazmek %} | ||||||
|  | |||||||
|  |               {% endif %} | ||||||
|  |               <div class="nazev_galerie"> | ||||||
|  |               {{ pgalerie|truncatechars:max_delka_nazvu }} | ||||||
|  |               </div> | ||||||
|  |           </a> | ||||||
|  |           {% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %} | ||||||
|  |           {% if user.je_org %} | ||||||
|  |             <div class="mam-org-only-galerie"> | ||||||
|  |               ({{pgalerie.poradi}}) | ||||||
|  |               <span class="plus"><a href="plus/{{pgalerie.pk}}/">+</a></span> | ||||||
|  |               <span class="minus"><a href="minus/{{pgalerie.pk}}/">-</a></span> | ||||||
|             </div> |             </div> | ||||||
|         </a> |           {% endif %} | ||||||
|         {% if user.je_org and galerie.zobrazit > 0 %} |           {% endif %} | ||||||
|           <div class="mam-org-only-galerie"> |  | ||||||
|             ({{galerie.poradi}}) |  | ||||||
|             <span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span> |  | ||||||
|             <span class="minus"><a href="minus/{{galerie.pk}}/">-</a></span> |  | ||||||
|           </div> |  | ||||||
|         {% endif %} |  | ||||||
|       {% endfor %} |       {% endfor %} | ||||||
|       </div> |       </div> | ||||||
|       {% endwith %} |       {% endwith %} | ||||||
|     {% endif %} |     {% endif %} | ||||||
|   {% endif %} |   {% endif %} | ||||||
|   {% if user.je_org and galerie.zobrazit > 0 %} |   {% if user.je_org %} | ||||||
|   <div class="mam-org-only"> |   <div class="mam-org-only"> | ||||||
|       <a href="./new">Vytvořit novou podgalerii </a> |     {% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %} | ||||||
|  |       <a href="./new">Vytvořit novou podgalerii</a>, <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">upravit galerii v adminu</a> | ||||||
|  |     {% else %} | ||||||
|  |       Jestli chceš změnit pořadí podgalerií nebo přidat novou, nastav zobrazení jen pro orgy v <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">adminu</a>. | ||||||
|  |     {% endif %} | ||||||
|   </div> |   </div> | ||||||
|   {% endif %} |   {% endif %} | ||||||
| 
 | 
 | ||||||
|  | @ -118,8 +127,10 @@ Galerie {{galerie.nazev}} | ||||||
|     {% endif %} |     {% endif %} | ||||||
|   {% endif %} |   {% endif %} | ||||||
| 
 | 
 | ||||||
|   {% if galerie.zobrazit > 0 %} |   {% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %} | ||||||
|     </div> {# mam-org-only #} |     </div> {# mam-org-only #} | ||||||
|  |   {% elif galerie.zobrazit == 2 %} | ||||||
|  |     </div> {# mam-resitel-only #} | ||||||
|   {% endif %} |   {% endif %} | ||||||
| 
 | 
 | ||||||
| {% endblock content %} | {% endblock content %} | ||||||
|  |  | ||||||
|  | @ -2,5 +2,5 @@ | ||||||
| {% load static %} | {% load static %} | ||||||
| 
 | 
 | ||||||
| {% block custom_css %} | {% block custom_css %} | ||||||
|   <link href="{% static 'css/galerie.css' %}?version=1" rel="stylesheet"> |   <link href="{% static 'css/galerie.css' %}?version=2" rel="stylesheet"> | ||||||
| {% endblock %} | {% endblock %} | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								galerie/utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								galerie/utils.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | from galerie.models import Galerie | ||||||
|  | 
 | ||||||
|  | def top_galerie(g: Galerie) -> Galerie: | ||||||
|  | 	while g.galerie_up is not None: | ||||||
|  | 		g = g.galerie_up | ||||||
|  | 	return g | ||||||
							
								
								
									
										137
									
								
								galerie/views.py
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								galerie/views.py
									
									
									
									
									
								
							|  | @ -1,22 +1,41 @@ | ||||||
| import random | import random | ||||||
| 
 | 
 | ||||||
| from django.http import HttpResponse, Http404 | from django.http import HttpResponse, Http404, HttpRequest | ||||||
| from django.shortcuts import render, HttpResponseRedirect, get_object_or_404 | from django.shortcuts import render, HttpResponseRedirect, get_object_or_404 | ||||||
| from django.template import RequestContext | from django.template import RequestContext | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| 
 | 
 | ||||||
| from galerie.models import Obrazek, Galerie | from galerie.utils import top_galerie | ||||||
|  | from personalni.utils import resitel_uzivatele | ||||||
|  | 
 | ||||||
|  | from galerie.models import Obrazek, Galerie, VZDY, ORG, UCASTNIK, NIKDY | ||||||
| from soustredeni.models import Soustredeni | from soustredeni.models import Soustredeni | ||||||
| from galerie.forms import KomentarForm, NewGalerieForm | from galerie.forms import KomentarForm, NewGalerieForm | ||||||
| 
 | 
 | ||||||
| def zobrazit(galerie, request): | import logging | ||||||
| 	preview = False | logger = logging.getLogger(__name__) | ||||||
| 	if galerie.zobrazit >= 1: | 
 | ||||||
| 		if request.user.je_org: | def galerie_ke_zobrazeni(soustredeni: Soustredeni | None, request: HttpRequest) -> tuple[int]: | ||||||
| 			preview = True; | 	if request.user.is_superuser: return (VZDY, ORG, UCASTNIK, NIKDY) | ||||||
|  | 	if request.user.je_org: return (VZDY, ORG, UCASTNIK) | ||||||
|  | 	if request.user.is_anonymous: return (VZDY,) | ||||||
|  | 	if soustredeni is None: return (VZDY,) | ||||||
|  | 	if (resitel := resitel_uzivatele(request.user)) is not None: | ||||||
|  | 		if resitel.soustredeni_set.contains(soustredeni): | ||||||
|  | 			return (VZDY, UCASTNIK) | ||||||
| 		else: | 		else: | ||||||
| 			raise Http404 | 			return (VZDY,) | ||||||
| 	return preview | 	logger.warning("Nepodařilo se zjistit, jaké galerie se mají zobrazit!") | ||||||
|  | 	return (VZDY,) | ||||||
|  | 	 | ||||||
|  | 	 | ||||||
|  | def zobrazit(galerie: Galerie, request: HttpRequest) -> bool: | ||||||
|  | 	soustredeni = top_galerie(galerie).soustredeni | ||||||
|  | 	return galerie.zobrazit in galerie_ke_zobrazeni(soustredeni, request) | ||||||
|  | 
 | ||||||
|  | def dovolit_upravy_popisku(galerie: Galerie, request: HttpRequest) -> bool: | ||||||
|  | 	# FIXME: Dočasné: úpravy jen když je to v org-only stavu. (Odpovídá předchozímu chování) | ||||||
|  | 	return request.user.je_org and galerie.zobrazit in (ORG, NIKDY) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def cesta_od_korene(g): | def cesta_od_korene(g): | ||||||
|  | @ -31,19 +50,19 @@ def cesta_od_korene(g): | ||||||
| def nahled(request, pk, soustredeni): | def nahled(request, pk, soustredeni): | ||||||
| 	"""Zobrazeni nahledu vsech fotek ve skupine.""" | 	"""Zobrazeni nahledu vsech fotek ve skupine.""" | ||||||
| 	galerie = get_object_or_404(Galerie, pk=pk) | 	galerie = get_object_or_404(Galerie, pk=pk) | ||||||
|  | 	soustredeni = top_galerie(galerie).soustredeni | ||||||
| 
 | 
 | ||||||
|  | 	# FIXME: přepsat model a použít přímo dolů… | ||||||
| 	podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') | 	podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi') | ||||||
| 	if not request.user.je_org: | 	podgalerie = podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)) | ||||||
| 		podgalerie = podgalerie.filter(zobrazit__lt=1) |  | ||||||
| 
 | 
 | ||||||
| 	obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev') | 	obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev') | ||||||
| 	preview = zobrazit(galerie, request) | 	ma_se_zobrazit = zobrazit(galerie, request) | ||||||
|  | 	if not ma_se_zobrazit: raise Http404("Galerie sice existuje, ale my se tváříme, že ne :-D") | ||||||
| 
 | 
 | ||||||
| 	sourozenci = [] | 	sourozenci = [] | ||||||
| 	if galerie.galerie_up: | 	if galerie.galerie_up: | ||||||
| 		sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi') | 		sourozenci = galerie.galerie_up.galerie_set.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi') | ||||||
| 		if not request.user.je_org: |  | ||||||
| 			sourozenci = sourozenci.filter(zobrazit__lt=1) |  | ||||||
| 
 | 
 | ||||||
| 	predchozi = None | 	predchozi = None | ||||||
| 	nasledujici = None | 	nasledujici = None | ||||||
|  | @ -62,7 +81,6 @@ def nahled(request, pk, soustredeni): | ||||||
| 		{'galerie' : galerie, | 		{'galerie' : galerie, | ||||||
| 		 'podgalerie' : podgalerie, | 		 'podgalerie' : podgalerie, | ||||||
| 		 'obrazky' : obrazky, | 		 'obrazky' : obrazky, | ||||||
| 		 'preview' : preview, |  | ||||||
| 		 'cesta': cesta, | 		 'cesta': cesta, | ||||||
| 		 'sourozenci': sourozenci, | 		 'sourozenci': sourozenci, | ||||||
| 		 'predchozi': predchozi, | 		 'predchozi': predchozi, | ||||||
|  | @ -78,9 +96,41 @@ def detail(request, pk, fotka, soustredeni): | ||||||
| 	NAHLEDU = 1 | 	NAHLEDU = 1 | ||||||
| 
 | 
 | ||||||
| 	galerie = get_object_or_404(Galerie, pk=pk) | 	galerie = get_object_or_404(Galerie, pk=pk) | ||||||
| 	preview = zobrazit(galerie, request) | 	soustredeni = top_galerie(galerie).soustredeni | ||||||
|  | 	ma_se_zobrazit = zobrazit(galerie, request) | ||||||
|  | 	if not ma_se_zobrazit: raise Http404("Obrázek neukážu!") | ||||||
| 	obrazek = get_object_or_404(Obrazek, pk=fotka) | 	obrazek = get_object_or_404(Obrazek, pk=fotka) | ||||||
|  | 
 | ||||||
|  | 	# Pořadí není povinné. FIXME: `nazev` je zavádějící… Ale tohle je kanonické pořadí obrázků v galerii… | ||||||
| 	obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev') | 	obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev') | ||||||
|  | 	obrazky = list(obrazky) | ||||||
|  | 	index_obrazku = obrazky.index(obrazek) | ||||||
|  | 	# Podle mě se nemůže stát, že by volání výš selhalo, kdyžtak shodí web. (původně to byl explicitně ošetřený stav dávající 404) | ||||||
|  | 	predchozi_obrazky = list(reversed(obrazky[:index_obrazku])) | ||||||
|  | 	nasledujici_obrazky = obrazky[index_obrazku+1:] | ||||||
|  | 	# Může jich být hodně… | ||||||
|  | 	predchozi_obrazky = predchozi_obrazky[:NAHLEDU] | ||||||
|  | 	nasledujici_obrazky = nasledujici_obrazky[:NAHLEDU] | ||||||
|  | 	# Předchozí obrázky chceme v normálním pořadí | ||||||
|  | 	predchozi_obrazky = list(reversed(predchozi_obrazky)) | ||||||
|  | 
 | ||||||
|  | 	if galerie.galerie_up is not None: | ||||||
|  | 		sousedni_galerie = Galerie.objects.filter(galerie_up=galerie.galerie_up, zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi') | ||||||
|  | 		sousedni_galerie = list(sousedni_galerie) | ||||||
|  | 		# Teoreticky se můžeme dívat na galerie.poradi, ale jednak už tenhle pattern stejně je výš a druhak je galerií málo, takže pomalost nevadí. | ||||||
|  | 		index_galerie = sousedni_galerie.index(galerie) | ||||||
|  | 		predchozi_galerie = sousedni_galerie[index_galerie-1] if index_galerie > 0 else None | ||||||
|  | 		nasledujici_galerie = sousedni_galerie[index_galerie+1] if index_galerie < len(sousedni_galerie) - 1 else None | ||||||
|  | 	else: | ||||||
|  | 		predchozi_galerie = None | ||||||
|  | 		nasledujici_galerie = None | ||||||
|  | 
 | ||||||
|  | 	# Pokud je obrázků dost, tak další galerii nepotřebujeme | ||||||
|  | 	# (jo, mohli jsme si ušetřit práci, ale takhle je kód imho přehlednější a za pár ušetřených dotazů do DB to nestojí) | ||||||
|  | 	if len(predchozi_obrazky) >= NAHLEDU: | ||||||
|  | 		predchozi_galerie = None | ||||||
|  | 	if len(nasledujici_obrazky) >= NAHLEDU: | ||||||
|  | 		nasledujici_galerie = None | ||||||
| 
 | 
 | ||||||
| 	# vytvoreni a obslouzeni formulare | 	# vytvoreni a obslouzeni formulare | ||||||
| 	if request.method == 'POST': | 	if request.method == 'POST': | ||||||
|  | @ -90,49 +140,6 @@ def detail(request, pk, fotka, soustredeni): | ||||||
| 			obrazek.save() | 			obrazek.save() | ||||||
| 	else: | 	else: | ||||||
| 		form = KomentarForm({'komentar': obrazek.popis}) | 		form = KomentarForm({'komentar': obrazek.popis}) | ||||||
| 
 |  | ||||||
| 	# Poradi aktualniho obrazku v galerii/stitku. |  | ||||||
| 	for i in range(len(obrazky)): |  | ||||||
| 		if obrazky[i] == obrazek: |  | ||||||
| 			poradi = i |  | ||||||
| 			break |  | ||||||
| 	else: |  | ||||||
| 		# Obrazek neni v galerii/stitku. |  | ||||||
| 		raise Http404 |  | ||||||
| 
 |  | ||||||
| 	 |  | ||||||
| 	# Nacteni okolnich obrazku a galerii |  | ||||||
| 	# TODO vyjmout zjisteni predchozich a nasledujicich galerii |  | ||||||
| 	# a udelat z toho funkci, ktera se pouzije u nahledu |  | ||||||
| 	predchozi_galerie = None |  | ||||||
| 	nasledujici_galerie = None |  | ||||||
| 	obrazky_dalsi = obrazky[poradi+1:poradi+NAHLEDU+1] |  | ||||||
| 	if (poradi+1) > NAHLEDU: |  | ||||||
| 		obrazky_predchozi = obrazky[poradi-NAHLEDU:poradi] |  | ||||||
| 	else: |  | ||||||
| 		obrazky_predchozi = obrazky[0:poradi] |  | ||||||
| 		if galerie.poradi > 1: |  | ||||||
| 			predchozi_galerie = Galerie.objects.\ |  | ||||||
| 				filter(galerie_up=galerie.galerie_up).\ |  | ||||||
| 				filter(poradi=(galerie.poradi-1)) |  | ||||||
| 		if predchozi_galerie: |  | ||||||
| 			predchozi_galerie = predchozi_galerie[0] |  | ||||||
| 		else: |  | ||||||
| 			predchozi_galerie = None |  | ||||||
| 	if (poradi+1) == len(obrazky):		# Tohle je poslední obrázek |  | ||||||
| 		if (galerie.poradi is not None |  | ||||||
| 			and galerie.galerie_up is not None): |  | ||||||
| 				nasledujici_galerie = Galerie.objects.\ |  | ||||||
| 					filter(galerie_up=galerie.galerie_up).\ |  | ||||||
| 					filter(poradi=(galerie.poradi+1)) |  | ||||||
| 		else: |  | ||||||
| 			nasledujici_galerie = None |  | ||||||
| 		if nasledujici_galerie: |  | ||||||
| 			nasledujici_galerie = nasledujici_galerie[0] |  | ||||||
| 		else: |  | ||||||
| 			nasledujici_galerie = None |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 	 | 	 | ||||||
| 	# Preskalovani obrazku do vybraneho prostoru. | 	# Preskalovani obrazku do vybraneho prostoru. | ||||||
| 	vyska = obrazek.obrazek_stredni.height | 	vyska = obrazek.obrazek_stredni.height | ||||||
|  | @ -151,9 +158,9 @@ def detail(request, pk, fotka, soustredeni): | ||||||
| 		 'obrazek' : obrazek, | 		 'obrazek' : obrazek, | ||||||
| 		 'vyska' : vyska, | 		 'vyska' : vyska, | ||||||
| 		 'sirka' : sirka, | 		 'sirka' : sirka, | ||||||
| 		 'obrazky_predchozi' : obrazky_predchozi, | 		 'obrazky_predchozi' : predchozi_obrazky, | ||||||
| 		 'obrazky_dalsi' : obrazky_dalsi, | 		 'obrazky_dalsi' : nasledujici_obrazky, | ||||||
| 		 'preview' : preview, | 		 'upravy_popisku' : dovolit_upravy_popisku(galerie, request), | ||||||
| 		 'form' : form, | 		 'form' : form, | ||||||
| 		 'cesta': cesta_od_korene(galerie), | 		 'cesta': cesta_od_korene(galerie), | ||||||
| 		}) | 		}) | ||||||
|  | @ -179,7 +186,7 @@ def new_galerie(request, galerie, soustredeni): | ||||||
| 			gal = Galerie() | 			gal = Galerie() | ||||||
| 			gal.nazev = form.cleaned_data['nazev'] | 			gal.nazev = form.cleaned_data['nazev'] | ||||||
| 			#gal.popis = form.cleaned_data['popis'] # popis nepouzivame | 			#gal.popis = form.cleaned_data['popis'] # popis nepouzivame | ||||||
| 			gal.zobrazit = 1 # galerie je v procesu vytvareni | 			gal.zobrazit = ORG # galerie je v procesu vytvareni | ||||||
| 			''' pokud je to podgalerie pridej nadrazenou galerii | 			''' pokud je to podgalerie pridej nadrazenou galerii | ||||||
| 			a nadrazene soustredeni nechej volne, | 			a nadrazene soustredeni nechej volne, | ||||||
| 			pokud je to hlavni galerie, tak nadrazena galerie neexistuje, | 			pokud je to hlavni galerie, tak nadrazena galerie neexistuje, | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								odevzdavatko/static/css/odevzdavatko.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								odevzdavatko/static/css/odevzdavatko.css
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | .odevzdavatko-role { | ||||||
|  | 	font-size: 0.8em; | ||||||
|  | 	 | ||||||
|  | 	.vyrazne { | ||||||
|  | 		color: var(--hlavni-oranzova); | ||||||
|  | 	} | ||||||
|  | 	.nevyrazne { | ||||||
|  | 		color: #aaa; | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								odevzdavatko/templates/odevzdavatko/base.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								odevzdavatko/templates/odevzdavatko/base.html
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | {% extends "base.html" %} | ||||||
|  | {% load static %} | ||||||
|  | 
 | ||||||
|  | {% block custom_css %} | ||||||
|  |   <link href="{% static 'css/odevzdavatko.css' %}?version=1" rel="stylesheet"> | ||||||
|  | {% endblock %} | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| {% extends "base.html" %} | {% extends "odevzdavatko/base.html" %} | ||||||
| 
 | 
 | ||||||
| {% load barvy_reseni %} | {% load barvy_reseni %} | ||||||
|  | {% load orgove %} | ||||||
| 
 | 
 | ||||||
| {% block content %} | {% block content %} | ||||||
| 
 | 
 | ||||||
|  | @ -27,7 +28,15 @@ Do data (včetně): {{ filtr.reseni_do }} | ||||||
| 		{% for p in problemy %} | 		{% for p in problemy %} | ||||||
| 		<th> | 		<th> | ||||||
| 			{# TODO: Přehled řešení k problému, odkázaný odsud? #} | 			{# TODO: Přehled řešení k problému, odkázaný odsud? #} | ||||||
| 			{{ p }} | 			<span title="Autor: {{ p.autor }}, Garant: {{ p.garant }}, Opravovatelé: {{ p.opravovatele.all | join:", " }}">{{ p }} | ||||||
|  | 				<span class="odevzdavatko-role"> | ||||||
|  | 					{% spaceless %} | ||||||
|  | 						<span class="{{ p|ma_autora:user|yesno:"vyrazne,nevyrazne" }}">A</span> | ||||||
|  | 						<span class="{{ p|ma_garanta:user|yesno:"vyrazne,nevyrazne" }}">G</span> | ||||||
|  | 						<span class="{{ p|ma_opravovatele:user|yesno:"vyrazne,nevyrazne" }}">O</span> | ||||||
|  | 					{% endspaceless %} | ||||||
|  | 				</span> | ||||||
|  | 			</span> | ||||||
| 		</th> | 		</th> | ||||||
| 		{% endfor %} | 		{% endfor %} | ||||||
| 	</tr> | 	</tr> | ||||||
|  |  | ||||||
							
								
								
									
										27
									
								
								odevzdavatko/templatetags/orgove.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								odevzdavatko/templatetags/orgove.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | ||||||
|  | from django import template | ||||||
|  | register = template.Library() | ||||||
|  | 
 | ||||||
|  | from personalni.utils import organizator_cehokoliv | ||||||
|  | 
 | ||||||
|  | # Jen typová anotace | ||||||
|  | from tvorba.models import Problem | ||||||
|  | from personalni.models import Osoba, Organizator, Resitel, Prijemce | ||||||
|  | from django.contrib.auth.models import AnonymousUser, User | ||||||
|  | 
 | ||||||
|  | @register.filter | ||||||
|  | def ma_autora(p: Problem, o: Osoba | Organizator | User | AnonymousUser | Resitel | Prijemce) -> bool | None: | ||||||
|  | 	o = organizator_cehokoliv(o) | ||||||
|  | 	if o is None: return None | ||||||
|  | 	return p.autor == o | ||||||
|  | 
 | ||||||
|  | @register.filter | ||||||
|  | def ma_garanta(p: Problem, o: Osoba | Organizator | User | AnonymousUser | Resitel | Prijemce) -> bool | None: | ||||||
|  | 	o = organizator_cehokoliv(o) | ||||||
|  | 	if o is None: return None | ||||||
|  | 	return p.garant == o | ||||||
|  | 
 | ||||||
|  | @register.filter | ||||||
|  | def ma_opravovatele(p: Problem, o: Osoba | Organizator | User | AnonymousUser | Resitel | Prijemce) -> bool | None: | ||||||
|  | 	o = organizator_cehokoliv(o) | ||||||
|  | 	if o is None: return None | ||||||
|  | 	return p.opravovatele.contains(o) | ||||||
|  | @ -3,7 +3,7 @@ import re | ||||||
| 
 | 
 | ||||||
| from django.contrib.auth import get_user_model | from django.contrib.auth import get_user_model | ||||||
| from django.contrib.auth.decorators import permission_required, user_passes_test | from django.contrib.auth.decorators import permission_required, user_passes_test | ||||||
| from django.contrib.auth.models import AnonymousUser | from django.contrib.auth.models import AnonymousUser, User | ||||||
| from django.db import transaction | from django.db import transaction | ||||||
| 
 | 
 | ||||||
| import soustredeni.models | import soustredeni.models | ||||||
|  | @ -182,3 +182,46 @@ def merge_osoby(cilova, zdrojova): | ||||||
| 	cilova.save() | 	cilova.save() | ||||||
| 
 | 
 | ||||||
| 	input("Potvrdit transakci osob (^C pro zrušení) ") | 	input("Potvrdit transakci osob (^C pro zrušení) ") | ||||||
|  | 
 | ||||||
|  | def osoba_uzivatele(u: User | AnonymousUser) -> Osoba | None: | ||||||
|  | 	if u.is_anonymous: return None | ||||||
|  | 	try: | ||||||
|  | 		return u.osoba | ||||||
|  | 	except User.osoba.RelatedObjectDoesNotExist: | ||||||
|  | 		return None | ||||||
|  | 
 | ||||||
|  | def resitel_osoby(o: Osoba) -> Resitel | None: | ||||||
|  | 	try: | ||||||
|  | 		return o.resitel | ||||||
|  | 	except Osoba.resitel.RelatedObjectDoesNotExist: | ||||||
|  | 		return None | ||||||
|  | 
 | ||||||
|  | def resitel_uzivatele(u: User | AnonymousUser) -> Resitel | None: | ||||||
|  | 	o = osoba_uzivatele(u) | ||||||
|  | 	if o is None: return None | ||||||
|  | 	return resitel_osoby(o) | ||||||
|  | 
 | ||||||
|  | def resitel_cehokoliv(r: User | AnonymousUser | Osoba | Organizator | Resitel | Prijemce) -> Organizator | None: | ||||||
|  | 		if isinstance(r, User): r = resitel_uzivatele(r) | ||||||
|  | 		if isinstance(r, Osoba): r = resitel_osoby(r) | ||||||
|  | 		if isinstance(r, Resitel) or isinstance(r, Prijemce): r = resitel_osoby(r.osoba) | ||||||
|  | 		assert isinstance(r, Resitel) or r is None | ||||||
|  | 		return r | ||||||
|  | 
 | ||||||
|  | def organizator_osoby(o: Osoba) -> Organizator | None: | ||||||
|  | 	try: | ||||||
|  | 		return o.org | ||||||
|  | 	except Osoba.org.RelatedObjectDoesNotExist: | ||||||
|  | 		return None | ||||||
|  | 
 | ||||||
|  | def organizator_uzivatele(u: User | AnonymousUser) -> Organizator | None: | ||||||
|  | 	o = osoba_uzivatele(u) | ||||||
|  | 	if o is None: return None | ||||||
|  | 	return organizator_osoby(o) | ||||||
|  | 
 | ||||||
|  | def organizator_cehokoliv(o: User | AnonymousUser | Osoba | Organizator | Resitel | Prijemce) -> Organizator | None: | ||||||
|  | 		if isinstance(o, User): o = organizator_uzivatele(o) | ||||||
|  | 		if isinstance(o, Osoba): o = organizator_osoby(o) | ||||||
|  | 		if isinstance(o, Resitel) or isinstance(o, Prijemce): o = organizator_osoby(o.osoba) | ||||||
|  | 		assert isinstance(o, Organizator) or o is None | ||||||
|  | 		return o | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	
Má mít class nebo tam ten atribut nemá být vůbec