Compare commits

...

25 Commits

Author SHA1 Message Date
ffca96d89f import .drone.yml from master
All checks were successful
continuous-integration/drone/push Build is passing
2023-07-25 16:55:52 +02:00
6ef6ea59af Feat: add umami analytics
All checks were successful
continuous-integration/drone/push Build is passing
2022-06-15 09:25:02 +02:00
dc1829756a Fix: link to projets-informatiques
All checks were successful
continuous-integration/drone/push Build is passing
2020-08-16 10:34:12 +02:00
30a3d3a361 Feat: remove link to bopytex and mapytex
All checks were successful
continuous-integration/drone/push Build is passing
2020-08-16 10:30:35 +02:00
d8eb6a43c5 Feat: deploy to Opytex
All checks were successful
continuous-integration/drone/push Build is passing
2020-08-06 16:14:26 +02:00
ccd6a08295 Feat: drone for 2017-2018
All checks were successful
continuous-integration/drone/push Build is passing
2020-08-05 14:17:02 +02:00
7ea73772ac Fix: date de l'année 2020-07-01 14:59:13 +02:00
bae53da865 Feat: start using invoke 2020-07-01 14:58:15 +02:00
d7468c607c Fix: tagcloud display and link color 2020-06-30 14:36:23 +02:00
995a11803e Feat: add in html rule less processing 2020-06-30 14:36:13 +02:00
3cb50d6e0f Feat: Title link to /, date to /ense.... 2020-06-30 14:36:02 +02:00
d1e4f1c813 Feat: move HOME to links 2020-06-30 14:35:51 +02:00
6cf8feeb47 Feat: home line point to root of website 2020-06-23 10:58:23 +02:00
5bbfc35ca7 Feat: adapt to the year! 2020-06-23 10:48:40 +02:00
da8b91989f Feat: create directory before rsync it 2020-06-23 10:38:14 +02:00
5239c34f50 Feat: split with globalconf 2020-06-23 10:05:25 +02:00
adab4cdd33 Feat: menu is ok 2020-06-23 10:03:36 +02:00
dbb4f2f9e5 Feat: add content 2020-06-23 09:46:26 +02:00
75c13ae761 Feat: activate pdf-img 2020-06-23 09:45:42 +02:00
c015b18394 Feat: add FAKEDIR and remove RSYNC_EXCLUDE 2020-06-23 09:45:14 +02:00
9037131275 Feat: clean rsync commands 2020-06-22 15:10:51 +02:00
b56e99040e Feat: clean Makefile 2020-06-05 10:45:35 +02:00
ad1275cfe8 Feat: clean pelicanconf, prod env in publishconf 2020-06-05 10:42:51 +02:00
81dc32f301 Feat: remove logo 2020-06-05 10:41:20 +02:00
7e4121a577 Feat: remove pages 2020-06-05 10:40:06 +02:00
16 changed files with 373 additions and 306 deletions

101
.drone.yml Normal file
View File

@ -0,0 +1,101 @@
---
kind: pipeline
name: Opytex Main
type: docker
trigger:
branch:
- master
steps:
- name: Build Opytex base
image: python:3.8-alpine
volumes:
- name: pelican-output
path: /output
commands:
- apk add --no-cache git imagemagick-dev imagemagick
- git submodule init
- git submodule update
- pip install --no-cache-dir -r requirements.txt
- export MAGICK_HOME=/usr
- pelican ./content/ -o /output -s publishconf.py --relative-urls
- ls /output
- name: Push to bucket opytex.org
image: plugins/s3
volumes:
- name: pelican-output
path: /output
settings:
bucket: opytex.org
endpoint: https://storage.opytex.org
access_key:
from_secret: minio_access_key
secret_key:
from_secret: minio_secret_key
source: /output/**/*
target: /
path_style: true
strip_prefix: /output
volumes:
- name: pelican-output
temp: {}
---
kind: pipeline
name: Opytex Year
type: docker
trigger:
branch:
- 2022-2023
- 2021-2022
- 2020-2021
- 2019-2020
- 2018-2019
- 2017-2018
- 2016-2017
- 2015-2016
steps:
- name: Build Opytex ${DRONE_BRANCH}
image: python:3.8-alpine
volumes:
- name: pelican-output
path: /output
commands:
- apk add --no-cache git imagemagick-dev imagemagick
- git submodule init
- git submodule update
- git clone https://git.opytex.org/lafrite/${DRONE_BRANCH}.git content
- pip install --no-cache-dir -r requirements.txt
- apk add --no-cache git imagemagick-dev imagemagick
- pip install --no-cache-dir -r requirements.txt
- export MAGICK_HOME=/usr
- pelican ./content/ -o /output -s publishconf.py --relative-urls
- ls /output
- name: Push to bucket opytex.org
image: plugins/s3-sync:1
volumes:
- name: pelican-output
path: /drone/src/output
settings:
bucket: opytex.org
endpoint: https://storage.opytex.org
access_key:
from_secret: minio_access_key
secret_key:
from_secret: minio_secret_key
source: /output
target: /enseignements/${DRONE_BRANCH}
path_style: true
delete: true
volumes:
- name: pelican-output
temp: {}

3
.gitignore vendored
View File

@ -2,7 +2,8 @@ cache/*
output/* output/*
pelican-plugins/* pelican-plugins/*
pelican-themes/* pelican-themes/*
content/Enseignements/2* content
__pycache__ __pycache__
*.pid *.pid
venv/ venv/
.vim/

View File

@ -2,11 +2,14 @@ PY?=python3
PELICAN?=pelican PELICAN?=pelican
PELICANOPTS= PELICANOPTS=
YEARSUBFOLDER=enseignements/2017-2018/
BASEDIR=$(CURDIR) BASEDIR=$(CURDIR)
INPUTDIR=$(BASEDIR)/content INPUTDIR=$(BASEDIR)/content
OUTPUTDIR=$(BASEDIR)/output OUTPUTDIR=$(BASEDIR)/output
CONFFILE=$(BASEDIR)/pelicanconf.py CONFFILE=$(BASEDIR)/pelicanconf.py
PUBLISHCONF=$(BASEDIR)/publishconf.py PUBLISHCONF=$(BASEDIR)/publishconf.py
FAKEDIR=../../output/
FTP_HOST=localhost FTP_HOST=localhost
FTP_USER=anonymous FTP_USER=anonymous
@ -15,20 +18,7 @@ FTP_TARGET_DIR=/
SSH_HOST=localhost SSH_HOST=localhost
SSH_CONF=Embrevade SSH_CONF=Embrevade
#SSH_TARGET_DIR=/var/docker/opytex.org/www/ #SSH_TARGET_DIR=/var/docker/opytex.org/www/
SSH_TARGET_DIR=/home/sshcontent/opytex.org/www/ SSH_TARGET_DIR=/home/sshcontent/opytex.org/www/$(YEARSUBFOLDER)
S3_BUCKET=my_s3_bucket
CLOUDFILES_USERNAME=my_rackspace_username
CLOUDFILES_API_KEY=my_rackspace_api_key
CLOUDFILES_CONTAINER=my_cloudfiles_container
DROPBOX_DIR=~/Dropbox/Public/
GITHUB_PAGES_BRANCH=gh-pages
SRC_ENS=~/Cours/Prof/Enseignements/
SRC_EXCLUDE=--exclude '*/Archive' --exclude '*/tools' --exclude '.git' --exclude '.gitignore' --exclude '*/__pycache__' --exclude '*/config.py' --exclude '*/reflections' --exclude '*/Notes' --exclude '*/notes' --exclude '*/.*' --exclude '*/Makefile' --exclude '2012-2013' --exclude '2013-2014' --exclude '2014-2015' --exclude 'Clipart' --exclude "Shombos" --exclude '*/venv' --exclude "*/.venv"
DEBUG ?= 0 DEBUG ?= 0
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
@ -58,6 +48,7 @@ help:
@echo ' ' @echo ' '
html: html:
lessc $(BASEDIR)/theme/static/stylesheet/style.less $(BASEDIR)/theme/static/stylesheet/style.min.css -x
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS) $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
clean: clean:
@ -92,12 +83,11 @@ ssh_upload: publish
scp -r $(OUTPUTDIR)/* $(SSH_CONF):$(SSH_TARGET_DIR) scp -r $(OUTPUTDIR)/* $(SSH_CONF):$(SSH_TARGET_DIR)
rsync_upload: publish rsync_upload: publish
rsync -e "ssh" -P -rvzc --delete --exclude "pymath" --exclude "opytex" $(OUTPUTDIR)/ $(SSH_CONF):$(SSH_TARGET_DIR) --cvs-exclude #rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --cvs-exclude --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
rsync -e "ssh" -P -rvzc --delete $(RSYNC_EXCLUDE) $(OUTPUTDIR)/ $(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
#import_year: fake_upload: html
# rsync -rv --delete $(SRC_EXCLUDE) --delete-excluded --include '*/' --include '*' --prune-empty-dirs $(SRC_ENS)/Archive/$$year/ $(INPUTDIR)/Enseignements/$$year mkdir -p $(FAKEDIR)$(YEARSUBFOLDER)
rsync -P -rvzc --delete $(OUTPUTDIR)/ $(FAKEDIR)$(YEARSUBFOLDER) --cvs-exclude
import_ens:
rsync -av --delete $(SRC_EXCLUDE) --delete-excluded --include '*/' --include '*' --prune-empty-dirs $(SRC_ENS) $(INPUTDIR)/Enseignements/
.PHONY: html help clean regenerate serve devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github import_ens .PHONY: html help clean regenerate serve devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github import_ens

View File

@ -1,47 +0,0 @@
Tout sur les cours
##################
:date: 2016-01-23
:modified: 2016-01-24
:authors: Benjamin Bertrand
:summary: Résumé sur ma façon d'enseigner
:save_as: Enseignements/index.html
Les années qui s'écoulent
=========================
- `2015/2016 <./2015-2016/>`_
- `2016/2017 <./2016-2017/>`_
- `2017/2018 <./2017-2018/>`_
- `2018/2019 <./2018-2019/>`_
- `2019/2020 <./2019-2020/>`_
Mes outils pour faire mes cours
===============================
- `Zoologie des workflows <Divers/Workflows.html>`_
- `Outils Latex <tools/>`_
Méthodes, pratiques et inspirations
===================================
En classe, jaime me souvenir de cette phrase *Plus le professeur travaille, moins lélève travaille*. Je crois que lélève doit, le plus possible, **faire** et pas seulement écouter. Ainsi, lélève est source de contenu pour faire avancer le cours. Il nattend pas passivement que la bonne parole du prof lui soit donnée.
Jai donc abandonné le cahier de cours au profit dun **cahier de bord**, où lavancée et les résultats trouvés par la classe sont inscrits. Les théorèmes ne pouvant plus être donnés, ils sont découverts par la classe et, quand cest possible, démontrés. En relisant ce cahier, lélève peut refaire le cheminement qui nous a permis de trouver un résultat. Il a donc à nouveau la possibilité de **comprendre** et plus seulement dapprendre.
Pour que cela soit possible, il me faut choisir avec attention chaque activité. Elle a besoin dêtre fractale ou riche. Cest à dire dotée de plusieurs niveaux de lecture. Chaque élève doit avoir la possibilité de faire quelque chose. Certains comprendront le sens profond de lactivité tandis que dautres pourront simplement revoir et solidifier des acquis. Lactivité elle-même apporte de la **différenciation**.
Comme exemple, je donnerais lactivité de découverte de `cosinus <./2017-2018/3e/Geometrie/Triangle_rectangle/>`_ . Elle permet de construire des triangles, de revoir la notion dangle, de manipuler le rapporteur, de spiraler sur la notion dagrandissement, de remobiliser les notions de proportionnalité, de définir le cosinus et enfin de ne pas enfermer ce cosinus dans une seule formule.
Ce genre dactivité, exigeante pour les élèves, peut difficilement se faire sur une heure complète. Cest pourquoi, mes heures de classe sont découpées en 2 ou 3 parties distinctes.
Une partie peut être dédiée à la découverte dune notion et la suivante à la consolidation dune notion dans un autre domaine. Ainsi les élèves ne restent pas toute lheure en situation déchec et ont, à chaque cours, lopportunité de montrer quils savent faire des choses. De plus, cette organisation étale davantage dans le temps lapprentissage dune notion pour la rendre plus pérenne.
Certains thèmes sont traités tout au long de lannée à raison dune heure par semaine. Cest le cas du calcul littéral et de la programmation avec Scratch. Au collège, nous avons désormais accès à la salle informatique une heure par semaine. Jen profite pour travailler régulièrement la programmation avec Scratch au travers de **projets** à réaliser en équipe. La progression sur lannée est spiralée. Lobjectif étant davoir fait le tour du programme aux vacances de Noël et ensuite, de revoir et dapprofondir les notions. Cette organisation me laisse le temps de tester plusieurs approches et de désamorcer les problèmes.
Lorganisation de la classe a aussi été transformée afin de tirer profit de plus de diversité. Les élèves sont amenés à travailler individuellement, en groupe et en plénière. À chaque mode dorganisation son support. Quand les élèves travaillent individuellement, ils utilisent leur **cahier de recherche**. En groupe, les traces collectives sont inscrites dans le **cahier de groupe**. Et enfin, les plénières aboutissent généralement à une trace écrite dans le **cahier de bord**. Les cahiers de groupe sont ramassés à chaque fin dheure pour que je puisse préparer la plénière de mise en commun et utiliser les productions délèves.
Ma pratique et mes cours sont très largement inspirés du livre Les maths ensemble et pour chacun. Je minspire aussi de ce que font `Christian den Hartigh <https://pedagogieagile.com/>`_ , `Dan Meyer <http://mrmeyer.com/>`_ ou encore `Arnaud Durand et Julien Durand <http://mathix.org/>`_.

View File

@ -1,103 +0,0 @@
À bas le bon vieux: Classe -> eleve -> classe
#############################################
:date: 2018-07-07
:modified: 2018-07-07
:authors: Benjamin Bertrand
:category: Autres
:summary: Zoologie des workflows rencontrés, expérimentés ou imaginé pour la classe.
:save_as: Enseignements/Divers/Workflows.html
Ici j'essaie de faire une zoologie des façons de travailler que j'ai pu rencontrer, expérimenter ou imaginé. J'espère qu'elle va s'aggrandir avec le temps. J'espérais que cette première énumération m'aiderai à en découvrir d'autre, raté pour le moment..!
L'ancien
========
Le seul l'unique l'indetrônable, le workflow que l'on a tous subit dans notre scolarité.
Pleinière -> Seul -> Pleinière
**Description**: Le prof ecrit le cours (propriété/théorème, exemples), les élèves font les exercices seul dans leur coin (le plus grand silence est imposé) et enfin une correction est donnée au tableau (par les élèves ou le prof).
**Variantes**: Avant le cours, une activité d'introduction ou des révisions sont proposés aux élèves.
Le cours discuté
================
On écrit le cours en posant des micros questions aux élèves. On a donc des micro boucles du genre
Pleinière -> Seul -> Pleinière -> Seul ...
**Description**: Ce cours se fait à partir d'une alternance entre le prof qui fait avancer le cours et les élèves qui réfléchissent sur des temps plutôt court à des questions. Un veritable dialogue entre classe et l'enseignant s'organise.
Le classique
============
Celui là est celui qu'on utilise le plus souvent
Seul -> Groupe -> Pleinière
**Description**: Une activité est donnée au élèves. Ils commencent à plancher dessus seul (sans interactions avec les autres élèves ou avec l'enseignant). Quand ils semblent tous se l'être appropriée (signal de l'enseignant), un travail de groupe démarre. Il se termine sur une production de groupe. Enfin, l'enseignant séléctionne quelques productions pour en faire un bilan en pleinière où la classe toute ensemble reprend les productions les critiques et les améliore pour laisser finalement une trace "parfaite" (point de vue de la classe) sur le cahier de bord.
**Variantes**:
- Avant le travail individuel, il peut être interessant de faire une lecture collective de l'activité pour s'assurer que tout le monde à le vocabulaire ou les notions traitées (à Mayotte c'est la problématique permanante).
- Pour sortir du syndrome de la page blanche, on peut fixer le temps de sortie du travail individuel uniquement une fois que tous les élèves ont commencé à écrire quelque chose d'interessant sur leur cahier de recherche.
- Le temps de travail de groupe peut être coupé par des rapides retours en pleinières pour que les groupes les plus avancés partagent leurs découvertes (surtout celles non terminées).
- Il peut être interessant de changer la composition des groupes surtout vers la fin. Les élèves devront alors expliquer ce qui avait été découvert dans leur ancien groupe et integrer les découvertes des autres groupes.
- Dans le même style, on peut designer un temps où des butineurs (un par équipe) va pouvoir aller voir (sans moyen de prendre de notes) les autres groupes.
- La pleinière peut aussi être annimée par les élèves eux même qui viendront expliquer leur travail aux autres.
DMTC
====
J'aime ce workflow quand il s'ajit de faire faire des taches complexes aux élèves.
Seul -> Groupe -> Seul
**Description**: L'activité débute comme *le classique*. Les élèves décrouvrent le sujet, font leurs première expérimentations puis commencent le travail de groupe. Par contre au lieu de faire un pleinière de mise en commun, les élèves terminent la rédaction seul à la maison. Le but c'est que les difficultés techniques aient été résoluent en classe et avec l'aide des autres et que le travail de rédaction, de représentation (...) soit fait individuellement.
**Variantes**:
- Pour la partie Seul et Groupe, on retrouve les même que pour le *classique*.
- Dan Meyer dans ses 3acts proposent que les élèves cherchent eux même la question et les informations dont ils voudraient avoir accès avant le travail individuel. Cette étape peut être faire sous forme d'un petit *cours discuté*.
La TC prépréparé
================
Le workflow précendent est particulièrement difficile à mettre en place avec les petites classes (6e, 5e). On peut alors plutôt expérimenter celui là
Pleinière -> Pleinière -> individuel/groupe
**Description**: L'activité est donnée relativement en avance. À chaque cours on en parle en pleinière et les élèves sont invités la commencer. Ensuite, on faire l'activité en classe, individuellement ou en groupe.
Je n'ai jamais expérimenté ce workflow mais je sais que Maxime Dupont en était adepte (en espérant ne pas l'avoir trop dénaturé) et arrivait à faire des choses interessantes avec.
La technique/le bachotage
=========================
Workflow parfait pour les séances de travail technique ou les séances de révisions.
Seul -> Groupe -> Seul -> Groupe ...
**Description**: Une série d'exercices techniques est données. Les élèves planchent individuellement dessus. Quand les membres du groupe en ont fait quelques uns, ils mettent leurs résultats en commun et discute des différences constatés pour aboutir à la réponse "parfaite". Si un point de désaccord n'arrive pas à trouver consensus, une correction est sur le bureau qu'ils penvent consulter. Pendant ce genre de scéance, l'enseignant doit être peu solicité, c'est lui qui décide qui il veut voir.
**Variantes**: Organisation du travail avec un kanban. Les élèves y indiquent ce qu'ils prévoient de travailler et là où ils en sont.
Pair à pair
===========
Workflow trop peu exploité. Les élèves produisent des documents à destinations des autres élèves.
Seul -> Groupe -> Seul
**Description**: Les élèves font un premier exercice seul (ou en suivant n'importe quel workflow). Puis en groupe, ils doivent produire un ou plusieurs exercices du même type avec la correction. Les exercices produits sont redonnés aux autres élèves.
On peut demander aux groupes de produire plusieurs exercices du même type mais de difficultés différentes.
**Variantes**:
- Dire aux élèves que le meileur exercice (pas forcement le plus dure) sera dans la prochaine évaluation.
- Echange de travaux de reproduction/codage géométrique.

View File

@ -1,12 +0,0 @@
À propos
########
:date: 2015-05-16
:modified: 2015-05-16
:slug: about
:authors: Benjamin Bertrand
:summary: À propos de l'auteur.
:save_as: about.html
Une petite présentation de ... moi!

View File

@ -1,36 +0,0 @@
Karibu Opytex
##############
:date: 2015-05-16
:modified: 2015-05-16
:slug: index
:authors: Benjamin Bertrand
:summary: Page d'accueil
:save_as: index.html
`Mes cours </Enseignements/>`_
===============================
Ce site regroupe tout ce que j'ai pu écrire pour mes cours de math au collège et au lycée. Vous y trouverez des notes de cours (souvent incomplètes), des fiches d'exercices, des devoirs et quelques réflexions ou commentaires à leur sujet.
`Opytex </opytex>`_
=======================
Outil en ligne de commande pour générer puis compiler des fichiers latex.
J'utilise ce programme essentiellement pour produire des DM aléatoirement avec, quand c'est possible, leur correction (utilise pyMath). En voici un exemple: `DM_15_12_09 <Enseignements/3e/DM/DM_15_12_09/all_DM_15_12_09.pdf>`_.
Voir `la documentation de Opytex </opytex>`_ .
Et `ici <http://opytex.org/Enseignements/3e/DM/DM_15_12_09/>`_ pour des explications sur la création de ces sujets.
Dans la pratique, OpyTex utilise `Jinja2 <http://jinja.pocoo.org/>`_ pour inclure python dans des documents en latex.
`pyMath </pymath>`_
=====================
pyMath est un ensemble de modules écrits en Python qui vise à faciliter et automatiser la conception d'exercices de math et leur correction.
C'est le moteur qui va permettre à `Opytex </opytex>`_ de manipuler les données créées pour faire ces exercices. Il est capable de créer aléatoirement des expressions (calculs de fractions, polynômes, expressions littérales...), des données statistiques, de les simplifier et de faire des calculs avec.
À la différence d'un logiciel de calcul formel classique (comme `sympy <sympy.org>`_), pyMath va non seulement être capable de simplifier des calculs mais surtout d'expliquer comme un élève les étapes qui permettent d'arriver au résultat.

17
globalconf.py Normal file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*- #
from __future__ import unicode_literals
# Menu
MAIN_MENU = True
DISPLAY_PAGES_ON_MENU = False
DISPLAY_CATEGORIES_ON_MENU = False
MENUITEMS = [
#("Dernières modifications", SITEURL+"blog_index.html"),
("Accueil", "/"),
("Contenus de cours", "/pages/tout-sur-mes-cours.html"),
('Blog', '/blog_index.html'),
('Informatique', "/pages/projets-informatiques.html"),
('À propos', "/pages/a-propos.html"),
]

View File

@ -1,18 +1,21 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # # -*- coding: utf-8 -*- #
from __future__ import unicode_literals from __future__ import unicode_literals
import os
import sys
sys.path.append(os.curdir)
from globalconf import *
AUTHOR = 'Benjamin Bertrand' AUTHOR = 'Benjamin Bertrand'
SITENAME = 'OpyTex' SITENAME = 'OpyTex'
SITETITLE = 'OpyTex' SITETITLE = 'OpyTex'
SITESUBTITLE = "Des cours de maths, d'info et un peu de réfléxions personnelles." SITESUBTITLE = "2017-2018"
#SITEURL = 'opytex.org'
SITEURL = '' SITEURL = ''
CC_LICENSE_COMMERCIAL = True CC_LICENSE_COMMERCIAL = True
CC_LICENSE = True CC_LICENSE = True
PATH = 'content' PATH = './content'
TIMEZONE = 'Europe/Paris' TIMEZONE = 'Europe/Paris'
@ -22,27 +25,18 @@ DEFAULT_LANG = 'fr'
THEME = "./theme/" THEME = "./theme/"
USE_GOOGLE_FONTS = False USE_GOOGLE_FONTS = False
IGNORE_FILES = ['venv', '.git', 'tools']
# Pages, articles and static # Pages, articles and static
PAGE_PATHS = ['pages'] PAGE_PATHS = ['pages']
#ARTICLE_PATHS = ['pages/Enseignement', 'Blog'] #ARTICLE_PATHS = ['pages/Enseignement', 'Blog']
ARTICLE_PATHS = ['Enseignements'] ARTICLE_PATHS = ['.']
STATIC_PATHS = ['./'] STATIC_PATHS = ['.']
INDEX_SAVE_AS = 'blog_index.html' INDEX_SAVE_AS = 'blog_index.html'
# Menu # Mirror source structure
MAIN_MENU = True PATH_METADATA = '(?P<path_no_ext>.*)\..*'
DISPLAY_PAGES_ON_MENU = False ARTICLE_URL = ARTICLE_SAVE_AS = PAGE_URL = PAGE_SAVE_AS = '{path_no_ext}.html'
DISPLAY_CATEGORIES_ON_MENU = False
MENUITEMS = [
('Opytex', "/opytex/"),
("pyMath", "/pymath/"),
("Enseignement", "/Enseignements"),
#('blog', '/blog_index.html'),
('À propos', "/about.html"),
('Archives', "/archives.html"),
]
# Feed generation is usually not desired when developing # Feed generation is usually not desired when developing
FEED_ALL_ATOM = None FEED_ALL_ATOM = None
@ -53,11 +47,11 @@ AUTHOR_FEED_RSS = None
# Blogroll # Blogroll
LINKS = ( LINKS = (
('2019/2020', "/Enseignements/2019-2020/"), #('2019/2020', "/Enseignements/2019-2020/"),
('2018/2019', "/Enseignements/2018-2019/"), #('2018/2019', "/Enseignements/2018-2019/"),
('2017/2018', "/Enseignements/2017-2018/"), #('2017/2018', "/Enseignements/2017-2018/"),
('2016/2017', "/Enseignements/2016-2017/"), #('2016/2017', "/Enseignements/2016-2017/"),
('2015/2016', "/Enseignements/2015-2016/"), #('2015/2016', "/Enseignements/2015-2016/"),
) )
# Social widget # Social widget
@ -73,12 +67,12 @@ ARTICLE_ORDER_BY = "modified"
DISPLAY_ARTICLE_INFO_ON_INDEX = True DISPLAY_ARTICLE_INFO_ON_INDEX = True
# Uncomment following line if you want document-relative URLs when developing # Uncomment following line if you want document-relative URLs when developing
#RELATIVE_URLS = True RELATIVE_URLS = True
BOOTSTRAP_THEME = "flatly" BOOTSTRAP_THEME = "flatly"
PLUGIN_PATHS = ['./plugins', './pelican-plugins'] PLUGIN_PATHS = ['./plugins', './pelican-plugins']
PLUGINS = ['hierarchy', PLUGINS = [#'hierarchy',
'tag_cloud', 'tag_cloud',
"list_files", "list_files",
"render_math", "render_math",
@ -89,11 +83,10 @@ PLUGINS = ['hierarchy',
READERS = {"html": None} READERS = {"html": None}
# hierarchy plugin config # hierarchy plugin config
ARTICLE_URL = 'Enseignements/{slug}/' # ARTICLE_URL = 'Enseignements/{slug}/'
ARTICLE_SAVE_AS = 'Enseignements/{slug}/index.html' # ARTICLE_SAVE_AS = 'Enseignements/{slug}/index.html'
#SLUGIFY_SOURCE = 'basename' # #SLUGIFY_SOURCE = 'basename'
ARTICLE_NAVIGATION = True # ARTICLE_NAVIGATION = True
TAGS_URL = "tags.html" TAGS_URL = "tags.html"
DISPLAY_TAGS_INLINE = True DISPLAY_TAGS_INLINE = True

View File

@ -10,11 +10,12 @@ import sys
sys.path.append(os.curdir) sys.path.append(os.curdir)
from pelicanconf import * from pelicanconf import *
SITEURL = 'opytex.org' # If your site is available via HTTPS, make sure SITEURL begins with https://
RELATIVE_URLS = True SITEURL = 'https://opytex.org/enseignements/2019-2020/'
RELATIVE_URLS = False
FEED_ALL_ATOM = 'feeds/all.atom.xml' FEED_ALL_ATOM = 'feeds/all.atom.xml'
CATEGORY_FEED_ATOM = 'feeds/%s.atom.xml' CATEGORY_FEED_ATOM = 'feeds/{slug}.atom.xml'
DELETE_OUTPUT_DIRECTORY = True DELETE_OUTPUT_DIRECTORY = True

View File

@ -1,11 +1,15 @@
beautifulsoup4==4.9.1
blinker==1.4 blinker==1.4
docutils==0.13.1 bs4==0.0.1
feedgenerator==1.9 docutils==0.16
Jinja2==2.9.6 feedgenerator==1.9.1
MarkupSafe==1.0 Jinja2==2.11.2
pelican==3.7.1 MarkupSafe==1.1.1
Pygments==2.2.0 pelican==4.2.0
python-dateutil==2.6.0 Pygments==2.6.1
pytz==2017.2 python-dateutil==2.8.1
six==1.10.0 pytz==2020.1
Unidecode==0.4.20 six==1.15.0
soupsieve==2.0.1
Unidecode==1.1.1
Wand==0.6.1

136
tasks.py Normal file
View File

@ -0,0 +1,136 @@
# -*- coding: utf-8 -*-
import os
import shutil
import sys
import datetime
from invoke import task
from invoke.util import cd
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
from pelican.settings import DEFAULT_CONFIG, get_settings_from_file
SETTINGS_FILE_BASE = 'pelicanconf.py'
SETTINGS = {}
SETTINGS.update(DEFAULT_CONFIG)
LOCAL_SETTINGS = get_settings_from_file(SETTINGS_FILE_BASE)
SETTINGS.update(LOCAL_SETTINGS)
CONFIG = {
'current_path': os.getcwd(),
'settings_base': SETTINGS_FILE_BASE,
'settings_publish': 'publishconf.py',
'year_subfolder': 'enseignements/2018-2019/',
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
'deploy_path': SETTINGS['OUTPUT_PATH'],
'fake_path': '../../output/',
# Remote server configuration
'ssh_user': 'sshcontent',
'ssh_host': 'Embrevade',
'ssh_port': '22',
'ssh_path': '/home/sshcontent/opytex.org/www/',
# Rsync config
'rsync_exclude': '',
# Port for `serve`
'port': 8000,
}
@task
def clean(c):
"""Remove generated files"""
if os.path.isdir(CONFIG['deploy_path']):
shutil.rmtree(CONFIG['deploy_path'])
os.makedirs(CONFIG['deploy_path'])
@task
def build(c):
"""Build local version of site"""
c.run('lessc {current_path}/theme/static/stylesheet/style.less {current_path}/theme/static/stylesheet/style.min.css -x'.format(**CONFIG))
c.run('pelican -s {settings_base}'.format(**CONFIG))
@task
def rebuild(c):
"""`build` with the delete switch"""
c.run('pelican -d -s {settings_base}'.format(**CONFIG))
@task
def regenerate(c):
"""Automatically regenerate site upon file modification"""
c.run('pelican -r -s {settings_base}'.format(**CONFIG))
@task
def serve(c):
"""Serve site at http://localhost:$PORT/ (default port is 8000)"""
class AddressReuseTCPServer(RootedHTTPServer):
allow_reuse_address = True
server = AddressReuseTCPServer(
CONFIG['deploy_path'],
('', CONFIG['port']),
ComplexHTTPRequestHandler)
sys.stderr.write('Serving on port {port} ...\n'.format(**CONFIG))
server.serve_forever()
@task
def reserve(c):
"""`build`, then `serve`"""
build(c)
serve(c)
@task
def preview(c):
"""Build production version of site"""
c.run('pelican -s {settings_publish}'.format(**CONFIG))
@task
def livereload(c):
"""Automatically reload browser tab upon file modification."""
from livereload import Server
build(c)
server = Server()
# Watch the base settings file
server.watch(CONFIG['settings_base'], lambda: build(c))
# Watch content source files
content_file_extensions = ['.md', '.rst']
for extension in content_file_extensions:
content_blob = '{0}/**/*{1}'.format(SETTINGS['PATH'], extension)
server.watch(content_blob, lambda: build(c))
# Watch the theme's templates and static assets
theme_path = SETTINGS['THEME']
server.watch('{}/templates/*.html'.format(theme_path), lambda: build(c))
static_file_extensions = ['.css', '.js']
for extension in static_file_extensions:
static_file = '{0}/static/**/*{1}'.format(theme_path, extension)
server.watch(static_file, lambda: build(c))
# Serve output path on configured port
server.serve(port=CONFIG['port'], root=CONFIG['deploy_path'])
@task
def publish(c):
"""Publish to production via rsync"""
c.run('pelican -s {settings_publish}'.format(**CONFIG))
c.run(
'rsync --delete {rsync_exclude} -pthrvz -c '
'-e "ssh " '
'{} {ssh_host}:{ssh_path}'.format(
CONFIG['deploy_path'].rstrip('/') + '/',
**CONFIG))
@task(
pre=[build]
)
def fake(c):
""" Mimic a push to server """
print('{fake_path}{year_subfolder}'.format(**CONFIG))
os.makedirs('{fake_path}{year_subfolder}'.format(**CONFIG), exist_ok=True)
c.run('rsync -P -rvzc --delete {rsync_exclude} {deploy_path}/ {fake_path}{year_subfolder} --cvs-exclude'.format(**CONFIG))

View File

@ -113,6 +113,48 @@ aside {
} }
} }
} }
.tagcloud {
padding: 0;
list-style: none;
li {
display: inline-block;
}
h2 {
background-color: @sidebar-bg;
margin-bottom: 0;
}
ul {
list-style: none;
padding: 0;
}
ul li {
display: inline-block;
}
li.tag-0 {
font-size: 170%;
}
li.tag-1 {
font-size: 150%;
}
li.tag-2 {
font-size: 120%;
}
li.tag-3 {
font-size: 100%;
}
li.tag-4 {
font-size: 80%;
}
}
} }
main { main {

File diff suppressed because one or more lines are too long

View File

@ -23,7 +23,7 @@
@sidebar-bg: @grey; @sidebar-bg: @grey;
@sidebar-text-color: @white; @sidebar-text-color: @white;
@sidebar-link-color: @white; @sidebar-link-color: @white;
@sidebar-link-hover-color: @light-grey; @sidebar-link-hover-color: @light-orange;
// Buttons // Buttons
@btn-bg: @orange; @btn-bg: @orange;

View File

@ -72,6 +72,7 @@
<body> <body>
<aside> <aside>
<div> <div>
<!--
<a href="{{ SITEURL }}/"> <a href="{{ SITEURL }}/">
{% if SITELOGO %} {% if SITELOGO %}
<img src="{{ SITELOGO }}" alt="{{ SITETITLE }}" title="{{ SITETITLE }}"> <img src="{{ SITELOGO }}" alt="{{ SITETITLE }}" title="{{ SITETITLE }}">
@ -79,10 +80,12 @@
<img src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/img/profile.png" alt="{{ SITETITLE }}" title="{{ SITETITLE }}"> <img src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/img/profile.png" alt="{{ SITETITLE }}" title="{{ SITETITLE }}">
{% endif %} {% endif %}
</a> </a>
<h1><a href="{{ SITEURL }}/">{{ SITETITLE }}</a></h1> -->
<h1><a href="/">{{ SITETITLE }}</a></h1>
{% if SITESUBTITLE %}<p>{{ SITESUBTITLE }}</p>{% endif %} {% if SITESUBTITLE %}<p><a href="{{ SITEURL }}/">{{ SITESUBTITLE }}</a></p>{% endif %}
<!--
<h2>Années</h2> <h2>Années</h2>
<nav> <nav>
<ul class="list"> <ul class="list">
@ -91,30 +94,33 @@
{% endfor %} {% endfor %}
</ul> </ul>
</nav> </nav>
-->
<h2>Niveaux</h2> <h2>Niveaux</h2>
<nav> <nav>
<ul class="list"> <ul class="list">
{% for category, articles in categories|sort %} {% for category, articles in categories|sort %}
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a> ({{ articles|count }})</li> <li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }} ({{ articles|count }})</a></li>
{% endfor %} {% endfor %}
</ul> </ul>
</nav> </nav>
<h2><a href="{{ SITEURL }}/tags.html"> <h2><a href="{{ SITEURL }}/tags.html">
Thèmes Thèmes
</a></h2> </a></h2>
<nav> <nav>
<ul class="tagcloud">
{% for tag in tag_cloud %} <ul class="tagcloud">
<li class="tag-{{ tag.1 }}"> {% for tag in tag_cloud %}
<a href="{{ SITEURL }}/{{ tag.0.url }}"> <li class="tag-{{ tag.1 }}">
{{ tag.0 }} <a href="{{ SITEURL }}/{{ tag.0.url }}">
{% if TAG_CLOUD_BADGE %} {{ tag.0 }}
<span class="badge">{{ tag.2 }}</span> {% if TAG_CLOUD_BADGE %}
{% endif %} <span class="badge">{{ tag.2 }}</span>
</a> {% endif %}
</li> </a>
{% endfor %} </li>
</ul> {% endfor %}
</ul>
</nav> </nav>
</div> </div>
@ -122,8 +128,6 @@
<main> <main>
{% if MAIN_MENU %} {% if MAIN_MENU %}
<nav> <nav>
<a href="{{ SITEURL }}/">{{ _('Home') }}</a>
{% for title, link in MENUITEMS %} {% for title, link in MENUITEMS %}
<a href="{{ link }}">{{ title }}</a> <a href="{{ link }}">{{ title }}</a>
{% endfor %} {% endfor %}
@ -169,5 +173,6 @@
{% if GITHUB_CORNER_URL %} {% if GITHUB_CORNER_URL %}
{% include 'partial/github.html' %} {% include 'partial/github.html' %}
{% endif %} {% endif %}
<script type="text/javascript" async defer data-website-id="2cb9cd4c-66da-4e4f-9e84-a2d53c7b07bc" src="https://stat.opytex.org/umami.js"></script>
</body> </body>
</html> </html>