Merge pull request 'Ajout de l'administration par Directus' (#1) from drone into master
Reviewed-on: https://git.weko.io/weko/lestoitsduval/pulls/1
This commit is contained in:
commit
4275fed4f3
|
@ -0,0 +1,107 @@
|
||||||
|
---
|
||||||
|
# drone encrypt weko/lestoitsduval $REGISTRY_PASSWORD
|
||||||
|
kind: secret
|
||||||
|
name: REGISTRY_PASSWORD
|
||||||
|
data: RrJX1Ir1Fqp83P43po3iQh4RE+SULN060LDe/PkEYw+mxPLrdDREEoQNKfh8RvAMjvocNojY9OuxXaZSpC72GOpi8qzslnHAbHhQfCX/
|
||||||
|
|
||||||
|
---
|
||||||
|
# drone encrypt weko/lestoitsduval $REGISTRY_USER
|
||||||
|
kind: secret
|
||||||
|
name: REGISTRY_USER
|
||||||
|
data: fyPAM/EECUhDI5XGhj3RbQWgzbGija2DAwepuAWmnEx1+A==
|
||||||
|
|
||||||
|
---
|
||||||
|
# drone encrypt weko/lestoitsduval "{\"auths\":{\"https://registry.weko.io\":{\"auth\":\"$(echo -n "$REGISTRY_USER:$REGISTRY_PASSWORD" | base64)\",\"email\":\"$REGISTRY_USER\"}}}"
|
||||||
|
kind: secret
|
||||||
|
name: REGISTRY_CONFIG
|
||||||
|
data: NsJ77R/8TEmyCM7h6OXkOeGhKAdctofukKezjfjIMGaBv5aGYN4CKYCIBlLsBWfFvMb+0SIDqrExyLw4i5dFWfDepwdNacJXNRmjIEkxuaJmvGxV8BZpcof28LjhB4psKrKjmTFpGioS3kG1MRfnljD/AlwckUd6S4KYNfGgJW0hQccxbamW9M0tqagPddayGEDghwxUfzqQk937rmOV7ngI+mon9f4DCWVA
|
||||||
|
|
||||||
|
---
|
||||||
|
# drone encrypt weko/lestoitsduval $DIRECTUS_URL
|
||||||
|
kind: secret
|
||||||
|
name: DIRECTUS_URL
|
||||||
|
data: pPaOgtpSRFhEZ6zq61OoN+gYxZ6nzg+FlmFYEhUq/GLoFXTwA3i+Yci7ZrwJUmhOpLtG
|
||||||
|
|
||||||
|
---
|
||||||
|
# drone encrypt weko/lestoitsduval $DIRECTUS_EMAIL
|
||||||
|
kind: secret
|
||||||
|
name: DIRECTUS_EMAIL
|
||||||
|
data: Egj2gQqz40mbxx9tFc7bfTOiUc36Dch+2Y4RjVEt9qpoL1y5d5KEpSE=
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# drone encrypt weko/lestoitsduval $DIRECTUS_PASSWORD
|
||||||
|
kind: secret
|
||||||
|
name: DIRECTUS_PASSWORD
|
||||||
|
data: TC0fUdQ7NvL7Qri7SuqTK6JC9zbX0xVSyndHl/zbFlecARlc7Yzru65OO1fvf1VQxSejIVlPcyorZRiHepUeTnt0nEXTgDmO
|
||||||
|
|
||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
type: docker
|
||||||
|
name: default
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: arm64
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: install submodule
|
||||||
|
image: drone/git
|
||||||
|
commands:
|
||||||
|
- git config --global http.sslverify false
|
||||||
|
- git submodule update --init
|
||||||
|
|
||||||
|
- name: install npm
|
||||||
|
image: node:current-alpine
|
||||||
|
volumes:
|
||||||
|
- name: hugo-theme-directus-import_node_modules
|
||||||
|
path: /drone/src/themes/hugo-theme-directus-import/node_modules
|
||||||
|
- name: hugo-theme-lowtech_node_modules
|
||||||
|
path: /drone/src/themes/hugo-theme-lowtech/node_modules
|
||||||
|
environment:
|
||||||
|
DIRECTUS_URL:
|
||||||
|
from_secret: DIRECTUS_URL
|
||||||
|
DIRECTUS_EMAIL:
|
||||||
|
from_secret: DIRECTUS_EMAIL
|
||||||
|
DIRECTUS_PASSWORD:
|
||||||
|
from_secret: DIRECTUS_PASSWORD
|
||||||
|
commands:
|
||||||
|
- (cd themes/hugo-theme-lowtech && npm i)
|
||||||
|
- (cd themes/hugo-theme-directus-import && npm i)
|
||||||
|
- node themes/hugo-theme-directus-import/import.js
|
||||||
|
|
||||||
|
- name: build website
|
||||||
|
image: jakejarvis/hugo-extended
|
||||||
|
commands:
|
||||||
|
- hugo --minify --environment production
|
||||||
|
|
||||||
|
- name: typo
|
||||||
|
image: node:current-alpine
|
||||||
|
volumes:
|
||||||
|
- name: hugo-theme-lowtech_node_modules
|
||||||
|
path: /drone/src/themes/hugo-theme-lowtech/node_modules
|
||||||
|
commands:
|
||||||
|
- node themes/hugo-theme-lowtech/scripts/typo
|
||||||
|
|
||||||
|
- name: push docker image on registry
|
||||||
|
image: plugins/docker
|
||||||
|
settings:
|
||||||
|
username:
|
||||||
|
from_secret: REGISTRY_USER
|
||||||
|
password:
|
||||||
|
from_secret: REGISTRY_PASSWORD
|
||||||
|
repo: registry.weko.io/lestoitsduval
|
||||||
|
registry: registry.weko.io
|
||||||
|
tags:
|
||||||
|
- latest
|
||||||
|
|
||||||
|
image_pull_secrets:
|
||||||
|
- REGISTRY_CONFIG
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: hugo-theme-directus-import_node_modules
|
||||||
|
host:
|
||||||
|
path: /tmp/drone/cache/weko/lestoitsduval/themes/hugo-theme-directus-import
|
||||||
|
- name: hugo-theme-lowtech_node_modules
|
||||||
|
host:
|
||||||
|
path: /tmp/drone/cache/weko/lestoitsduval/themes/hugo-theme-lowtech
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 1
|
||||||
title: Stand à la Marche du Cidre
|
title: Stand à la Marche du Cidre
|
||||||
date: 2019-11-11
|
date: '2019-11-11'
|
||||||
image: stand.jpg
|
image: stand.jpg
|
||||||
image_credit: Françoise sur le stand
|
image_credit: Françoise sur le stand
|
||||||
|
slug: 2019-11-11-marche-du-cidre
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Stand à la Marche du Cidre
|
## Stand à la Marche du Cidre
|
||||||
|
|
||||||
Nous étions présents lors de la marche du Château d’Aix (Marche du cidre) où
|
Nous étions présents lors de la marche du Château d’Aix (Marche du cidre) où
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 4
|
||||||
title: Rencontre avec la ComCom de Saint Just-en-Chevalet
|
title: Rencontre avec la ComCom de Saint Just-en-Chevalet
|
||||||
date: 2020-01-16
|
date: '2020-01-16'
|
||||||
image: mairie.jpg
|
image: mairie.jpg
|
||||||
image_credit: Mairie de Saint Just en Chevalet (Loire 42)
|
image_credit: Mairie de Saint Just en Chevalet (Loire 42)
|
||||||
|
slug: 2020-01-16-rencontre-comcom-st-just
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Rencontre avec le Conseil Communautaire du Pays d'Urfé
|
## Rencontre avec le Conseil Communautaire du Pays d'Urfé
|
||||||
|
|
||||||
Nous nous sommes rendus à la communauté de communes de St Just-en-Chevalet. Les maires étaient curieux de comprendre cette démarche citoyenne soutenant la transition énergétique. Nous avons évoqué le fait que nous n’étions pas les seuls à œuvrer dans ce sens ; d’autres projets similaires existent dans des territoires voisins : [« Com toit »](https://comtoit.org/) dans le bassin de Vichy et la montagne bourbonnaise , [« Toi et Toits »](https://www.toi-toits.fr/) dans le Livradois Forez.
|
Nous nous sommes rendus à la communauté de communes de St Just-en-Chevalet. Les maires étaient curieux de comprendre cette démarche citoyenne soutenant la transition énergétique. Nous avons évoqué le fait que nous n’étions pas les seuls à œuvrer dans ce sens ; d’autres projets similaires existent dans des territoires voisins : [« Com toit »](https://comtoit.org/) dans le bassin de Vichy et la montagne bourbonnaise , [« Toi et Toits »](https://www.toi-toits.fr/) dans le Livradois Forez.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 5
|
||||||
title: Réunion publique à Dancé
|
title: Réunion publique à Dancé
|
||||||
date: 2020-01-20
|
date: '2020-01-20'
|
||||||
image: equipe.jpg
|
image: equipe.jpg
|
||||||
image_credit: L'équipe pour répondre aux questions
|
image_credit: L'équipe pour répondre aux questions
|
||||||
|
slug: 2020-01-20-reunion-publique-dance
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Réunion autour du photovoltaïque
|
## Réunion autour du photovoltaïque
|
||||||
|
|
||||||
Nous étions invités à Dancé par l’Association des Jeunes qui avaient étendu l’information à la municipalité élargie de Vézelin sur Loire. Plus d'une vingtaine de personnes étaient présentes, en plus des 8 de notre groupe.
|
Nous étions invités à Dancé par l’Association des Jeunes qui avaient étendu l’information à la municipalité élargie de Vézelin sur Loire. Plus d'une vingtaine de personnes étaient présentes, en plus des 8 de notre groupe.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 6
|
||||||
title: Rencontre avec la ComCom de Saint-Germain
|
title: Rencontre avec la ComCom de Saint-Germain
|
||||||
date: 2020-02-13
|
date: '2020-02-13'
|
||||||
image: comcom.jpg
|
image: comcom.jpg
|
||||||
image_credit: Communauté de Communes des Vals d'Aix et Isable
|
image_credit: Communauté de Communes des Vals d'Aix et Isable
|
||||||
|
slug: 2020-02-13-rencontre-comcom-st-germain
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Rencontre avec le Conseil Communautaire des Vals d'Aix et Isable
|
## Rencontre avec le Conseil Communautaire des Vals d'Aix et Isable
|
||||||
|
|
||||||
Le jeudi 13 février, à l'occasion de la dernière réunion du conseil communautaire des Vals d'Aix et Isable avant les élections municipales, nous sommes venus présenter l'avancée du projet :
|
Le jeudi 13 février, à l'occasion de la dernière réunion du conseil communautaire des Vals d'Aix et Isable avant les élections municipales, nous sommes venus présenter l'avancée du projet :
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 7
|
||||||
title: La Subvention acceptée !!!
|
title: La Subvention acceptée !!!
|
||||||
date: 2020-06-09
|
date: '2020-06-09'
|
||||||
image: love.jpg
|
image: love.jpg
|
||||||
image_credit: Un coeur en lettre
|
image_credit: Un coeur en lettre
|
||||||
|
slug: 2020-06-09-starter-enr
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Subvention de l'étude de faisabilité acceptée !!!
|
## Subvention de l'étude de faisabilité acceptée !!!
|
||||||
|
|
||||||
{{< figure src="/actualites/2020-06-09-starter-enr/STARTER_EnR.png" class="center" alt="Logo STARTER EnR" >}}
|
{{< figure src="/actualites/2020-06-09-starter-enr/STARTER_EnR.png" class="center" alt="Logo STARTER EnR" >}}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 8
|
||||||
title: Réunion au Cheval Blanc
|
title: Réunion au Cheval Blanc
|
||||||
date: 2020-09-23
|
date: '2020-09-23'
|
||||||
image: affiche.jpg
|
image: affiche.jpg
|
||||||
image_credit: Logo des Toits du Val et du Cheval Blanc
|
image_credit: Logo des Toits du Val et du Cheval Blanc
|
||||||
|
slug: 2020-09-23-reunion-au-cheval-blanc
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
# Energie renouvelable, locale et citoyenne à Saint Germain Laval ?
|
# Energie renouvelable, locale et citoyenne à Saint Germain Laval ?
|
||||||
|
|
||||||
L'association « Les Toits du Val » vous invite le **vendredi 9 octobre** à 20h pour une **réunion d'information** au Cheval Blanc.
|
L'association « Les Toits du Val » vous invite le **vendredi 9 octobre** à 20h pour une **réunion d'information** au Cheval Blanc.
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 9
|
||||||
title: Bilan de l'étude de faisabilité
|
title: Bilan de l'étude de faisabilité
|
||||||
date: 2021-01-13
|
date: '2021-01-13'
|
||||||
image: jon-flobrant-_r19nfvS3wY.jpg
|
image: jon-flobrant-_r19nfvS3wY.jpg
|
||||||
image_credit: Photo de Jon Flobrant sur Unsplash
|
image_credit: Photo de Jon Flobrant sur Unsplash
|
||||||
|
slug: 2021-01-13-bilan-etude-faisabilite
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Des nouvelles de l’étude de faisabilité des toitures proposées
|
## Des nouvelles de l’étude de faisabilité des toitures proposées
|
||||||
|
|
||||||
Pour rappel, nous avons bénéficié de la subvention [STARTER EnR](/actualites/2020-06-09-starter-enr/) nous permettant de faire intervenir un bureau d'étude pour examiner la solidité des charpentes de 4 bâtiments :
|
Pour rappel, nous avons bénéficié de la subvention [STARTER EnR](/actualites/2020-06-09-starter-enr/) nous permettant de faire intervenir un bureau d'étude pour examiner la solidité des charpentes de 4 bâtiments :
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 10
|
||||||
title: AG de l'association des Centrales Villageoises
|
title: AG de l'association des Centrales Villageoises
|
||||||
date: 2021-03-27
|
date: '2021-03-27'
|
||||||
image: sincerely-media-dGxOgeXAXm8-unsplash.jpg
|
image: sincerely-media-dGxOgeXAXm8-unsplash.jpg
|
||||||
image_credit: Photo de Sincerely Media sur Unsplash
|
image_credit: Photo de Sincerely Media sur Unsplash
|
||||||
|
slug: null
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Assemblée Générale de l'association des Centrales Villageoises
|
## Assemblée Générale de l'association des Centrales Villageoises
|
||||||
|
|
||||||
_Nous avons participé à l'assemblée générale de l'association des Centrales Villageoises._
|
_Nous avons participé à l'assemblée générale de l'association des Centrales Villageoises._
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
---
|
---
|
||||||
|
id: 3
|
||||||
title: Le printemps des Toits du Val
|
title: Le printemps des Toits du Val
|
||||||
date: 2021-04-27
|
date: '2021-04-27'
|
||||||
image: lucie-morel-K4vmb0VT8tU-unsplash.jpg
|
image: lucie-morel-K4vmb0VT8tU-unsplash.jpg
|
||||||
image_credit: Photo de Lucie Morel sur Unsplash
|
image_credit: Photo de Lucie Morel sur Unsplash
|
||||||
|
slug: null
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
## Le printemps des Toits du Val
|
||||||
|
|
||||||
_Suite à l’étude de faisabilité des 4 toitures, [une seule a été jugée suffisamment solide pour accueillir des panneaux solaires](/actualites/2021-01-13-bilan-etude-faisabilite/), à notre grande déception..._
|
_Suite à l’étude de faisabilité des 4 toitures, [une seule a été jugée suffisamment solide pour accueillir des panneaux solaires](/actualites/2021-01-13-bilan-etude-faisabilite/), à notre grande déception..._
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
---
|
---
|
||||||
|
id: 2
|
||||||
title: Consultation des artisans
|
title: Consultation des artisans
|
||||||
date: 2021-05-04
|
date: '2021-05-04'
|
||||||
image: science-in-hd-67tIEcN2mOA-unsplash.jpg
|
image: science-in-hd-67tIEcN2mOA-unsplash.jpg
|
||||||
image_credit: Photo de Science in HD sur Unsplash
|
image_credit: Photo de Science in HD sur Unsplash
|
||||||
|
slug: null
|
||||||
|
draft: 'false'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Consultation des artisans
|
## Consultation des artisans
|
||||||
|
|
||||||
L’équipe technique a rédigé [le cahier des charges](https://cloud.weko.io/s/BgW4SZxNC2XefNS) afin de consulter 3 artisans locaux pour la « Réalisation d’une installation d’un générateur photovoltaïque ».
|
L’équipe technique a rédigé [le cahier des charges](https://cloud.weko.io/s/BgW4SZxNC2XefNS) afin de consulter 3 artisans locaux pour la « Réalisation d’une installation d’un générateur photovoltaïque ».
|
||||||
|
|
|
@ -10,11 +10,13 @@ services:
|
||||||
ltdv-prod:
|
ltdv-prod:
|
||||||
container_name: ltdv-prod
|
container_name: ltdv-prod
|
||||||
build: .
|
build: .
|
||||||
|
image: registry.weko.io/lestoitsduval
|
||||||
restart: always
|
restart: always
|
||||||
labels:
|
labels:
|
||||||
traefik.enable: "true"
|
- "traefik.enable=true"
|
||||||
traefik.http.routers.ltdv-prod.rule: "Host(`${URL}`)"
|
- "traefik.http.routers.ltdv-prod.rule=Host(`${URL}`)"
|
||||||
traefik.http.routers.ltdv-prod.entrypoints: "web"
|
- "traefik.http.routers.ltdv-prod.entrypoints=web"
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
volumes:
|
volumes:
|
||||||
- ltdv-log:/var/log/nginx
|
- ltdv-log:/var/log/nginx
|
||||||
- ltdv-stats:/usr/share/nginx/html/stats
|
- ltdv-stats:/usr/share/nginx/html/stats
|
||||||
|
@ -35,5 +37,4 @@ services:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
external:
|
|
||||||
name: traefik
|
name: traefik
|
||||||
|
|
|
@ -2,7 +2,6 @@ version: "3.8"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
external:
|
|
||||||
name: traefik
|
name: traefik
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
node_modules
|
|
@ -0,0 +1,23 @@
|
||||||
|
const DirectusHugoDriver = require('.');
|
||||||
|
|
||||||
|
const driverOptions = {
|
||||||
|
url: process.env.DIRECTUS_URL,
|
||||||
|
email: process.env.DIRECTUS_EMAIL,
|
||||||
|
password: process.env.DIRECTUS_PASSWORD,
|
||||||
|
buildDrafts: false,
|
||||||
|
collections: {
|
||||||
|
'lestoitsduval_actualites': {
|
||||||
|
pathBuilder: (path, article, urlslug) => {
|
||||||
|
if (article.slug) {
|
||||||
|
return `${path}/actualites/${article.slug}`
|
||||||
|
}
|
||||||
|
return `${path}/actualites/${article.date}-${urlslug(article.title, { remove: /\./g })}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
path: './content'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const driver = new DirectusHugoDriver(driverOptions);
|
||||||
|
driver.import()
|
|
@ -0,0 +1,244 @@
|
||||||
|
const util = require('util');
|
||||||
|
|
||||||
|
const DirectusSDK = require('@directus/sdk-js');
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
const urlslug = require('url-slug');
|
||||||
|
const fs = require('fs');
|
||||||
|
const mime = require('mime-types');
|
||||||
|
|
||||||
|
const express = require('express')
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
|
||||||
|
const { exec } = require("child_process");
|
||||||
|
|
||||||
|
const uuidregex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
||||||
|
|
||||||
|
|
||||||
|
class Driver {
|
||||||
|
constructor(config = {}, directusConfig = {}){
|
||||||
|
this.url = config.url || 'http://localhost:8055';
|
||||||
|
this.email = config.email || '';
|
||||||
|
this.password = config.password || '';
|
||||||
|
this.frontMatter = (config.frontMatter && config.frontMatter.toUpperCase()) || 'YAML'; // TODO: Add TOML and JSON frontmatter support
|
||||||
|
this.collection = config.collection
|
||||||
|
this.collections = config.collections
|
||||||
|
|
||||||
|
this.content = {}
|
||||||
|
this.content.path = (config.content && config.content.path) ? config.content.path : 'content';
|
||||||
|
this.content.home = (config.content && config.content.home) ? config.content.home.toLowerCase() : 'home';
|
||||||
|
this.content.index = (config.content && config.content.index) ? config.content.index.toLowerCase() : 'index';
|
||||||
|
this.content.map = (config.content && config.content.map) ? config.content.map : [];
|
||||||
|
|
||||||
|
this.directus = new DirectusSDK(this.url, directusConfig);
|
||||||
|
|
||||||
|
this.pathMethod = config.pathBuilder || this._pathBuilder;
|
||||||
|
this._auth = null;
|
||||||
|
|
||||||
|
this.buildDrafts = config.buildDrafts || false;
|
||||||
|
// Auto-rebuild server related
|
||||||
|
this.buildPort = config.buildPort || 8060;
|
||||||
|
this.buildHost = config.buildHost || 'http://localhost';
|
||||||
|
this.autoWebhook = config.autoWebhook || true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_checkAuth(){
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (this.email && this.password && this._auth === null){
|
||||||
|
this._auth = this.directus.auth.login({ email: this.email, password: this.password })
|
||||||
|
.then(() => {
|
||||||
|
console.info('Login with user', this.email);
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static emptyPromise(){
|
||||||
|
return new Promise(resolve => resolve())
|
||||||
|
}
|
||||||
|
|
||||||
|
getCollections(){
|
||||||
|
return this.directus.collections.read()
|
||||||
|
// Let not following .then() confuse you. It is an arrow function running an arrow filter.
|
||||||
|
// The Directus internal system fields have "meta.system == true" and those we discard here.
|
||||||
|
// .then(data => {
|
||||||
|
// console.log(util.inspect(data, false, null, true /* enable colors */))
|
||||||
|
// return data
|
||||||
|
// })
|
||||||
|
.then(data => data.data.filter(collection => !collection.meta.system))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build path string where the articles will be stored exlcluding individual article slug
|
||||||
|
* @param {*} article
|
||||||
|
* @param {*} collection
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
_pathBuilder(article, collection){
|
||||||
|
console.log('article', article);
|
||||||
|
// console.log('collection', collection);
|
||||||
|
|
||||||
|
if (this.collections && this.collections[collection.collection] && this.collections[collection.collection].pathBuilder) {
|
||||||
|
return this.collections[collection.collection].pathBuilder(this.content.path, article, urlslug)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._isHome(article, collection)) {
|
||||||
|
return `${this.content.path}`;
|
||||||
|
}
|
||||||
|
if (this._isBranch(article, collection) || this._isPage(article, collection)){
|
||||||
|
return `${this.content.path}/${collection.collection}`;
|
||||||
|
}
|
||||||
|
// console.log(article.date)
|
||||||
|
const datePrefix = article.date_created ? `${article.date_created.split('T')[0]}_` : '';
|
||||||
|
|
||||||
|
|
||||||
|
const [year, mouth, day] = article.date.split('-')
|
||||||
|
// console.log(year)
|
||||||
|
// return `${this.content.path}/${collection.collection}/${article.id}_${datePrefix}${urlslug(article.title, { remove: /\./g })}`;
|
||||||
|
return `${this.content.path}/actualites/${year}/${mouth}/${article.date.replaceAll('-', '_')}-${urlslug(article.title, { remove: /\./g })}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isHome(article, collection){
|
||||||
|
return (collection.meta.singleton === true && collection.collection === this.content.home)
|
||||||
|
}
|
||||||
|
|
||||||
|
_isBranch(article, collection){
|
||||||
|
return (collection.meta.singleton === false && article.title.toLowerCase() === this.content.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
_isPage(article, collection){
|
||||||
|
return (collection.meta.singleton === true)
|
||||||
|
}
|
||||||
|
|
||||||
|
_formatFrontMatter(article, collection = {}){
|
||||||
|
let front = { ...article };
|
||||||
|
|
||||||
|
// Manipulate some variable property names
|
||||||
|
if (front.date_created){
|
||||||
|
front.date = front.date_created
|
||||||
|
delete front.date_created
|
||||||
|
}
|
||||||
|
if (front.date_updated){
|
||||||
|
front.lastmod = front.date_updated
|
||||||
|
delete front.date_updated
|
||||||
|
}
|
||||||
|
delete front.body
|
||||||
|
|
||||||
|
// Finally, transform from object to string
|
||||||
|
if (this.frontMatter === 'YAML'){
|
||||||
|
front = `---\r\n${yaml.safeDump(front).trim()}\r\n---\r\n`
|
||||||
|
}
|
||||||
|
return front
|
||||||
|
}
|
||||||
|
|
||||||
|
static _writeFileStream(path, readstream, passtrough = {}){
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const fileWriter = fs.createWriteStream(path);
|
||||||
|
fileWriter.on('finish', () => {
|
||||||
|
resolve(passtrough)
|
||||||
|
});
|
||||||
|
fileWriter.on('error', error => {
|
||||||
|
console.log(error)
|
||||||
|
fileWriter.close();
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
readstream.pipe(fileWriter);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {object} article
|
||||||
|
* @param {object} collection
|
||||||
|
* @returns {promise}
|
||||||
|
*/
|
||||||
|
_importItem(originArticle, collection){
|
||||||
|
const article = { ...originArticle }
|
||||||
|
const itemPath = this.pathMethod(article, collection);
|
||||||
|
const indexName = this._isHome(article, collection) || this._isBranch(article, collection) || this._isPage(article, collection) ? '_index' : 'index'
|
||||||
|
|
||||||
|
// Only continue if this is a published article or we have explicitly set to import Drafts
|
||||||
|
// Archived items would be always discarded
|
||||||
|
|
||||||
|
if ((article.status === 'archived') || (article.draft === 'true' && this.buildDrafts === false)){
|
||||||
|
return Driver.emptyPromise();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if ((article.status !== 'published') && (article.status === 'draft' && this.buildDrafts === false)){
|
||||||
|
// return Driver.emptyPromise();
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (!fs.existsSync(itemPath)){
|
||||||
|
fs.mkdirSync(itemPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const writePromises = []
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(article)){
|
||||||
|
// TODO: instead of trying to pull asset and hope for the best,
|
||||||
|
// crosscheck things with the /fields and play by the rules
|
||||||
|
if (typeof value === 'string' && value.match(uuidregex)) {
|
||||||
|
// console.log([key, value]);
|
||||||
|
|
||||||
|
const downloadPromise = this.directus.axios.get(`assets/${value}?download`, { responseType: 'stream' })
|
||||||
|
.then(response => {
|
||||||
|
const disposition = response.headers['content-disposition'].match(/filename="(.*)"/);
|
||||||
|
const downloadName = disposition ? disposition[1] : `${value}.${mime.extension(response.headers['content-type'])}`;
|
||||||
|
const savePath = `${itemPath}/${downloadName}`;
|
||||||
|
return Driver._writeFileStream(savePath, response.data, { key, downloadName })
|
||||||
|
})
|
||||||
|
.then(passtrough => {
|
||||||
|
article[passtrough.key] = passtrough.downloadName
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
if (error.response && error.response.status && error.response.status !== 403) {
|
||||||
|
console.error(error.response.status, error.response.statusText)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
writePromises.push(downloadPromise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(writePromises).then(() => {
|
||||||
|
const frontMatter = this._formatFrontMatter(article, collection);
|
||||||
|
const itemContent = `${frontMatter}${article.body ? article.body.toString() : ''}`
|
||||||
|
fs.writeFileSync(`${itemPath}/${indexName}.md`, itemContent)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_importCollection(collection){
|
||||||
|
const col = this.directus.items(collection.collection).read() // TODO: IMPORTANT handle pagination when a lot of content in CMS
|
||||||
|
return col
|
||||||
|
.then(data => {
|
||||||
|
// normalize to always have an array of content.
|
||||||
|
const content = (collection.meta.singleton === true) ? [data.data] : data.data;
|
||||||
|
return content.map(article => this._importItem(article, collection))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
import() {
|
||||||
|
console.info('Let\'s import from', this.url);
|
||||||
|
this._checkAuth()
|
||||||
|
.then(() => this.getCollections())
|
||||||
|
.then(collections => {
|
||||||
|
if (this.collections) {
|
||||||
|
return collections.filter(collection => Object.keys(this.collections).includes(collection.collection))
|
||||||
|
}
|
||||||
|
return collections
|
||||||
|
})
|
||||||
|
.then(collections => {
|
||||||
|
return collections.map(collection => this._importCollection(collection))
|
||||||
|
})
|
||||||
|
.then(collectionPromises => {
|
||||||
|
return Promise.all(collectionPromises)
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Driver
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"name": "directus-hugo-driver",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "Translates content from Directus.io to gohugo.io",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/pilskalns/directus-hugo-driver.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"directus",
|
||||||
|
"hugo",
|
||||||
|
"npm",
|
||||||
|
"cms",
|
||||||
|
"headless",
|
||||||
|
"headless-cms",
|
||||||
|
"automation"
|
||||||
|
],
|
||||||
|
"author": "Andžs Pilskalns",
|
||||||
|
"license": "ISC",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/pilskalns/directus-hugo-driver/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/pilskalns/directus-hugo-driver#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"@directus/sdk-js": "^9.0.0-rc.32",
|
||||||
|
"body-parser": "^1.19.0",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"js-yaml": "^3.14.1",
|
||||||
|
"mime-types": "^2.1.28",
|
||||||
|
"url-slug": "^3.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^7.18.0",
|
||||||
|
"eslint-config-airbnb-base": "^14.2.1",
|
||||||
|
"eslint-plugin-import": "^2.22.1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4675c3a10fc35c23c01186faa7f7ccc6dd7d2e72
|
Subproject commit 437ab76c51a94e646333f77162934b147b5163ac
|
Loading…
Reference in New Issue