From 737b2ffe693cc54568c00f2714ae909ad2637953 Mon Sep 17 00:00:00 2001 From: cellarspoon Date: Wed, 15 Dec 2021 11:29:58 +0100 Subject: [PATCH] pull scripts out for now --- beta.lumbung.space/.drone.yml | 23 + beta.lumbung.space/.gitignore | 3 + beta.lumbung.space/Dockerfile | 11 + beta.lumbung.space/README.md | 7 + beta.lumbung.space/archetypes/default.md | 5 + beta.lumbung.space/compose.yml | 30 + beta.lumbung.space/config.toml | 4 + beta.lumbung.space/makefile | 6 + .../themes/lumbung-theme/README.md | 18 + .../lumbung-theme/archetypes/default.md | 2 + .../themes/lumbung-theme/layouts/404.html | 0 .../_default/_markdown/render-image.html | 2 + .../layouts/_default/baseof.html | 30 + .../lumbung-theme/layouts/_default/list.html | 32 ++ .../layouts/_default/single.html | 16 + .../themes/lumbung-theme/layouts/index.html | 33 ++ .../layouts/partials/calendar_card.html | 30 + .../layouts/partials/calendar_list.html | 24 + .../lumbung-theme/layouts/partials/card.html | 34 ++ .../layouts/partials/footer.html | 5 + .../lumbung-theme/layouts/partials/head.html | 25 + .../layouts/partials/header.html | 12 + .../layouts/partials/network_card.html | 33 ++ .../lumbung-theme/layouts/partials/test.html | 35 ++ .../layouts/partials/video_box.html | 37 ++ .../themes/lumbung-theme/static/css/main.css | 535 ++++++++++++++++++ .../lumbung-theme/static/css/video-box.css | 155 +++++ .../themes/lumbung-theme/theme.toml | 21 + lumbung-calendar-prototype/.gitignore | 2 - lumbung-calendar-prototype/README.md | 9 - lumbung-calendar-prototype/event_feed.py | 194 ------- lumbung-calendar-prototype/event_template.md | 21 - lumbung-calendar-prototype/requirements.txt | 16 - lumbung-feed-aggregator/.gitignore | 2 - lumbung-feed-aggregator/README.md | 11 - lumbung-feed-aggregator/feeds_list.txt | 11 - lumbung-feed-aggregator/post_template.md | 13 - lumbung-feed-aggregator/rss_aggregator.py | 248 -------- lumbung-hashtag-bot/.gitignore | 3 - lumbung-hashtag-bot/README.md | 30 - lumbung-hashtag-bot/post_template.md | 14 - lumbung-hashtag-bot/publish_hashtags.py | 137 ----- lumbung-video-prototype/README.md | 27 - lumbung-video-prototype/index_template.md | 15 - lumbung-video-prototype/requirements.txt | 12 - lumbung-video-prototype/video-feed.html | 251 -------- lumbung-video-prototype/video-feed.py | 131 ----- 47 files changed, 1168 insertions(+), 1147 deletions(-) create mode 100644 beta.lumbung.space/.drone.yml create mode 100644 beta.lumbung.space/.gitignore create mode 100644 beta.lumbung.space/Dockerfile create mode 100644 beta.lumbung.space/README.md create mode 100644 beta.lumbung.space/archetypes/default.md create mode 100644 beta.lumbung.space/compose.yml create mode 100644 beta.lumbung.space/config.toml create mode 100644 beta.lumbung.space/makefile create mode 100644 beta.lumbung.space/themes/lumbung-theme/README.md create mode 100644 beta.lumbung.space/themes/lumbung-theme/archetypes/default.md create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/404.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/_default/_markdown/render-image.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/_default/baseof.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/_default/list.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/_default/single.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/index.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_card.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_list.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/card.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/footer.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/head.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/header.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/network_card.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/test.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/layouts/partials/video_box.html create mode 100644 beta.lumbung.space/themes/lumbung-theme/static/css/main.css create mode 100644 beta.lumbung.space/themes/lumbung-theme/static/css/video-box.css create mode 100644 beta.lumbung.space/themes/lumbung-theme/theme.toml delete mode 100644 lumbung-calendar-prototype/.gitignore delete mode 100644 lumbung-calendar-prototype/README.md delete mode 100644 lumbung-calendar-prototype/event_feed.py delete mode 100644 lumbung-calendar-prototype/event_template.md delete mode 100644 lumbung-calendar-prototype/requirements.txt delete mode 100644 lumbung-feed-aggregator/.gitignore delete mode 100644 lumbung-feed-aggregator/README.md delete mode 100644 lumbung-feed-aggregator/feeds_list.txt delete mode 100644 lumbung-feed-aggregator/post_template.md delete mode 100644 lumbung-feed-aggregator/rss_aggregator.py delete mode 100644 lumbung-hashtag-bot/.gitignore delete mode 100644 lumbung-hashtag-bot/README.md delete mode 100644 lumbung-hashtag-bot/post_template.md delete mode 100644 lumbung-hashtag-bot/publish_hashtags.py delete mode 100644 lumbung-video-prototype/README.md delete mode 100644 lumbung-video-prototype/index_template.md delete mode 100644 lumbung-video-prototype/requirements.txt delete mode 100644 lumbung-video-prototype/video-feed.html delete mode 100644 lumbung-video-prototype/video-feed.py diff --git a/beta.lumbung.space/.drone.yml b/beta.lumbung.space/.drone.yml new file mode 100644 index 0000000..3c5f7f0 --- /dev/null +++ b/beta.lumbung.space/.drone.yml @@ -0,0 +1,23 @@ +--- +kind: pipeline +name: deploy beta.lumbung.space +steps: + - name: bundle static + image: plugins/docker + settings: + username: decentral1se + password: + from_secret: docker_reg_passwd + repo: decentral1se/beta.lumbung.space + tags: latest + + - name: deployment + image: decentral1se/stack-ssh-deploy:latest + settings: + stack: beta_lumbung_space + host: lumbung.space + deploy_key: + from_secret: drone_ssh_lumbung.space +trigger: + branch: + - main diff --git a/beta.lumbung.space/.gitignore b/beta.lumbung.space/.gitignore new file mode 100644 index 0000000..fac5512 --- /dev/null +++ b/beta.lumbung.space/.gitignore @@ -0,0 +1,3 @@ +.env +/public/ +/content/ diff --git a/beta.lumbung.space/Dockerfile b/beta.lumbung.space/Dockerfile new file mode 100644 index 0000000..898ced1 --- /dev/null +++ b/beta.lumbung.space/Dockerfile @@ -0,0 +1,11 @@ +FROM klakegg/hugo:alpine + +RUN apk add --no-cache curl git + +EXPOSE 1313 + +COPY . /src/ + +ENTRYPOINT ["/bin/bash"] + +CMD ["-c", "hugo server --appendPort='false' --bind 0.0.0.0 --baseUrl='https://beta.lumbung.space' --port='1313' -F"] diff --git a/beta.lumbung.space/README.md b/beta.lumbung.space/README.md new file mode 100644 index 0000000..850fcb5 --- /dev/null +++ b/beta.lumbung.space/README.md @@ -0,0 +1,7 @@ +# beta.lumbung.space + +[![Build Status](https://drone.autonomic.zone/api/badges/ruangrupa/beta.lumbung.space/status.svg?ref=refs/heads/main)](https://drone.autonomic.zone/ruangrupa/beta.lumbung.space) + +Public front-end for [lumbung.space](https://lumbung.space). + +The theme comes from [git.vvvvvvaria.org/rra/lumbung-theme](https://git.vvvvvvaria.org/rra/lumbung-theme). diff --git a/beta.lumbung.space/archetypes/default.md b/beta.lumbung.space/archetypes/default.md new file mode 100644 index 0000000..26f317f --- /dev/null +++ b/beta.lumbung.space/archetypes/default.md @@ -0,0 +1,5 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +--- diff --git a/beta.lumbung.space/compose.yml b/beta.lumbung.space/compose.yml new file mode 100644 index 0000000..c850efb --- /dev/null +++ b/beta.lumbung.space/compose.yml @@ -0,0 +1,30 @@ +--- +version: "3.8" +services: + app: + image: decentral1se/beta.lumbung.space:latest + networks: + - proxy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:1313"] + interval: 10s + timeout: 10s + retries: 10 + start_period: 15s + volumes: + - content:/src/content + deploy: + update_config: + failure_action: rollback + order: start-first + labels: + - "traefik.enable=true" + - "traefik.http.routers.coop-cloud-site.rule=Host(`beta.lumbung.space`)" + - "traefik.http.routers.coop-cloud-site.entrypoints=web-secure" + - "traefik.http.services.coop-cloud-site.loadbalancer.server.port=1313" + - "traefik.http.routers.coop-cloud-site.tls.certresolver=production" +volumes: + content: +networks: + proxy: + external: true diff --git a/beta.lumbung.space/config.toml b/beta.lumbung.space/config.toml new file mode 100644 index 0000000..bc2e1fe --- /dev/null +++ b/beta.lumbung.space/config.toml @@ -0,0 +1,4 @@ +baseURL = "https://beta.lumbung.space" +languageCode = "en-gb" +title = "beta.lumbung.space" +theme = "lumbung-theme" diff --git a/beta.lumbung.space/makefile b/beta.lumbung.space/makefile new file mode 100644 index 0000000..184625a --- /dev/null +++ b/beta.lumbung.space/makefile @@ -0,0 +1,6 @@ +DEFAULT: serve + +serve: + @hugo serve + +.PHONY: serve diff --git a/beta.lumbung.space/themes/lumbung-theme/README.md b/beta.lumbung.space/themes/lumbung-theme/README.md new file mode 100644 index 0000000..9ec81b9 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/README.md @@ -0,0 +1,18 @@ +# lumbung-theme + +A Hugo theme for lumbung.space + +### Installation + +`cd /my/hugosite/themes` +`git clone https://git.vvvvvvaria.org/rra/lumbung-theme` + +edit `/my/hugosite/config.toml`: + +``` +cat config.toml +baseURL = "http://localhost/" +languageCode = "en-us" +title = "lumbung.space" +theme = 'lumbung-theme' +``` diff --git a/beta.lumbung.space/themes/lumbung-theme/archetypes/default.md b/beta.lumbung.space/themes/lumbung-theme/archetypes/default.md new file mode 100644 index 0000000..ac36e06 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/archetypes/default.md @@ -0,0 +1,2 @@ ++++ ++++ diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/404.html b/beta.lumbung.space/themes/lumbung-theme/layouts/404.html new file mode 100644 index 0000000..e69de29 diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/_default/_markdown/render-image.html b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/_markdown/render-image.html new file mode 100644 index 0000000..7d332b9 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/_markdown/render-image.html @@ -0,0 +1,2 @@ +{{- $image := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL)) -}} +{{- .PlainText | htmlUnescape -}} diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/_default/baseof.html b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/baseof.html new file mode 100644 index 0000000..13acd96 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/baseof.html @@ -0,0 +1,30 @@ + + + {{- partial "head.html" . -}} + + {{- partial "header.html" . -}} +
+ {{- block "main" . }}{{- end }} +
+ {{- partial "footer.html" . -}} + + + + + diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/_default/list.html b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/list.html new file mode 100644 index 0000000..ba88fdd --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/list.html @@ -0,0 +1,32 @@ +{{ define "main" }} +
+
+ {{ range (.Paginator 13).Pages }} + + {{ if in .Params.categories "tv"}} + + {{- partial "video_box.html" . -}} + + {{ else if in .Params.categories "calendar" }} + + {{- partial "calendar_card.html" . -}} + + {{ else if in .Params.categories "network" }} + + {{- partial "network_card.html" . -}} + + {{ else }} + + {{- partial "card.html" . -}} + + {{ end }} + + {{ end }} +
+ + + + +{{ end }} diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/_default/single.html b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/single.html new file mode 100644 index 0000000..25f08f3 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/_default/single.html @@ -0,0 +1,16 @@ +{{ define "main" }} +
+ +
+{{ end }} diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/index.html b/beta.lumbung.space/themes/lumbung-theme/layouts/index.html new file mode 100644 index 0000000..546e4b7 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/index.html @@ -0,0 +1,33 @@ +{{ define "main" }} +
+
+ {{ range (.Paginator 13).Pages }} + + {{ if in .Params.categories "tv"}} + + {{- partial "video_box.html" . -}} + + {{ else if in .Params.categories "calendar" }} + + {{- partial "calendar_card.html" . -}} + + {{ else if in .Params.categories "network" }} + + {{- partial "network_card.html" . -}} + + {{ else }} + + {{- partial "card.html" . -}} + + {{ end }} + + {{ end }} +
+ + + + +{{ end }} + diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_card.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_card.html new file mode 100644 index 0000000..6c65f76 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_card.html @@ -0,0 +1,30 @@ +{{ $t := (time .Params.event_end) }} +
+
+
+

{{ .Title }}

+
+ {{ range first 1 (.Resources.ByType "image") }} + + {{ end }} +
+ + {{ .Params.localized_begin | markdownify }} + +
+ + + + +
+
+ \ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_list.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_list.html new file mode 100644 index 0000000..60bc5ca --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/calendar_list.html @@ -0,0 +1,24 @@ +
+
+
+

{{ .Title }}

+
+
+ + {{ .Params.localized_begin | markdownify }} + +
+ + + + +
+
\ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/card.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/card.html new file mode 100644 index 0000000..9154a32 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/card.html @@ -0,0 +1,34 @@ +
+
+
+

{{ .Title }}

+ +
+ + {{ $img := (.Resources.ByType "image").GetMatch "*featured*" }} + +
+
+ {{ .Summary }} +
+ {{ with $img }} + {{ $thumb := .Resize "400x300"}} +
+ {{ .Title }} +
+ {{ end }} +
+ {{ if .Truncated }} + + {{ end }} + +
+
\ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/footer.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/footer.html new file mode 100644 index 0000000..e033aca --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/footer.html @@ -0,0 +1,5 @@ +
+
+ Imprint - Privacy Policy - Copyright +
+
\ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/head.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/head.html new file mode 100644 index 0000000..3180365 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/head.html @@ -0,0 +1,25 @@ + + + + + {{ if .IsHome }} {{ .Site.Title }} {{ else }} {{ .Title }} | {{ .Site.Title }} {{ end }} + + {{- if or .Description .Site.Params.description }} + + {{- end }} + {{- if or .Description .Site.Params.description }} + + {{- end }} + + + + + + {{ with .Site.Params.favicon }} + + {{ end }} + + {{ with .OutputFormats.Get "rss" -}} + {{ printf `` .Rel .MediaType.Type .Permalink $.Site.Title | safeHTML }} + {{ end -}} + diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/header.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/header.html new file mode 100644 index 0000000..65d7386 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/header.html @@ -0,0 +1,12 @@ +
+

{{ .Site.Title }}

+ +
\ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/network_card.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/network_card.html new file mode 100644 index 0000000..bc21bb3 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/network_card.html @@ -0,0 +1,33 @@ +
+
+
+

{{ .Title }}

+ +
+ +
From {{ if .Params.author }}{{.Params.author}} at {{ end }}{{ .Params.feed_name }}
+ +
+ {{ with (index (.Resources.ByType "image") 0) }} + {{ $thumb := .Fit "540x360"}} +
+ {{ .Title }} +
+ {{ end }} +
+ {{ .Summary }} +
+ +
+ {{ if .Truncated }} + + {{ end }} + +
+
\ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/test.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/test.html new file mode 100644 index 0000000..83bb54f --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/test.html @@ -0,0 +1,35 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/layouts/partials/video_box.html b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/video_box.html new file mode 100644 index 0000000..711800e --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/layouts/partials/video_box.html @@ -0,0 +1,37 @@ +
+
+ + + + {{ if .Params.is_live}} +
LIVE
+ {{ else }} +
{{.Params.video_duration}}
+ {{ end }} + +
+
+
+
+
+ +
+ diff --git a/beta.lumbung.space/themes/lumbung-theme/static/css/main.css b/beta.lumbung.space/themes/lumbung-theme/static/css/main.css new file mode 100644 index 0000000..a34a31f --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/static/css/main.css @@ -0,0 +1,535 @@ +/*nice body-border color combos + +antiquewhite - burlywood +peachpuff - tomato +lightpink - crimson +lightblue - cornflowerblue +palegreen - lightseagreen + +fonts +bungeeshade +allerta +*/ + +:root { + --border-color: tomato; +} + +/*Main Stuff*/ +body { + font-size:16px; + font-family: sans-serif; + color: maroon; +} + + a { + color: #1B4C8A; + } + +* { + box-sizing: border-box; +} + +#content { + margin: 2em auto; + max-width: 80%; + margin-bottom: 0; + } + +.card{ + + border: 2px solid var(--border-color); + box-shadow:1em 1em 0 #d2d1c8; + background-color: #fff09d; + max-width: 600px; + margin-bottom: 2em; + flex: auto; + margin: 0 3em 3em 0; + align-self: start; + + } + + .card{ + background-color: peachpuff; + } + + .side-bar { + border: 2px solid var(--border-color); + max-width: 400px; + } + + + .card:nth-child(even){ + transform: rotate(-1deg); + } + + .card:nth-child(odd){ + transform: rotate(1deg); + } + + .card:nth-child(5){ + transform: rotate(2deg); + } + + + .video.box{ + margin-top:3em; + } + + .bar{ + border: 2px solid var(--border-color); + box-shadow: 0.6em 0.6em 0 #d2d1c8; + margin-bottom: 2em; + margin-top:3em; + display: inline-block; + background-color: #fff09d; + } + +.h-feed{ + display: flex; + flex-flow: row wrap; + width: 100%; + +} + +.entries{ + padding-top: 5%; +} + + +/* base header & menu */ + +#top-menu{ + position: fixed; + left: 50%; + transform: translate(-50%); + width: 90%; + z-index: 1; + margin-top: 1em; + display: none; +} + +.logo { + margin-left: 0.5em; + margin-right: 0.5em; + margin-top: 0.2em; + margin-bottom: 0.2em; +} + +.logo a { + text-decoration: none; +} + +.menu { + border-top: 2px solid var(--border-color); + margin: 0px; + padding: 0px; + +} + +.menu ul{ + list-style-type: none; + margin: 0; + padding: 0; + display: flex; +} + +.menu-nav-item { + border-right: 2px solid var(--border-color); + padding: 0.5em; +} + +/*Article Summary Cards*/ + +.h-entry header { + display: flex; + border-bottom: 2px solid var(--border-color); + justify-content: space-between; +} + +.h-entry header h2{ + padding: 0.2em; + margin: 0; + padding-right: 0.3em; + padding-left: 0.3em; + border-left: 2px solid var(--border-color); + flex-grow: 1; +} + +.h-entry header h2:hover{ + box-shadow: inset 4px 4px 0px tomato; + cursor: pointer; +} + +.h-entry header h2 a { + text-decoration: none; + color: var(--border-color); +} + + +.h-entry header .header-metadata{ + margin: 0; + display: flex; + flex-flow: column wrap; + font-size: 0.8rem; +} + +.header-metadata .dt-published{ + padding: 0.5em 1.2em 0.5em 1.2em; +} + +.author.p-author { + border-top: 2px solid var(--border-color); + padding: 0.5em 1.2em 0.5em 1.2em; +} + + +.p-summary.truncated.image { + display: flex; + flex-direction: row-reverse; +} + +.p-summary.truncated { + display: flex; + flex-direction: column; +} + +.summary-text { + flex: 1; + padding: 1em; + max-height: 300px; + min-width: 20ch; + text-overflow: ellipsis; + overflow: hidden; +} + +.summary-image > img { + height: 100%; + object-fit: cover; + max-width: 100%; + +} + +.summary-image{ + border-right: 2px solid var(--border-color); +} + +footer.post-footer { + display: flex; + flex-flow: row-reverse; +} + +.footer-filler{ + border-top: 2px solid var(--border-color); + flex-grow: 1; +} +.read-more { + border-top: 2px solid var(--border-color); + border-left: 2px solid var(--border-color); + align-content: flex-end; + padding: 0.2em 1em 0.2em 1em; + font-size: 0.9rem; +} + +/* network cards */ + +.card.network{ + + border: 2px solid darkcyan; + box-shadow:1em 1em 0 #d2d1c8; + background-color: lightgreen; + max-width: 540px; + margin-bottom: 2em; + flex: auto; + margin: 0 3em 3em 0; + align-self: start; + color: darkcyan; + } + +.h-entry.network header { + display: flex; + border-bottom: 2px solid darkcyan; + flex-direction: row-reverse; +} + +.h-entry.network header h2{ + padding: 0.2em 0.5em 0.2em 0.5em; + margin: 0; + border-color: darkcyan; +} + +.h-entry.network header h2:hover{ + box-shadow: inset 4px 4px 0px darkcyan; + cursor: pointer; +} + +.h-entry.network header h2 a { + text-decoration: none; + color: darkcyan; +} + +.network .header-metadata { + align-items: center; +} + +.network .header-metadata .dt-published{ + padding-left: 1.2em; + min-width: 16ch; + border-bottom: 2px solid darkcyan; +} + +.network .filler { + min-height: 1rem; +} + +.network .author.p-author { + border-color: darkcyan; + padding: 0.5em 1.2em 0.5em 1.2em; +} + +.network footer.post-footer{ + border-top: 2px solid darkcyan; +} + +.network .summary-image { + border-bottom: 2px solid darkcyan; + border-right: none; +} + +.network .summary-image > img { + display: inherit; +} +.network .summary-text { + font-size: 14px; +} + +div.network-source{ + padding: 0.5em 1.2em 0.5em 1.2em; + border-bottom: 2px solid darkcyan; + font-size: 14px; + display: flex; + justify-content: space-between; +} + +.network-source a { + font-weight: bold; + color: darkcyan; +} + +.network .footer-filler{ + border: none; +} +.network .read-more { + border: none; + border-left: 2px solid darkcyan; +} + + +/* calendar cards */ + +.card.calendar { + border: 2px solid cornflowerblue; + box-shadow:1em 1em 0 #d2d1c8; + background-color: lightblue; + max-width: 360px; + margin-bottom: 2em; + flex: auto; + margin: 0 3em 3em 0; + align-self: start; + color: royalblue; + +} + +.card.calendar.past { + opacity: 0.3; +} + +.card.calendar.past:hover { + opacity: 1; +} + +.h-event.calendar header { + display: flex; + border-bottom: 2px solid cornflowerblue; +} + +.h-event.calendar header h2{ + padding: 0.2em 0.5em 0.2em 0.5em; + margin: 0; + border-right: none; +} + +.h-event.calendar header h2:hover{ + box-shadow: inset 4px 4px 0px royalblue; + cursor: pointer; +} + +.h-event.calendar header h2 a { + text-decoration: none; + color: royalblue; +} + +.header-filler { + min-width: 10%; +} + +.calendar-location{ + font-size: 0.8rem; + min-width: 20%; + padding: 0.5em 0.9em 0.5em 0.9em; + border-left: 2px solid cornflowerblue; +} + +.calendar-duration{ + font-size: 0.8rem; + border-right: 2px solid cornflowerblue; + padding: 0.5em 0.9em 0.5em 0.9em; +} + +.start-scroller { + display: flex; + flex-flow: row-reverse; + border-bottom: 2px solid cornflowerblue; +} +.start-scroller marquee{ + font-size: 0.8rem; + padding-top: 0.2em; + padding-bottom: 0.2em; +} + +.calendar .description { + border-top: 2px solid cornflowerblue; +} + +.calendar-image-holder{ + border-bottom: 2px solid cornflowerblue; +} + +.calendar-image-holder a { + display: inherit; +} + +.calendar-image{ + max-width: 100%; + display: inherit; +} + +/* Card metadata (video & calendar) */ + +.metadata { + display: flex; + justify-content: space-between; + flex-wrap: wrap; +} + +.description p:first-of-type { + margin:0; +} + +.description ul:first-of-type { + margin:0; +} + +input + label +.calendar-location+.description{ + display: none; + } + +input:checked + label +.calendar-location+.description { + display: block; + transition: ease .5s; + } + +.metadata label { + text-align: center; + vertical-align: sub; + flex-grow: 1; + font-weight: normal; + cursor: pointer; + padding: 0.4em 0.9em 0.4em 0.9em; + font-size: 0.9em; +} + +label:hover { + box-shadow: inset 2px 2px 0px #95948c; +} + +.description{ + padding: 0.5em 0.7em 0.7em 0.5em; + overflow: hidden; + flex-basis: 100%; +} + +.descr_button { + cursor: pointer; + flex-grow: 1; + text-align: center; +} + +/* Paginator */ + +nav.pagination{ + width: 60%; + margin: auto; + margin-top: 2em; + margin-bottom: 2em; +} + +ul.pagination{ + display: flex; + justify-content: space-evenly; /* align horizontal */ + align-items: center; /* align vertical */ +} + +.page-item{ + display: block; + text-align: center; + vertical-align: middle; + font-size: 38px; + border: 2px solid #1B4C8A; + box-shadow:0.4em 0.4em 0 #d2d1c8; + +} + +li.page-item{ + background-color: lightblue; + padding: 0.4em; +} + +li.page-item.active{ + background-color: peachpuff; + border: 2px solid tomato; + padding: 0.4em; +} + +li.page-item.disabled{ + display: none; +} + + li.page-item:nth-child(even){ + transform: rotate(-1deg); + } + + li.page-item:nth-child(odd){ + transform: rotate(1deg); + } + + li.page-item:nth-child(5){ + transform: rotate(2deg); + } + + li.page-item:nth-child(8){ + transform: rotate(-3deg); + } + + + +/* Page footer */ + +footer.bar { + margin-top: 0; + width: 80%; + margin-left: auto; + display: block; + margin-right: auto; + margin-bottom: 2em; +} \ No newline at end of file diff --git a/beta.lumbung.space/themes/lumbung-theme/static/css/video-box.css b/beta.lumbung.space/themes/lumbung-theme/static/css/video-box.css new file mode 100644 index 0000000..051cd70 --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/static/css/video-box.css @@ -0,0 +1,155 @@ +:root { + --video-border-color: burlywood; + --video-background-color: antiquewhite; +} + .video-box { + border:2px solid var(--video-border-color); + max-width:560px; + margin:auto; + box-shadow:1em 1em 0 #d2d1c8; + margin-bottom: 2em; + color: chocolate; + } + + .video-box:nth-child(even){ + transform: rotate(-1deg); + } + + .video-box:nth-child(odd){ + transform: rotate(1deg); + } + + .video-box:nth-child(5){ + transform: rotate(3deg); + } + + + .video-box img { + max-width: 100%; + } + + .video-box iframe { + max-width: 100%; +} + + .video-box .media { + line-height: 0; + } + + .video { + background-color: var(--video-background-color); + } + + .video .metadata{ + font-size:0.9rem; + justify-content: space-between; + flex-wrap: wrap; + } + + .metadata .title{ + margin-top:0; + border-top: 2px solid var(--video-border-color); + border-bottom: 2px solid var(--video-border-color); + padding:0.5em; + font-weight:700; + font-size:1.3rem; + flex-basis: 100%; + } + + .video.channel{ + border-right: 2px solid var(--video-border-color); + padding: 0.5em 0.9em 0.5em 0.9em; + font-size: 0.8rem; + } + + .video.date { + float:right; + border-left: 2px solid var(--video-border-color); + padding: 0.5em 0.9em 0.5em 0.9em; + font-size: 0.8rem; + } + + .video.description { + border-top: 2px solid var(--video-border-color); + padding: 0.8em 0.8em 0.8em 0.8em; + + } + .descr_button a { + color:inherit; + text-decoration: inherit; + } + + input.descr_button { + display: none; + } + + input + label + .video.date + .description{ + display: none; + } + + input:checked + label + .video.date +.description { + display: block; + } + + .play-icon { + width: 0; + height: 0; + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%,-50%) scale(.5); + border-top: 13px solid transparent; + border-bottom: 13px solid transparent; + border-left: 18px solid hsla(0,0%,100%,.95); + } + + .video-thumbnail { + position: absolute; + width: 100%; + height: 100%; + top: 0; + } + .video-thumbnail { + display: flex; + flex-direction: column; + position: relative; + overflow: hidden; + background-color: #ececec; + transition: filter .2s ease; + } + +.video-thumbnail-duration-overlay { + display: inline-block; + background-color: var(--video-background-color); + color: chocolate; + font-size: 14px; + line-height: 1.1; + z-index: 10; + position: absolute; + padding: 1px 3px 1px 3px; + right: 5px; + bottom: 5px; + border: 2px solid var(--video-border-color); + } + + .play-overlay { + transition: all .2s ease; + position: absolute; + right: 0; + bottom: 0; + width: inherit; + height: inherit; + opacity: 0; + background-color: rgba(0,0,0,.3); + cursor: pointer; + } + +.video-thumbnail:hover { + text-decoration:none!important +} +.video-thumbnail:hover .play-overlay { +opacity:1 +} +.video-thumbnail:hover .play-overlay .play-icon { +transform:translate(-50%,-50%) scale(1) +} diff --git a/beta.lumbung.space/themes/lumbung-theme/theme.toml b/beta.lumbung.space/themes/lumbung-theme/theme.toml new file mode 100644 index 0000000..72ac31f --- /dev/null +++ b/beta.lumbung.space/themes/lumbung-theme/theme.toml @@ -0,0 +1,21 @@ +# theme.toml template for a Hugo theme +# See https://github.com/gohugoio/hugoThemes#themetoml for an example + +name = "Lumbung" +license = "AGPL3" +licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE" +description = "" +homepage = "http://example.com/" +tags = [] +features = [] +min_version = "0.41.0" + +[author] + name = "" + homepage = "" + +# If porting an existing theme +[original] + name = "" + homepage = "" + repo = "" diff --git a/lumbung-calendar-prototype/.gitignore b/lumbung-calendar-prototype/.gitignore deleted file mode 100644 index 54d69e5..0000000 --- a/lumbung-calendar-prototype/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -event_feed_config.py -__pycache__ diff --git a/lumbung-calendar-prototype/README.md b/lumbung-calendar-prototype/README.md deleted file mode 100644 index 62fe8ff..0000000 --- a/lumbung-calendar-prototype/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Calendar Feed -Generate HUGO posts based on a publicly accessible ICS calendar. - -## Use -Fill in your details in `calendar_feed_config.py` - -## TODO / FIXME - - * Multiple calendars to multiple hugo categories diff --git a/lumbung-calendar-prototype/event_feed.py b/lumbung-calendar-prototype/event_feed.py deleted file mode 100644 index d11fb1c..0000000 --- a/lumbung-calendar-prototype/event_feed.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/python3 - -#lumbung.space calendar feed generator -#© 2021 roel roscam abbing gplv3 etc - -from ics import Calendar -import requests -import jinja2 -import os -import shutil -from slugify import slugify -from natural import date -from event_feed_config import calendar_url, output_dir -from urllib.parse import urlparse -import arrow -import re - -cal = Calendar(requests.get(calendar_url).text) - -env = jinja2.Environment( - loader=jinja2.FileSystemLoader(os.path.curdir) - ) - -if not os.path.exists(output_dir): - os.mkdir(output_dir) - -template = env.get_template('event_template.md') - -existing_posts = os.listdir(output_dir) - -def findURLs(string): - """ - return all URLs in a given string - """ - regex = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))" - url = re.findall(regex,string) - return [x[0] for x in url] - -def find_imageURLS(string): - """ - return all image URLS in a given string - """ - regex = r"(?:http\:|https\:)?\/\/.*?\.(?:png|jpg|jpeg|gif|svg)" - - img_urls = re.findall(regex, string, flags=re.IGNORECASE) - return img_urls - -def create_metadata(event): - """ - construct a formatted dict of event metadata for use as frontmatter for HUGO post - """ - - if event.location: - location_urls = findURLs(event.location) - - if location_urls: - location_url = location_urls[0] - event.location = '[{}]({})'.format(urlparse(location_url).netloc, location_url) - - - event_metadata = { - 'name':event.name, - 'created':event.created.format(), - 'description': event.description, - 'localized_begin': '           '.join(localize_time(event.begin)), #non-breaking space characters to defeat markdown - 'begin': event.begin.format(), - 'end': event.end.format(), - 'duration': date.compress(event.duration), - 'location': event.location, - 'uid': event.uid, - 'images' : find_imageURLS(event.description) # currently not used in template - } - - return event_metadata - -def localize_time(date): - """ - Turn a given date into various timezones - Takes arrow objects - """ - - # 3 PM Kassel, Germany, 4 PM Ramallah/Jerusalem, Palestina (QoF), - # 8 AM Bogota, Colombia (MaMa), 8 PM Jakarta, Indonesia (Gudskul), - # 1 PM (+1day) Wellington, New Zealand (Fafswag), 9 AM Havana, Cuba (Instar). - - - tzs = [ - ('Kassel','Europe/Berlin'), - ('Bamako', 'Europe/London'), - ('Palestine','Asia/Jerusalem'), - ('Bogota','America/Bogota'), - ('Jakarta','Asia/Jakarta'), - ('Makassar','Asia/Makassar'), - ('Wellington', 'Pacific/Auckland') - ] - - localized_begins =[] - for location, tz in tzs: - localized_begins.append( #javascript formatting because of string creation from hell - '__{}__ {}'.format( - str(location), - str(date.to(tz).format("YYYY-MM-DD __HH:mm__")) - ) - ) - return localized_begins - -def create_event_post(post_dir, event): - """ - Create HUGO post based on calendar event metadata - Searches for image URLS in description and downloads them - Function is also called when post is in need of updating - In that case it will also delete images no longer in metadata - TODO: split this up into more functions for legibility - """ - - if not os.path.exists(post_dir): - os.mkdir(post_dir) - - event_metadata = create_metadata(event) - - #list already existing images - #so we can later delete them if we dont find them in the event metadata anymore - existing_images = os.listdir(post_dir) - try: - existing_images.remove('index.md') - existing_images.remove('.timestamp') - except: - pass - - for img in event_metadata['images']: - - #parse img url to safe local image name - img_name = img.split('/')[-1] - fn, ext = img_name.split('.') - img_name = slugify(fn) + '.' + ext - - local_image = os.path.join(post_dir, img_name) - - if not os.path.exists(local_image): - #download preview image - response = requests.get(img, stream=True) - with open(local_image, 'wb') as img_file: - shutil.copyfileobj(response.raw, img_file) - print('Downloaded image for event "{}"'.format(event.name)) - event_metadata['description'] = event_metadata['description'].replace(img, '![]({})'.format(img_name)) - if img_name in existing_images: - existing_images.remove(img_name) - - for left_over_image in existing_images: - #remove images we found, but which are no longer in remote event - os.remove(os.path.join(post_dir,left_over_image)) - print('deleted image', left_over_image) - - with open(os.path.join(post_dir,'index.md'),'w') as f: - post = template.render(event = event_metadata) - f.write(post) - print('created post for', event.name, '({})'.format(event.uid)) - - with open(os.path.join(post_dir,'.timestamp'),'w') as f: - f.write(event_metadata['created']) - - -def update_event_post(post_dir, event): - """ - Update a post based on the VCARD event 'created' field which changes when updated - """ - if os.path.exists(post_dir): - old_timestamp = open(os.path.join(post_dir,'.timestamp')).read() - if event.created > arrow.get(old_timestamp): - print('Updating', event.name, '({})'.format(event.uid)) - create_event_post(post_dir, event) - else: - print('Event current: ', event.name, '({})'.format(event.uid)) - -for event in list(cal.events): - - post_dir = os.path.join(output_dir, event.uid) - - if event.uid not in existing_posts: - #if there is an event we dont already have, make it - create_event_post(post_dir, event) - - elif event.uid in existing_posts: - #if we already have it, update - update_event_post(post_dir, event) - existing_posts.remove(event.uid) # create list of posts which have not been returned by the calendar - - -for post in existing_posts: - #remove events not returned by the calendar (deletion) - print('deleted', post) - shutil.rmtree(os.path.join(output_dir,post)) - - diff --git a/lumbung-calendar-prototype/event_template.md b/lumbung-calendar-prototype/event_template.md deleted file mode 100644 index 441f3da..0000000 --- a/lumbung-calendar-prototype/event_template.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: "{{ event.name }}" -date: "{{ event.begin }}" #2021-06-10T10:46:33+02:00 -draft: false -categories: "calendar" -event_begin: "{{ event.begin }}" -event_end: "{{ event.end }}" -duration: "{{ event.duration }}" -localized_begin: "{{ event.localized_begin }}" -uid: "{{ event.uid }}" -{% if event.location %} -location: "{{ event.location }}" -{% endif %} - - ---- -{% if event.description %} - -{{ event.description }} - -{% endif %} diff --git a/lumbung-calendar-prototype/requirements.txt b/lumbung-calendar-prototype/requirements.txt deleted file mode 100644 index 356637c..0000000 --- a/lumbung-calendar-prototype/requirements.txt +++ /dev/null @@ -1,16 +0,0 @@ -# Automatically generated by https://github.com/damnever/pigar. - -# calendar-feed/event_feed.py: 3 -Jinja2 == 2.10 - -# calendar-feed/event_feed.py: 1 -ics == 0.7 - -# calendar-feed/event_feed.py: 6 -natural == 0.2.0 - -# calendar-feed/event_feed.py: 5 -python_slugify == 5.0.2 - -# calendar-feed/event_feed.py: 2 -requests == 2.21.0 diff --git a/lumbung-feed-aggregator/.gitignore b/lumbung-feed-aggregator/.gitignore deleted file mode 100644 index ecf1da3..0000000 --- a/lumbung-feed-aggregator/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -network/ -etags/ diff --git a/lumbung-feed-aggregator/README.md b/lumbung-feed-aggregator/README.md deleted file mode 100644 index 97d32e9..0000000 --- a/lumbung-feed-aggregator/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# lumbung feed aggregator - -* Grab feeds listed in `feeds_list.txt` -* Parse feed for blogpost entries -* * Download images linked in blogposts -* Turn blogpost entries into HUGO posts - -# TODO/FIXME - -* only include posts with a certain tag - diff --git a/lumbung-feed-aggregator/feeds_list.txt b/lumbung-feed-aggregator/feeds_list.txt deleted file mode 100644 index 7334acb..0000000 --- a/lumbung-feed-aggregator/feeds_list.txt +++ /dev/null @@ -1,11 +0,0 @@ -https://www.masartemasaccion.org/feed/ -https://fafswag.wordpress.com/feed/ -https://wajukuuarts.wordpress.com/feed/ -https://inland.org/feed/ -https://jatiwangiartfactory.tumblr.com/rss/ -https://brittoartstrust.org/feed/ -https://artivismo.org/feed/ -http://www.festivalsegou.org/spip.php?page=backend&lang=fr -https://gudskul.art/feed/ -https://projectartworks.org/feed/ -https://ruangrupa.id/feed/ \ No newline at end of file diff --git a/lumbung-feed-aggregator/post_template.md b/lumbung-feed-aggregator/post_template.md deleted file mode 100644 index 9dbc449..0000000 --- a/lumbung-feed-aggregator/post_template.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: "{{ frontmatter.title }}" -date: "{{ frontmatter.date }}" #2021-06-10T10:46:33+02:00 -draft: false -summary: "{{ frontmatter.summary }}" -author: "{{ frontmatter.author }}" -original_link: "{{ frontmatter.original_link }}" -feed_name: "{{ frontmatter.feed_name}}" -categories: ["network", "{{ frontmatter.feed_name}}"] -tags: {{ frontmatter.tags }} ---- - -{{ content }} \ No newline at end of file diff --git a/lumbung-feed-aggregator/rss_aggregator.py b/lumbung-feed-aggregator/rss_aggregator.py deleted file mode 100644 index 0f65c93..0000000 --- a/lumbung-feed-aggregator/rss_aggregator.py +++ /dev/null @@ -1,248 +0,0 @@ -#!/bin/python3 - -#lumbung.space rss feed aggregator -#© 2021 roel roscam abbing gplv3 etc - -import requests -import jinja2 -import os -import shutil -import feedparser -from urllib.parse import urlparse -from ast import literal_eval as make_tuple -from slugify import slugify -from bs4 import BeautifulSoup -import time -import arrow - - -def write_etag(feed_name, feed_data): - """ - save timestamp of when feed was last modified - """ - etag = '' - modified = '' - - if 'etag' in feed_data: - etag = feed_data.etag - if 'modified' in feed_data: - modified = feed_data.modified - - if etag or modified: - with open(os.path.join('etags',feed_name +'.txt'),'w') as f: - f.write(str((etag, modified))) - -def get_etag(feed_name): - """ - return timestamp of when feed was last modified - """ - fn = os.path.join('etags',feed_name +'.txt') - etag = '' - modified = '' - - if os.path.exists(fn): - etag, modified = make_tuple(open(fn,'r').read()) - - return etag, modified - -def create_frontmatter(entry): - """ - parse RSS metadata and return as frontmatter - """ - if 'published' in entry: - published = entry.published_parsed - if 'updated' in entry: - published = entry.updated_parsed - - published = arrow.get(published) - - if 'author' in entry: - author = entry.author - else: - author = '' - - tags = [] - if 'tags' in entry: - #TODO finish categories - for t in entry.tags: - tags.append(t['term']) - - frontmatter = { - 'title':entry.title, - 'date': published.format(), - 'summary': '', - 'author': author, - 'original_link': entry.link, - 'feed_name': entry['feed_name'], - 'tags': str(tags) - } - - return frontmatter - -def create_post(post_dir, entry): - """ - write hugo post based on RSS entry - """ - frontmatter = create_frontmatter(entry) - - if not os.path.exists(post_dir): - os.makedirs(post_dir) - - if 'content' in entry: - post_content = entry.content[0].value - else: - post_content = entry.summary - - parsed_content = parse_posts(post_dir, post_content) - - with open(os.path.join(post_dir,'index.html'),'w') as f: #n.b. .html - post = template.render(frontmatter=frontmatter, content=parsed_content) - f.write(post) - print('created post for', entry.title, '({})'.format(entry.link)) - -def grab_media(post_directory, url): - """ - download media linked in post to have local copy - if download succeeds return new local path otherwise return url - """ - image = urlparse(url).path.split('/')[-1] - - try: - if not os.path.exists(os.path.join(post_directory, image)): - #TODO: stream is true is a conditional so we could check the headers for things, mimetype etc - response = requests.get(url, stream=True) - if response.ok: - with open(os.path.join(post_directory, image), 'wb') as img_file: - shutil.copyfileobj(response.raw, img_file) - print('Downloaded cover image', image) - return image - return image - elif os.path.exists(os.path.join(post_directory, image)): - return image - - except Exception as e: - print('Failed to download image', url) - print(e) - return url - - -def parse_posts(post_dir, post_content): - """ - parse the post content to for media items - replace foreign image with local copy - filter out iframe sources not in allowlist - """ - soup = BeautifulSoup(post_content, "html.parser") - allowed_iframe_sources = ['youtube.com', 'vimeo.com', 'tv.lumbung.space'] - media = [] - - for img in soup(['img','object']): - local_image = grab_media(post_dir, img['src']) - if img['src'] != local_image: - img['src'] = local_image - - for iframe in soup(['iframe']): - if not any(source in iframe['src'] for source in allowed_iframe_sources): - print('filtered iframe: {}...'.format(iframe['src'][:25])) - iframe.decompose() - return soup.decode() - -def grab_feed(feed_url): - """ - check whether feed has been updated - download & return it if it has - """ - feed_name = urlparse(feed_url).netloc - - etag, modified = get_etag(feed_name) - - try: - if modified: - data = feedparser.parse(feed_url, modified=modified) - elif etag: - data = feedparser.parse(feed_url, etag=etag) - else: - data = feedparser.parse(feed_url) - except Exception as e: - print('Error grabbing feed') - print(feed_name) - print(e) - return False - - print(data.status, feed_url) - if data.status == 200: - #304 means the feed has not been modified since we last checked - write_etag(feed_name, data) - return data - return False - - -feed_urls = open('feeds_list.txt','r').read().splitlines() - -start = time.time() - -if not os.path.exists('etags'): - os.mkdir('etags') - - -env = jinja2.Environment( - loader=jinja2.FileSystemLoader(os.path.curdir) - ) - -output_dir = os.environ.get('OUTPUT_DIR', '/home/r/Programming/lumbung.space/lumbung.space-web/content/posts/') -#output_dir = os.environ.get('OUTPUT_DIR', 'network/') - -if not os.path.exists(output_dir): - os.makedirs(output_dir) - -template = env.get_template('post_template.md') - -#add iframe to the allowlist of feedparser's sanitizer, -#this is now handled in parse_post() -feedparser.sanitizer._HTMLSanitizer.acceptable_elements |= {'iframe'} - -for feed_url in feed_urls: - - feed_name = urlparse(feed_url).netloc - - feed_dir = os.path.join(output_dir, feed_name) - - if not os.path.exists(feed_dir): - os.makedirs(feed_dir) - - existing_posts = os.listdir(feed_dir) - - data = grab_feed(feed_url) - - if data: - for entry in data.entries: - # if 'tags' in entry: - # for tag in entry.tags: - # for x in ['lumbung.space', 'D15', 'lumbung']: - # if x in tag['term']: - # print(entry.title) - entry['feed_name'] = feed_name - - post_name = slugify(entry.title) - post_dir = os.path.join(output_dir, feed_name, post_name) - - if post_name not in existing_posts: - #if there is a blog entry we dont already have, make it - create_post(post_dir, entry) - - elif post_name in existing_posts: - #if we already have it, update it - create_post(post_dir, entry) - existing_posts.remove(post_name) # create list of posts which have not been returned by the feed - - for post in existing_posts: - #remove blog posts no longer returned by the RSS feed - print('deleted', post) - shutil.rmtree(os.path.join(feed_dir, slugify(post))) - - - -end = time.time() - -print(end - start) - diff --git a/lumbung-hashtag-bot/.gitignore b/lumbung-hashtag-bot/.gitignore deleted file mode 100644 index 8afa646..0000000 --- a/lumbung-hashtag-bot/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -config_hashtag_bot.py -*.secret -__pycache__/* diff --git a/lumbung-hashtag-bot/README.md b/lumbung-hashtag-bot/README.md deleted file mode 100644 index 618a3ac..0000000 --- a/lumbung-hashtag-bot/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# lumbung.space hashtag publishing bot - -This script makes [Hugo page bundles](https://gohugo.io/content-management/page-bundles/) out of Hashtag feeds on a Mastodon Hometown or Glitchsoc instance. - -## Install requirements - -`pip3 install Mastodon.py jinja2` - -## Setup - -This script requires access to an account on said Mastodon instance. This instance and the credentials can be set in `config_hashtag_bot.py`. - -If it is the first time you are running the script, you need to register the application on the Mastodon instance. Have a look at the [Mastodon.py documentation](https://mastodonpy.readthedocs.io/en/stable/#module-mastodon) for how to do that. - -This bot only uses read permissions. - -Set which hashtags you want to publish by adding them to the list `hashtags` in `config_hashtag_bot.py`. Omit the '#'. - -## What it does - -* The Bot only looks at the **local timeline** for posts under each hashtag configured in `config_hashtag_bot.py`. -* This means posts need to be **public** or directly addressed to the bot -* This script respects the mental model of 'local only' posts in the sense that people do not expect them to appear elsewhere. So **local only posts are ignored** -* It takes only posts with Media attached and then only those with images - -## What it doesn't do - -* Different types of media or embeds -* No thread recreation, each post is treated as a top level post - diff --git a/lumbung-hashtag-bot/post_template.md b/lumbung-hashtag-bot/post_template.md deleted file mode 100644 index 6aeff3e..0000000 --- a/lumbung-hashtag-bot/post_template.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -date: "{{ post_metadata.created_at }}" #2021-06-10T10:46:33+02:00 -draft: false -author: "{{ post_metadata.account.display_name }}" -avatar: "{{ post_metadata.account.avatar }}" -categories: ["shouts"] -tags: [{% for i in post_metadata.tags %} "{{ i.name }}", {% endfor %}] ---- - -{% for item in post_metadata.media_attachments %} -{{item.description}} -{% endfor %} - -{{ post_metadata.content | filter_mastodon_urls }} \ No newline at end of file diff --git a/lumbung-hashtag-bot/publish_hashtags.py b/lumbung-hashtag-bot/publish_hashtags.py deleted file mode 100644 index 09e09d7..0000000 --- a/lumbung-hashtag-bot/publish_hashtags.py +++ /dev/null @@ -1,137 +0,0 @@ -# lumbung.space hashtag publishing bot -# © 2021 roel roscam abbing agplv3 -# Makes Hugo posts out of hashtag feeds on Mastodon. -# Requires an account on the Mastodon instance configured. -# Currently does not do any thread recreation and only handles images - -import os -import requests -import shutil - -import jinja2 - -from mastodon import Mastodon -import config_hashtag_bot - -def login_mastodon_bot(): - mastodon = Mastodon( - client_id = 'publishbot_clientcred.secret', - api_base_url = config_hashtag_bot.instance - ) - - mastodon.log_in( - config_hashtag_bot.email, - config_hashtag_bot.password, - to_file = 'publishbot_usercred.secret', scopes=['read'] - ) - - return mastodon - -def create_frontmatter(post_metadata): - """ - Parse post metadata and return it as HUGO frontmatter - """ - - frontmatter = "" - return frontmatter - -def download_media(post_directory, media_attachments): - """ - Download media attached to posts. N.b. currently only images - See: https://mastodonpy.readthedocs.io/en/stable/#media-dicts - """ - - for item in media_attachments: - if item['type'] == 'image': - image = localize_media_url(item['url']) - #TODO check whether this needs to handle delete & redraft with different images - if not os.path.exists(os.path.join(post_directory, image)): - #download image - response = requests.get(item['url'], stream=True) - with open(os.path.join(post_directory, image), 'wb') as img_file: - shutil.copyfileobj(response.raw, img_file) - print('Downloaded cover image', image) - -def create_post(post_directory, post_metadata): - """ - Create Hugo posts based on Toots/posts retuned in timeline. - See: https://mastodonpy.readthedocs.io/en/stable/#toot-dicts - """ - - if not os.path.exists(post_directory): - os.mkdir(post_directory) - - with open(os.path.join(post_directory,'index.html'),'w') as f: - post = template.render(post_metadata=post_metadata) - f.write(post) - - download_media(post_directory, post_metadata['media_attachments']) - -def localize_media_url(url): - """ - Returns the filename, used also as custom jinja filter - """ - return url.split('/')[-1] - - -def filter_mastodon_urls(content): - """ - Filters out Mastodon generated URLS for tags - e.g. - - - - diff --git a/lumbung-video-prototype/video-feed.py b/lumbung-video-prototype/video-feed.py deleted file mode 100644 index 15f7da3..0000000 --- a/lumbung-video-prototype/video-feed.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/python3 - -#lumbung.space video feed generator -#c 2021 roel roscam abbing gpvl3 etc - -import peertube -import jinja2 -import json -import os -import datetime -import shutil -import requests -import ast -import arrow - - -#jinja filters & config -def duration(n): - """ - convert '6655' in '1:50:55' - - """ - return str(datetime.timedelta(seconds = n)) - -def linebreaks(text): - if not text: - return text - else: - import re - br = re.compile(r"(\r\n|\r|\n)") - return br.sub(r"
\n", text) - - -env = jinja2.Environment( - loader=jinja2.FileSystemLoader(os.path.curdir) - ) -env.filters['duration'] = duration -env.filters['linebreaks'] = linebreaks - -host = 'https://tv.lumbung.space' - -configuration = peertube.Configuration( - host = host+"/api/v1" -) - -client = peertube.ApiClient(configuration) - -v = peertube.VideoApi(client) - -response = v.videos_get(count=100, filter='local', tags_one_of='publish') - -videos = response.to_dict() -videos = videos['data'] - - -def create_post(post_directory, video_metadata): - global client #lazy - - if not os.path.exists(post_dir): - os.mkdir(post_directory) - - preview_image = video_metadata['preview_path'].split('/')[-1] - - if not os.path.exists(os.path.join(post_directory, preview_image)): - #download preview image - response = requests.get(host+video_metadata['preview_path'], stream=True) - with open(os.path.join(post_directory, preview_image), 'wb') as img_file: - shutil.copyfileobj(response.raw, img_file) - print('Downloaded cover image') - - #replace the truncated description with the full video description - #peertube api is some broken thing in between a py dict and a json file - api_response = peertube.VideoApi(client).videos_id_description_get(video_metadata['uuid']) - long_description = ast.literal_eval(api_response) - video_metadata['description'] = long_description['description'] - - - with open(os.path.join(post_directory,'index.md'),'w') as f: - post = template.render(v=video_metadata, host=host, preview_image=preview_image) - f.write(post) - - - with open(os.path.join(post_directory, '.timestamp'), 'w') as f: - timestamp = arrow.get(video_metadata['updated_at']) - f.write(timestamp.format('X')) - -def update_post(post_directory, video_metadata): - if os.path.exists(post_directory): - if os.path.exists(os.path.join(post_directory,'.timestamp')): - old_timestamp = open(os.path.join(post_directory,'.timestamp')).read() - - #FIXME: this is ugly but I need to do this because arrow removes miliseconds - current_timestamp = arrow.get(video_metadata['updated_at']) - current_timestamp = arrow.get(current_timestamp.format('X')) - - if current_timestamp > arrow.get(old_timestamp): - print('Updating', video_metadata['name'], '({})'.format(video_metadata['uuid'])) - create_post(post_dir, video_metadata) - else: - print('Video current: ', video_metadata['name'], '({})'.format(video_metadata['uuid'])) - else: - #compat for when there is no timestamp yet.. - create_post(post_dir, video_metadata) - - -output_dir = os.environ.get('OUTPUT_DIR', '/home/r/Programming/lumbung.space/lumbung.space-web/content/video') - -if not os.path.exists(output_dir): - os.mkdir(output_dir) - -template = env.get_template('index_template.md') - -existing_posts = os.listdir(output_dir) - -for video_metadata in videos: - post_dir = os.path.join(output_dir, video_metadata['uuid']) - - if video_metadata['uuid'] not in existing_posts: #if there is a video we dont already have, make it - print('New: ', video_metadata['name'], '({})'.format(video_metadata['uuid'])) - create_post(post_dir, video_metadata) - - elif video_metadata['uuid'] in existing_posts: # if we already have the video do nothing, possibly update - update_post(post_dir, video_metadata) - existing_posts.remove(video_metadata['uuid']) # create list of posts which have not been returned by peertube - -for post in existing_posts: - print('deleted', post) #rm posts not returned - shutil.rmtree(os.path.join(output_dir,post)) - - -