Skip to content

Commit 5757019

Browse files
author
Grzegorz Kocjan
committed
Add language support (PL/EN) to HugoMeetupGenerator
1 parent 62531cd commit 5757019

File tree

8 files changed

+308
-119
lines changed

8 files changed

+308
-119
lines changed

page/assets/icons/flag_gb.png

16.7 KB
Loading
810 KB
Loading
348 KB
Loading

page/content/spotkania/61/index.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
---
2+
title: "Meetup #61"
3+
date: 2025-11-26T18:00:00+02:00
4+
time: "18:00"
5+
place: "IndieBI, Piotrkowska 157A, Hi Piotrkowska"
6+
---
7+
<img src="featured.png" alt="Infographic" />
8+
9+
## Information
10+
11+
**📅 date:** 2025-11-26</br>
12+
**🕕 time:** 18:00</br>
13+
**📍 location:** IndieBI, Piotrkowska 157A, Hi Piotrkowska</br>
14+
➡️ [**SIGN UP LINK**](https://www.meetup.com/python-lodz/events/311933962/) ⬅️
15+
16+
## Presentations
17+
18+
### Airflow 3, and the boring, production AI plumbing, that nobody talks about
19+
{{< speaker speaker_id="jarek-potiuk" >}}
20+
Airflow 3 is out. Spring last year the Airflow community came to the conclusion that in order to respond to the growing needs of our users, we have to again reinvent ourselves in the modern AI world.
21+
22+
Airflow 3 is already out for a few months and we already know that we got on the right track - our users are already using Airflow to do with AI what they were doing several years ago for traditional ETL/ ELT workflows - turning experiments and local workflows into stable, production-ready way how to manage your various AI-related needs.
23+
24+
From my talk you will learn:
25+
26+
* why we decided to switch gears for Airflow 3 (yes, AI)
27+
* what are the architectural changes and improvements that lay foundation under Airflow 3 being modern and applicable to AI workflows
28+
* what are the features that help with production-ready workflows: Versioning, Enterprise level security isolation, better dependency management, execution isolation, dataset as first class citizen, modern react-based UI, schedulable and UI-controlled backfills, inference kind of workflows, "almost" streaming experience, and more
29+
* what early users of Airflow 3 say and how their workflow management improved
30+
* what is coming next (yes! we are not nearly done yet and more things are coming!)
31+
32+
### System init written in Python - project analysis
33+
{{< speaker speaker_id="mateusz-piwek" >}}
34+
Python is used in many areas – such as web development, artificial intelligence, data analysis, and embedded systems. But can it also be used as an init system in Linux, and does that idea make sense?
35+
36+
The init system is the main process that starts and monitors services in the operating system. Traditionally, such systems are developed in the C language to ensure high code efficiency – but perhaps it’s worth reconsidering this approach?
37+
38+
In this presentation, the author will present a working project, show performance test results, and share ideas for unconventional applications.
39+
40+
## Sponsors
41+
{{< article link="/sponsorzy/indiebi/" >}}
42+
43+
{{< article link="/sponsorzy/sunscrapers/" >}}

page/data/speakers/mateusz-piwek.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ name: "Mateusz Piwek"
22
avatar: "images/avatars/mateusz-piwek.png"
33
bio: "A software developer with 20 years of experience in the IT industry, with a strong interest in new technologies. Currently specializes in developing and deploying e-commerce solutions. An active user of open-source software, regularly publishing personal projects on GitHub – mainly in Python. Also passionate about computer hardware and electronics."
44
social:
5-
- link: https://github.com/tools200ms
5+
- github: https://github.com/tools200ms
Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
{{- $speaker_id := .Get "speaker_id" -}}
22

3-
{{ $speaker := index site.Data.speakers $speaker_id }}
3+
{{ $speaker := index site.Data.speakers $speaker_id }}
44
{{ $speakerAvatar := resources.Get $speaker.avatar }}
55

66
<div class="flex items-center space-x-3 mt-2">
7-
<img src="{{ $speakerAvatar.Permalink }}" alt="{{ $speaker.name }}" class="w-24 h-24 rounded-full object-cover" >
7+
<img src="{{ $speakerAvatar.Permalink }}" alt="{{ $speaker.name }}" class="w-24 h-24 rounded-full object-cover">
88
<div>
9-
<p class="text-sm text-gray-500">Prelegent: <strong>{{ $speaker.name }}</strong></p>
9+
<p class="text-sm text-gray-500"><strong>{{ $speaker.name }}</strong></p>
1010

11-
<div class="flex flex-wrap text-neutral-400 dark:text-neutral-500">
12-
{{ range $links := $speaker.social }}
13-
{{ range $name, $url := $links }}
14-
<a
15-
class="px-1 hover:text-primary-700 dark:hover:text-primary-400"
16-
href="{{ $url | safeURL }}"
17-
target="_blank"
18-
aria-label="{{ $name | title }}"
19-
rel="me noopener noreferrer"
20-
><span class="inline-block align-text-bottom">{{ partial "icon.html" $name }}</span></a
21-
>
22-
{{ end }}
23-
{{ end }}
11+
<div class="flex flex-wrap text-neutral-400 dark:text-neutral-500">
12+
{{ range $links := $speaker.social }}
13+
{{ range $name, $url := $links }}
14+
<a class="px-1 hover:text-primary-700 dark:hover:text-primary-400" href="{{ $url | safeURL }}" target="_blank"
15+
aria-label="{{ $name | title }}" rel="me noopener noreferrer"><span class="inline-block align-text-bottom">{{
16+
partial "icon.html" $name }}</span></a>
17+
{{ end }}
18+
{{ end }}
2419
</div>
2520
</div>
2621
</div>

src/pyldz/hugo_generator.py

Lines changed: 127 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -34,74 +34,149 @@ def generate_meetup_markdown(self, meetup: Meetup) -> str:
3434
content_parts.append("")
3535

3636
# Add information section
37-
content_parts.append("## Informacje")
38-
content_parts.append("")
39-
content_parts.append(f"**📅 data:** {meetup.date}</br>")
40-
content_parts.append(f"**🕕 godzina:** {meetup.time}</br>")
41-
content_parts.append(f"**📍 miejsce:** {meetup.location_name()}</br>")
42-
43-
# Add meetup link if available
44-
if meetup.meetup_url:
45-
content_parts.append(f" ➡️ [**LINK DO ZAPISÓW**]({meetup.meetup_url}) ⬅️")
46-
47-
# Add feedback link if available (TODO: Add feedback_url to Google Sheets)
48-
if meetup.feedback_url:
37+
if meetup.language == Language.EN:
38+
content_parts.append("## Information")
39+
content_parts.append("")
40+
content_parts.append(f"**📅 date:** {meetup.date}</br>")
41+
content_parts.append(f"**🕕 time:** {meetup.time}</br>")
4942
content_parts.append(
50-
f" </br></br> 📝 [**ANKIETA** - oceń spotkanie oraz prelekcje]({meetup.feedback_url})"
43+
f"**📍 location:** {meetup.location_name(meetup.language)}</br>"
5144
)
5245

53-
content_parts.append("")
46+
# Add meetup link if available
47+
if meetup.meetup_url:
48+
content_parts.append(f" ➡️ [**SIGN UP LINK**]({meetup.meetup_url}) ⬅️")
5449

55-
# Add live stream if available (TODO: Add livestream_id to Google Sheets)
56-
if meetup.livestream_id:
57-
content_parts.append("## Live Stream")
58-
content_parts.append(
59-
f'{{{{< youtubeLite id="{meetup.livestream_id}" label="Label" >}}}}'
60-
)
61-
content_parts.append("")
50+
# Add feedback link if available (TODO: Add feedback_url to Google Sheets)
51+
if meetup.feedback_url:
52+
content_parts.append(
53+
f" </br></br> 📝 [**SURVEY** - rate the meeting and presentations]({meetup.feedback_url})"
54+
)
6255

63-
# Add talks section
64-
content_parts.append("## Prelekcje")
65-
content_parts.append("")
56+
content_parts.append("")
6657

67-
if not meetup.talks:
68-
# No talks yet message
69-
content_parts.append(
70-
"Już wkrótce ogłosimy oficjalną agendę naszego najnowszego spotkania Python Łódź. "
71-
"Bądźcie czujni, bo szykujemy naprawdę interesujące prezentacje.\n\n"
72-
"Niezależnie od tematu, każde spotkanie to świetna okazja, by poszerzyć swoją wiedzę, "
73-
"poznać nowych ludzi i razem budować silną społeczność miłośników Pythona.\n\n"
74-
"Zarezerwuj swoje miejsce już teraz – nie daj się zaskoczyć, gdy ruszymy z pełną informacją o wydarzeniu."
75-
)
76-
else:
77-
# Add each talk
78-
for talk in meetup.talks:
79-
# Clean title (remove newlines and extra spaces)
80-
clean_title = " ".join(talk.title.split())
81-
content_parts.append(f"### {clean_title}")
58+
# Add live stream if available (TODO: Add livestream_id to Google Sheets)
59+
if meetup.livestream_id:
60+
content_parts.append("## Live Stream")
8261
content_parts.append(
83-
f'{{{{< speaker speaker_id="{talk.speaker_id}" >}}}}'
62+
f'{{{{< youtubeLite id="{meetup.livestream_id}" label="Label" >}}}}'
8463
)
64+
content_parts.append("")
8565

86-
if talk.description:
87-
# Convert newlines to markdown line breaks
88-
description = talk.description.replace("\n", " \n")
89-
content_parts.append(description)
66+
# Add talks section
67+
content_parts.append("## Presentations")
68+
content_parts.append("")
9069

91-
if talk.youtube_id:
92-
content_parts.append("#### Nagranie")
70+
if not meetup.talks:
71+
# No talks yet message
72+
content_parts.append(
73+
"Soon we will announce the official agenda of our latest Python Łódź meetup. "
74+
"Stay tuned, because we are preparing really interesting presentations.\n\n"
75+
"Regardless of the topic, every meeting is a great opportunity to expand your knowledge, "
76+
"meet new people and together build a strong community of Python enthusiasts.\n\n"
77+
"Reserve your spot now – don't be surprised when we launch with full event information."
78+
)
79+
else:
80+
# Add each talk
81+
for talk in meetup.talks:
82+
# Clean title (remove newlines and extra spaces)
83+
clean_title = " ".join(talk.title.split())
84+
content_parts.append(f"### {clean_title}")
9385
content_parts.append(
94-
f'{{{{< youtubeLite id="{talk.youtube_id}" label="Label" >}}}}'
86+
f'{{{{< speaker speaker_id="{talk.speaker_id}" >}}}}'
9587
)
9688

89+
if talk.description:
90+
# Convert newlines to markdown line breaks
91+
description = talk.description.replace("\n", " \n")
92+
content_parts.append(description)
93+
94+
if talk.youtube_id:
95+
content_parts.append("#### Recording")
96+
content_parts.append(
97+
f'{{{{< youtubeLite id="{talk.youtube_id}" label="Label" >}}}}'
98+
)
99+
100+
content_parts.append("")
101+
102+
# Add sponsors section
103+
content_parts.append("## Sponsors")
104+
for sponsor in meetup.sponsors:
105+
content_parts.append(
106+
f'{{{{< article link="/sponsorzy/{sponsor}/" >}}}}'
107+
)
108+
content_parts.append("")
109+
else:
110+
content_parts.append("## Informacje")
111+
content_parts.append("")
112+
content_parts.append(f"**📅 data:** {meetup.date}</br>")
113+
content_parts.append(f"**🕕 godzina:** {meetup.time}</br>")
114+
content_parts.append(f"**📍 miejsce:** {meetup.location_name()}</br>")
115+
116+
# Add meetup link if available
117+
if meetup.meetup_url:
118+
content_parts.append(f" ➡️ [**LINK DO ZAPISÓW**]({meetup.meetup_url}) ⬅️")
119+
120+
# Add feedback link if available (TODO: Add feedback_url to Google Sheets)
121+
if meetup.feedback_url:
122+
content_parts.append(
123+
f" </br></br> 📝 [**ANKIETA** - oceń spotkanie oraz prelekcje]({meetup.feedback_url})"
124+
)
125+
126+
content_parts.append("")
127+
128+
# Add live stream if available (TODO: Add livestream_id to Google Sheets)
129+
if meetup.livestream_id:
130+
content_parts.append("## Live Stream")
131+
content_parts.append(
132+
f'{{{{< youtubeLite id="{meetup.livestream_id}" label="Label" >}}}}'
133+
)
97134
content_parts.append("")
98135

99-
# Add sponsors section
100-
content_parts.append("## Sponsorzy")
101-
for sponsor in meetup.sponsors:
102-
content_parts.append(f'{{{{< article link="/sponsorzy/{sponsor}/" >}}}}')
136+
# Add talks section
137+
content_parts.append("## Prelekcje")
103138
content_parts.append("")
104139

140+
if not meetup.talks:
141+
# No talks yet message
142+
content_parts.append(
143+
"Już wkrótce ogłosimy oficjalną agendę naszego najnowszego spotkania Python Łódź. "
144+
"Bądźcie czujni, bo szykujemy naprawdę interesujące prezentacje.\n\n"
145+
"Niezależnie od tematu, każde spotkanie to świetna okazja, by poszerzyć swoją wiedzę, "
146+
"poznać nowych ludzi i razem budować silną społeczność miłośników Pythona.\n\n"
147+
"Zarezerwuj swoje miejsce już teraz – nie daj się zaskoczyć, gdy ruszymy z pełną informacją o wydarzeniu."
148+
)
149+
else:
150+
# Add each talk
151+
for talk in meetup.talks:
152+
# Clean title (remove newlines and extra spaces)
153+
clean_title = " ".join(talk.title.split())
154+
content_parts.append(f"### {clean_title}")
155+
content_parts.append(
156+
f'{{{{< speaker speaker_id="{talk.speaker_id}" >}}}}'
157+
)
158+
159+
if talk.description:
160+
# Convert newlines to markdown line breaks
161+
description = talk.description.replace("\n", " \n")
162+
content_parts.append(description)
163+
164+
if talk.youtube_id:
165+
content_parts.append("#### Nagranie")
166+
content_parts.append(
167+
f'{{{{< youtubeLite id="{talk.youtube_id}" label="Label" >}}}}'
168+
)
169+
170+
content_parts.append("")
171+
172+
# Add sponsors section
173+
content_parts.append("## Sponsorzy")
174+
for sponsor in meetup.sponsors:
175+
content_parts.append(
176+
f'{{{{< article link="/sponsorzy/{sponsor}/" >}}}}'
177+
)
178+
content_parts.append("")
179+
105180
# TODO: Add photos section (will need to check for images in resources)
106181

107182
return "\n".join(content_parts)
@@ -113,7 +188,7 @@ def generate_frontmatter(self, meetup: Meetup) -> str:
113188
f'title: "{meetup.title}"',
114189
f"date: {meetup.date}T{meetup.time}:00+02:00",
115190
f'time: "{meetup.time}"',
116-
f'place: "{meetup.location_name()}"',
191+
f'place: "{meetup.location_name(meetup.language)}"',
117192
"---",
118193
"",
119194
]

0 commit comments

Comments
 (0)