refacture all the things!

This commit is contained in:
XenGi 2023-06-13 12:47:07 +02:00
parent 9a7b9ba2c0
commit 2e3a02af0c
Signed by: xengi
SSH key fingerprint: SHA256:EvLbWxFCtfmd+8Xa6RkzkhIga+wFkKCekfFacYVn63M
12 changed files with 169 additions and 153 deletions

View file

@ -1,4 +1,4 @@
name: Test deployment name: Release website
on: on:
push: push:

View file

@ -1,42 +1,51 @@
![CCCB logo](static/img/logo.png)
# CCCB Website # CCCB Website
This is the website of CCCB. This is the website of the CCCB.
## Getting started ## Getting started
Get Hugo: <https://gohugo.io/getting-started/installing> 1. Get Hugo: <https://gohugo.io/getting-started/installing>
2. Clone this repo
Clone this repo ```shell
``` git clone https://github.com/cccb/www
git clone https://github.com/cccb/www ```
``` 3. Switch directory
```shell
Switch directory cd www
``` ```
cd www 3. Fetch Submodules
``` ```shell
git submodule update --recursive --remote --init
Fetch Submodules ```
```
git submodule update --recursive --remote --init
```
### Run site locally ### Run site locally
Run hugo webserver Run hugo webserver:
```
```shell
hugo serve hugo serve
``` ```
Point your browser to http://localhost:1313/
To ready your site for upload, run "./build.sh", which also generates all.ics and adds the calendar table to index.html Point your browser to: http://localhost:1313/
To ready your site for upload, run `./build.sh`, which also generates `all.ics` and adds the calendar table to `index.html`.
Every change you make on the project will be reflected in your browser as long as `hugo serve` is running. Every change you make on the project will be reflected in your browser as long as `hugo serve` is running.
## Making a change ## Making a change
* Use your local dev setup (see Getting started) or via GitLab editor. 1. Use your local dev setup (see Getting started) or via GitHub editor.
* Make your change in `staging` branch. 2. Make your change in `staging` branch.
* Commit (and push) your change. 3. Commit (and push) your change.
* Gitlab CI is running pipeline. If successfull, check [Staging Website](https://staging.berlin.ccc.de/) if change is correct. 4. GitHub Actions is running the release workflow.
* Create merge request to merge changes from `staging` to `production`. Ask somebody to check merge request or if small change, merge yourself. - If successful, check [Staging Website](https://staging.berlin.ccc.de/) if change is correct.
* Gitlab CI is running pipeline. If successfull, check [Website](https://berlin.ccc.de/) if change is correct. 5. Create merge request to merge changes from `staging` to `production` branch. Ask somebody to check merge request or if small change, merge yourself.
6. GitHub Actions is running the release workflow.
- If successfull, check [Website](https://berlin.ccc.de/) if change is correct.
7. Profit!
---
Made with ❤️ and [Hugo](https://gohugo.io).

12
TODO.md
View file

@ -1,15 +1,14 @@
Todo # Todo
----
- DSGVO-compliant Datenschutzerklärung reinbasteln - DSGVO-compliant Datenschutzerklärung reinbasteln
- Entscheiden, welche Seiten sonst noch konvertiert werden sollen und welche in die ewigen Datengründe gehen können - Entscheiden, welche Seiten sonst noch konvertiert werden sollen und welche in die ewigen Datengründe gehen können
Done # Done
----
- Template aussuchen - Template aussuchen
- Rausfinden, wie man eine Seite konvertiert - Rausfinden, wie man eine Seite konvertiert
- hugo new page/mypage.md - `hugo new page/mypage.md`
- pandoc -f mediawiki page.mw -t markdown >> page/mypage.md - `pandoc -f mediawiki page.mw -t markdown >> page/mypage.md`
- Wichtigste Seiten konvertieren - Wichtigste Seiten konvertieren
- Membership-Seite auf den aktuellen Stand der Wahrheit bringen - Membership-Seite auf den aktuellen Stand der Wahrheit bringen
- Ical template bauen - Ical template bauen
@ -17,3 +16,4 @@ Done
- Bestehende Datengarten-Termine konvertieren - Bestehende Datengarten-Termine konvertieren
- ggf. template mit frontmatter - ggf. template mit frontmatter
- Theme forken, alle assets sollten lokal gehosted sein und nicht von irgendwelchen CDNs bezogen werden (HTTP/2 ftw!) - Theme forken, alle assets sollten lokal gehosted sein und nicht von irgendwelchen CDNs bezogen werden (HTTP/2 ftw!)

View file

@ -1,7 +1,8 @@
#!/usr/bin/env sh #!/bin/sh
hugo $(cat .hugo-params) hugo $(cat .hugo-params)
tools/merge_cals.py ./tools/merge_cals.py
upcoming="$(tools/gen_upcoming.py static/all.ics 20 5|tr '\n' ' ')" upcoming="$(tools/gen_upcoming.py static/all.ics 20 5 | tr '\n' ' ')"
cp static/all.ics public/all.ics cp static/all.ics public/all.ics
sed -i "s#CALENDAR#$upcoming#g" public/index.html sed -i "s#CALENDAR#$upcoming#g" public/index.html

View file

@ -63,7 +63,6 @@ mediaTypes:
suffixes: suffixes:
- "xml" - "xml"
outputFormats: outputFormats:
RSS: RSS:
mediaType: "application/rss" mediaType: "application/rss"
@ -73,10 +72,11 @@ outputFormats:
outputs: outputs:
section: section:
- "HTML" - "HTML"
- "Calendar" - "Calendar"
- "RSS" - "RSS"
- "XML" - "XML"
page: page:
- "HTML" - "HTML"
- "Calendar" - "Calendar"

View file

@ -3,7 +3,7 @@
<div class="row"> <div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1"> <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<article role="main" class="blog-post"> <article role="main" class="blog-post">
{{ partial "talk-infobox" . }} {{ partial "talk-infobox" . }}
{{ .Content }} {{ .Content }}
{{ if .Params.tags }} {{ if .Params.tags }}
@ -11,7 +11,7 @@
{{ range .Params.tags }} {{ range .Params.tags }}
<a href="{{ $.Site.LanguagePrefix | absURL }}/tags/{{ . | urlize }}/">{{ . }}</a>&nbsp; <a href="{{ $.Site.LanguagePrefix | absURL }}/tags/{{ . | urlize }}/">{{ . }}</a>&nbsp;
{{ end }} {{ end }}
</div> </div><!--/.blog-tags-->
{{ end }} {{ end }}
{{ if .Site.Params.socialShare }} {{ if .Site.Params.socialShare }}
@ -19,24 +19,24 @@
<section id="social-share"> <section id="social-share">
<ul class="list-inline footer-links"> <ul class="list-inline footer-links">
{{ partial "share-links" . }} {{ partial "share-links" . }}
</ul> </ul><!--/.social-share-->
</section> </section><!--/.list-inline /.footer-links-->
{{ end }} {{ end }}
</article> </article><!--/.blog-post-->
{{ if ne .Type "page" }} {{ if ne .Type "page" }}
<ul class="pager blog-pager"> <ul class="pager blog-pager">
{{ if .PrevInSection }} {{ if .PrevInSection }}
<li class="previous"> <li class="previous">
<a href="{{ .PrevInSection.Permalink }}" data-toggle="tooltip" data-placement="top" title="{{ .PrevInSection.Title }}">&larr; {{ i18n "previousPost" }}</a> <a href="{{ .PrevInSection.Permalink }}" data-toggle="tooltip" data-placement="top" title="{{ .PrevInSection.Title }}">&larr; {{ i18n "previousPost" }}</a>
</li> </li><!--/.previous-->
{{ end }} {{ end }}
{{ if .NextInSection }} {{ if .NextInSection }}
<li class="next"> <li class="next">
<a href="{{ .NextInSection.Permalink }}" data-toggle="tooltip" data-placement="top" title="{{ .NextInSection.Title }}">{{ i18n "nextPost" }} &rarr;</a> <a href="{{ .NextInSection.Permalink }}" data-toggle="tooltip" data-placement="top" title="{{ .NextInSection.Title }}">{{ i18n "nextPost" }} &rarr;</a>
</li> </li><!--/.next-->
{{ end }} {{ end }}
</ul> </ul><!--/.pager /.blog-pager-->
{{ end }} {{ end }}
@ -44,16 +44,16 @@
{{ if .Site.DisqusShortname }} {{ if .Site.DisqusShortname }}
<div class="disqus-comments"> <div class="disqus-comments">
{{ template "_internal/disqus.html" . }} {{ template "_internal/disqus.html" . }}
</div> </div><!--/.disqus-comments-->
{{ end }} {{ end }}
{{ if .Site.Params.staticman }} {{ if .Site.Params.staticman }}
<div class="staticman-comments"> <div class="staticman-comments">
{{ partial "staticman-comments.html" . }} {{ partial "staticman-comments.html" . }}
</div> </div><!--/.staticman-comments-->
{{ end }} {{ end }}
{{ end }} {{ end }}
</div> </div><!--/.col-lg-8 /.col-lg-offset-2 /.col-md-10 /.col-md-offset-1-->
</div> </div><!--/.row-->
</div> </div><!--/.container-->
{{ end }} {{ end }}

View file

@ -1,29 +1,29 @@
{{ $series := or (.Get 0) $.Page.Params.series }} {{ $series := or (.Get 0) $.Page.Params.series }}
<table> <table>
<tr> <tr>
<th>No.</th> <th>No.</th>
<th>Date</th> <th>Date</th>
<th>Speaker</th> <th>Speaker</th>
<th>Topic</th> <th>Topic</th>
<th>Video</th> <th>Video</th>
</tr> </tr>
{{ range $ind,$art := $.Site.Pages.ByDate.Reverse }} {{ range $ind,$art := $.Site.Pages.ByDate.Reverse }}
{{ if eq $art.Params.series $series }} {{ if eq $art.Params.series $series }}
<tr> <tr>
<td>{{ $art.Params.no }}</td> <td>{{ $art.Params.no }}</td>
<td>{{ dateFormat "02.01.2006" $art.Params.event.start }}</td> <td>{{ dateFormat "02.01.2006" $art.Params.event.start }}</td>
{{ if isset $art.Params "speaker_url" }} {{ if isset $art.Params "speaker_url" }}
<td><a href="{{ $art.Params.speaker_url }}">{{ $art.Params.speaker }}</a></td> <td><a href="{{ $art.Params.speaker_url }}">{{ $art.Params.speaker }}</a></td>
{{ else }} {{ else }}
<td>{{ $art.Params.speaker }}</td> <td>{{ $art.Params.speaker }}</td>
{{ end }}
<td><a href="{{ $art.Permalink }}">{{ $art.Params.subtitle }}</a></td>
{{ if $art.Params.recording }}
<td><a href="{{ $art.Params.recording }}"><i class="fa fa-video fa-fw"></i></a></td>
{{ else }}
<td><i class="fa fa-video-slash fa-fw"></i></a></td>
{{ end }}
</tr>
{{ end }}
{{ end }} {{ end }}
<td><a href="{{ $art.Permalink }}">{{ $art.Params.subtitle }}</a></td>
{{ if $art.Params.recording }}
<td><a href="{{ $art.Params.recording }}"><i class="fa fa-video fa-fw"></i></a></td>
{{ else }}
<td><i class="fa fa-video-slash fa-fw"></i></a></td>
{{ end }}
</tr>
{{ end }}
{{ end }}
</table> </table>

View file

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
if [ $# -lt 2 ]; then if [ $# -lt 2 ]; then
echo "Usage: $0 Mediawiki_Page_Name [page|post]" echo "Usage: $0 Mediawiki_Page_Name [page|post]"
@ -7,9 +7,12 @@ fi
echo Converting $1... echo Converting $1...
page=$(echo $1 | sed 's,/,_,g'|tr '[:upper:]' '[:lower:]') page=$(echo $1 | sed 's,/,_,g' | tr '[:upper:]' '[:lower:]')
hugo new $2/$page.md hugo new $2/$page.md
curl -s https://berlin.ccc.de/api.php\?action\=query\&prop\=revisions\&rvprop\=content\&format\=json\&titles\=$1 | \ curl -s "https://berlin.ccc.de/api.php?action=query&prop=revisions&rvprop=content&format=json&titles=$1" \
jq -r '.query.pages |..| objects|.["*"]'| sed '/null/d' | pandoc -f mediawiki -t markdown \ | jq -r '.query.pages |..| objects|.["*"]' \
| sed '/null/d' \
| pandoc -f mediawiki -t markdown \
>> content/$2/$page.md >> content/$2/$page.md

View file

@ -3,7 +3,6 @@
import sys import sys
import logging import logging
import locale import locale
from pprint import pprint
from dateutil.parser import parse from dateutil.parser import parse
from datetime import datetime, timedelta from datetime import datetime, timedelta
from dateutil.rrule import rruleset, rrulestr from dateutil.rrule import rruleset, rrulestr
@ -12,79 +11,83 @@ import icalendar
def vevent_to_event(event, rrstart=None): def vevent_to_event(event, rrstart=None):
if rrstart == None: if rrstart == None:
begin = parse(event['DTSTART'].to_ical()) begin = parse(event["DTSTART"].to_ical())
else: else:
begin = rrstart begin = rrstart
return { "name": event['SUMMARY'].to_ical(), "url": event['URL'].to_ical(), "begin": begin }
return {
"name": event["SUMMARY"].to_ical(),
"url": event["URL"].to_ical(),
"begin": begin
}
def parse_single_event(event, start, end): def parse_single_event(event, start, end):
logging.info("Processing single event %s" % event['SUMMARY'].to_ical().decode('utf-8')) logging.info(f"Processing single event {event['SUMMARY'].to_ical().decode('utf-8')}")
dtstart = parse(event['DTSTART'].to_ical()) dtstart = parse(event["DTSTART"].to_ical())
if dtstart >= start and dtstart < end: if dtstart >= start and dtstart < end:
return vevent_to_event(event) return vevent_to_event(event)
else:
return None
def parse_recurring_event(event, start, end): def parse_recurring_event(event, start, end):
logging.info("Processing recurring event %s" % event['SUMMARY'].to_ical().decode('utf-8')) logging.info(f"Processing recurring event {event['SUMMARY'].to_ical().decode('utf-8')}")
dtstart = parse(event['DTSTART'].to_ical()) dtstart = parse(event["DTSTART"].to_ical())
rs = rruleset() rs = rruleset()
rs.rrule(rrulestr(event['RRULE'].to_ical().decode('utf-8'), dtstart=dtstart)) rs.rrule(rrulestr(event["RRULE"].to_ical().decode("utf-8"), dtstart=dtstart))
if 'EXDATE' in event.keys(): if "EXDATE" in event.keys():
exdates = event['EXDATE'] for exdate in event["EXDATE"]:
for exdate in exdates: rs.exdate(parse(exdate.to_ical()))
rs.exdate(parse(exdate.to_ical()))
dates = list(rs) events = []
events = [] for date in list(rs):
for date in dates: if date >= start and date < end:
if date >= start and date < end: events.append(vevent_to_event(event, date))
events.append(vevent_to_event(event, date))
return events return events
def find_events(icsfilestr, start, end, num): def find_events(icsfilestr, start, end, num):
with open(icsfilestr, 'r') as icsfile: with open(icsfilestr, "r") as icsfile:
cal=icalendar.Calendar.from_ical(icsfile.read()) cal = icalendar.Calendar.from_ical(icsfile.read())
events=[] events = []
for event in cal.subcomponents: for event in cal.subcomponents:
if event.name == 'VEVENT': if event.name == "VEVENT":
if 'RRULE' in event.keys(): if "RRULE" in event.keys():
events = events + parse_recurring_event(event, start, end) events.append(parse_recurring_event(event, start, end))
else: elif ev := parse_single_event(event, start, end) != None:
ev = parse_single_event(event, start, end) events.append(ev)
if ev != None:
events.append(ev)
events = sorted(events, key=lambda k: k['begin']) events = sorted(events, key=lambda k: k["begin"])
events = events[0:num] events = events[0:num]
return events
return events
def format_events(events): def format_events(events):
print('<table class="table table-condensed">') print("<table class=\"table table-condensed\">")
for event in events: for event in events:
dateStr = event['begin'].strftime("%A, %d.%m um %H:%M Uhr") print(
#print("<li><a href=\"%s\">%s: %s</a></li>" % (event['url'].decode('utf-8'), dateStr, event['name'].decode('utf-8'))) "<tr>"
print("<tr><td>%s</td><td><a href=\"%s\">%s</a></td></tr>" f"<td>{event['begin'].strftime('%A, %d.%m um %H:%M Uhr')}</td>"
% (dateStr, event['url'].decode('utf-8'), event['name'].decode('utf-8'))) f"<td><a href=\"{event['url'].decode('utf-8')}\">{event['name'].decode('utf-8')}</a></td>"
print('</table>') "</tr>"
)
print("</table><!--/.table /.table-condensed-->")
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 3: if len(sys.argv) < 3:
print("Usage: %s calendar max_days max_items" % sys.argv[0]) print(f"Usage: {sys.argv[0]} calendar max_days max_items")
sys.exit(-1) sys.exit(-1)
locale.setlocale(locale.LC_TIME, "de_DE.UTF-8") locale.setlocale(locale.LC_TIME, "de_DE.UTF-8")
calendar=sys.argv[1] calendar = sys.argv[1]
max_days=int(sys.argv[2]) max_days = int(sys.argv[2])
max_items=int(sys.argv[3]) max_items = int(sys.argv[3])
events=find_events(calendar, datetime.now(), datetime.now() + timedelta(days=max_days), max_items) now = datetime.now()
format_events(events) events = find_events(calendar, now, now + timedelta(days=max_days), max_items)
format_events(events)

View file

@ -6,22 +6,22 @@ import pytz
import icalendar import icalendar
cals = [] calendars = []
merged = icalendar.Calendar() merged = icalendar.Calendar()
merged.add('prodid', '-//CCCB Calendar Generator//berlin.ccc.de//') merged.add("prodid", "-//CCCB Calendar Generator//berlin.ccc.de//")
merged.add('version', '2.0') merged.add("version", "2.0")
for icsfilestr in glob('public/*/**/*.ics', recursive=True): for icsfilestr in glob("public/*/**/*.ics", recursive=True):
with open(icsfilestr, 'r') as icsfile: with open(icsfilestr, "r") as icsfile:
print('Importing', icsfilestr) print(f"Importing {icsfilestr}")
cals.append(icalendar.Calendar.from_ical(icsfile.read())) calendars.append(icalendar.Calendar.from_ical(icsfile.read()))
for cal in cals: for calendar in calendars:
for e in cal.subcomponents: for event in calendar.subcomponents:
merged.add_component(e) merged.add_component(event)
outfile = 'static/all.ics' outfile = "static/all.ics"
with open(outfile, 'wb') as f: with open(outfile, "wb") as f:
print(f'writing to {outfile}...') print(f"writing to {outfile}...")
f.write(merged.to_ical()) f.write(merged.to_ical())