Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • to/majak
  • b1242/majak
2 results
Show changes
Commits on Source (31)
Showing
with 61411 additions and 22 deletions
......@@ -137,15 +137,9 @@ dmypy.json
# Cython debug symbols
cython_debug/
# Requests-cache
redmine_cache.sqlite
#####################################################
# CUSTOM
# requests cache
instagram_cache.sqlite
# direnv
.envrc
......
......@@ -3,4 +3,4 @@
line_length = 88
multi_line_output = 3
include_trailing_comma = true
known_third_party = PyPDF2,arrow,bleach,bs4,captcha,celery,dateutil,django,environ,faker,fastjsonschema,icalevents,markdown,modelcluster,pirates,pytest,pytz,requests,requests_cache,sentry_sdk,taggit,wagtail,wagtailmetadata,weasyprint,yaml
known_third_party = PyPDF2,arrow,bleach,bs4,captcha,celery,dateutil,django,environ,faker,fastjsonschema,icalevents,markdown,modelcluster,pirates,pytest,pytz,requests,sentry_sdk,taggit,wagtail,wagtailmetadata,weasyprint,yaml
......@@ -157,6 +157,8 @@ Různé:
| `SENTRY_DSN` | | pokud je zadáno, pády se reportují do Sentry |
| `SEARCH_CONFIG` | english | nastavení jazyka fulltextového vyhledávání, viz níže |
| `DEBUG_TOOLBAR` | False | zobrazit Django Debug Toolbar (pro vývoj) |
| `MAILTRAIN_API_URL` | | URL k API Mailtrain |
| `MAILTRAIN_API_TOKEN` | | token k API Mailtrain |
Settings pro appky na weby:
......
import json
import logging
from datetime import date, timedelta
import arrow
from django.core.serializers.json import DjangoJSONEncoder
from django.core.validators import URLValidator, ValidationError
from django.db import models
from icalevents import icalevents
......@@ -25,10 +27,17 @@ class EventsJSONField(models.JSONField):
def from_db_value(self, value, expression, connection):
value = super().from_db_value(value, expression, connection)
urlValidator = URLValidator()
if value:
for event in value:
event["start"] = arrow.get(event.get("start")).datetime
event["end"] = arrow.get(event["end"]).datetime
try:
urlValidator(event.get("location"))
event["url"] = event.get("location")
except ValidationError:
pass
return value
......@@ -80,6 +89,26 @@ class CalendarMixin(models.Model):
class Meta:
abstract = True
def get_fullcalendar_data(self) -> str:
calendar_format_events = []
for event in self.calendar.past_events + self.calendar.future_events:
parsed_event = {
"allDay": event["all_day"],
"start": event["start"].isoformat(),
"end": event["end"].isoformat(),
}
if event["summary"] is not None:
parsed_event["title"] = event["summary"]
if event["url"] is not None:
parsed_event["url"] = event["url"]
calendar_format_events.append(parsed_event)
return json.dumps(calendar_format_events)
def save(self, *args, **kwargs):
# create or update related Calendar
if self.calendar_url:
......
......@@ -9,7 +9,7 @@ from django.conf import settings
if TYPE_CHECKING:
from icalevents.icalparser import Event
EVENT_KEYS = ("start", "end", "all_day", "summary", "description", "location")
EVENT_KEYS = ("start", "end", "all_day", "summary", "description", "location", "url")
def split_event_dict_list(event_list: "list[dict]") -> tuple[list[dict], list[dict]]:
......
......@@ -299,9 +299,7 @@ class CzechInspirationalDownloadPage(
pass
else:
subscribe_to_newsletter(
email,
settings.CZECH_INSPIRATIONAL_NEWSLETTER_ID,
settings.CZECH_INSPIRATIONAL_NEWSLETTER_SOURCE,
email, settings.CZECH_INSPIRATIONAL_NEWSLETTER_CID
)
return context
......@@ -339,3 +339,33 @@ class HeroBannerBlock(StructBlock):
template = "district/blocks/hero_banner_block.html"
icon = "image"
label = "Hero banner"
class ArticlesBlock(StructBlock):
articles = ListBlock(
PageChooserBlock(
"district.DistrictArticlePage", required=True, label="Aktualita"
),
label="Seznam aktualit",
required=True,
)
class Meta:
template = "district/blocks/articles_block.html"
icon = "list-ul"
label = "Blok aktualit"
class ArticleLinksBlock(StructBlock):
articles = ListBlock(
PageChooserBlock(
"district.DistrictArticlePage", required=True, label="Aktualita"
),
label="Seznam aktualit",
required=True,
)
class Meta:
template = "district/blocks/article_links_block.html"
icon = "list-ul"
label = "Seznam nadpisů článků"
# Generated by Django 4.1.8 on 2023-04-20 21:55
import wagtail.blocks
import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("district", "0108_alter_districtcenterpage_content_and_more"),
]
operations = [
migrations.AddField(
model_name="districthomepage",
name="footer_links",
field=wagtail.fields.StreamField(
[
(
"footer_links",
wagtail.blocks.StructBlock(
[
(
"label",
wagtail.blocks.CharBlock(
label="Titulek zápatí", required=True
),
),
(
"items",
wagtail.blocks.ListBlock(
wagtail.blocks.StructBlock(
[
(
"url",
wagtail.blocks.URLBlock(
label="Odkaz"
),
),
(
"text",
wagtail.blocks.CharBlock(
label="Text v odkazu"
),
),
]
),
label="Odkazy",
required=True,
),
),
]
),
)
],
blank=True,
use_json_field=True,
verbose_name="Odkazy v zápatí webu",
),
),
]
# Generated by Django 4.1.8 on 2023-04-13 08:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("district", "0108_alter_districtcenterpage_content_and_more"),
]
operations = [
migrations.AddField(
model_name="districtpersonpage",
name="ical_calendar_url",
field=models.URLField(
blank=True,
help_text="Podporuje Mrak, Google Kalendář a další. Návod na synchronizaci najdeš na pi2.cz/kalendare",
max_length=256,
null=True,
verbose_name="iCal adresa kalendáře",
),
),
]
# Generated by Django 4.1.8 on 2023-05-01 22:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("district", "0109_alter_districthomepage_subheader"),
]
operations = [
migrations.AddField(
model_name="districtelectioncampaignpage",
name="campaign_funding_info",
field=models.URLField(
blank=True,
help_text="Pokud ponecháte prázdné, použije se buď odkaz z nadřazené stránky, nebo https://wiki.pirati.cz/ft/start.",
null=True,
verbose_name="URL pro zjištění informací o financování kampaně",
),
),
migrations.AddField(
model_name="districtelectionprogrampage",
name="campaign_funding_info",
field=models.URLField(
blank=True,
help_text="Pokud ponecháte prázdné, použije se buď odkaz z nadřazené stránky, nebo https://wiki.pirati.cz/ft/start.",
null=True,
verbose_name="URL pro zjištění informací o financování kampaně",
),
),
migrations.AddField(
model_name="districtpostelectionstrategypage",
name="campaign_funding_info",
field=models.URLField(
blank=True,
help_text="Pokud ponecháte prázdné, použije se buď odkaz z nadřazené stránky, nebo https://wiki.pirati.cz/ft/start.",
null=True,
verbose_name="URL pro zjištění informací o financování kampaně",
),
),
]
# Generated by Django 4.1.8 on 2023-05-01 14:58
import wagtail.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("district", "0109_alter_districthomepage_subheader"),
]
operations = [
migrations.AddField(
model_name="districthomepage",
name="footer_extra_content",
field=wagtail.fields.RichTextField(
blank=True, verbose_name="Extra obsah pod šedou patičkou"
),
),
]
# Generated by Django 4.1.8 on 2023-04-16 12:45
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("calendar_utils", "0004_auto_20220505_1228"),
("district", "0109_districtpersonpage_ical_calendar_url"),
]
operations = [
migrations.RemoveField(
model_name="districtpersonpage",
name="ical_calendar_url",
),
migrations.AddField(
model_name="districtpersonpage",
name="calendar",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.PROTECT,
to="calendar_utils.calendar",
),
),
migrations.AddField(
model_name="districtpersonpage",
name="calendar_url",
field=models.URLField(
blank=True, null=True, verbose_name="URL kalendáře ve formátu iCal"
),
),
]
# Generated by Django 4.1.8 on 2023-05-02 14:33
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
(
"district",
"0110_districtelectioncampaignpage_campaign_funding_info_and_more",
),
("district", "0110_districthomepage_footer_extra_content"),
]
operations = []
# Generated by Django 4.1.8 on 2023-05-02 16:54
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("district", "0109_districthomepage_footer_links"),
("district", "0112_alter_districtcenterpage_content_and_more"),
]
operations = []
# Generated by Django 4.1.8 on 2023-05-02 19:40
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('district', '0110_remove_districtpersonpage_ical_calendar_url_and_more'),
('district', '0113_merge_20230502_1854'),
]
operations = [
]
......@@ -40,6 +40,7 @@ from shared.blocks import (
ButtonGroupBlock,
ChartBlock,
FigureBlock,
FooterLinksBlock,
FullSizeHeaderBlock,
HeadlineBlock,
YouTubeVideoBlock,
......@@ -49,6 +50,7 @@ from shared.models import (
ArticleMixin,
ExtendedMetadataHomePageMixin,
ExtendedMetadataPageMixin,
FooterMixin,
MenuMixin,
SubpageMixin,
)
......@@ -59,12 +61,19 @@ from . import blocks
from .forms import JekyllImportForm
CONTENT_BLOCKS = DEFAULT_CONTENT_BLOCKS + [
("chart", ChartBlock(template="district/blocks/chart.html"))
("chart", ChartBlock(template="district/blocks/chart.html")),
("related", blocks.ArticlesBlock()),
("related_links", blocks.ArticleLinksBlock()),
]
class DistrictHomePage(
MenuMixin, ExtendedMetadataHomePageMixin, MetadataPageMixin, CalendarMixin, Page
MenuMixin,
ExtendedMetadataHomePageMixin,
MetadataPageMixin,
CalendarMixin,
FooterMixin,
Page,
):
### FIELDS
......@@ -188,6 +197,13 @@ class DistrictHomePage(
use_json_field=True,
)
# Extra komentar v paticce
footer_extra_content = RichTextField(
verbose_name="Extra obsah pod šedou patičkou",
blank=True,
features=RICH_TEXT_DEFAULT_FEATURES,
)
# settings
matomo_id = models.IntegerField(
"Matomo ID pro sledování návštěvnosti", blank=True, null=True
......@@ -244,6 +260,12 @@ class DistrictHomePage(
],
gettext_lazy("Lidé v zápatí stránky"),
),
MultiFieldPanel(
[
FieldPanel("footer_extra_content"),
],
gettext_lazy("Extra obsah v patičce"),
),
MultiFieldPanel(
[
FieldPanel("region_map_button_text"),
......@@ -252,6 +274,7 @@ class DistrictHomePage(
],
gettext_lazy("Nastavení lišty s kalendářem a mapou"),
),
FieldPanel("footer_links"),
FieldPanel("fallback_image"),
]
......@@ -596,7 +619,11 @@ class DistrictPersonTag(TaggedItemBase):
class DistrictPersonPage(
ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
ExtendedMetadataPageMixin,
SubpageMixin,
MetadataPageMixin,
CalendarMixin,
Page,
):
### FIELDS
job = models.CharField(
......@@ -694,6 +721,7 @@ class DistrictPersonPage(
],
"Kontaktní informace",
),
FieldPanel("calendar_url"),
MultiFieldPanel(
[
FieldPanel("facebook_url"),
......@@ -809,9 +837,19 @@ class DistrictElectionBasePage(
use_json_field=True,
)
campaign_funding_info = models.URLField(
"URL pro zjištění informací o financování kampaně",
blank=True,
null=True,
help_text="Pokud ponecháte prázdné, použije se buď odkaz z nadřazené stránky, nebo https://wiki.pirati.cz/ft/start.",
)
### PANELS
content_panels = Page.content_panels + [FieldPanel("content")]
content_panels = Page.content_panels + [
FieldPanel("content"),
FieldPanel("campaign_funding_info"),
]
promote_panels = make_promote_panels()
......@@ -1024,6 +1062,7 @@ class DistrictElectionCampaignPage(DistrictElectionBasePage):
"Hero banner",
),
FieldPanel("order"),
FieldPanel("campaign_funding_info"),
]
### RELATIONS
......
......@@ -19,7 +19,7 @@
<!-- Bootstrap CSS -->
<!-- Styles -->
<link rel="stylesheet" href="https://styleguide.pirati.cz/2.10.x/css/styles.css">
<link rel="stylesheet" href="https://styleguide.pirati.cz/2.12.x/css/styles.css">
<link href="{% static "shared/vendor/fancybox/jquery.fancybox.min.css" %}" rel="stylesheet">
<link rel="stylesheet" href="{% static "shared/css/helpers.css" %}">
......@@ -287,6 +287,10 @@
</ul>
</ui-footer-collapsible>
</div>
{% if page.root_page.footer_links %}
{% include_block page.root_page.footer_links with container="py-4 lg:py-0 border-t border-grey-400 lg:border-t-0" %}
{% endif %}
</section>
<section class="footer__social lg:text-right">
......@@ -322,14 +326,19 @@
</section>
</div>
{% if page.root_page.footer_person_list %}
{% if page.root_page.footer_person_list or page.root_page.footer_extra_content %}
<section class="bg-black py-4 lg:py-12">
<div class="container container--default">
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 xl:grid-cols-3">
{% for person_block in page.root_page.footer_person_list %}
{% include "shared/person_badge_snippet.html" with person_page=person_block.value.person title=person_block.value.position %}
{% endfor %}
</div>
<div class="grid gap-4 grid-cols-1 md:grid-cols-2 xl:grid-cols-3">
{% if page.root_page.footer_person_list %}
{% for person_block in page.root_page.footer_person_list %}
{% include "shared/person_badge_snippet.html" with person_page=person_block.value.person title=person_block.value.position %}
{% endfor %}
{% endif %}
{% if page.root_page.footer_extra_content %}
{{ page.root_page.footer_extra_content|richtext }}
{% endif %}
</div>
</div>
</section>
{% endif %}
......
<ul class="unordered-list">
{% for article in self.articles %}
<li>
<a href="{{ article.url }}" class="underline">
{{ article.title }}
</a>
</li>
{% endfor %}
</ul>
<div class="article-card-list grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 lg:gap-8">
{% for article in self.articles %}
{% include "shared/article_preview.html" with article=article perex_size="h-12" %}
{% endfor %}
</div>