+
+ {{ $postPermalink := .Permalink}}
+
+
+
+ {{ with (index (.Resources.ByType "image") 0) }}
+ {{ $height := add .Height 0.0}}
+ {{ $ratio := div $height .Width}}
+ {{ $thumb := .Fit "540x360"}}
+
+
+
+
+ {{ else }}
+
+ {{ end }}
+
+ {{ .Summary }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/lumbung-theme/layouts/partials/video_box.html b/lumbung-theme/layouts/partials/video_box.html
new file mode 100644
index 0000000..711800e
--- /dev/null
+++ b/lumbung-theme/layouts/partials/video_box.html
@@ -0,0 +1,37 @@
+
+
diff --git a/lumbung-theme/static/css/fonts/Anonymous_Pro_Regular.woff b/lumbung-theme/static/css/fonts/Anonymous_Pro_Regular.woff
new file mode 100644
index 0000000..220852e
Binary files /dev/null and b/lumbung-theme/static/css/fonts/Anonymous_Pro_Regular.woff differ
diff --git a/lumbung-theme/static/css/fonts/Barrio_Regular.woff b/lumbung-theme/static/css/fonts/Barrio_Regular.woff
new file mode 100644
index 0000000..d066b82
Binary files /dev/null and b/lumbung-theme/static/css/fonts/Barrio_Regular.woff differ
diff --git a/lumbung-theme/static/css/fonts/Zen_Maru_Gothic_Regular.woff b/lumbung-theme/static/css/fonts/Zen_Maru_Gothic_Regular.woff
new file mode 100644
index 0000000..ca6a3eb
Binary files /dev/null and b/lumbung-theme/static/css/fonts/Zen_Maru_Gothic_Regular.woff differ
diff --git a/lumbung-theme/static/css/main.css b/lumbung-theme/static/css/main.css
new file mode 100644
index 0000000..c457077
--- /dev/null
+++ b/lumbung-theme/static/css/main.css
@@ -0,0 +1,603 @@
+/*nice body-border color combos
+
+antiquewhite - burlywood
+peachpuff - tomato
+lightpink - crimson
+lightblue - cornflowerblue
+palegreen - lightseagreen
+steelblue - aliceblue
+
+fonts
+bungeeshade
+allerta
+*/
+
+@font-face {
+ font-family: BarrioRegular;
+ src: url(fonts/Barrio_Regular.woff);
+}
+
+@font-face {
+ font-family: ZenMaruGothic;
+ src: url(fonts/Zen_Maru_Gothic_Regular.woff);
+}
+
+@font-face {
+ font-family: AnonymousPro;
+ src: url(fonts/Anonymous_Pro_Regular.woff);
+}
+
+h1, h2, h3 {
+ font-family: BarrioRegular;
+}
+
+:root {
+ --border-color: tomato;
+}
+
+/*Main Stuff*/
+body {
+ font-size:24px;
+ font-family: ZenMaruGothic;
+ 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: 10%;
+}
+
+
+/* base header & menu */
+
+#top-menu{
+ position: fixed;
+ left: 5%;
+ transform: translate(-50%);
+ width: 30%;
+ z-index: 1;
+ margin-top: 1em;
+ transform: rotate(-3deg);
+}
+
+.menu-dropdown summary{
+ list-style: none;
+ cursor: pointer;
+}
+
+.dropdown-menu summary::-webkit-details-marker {
+ 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;
+ min-width: 34ch;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+.summary-image > img {
+/* height: 100%;
+ object-fit: cover;
+ max-width: 100%;*/
+
+}
+
+.summary-image > a {
+ display: flex;
+}
+
+.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: min-content;
+ 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: none;
+}
+
+.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{
+
+ 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 .p-summary {
+ display: flex;
+}
+
+.network .p-summary.portrait {
+ flex-direction: row;
+}
+.network .p-summary.landscape{
+ flex-direction: column;
+}
+.network .summary-image.portrait {
+ border-right: 2px solid darkcyan;
+}
+.network .summary-image.landscape {
+ border-bottom: 2px solid darkcyan;
+ border-right: none;
+}
+
+
+.network .summary-image > img {
+ display: inherit;
+}
+.network .summary-text {
+ font-size: 18px;
+}
+
+div.network-source{
+ padding: 0.5em 1em 0.5em 1em;
+ 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-left: 2px solid darkcyan;
+ border-top: none;
+}
+
+.network footer.post-footer{
+ border-top: 2px solid darkcyan;
+ flex-flow: row;
+ font-size: 0.9rem;
+}
+
+.network .read-more {
+ border: none;
+ border-left: 2px solid darkcyan;
+ padding: 0.5em 1.2em 0.5em 1.2em;
+}
+
+.network .footer-metadata {
+ padding: 0.5em 1.2em 0.5em 1.2em;
+}
+
+/* shouts cards */
+
+.card.shout{
+ border-color: steelblue;
+ border: 2px solid;
+ box-shadow:1em 1em 0 #d2d1c8;
+ background-color: aliceblue;
+ max-width: min-content;
+ margin-bottom: 2em;
+ flex: auto;
+ margin: 0 3em 3em 0;
+ align-self: start;
+ color: steelblue;
+ }
+
+/* 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/lumbung-theme/static/css/print.css b/lumbung-theme/static/css/print.css
new file mode 100644
index 0000000..e69de29
diff --git a/lumbung-theme/static/css/video-box.css b/lumbung-theme/static/css/video-box.css
new file mode 100644
index 0000000..051cd70
--- /dev/null
+++ b/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/lumbung-theme/theme.toml b/lumbung-theme/theme.toml
new file mode 100644
index 0000000..72ac31f
--- /dev/null
+++ b/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-video-prototype/README.md b/lumbung-video-prototype/README.md
new file mode 100644
index 0000000..a5d9115
--- /dev/null
+++ b/lumbung-video-prototype/README.md
@@ -0,0 +1,27 @@
+# video feed prototypes
+
+These scripts poll a peertube instance to return a list of videos and construct a static page for it using jinja2.
+
+See it in action on
+
+## video-feed.py
+
+Utility that returns Peertube videos tagged as `publish` and turns them in to `hugo` page bundles. Videos no longer tagged as `publish` are deleted.
+
+### index-template.md
+
+Jinja2 template of a hugo post for use with the above.
+
+## streams-feed.py
+
+Returns only livestreams and displays them differently depending on the tags associated with the video. E.g. audio stream or video stream. WIP.
+
+### video-feed.html
+The jinja template for creating video feeds. This is now used in the HUGO theme.
+
+### video-feed-prototype.html
+rendered example of above
+
+
+
+
diff --git a/lumbung-video-prototype/index_template.md b/lumbung-video-prototype/index_template.md
new file mode 100644
index 0000000..898746b
--- /dev/null
+++ b/lumbung-video-prototype/index_template.md
@@ -0,0 +1,15 @@
+---
+title: "{{ v.name }}"
+date: "{{ v.published_at }}" #2021-06-10T10:46:33+02:00
+draft: false
+uuid: "{{v.uuid}}"
+video_duration: "{{ v.duration | duration }} "
+video_channel: "{{ v.channel.display_name }}"
+channel_url: "{{ v.channel.url }}"
+preview_image: "{{ preview_image }}"
+categories: ["tv","{{ v.channel.display_name }}"]
+is_live: {{ v.is_live }}
+
+---
+
+{{ v.description }}
diff --git a/lumbung-video-prototype/requirements.txt b/lumbung-video-prototype/requirements.txt
new file mode 100644
index 0000000..eaec3c5
--- /dev/null
+++ b/lumbung-video-prototype/requirements.txt
@@ -0,0 +1,12 @@
+# Automatically generated by https://github.com/damnever/pigar.
+
+# video_feed/streams-feed.py: 7
+# video_feed/video-feed.py: 7
+Jinja2 == 2.10
+
+# video_feed/streams-feed.py: 6
+# video_feed/video-feed.py: 6
+git+https://framagit.org/framasoft/peertube/clients/python.git
+
+# video_feed/video-feed.py: 12
+requests == 2.21.0
diff --git a/lumbung-video-prototype/video-feed.html b/lumbung-video-prototype/video-feed.html
new file mode 100644
index 0000000..5ce0551
--- /dev/null
+++ b/lumbung-video-prototype/video-feed.html
@@ -0,0 +1,251 @@
+
+
+
+
+
+
+ lumbung.space video archive prototype
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% for video in videos %}
+
+ {% endfor %}
+
+
+
+
+
diff --git a/lumbung-video-prototype/video-feed.py b/lumbung-video-prototype/video-feed.py
new file mode 100644
index 0000000..15f7da3
--- /dev/null
+++ b/lumbung-video-prototype/video-feed.py
@@ -0,0 +1,131 @@
+#!/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))
+
+
+