# prose 

See this readme in english: [EN](#en).

prose est un outil simple pour écrire des billets de blog sans avoir à
se préoccuper d'installer PHP, de le mettre à jour, de maintenir une
base de données ou apprendre l'utilisation parfois complexe d'un CMS.  
`prose` ne requiert qu'un serveur mail (par exemple `smtpd` sur
OpenBSD ;)) : il ne vous reste plus qu'à envoyer un email à une adresse
dédiée à la publication d'un blog pour voir votre nouveau billet.

Par ailleurs, `prose` est écrit en C, ce qui assure sa rapidité et
permet de profiter de 
[pledge](http://man.openbsd.org/pledge) et
[unveil](http://man.openbsd.org/unveil) garantissant une sécurité
supplémentaire. Cela dit, il doit pouvoir fonctionner sur n'importe quel
système UNIX.

L'objectif principal est de mettre l'accent sur le contenu, sur
l'écriture. Tenir un blog ressemble davantage à écrire un journal intime
et non à fabriquer un site web.

N'hésitez pas à proposer des améliorations en envoyant vos diff.

## Installation et configuration
`prose` est censé être utilisé sans avoir être être root.
Puisqu'`unveil` est actif, le programme est enfermé dans le dossier qui
contiendra les articles et le site web.

On va donc présenter ici l'installation de `prose` pour un utilisateur
dédié à cette tâche. On l'appellera "writer". On crée cet utilisateur:

	useradd -m /home writer
	passwd writer


Ensuite, on se connecte en tant que "writer":

	su writer

on télécharge `prose` et le décompresse:

	ftp https://si3t.ch/code/prose.tgz
	tar xvzf prose
	cd prose/

Éditez le configuration en modifiant le fichier `config.h`:

	vi config.h

Ensuite, compilez prose en entrant:

	make prose

À ce point, le binaire est situé dans `$HOME/prose/prose`.

Maintenant, on crée un dossier pour contenir le blog:

	cd $HOME
	mkdir wwwblog

On s'assure maintenant que tous les messages envoyés à
`writer@domaine.tld` est pris en charge par `prose`. On utilise alors
[forward](https://man.openbsd.org/forward). Éditez le fichier
`$HOME/.forward` pour ajouter:

	|/home/writer/prose/prose /home/writer/wwwblog

`prose` prend comme argument le dossier de destination.

Si la manipulation ci-dessus ne fonctionne pas comme prévu (hum...
contactez l'admin...), vous pouvez modifier le fichier
`/etc/mail/aliases` ainsi (requiert un accès root, donc d'être l'admin):

	writer: "|/home/writer/prose/prose /home/writer/wwwblog"

Il faudra alors lancer ensuite `newaliases`.

Pour servir les fichiers de votre blog, il faudra copier le contenu du
dossier `wwwblog` à l'endroit approprié pour le serveur web.
Le plus simple avec les outils de base semble d'utiliser une tâche cron.
Entrez `crontab -e` puis ajoutez:

	@hourly /usr/bin/openrsync -r /home/writer/wwwblog/ /var/www/htdocs/blog/

Certains préférerons à la place créer un script autour de `prose` qui
appellera openrsync juste après prose.

Certains pr\xc3\xa9f\xc3\xa9rerons \xc3\xa0 la place cr\xc3\xa9er un script autour de `prose` qui
appellera openrsync juste apr\xc3\xa8s prose.
Le fichier `.forward` contiendra alors seulement l'appel \xc3\xa0 ce script:
 
	writer: "|/home/writer/blogit.sh"

et `/home/writer/blogit.sh` contiendra:
 
	 #!/bin/sh
	 /home/writer/prose/prose /home/writer/wwwblog
	/usr/bin/openrsync -r /home/writer/wwwblog/ /var/www/htdocs/blog/

Vous voilà prêt à publier un article.

## Utilisation

Envoyez un mail à `writer@domaine.tld`.
Gardez en tête que:

* La première ligne du corps de votre message contient le mot de passe
  définit dans le `config.h`. C'est tout. Si le mot de passe n'est pas
  trouvé, alors `prose` s'arrête.
* Les lignes vides suivantes sont ignorées.
* La première ligne suivante sera considérée comme le titre de votre
  article dans le flux ATOM.

Le corps du message peut-être du texte simple ou du code html.
Cependant, `prose` ne prend pas en charge les mails multiparts, veillez
donc à utiliser configurer votre client de messagerie afin qu'il envoie
les messages en text/plain.

Un flux ATOM et un fichier sitemap seront créés automatiquement.

### Exemple (un peu geek):

    $ vi /tmp/article.txt
    [...]:wq
    $ cat /tmp/article.txt | mail -s "article" writer@domaine.tld


## Configuration

### config.h
La majeure partie de la configuration se fait dans le fichier `config.h`
avant compilation. Vous pouvez définir:

* `pw` : le mot de passe
* `ext` : les extensions des articles bruts
* `url` : l'adresse vers votre blog
* `markup` : chemin vers un exécutable qui va convertir votre
message en html, comme markdown par exemple. Laissez la valeur à
"NULL" si vous ne voulez pas que le corps de votre message soit
modifié. C'est même encore plus sûr car les appels
à pledge à `unveil` et `pledge` seront plus durs.
* `atomfp` : le nom de fichier du flux atom
* `maxentry` : le nombre d'entrées maximales dans le flux atom
* `headhtml`, `footerhtml`, `atom`, `atomentry` : les modèles qui
  servent à générer les pages html.
  Veillez à bien laisser les "`%s`" et "`%d`" afin qu'ils soient
  remplacés par l'url de votre blog et le numéro de la page.


### CSS
Vous pouvez modifier l'apparence de votre blog en éditant une feuille de
style. Notez que les id et class suivant sont utilisés:

* `id="page"` : numéro de page
* `class="arrow"` : flèche vers article suivant ou précédent
* `class="next"` : article suivant
* `class="prev"` : article précédent


## FAQ

### prose ne supporte pas un langage markup?
Non.
Mais vous pouvez très bien rédiger par exemple en markdown puis
convertir ce dernier juste avant de l'envoyer par mail.

Plus sérieusement, vous pouvez définir l'option "`markup`"
dans le fichier config.h vers un exécutable de votre choix, par
exemple markdown. Ce dernier va convertir votre mail à la
réception.

### C'est sécurisé?
Autant que possible.
Au moins, il n'y a pas besoin de PHP ou python.
[pledge](http://man.openbsd.org/pledge) assure que `prose` ne peut que
lire et écrire dans des fichiers, rien d'autre (pas d'exécution de
commandes tierces par exemple).
[unveil](http://man.openbsd.org/unveil) enferme `prose` dans le dossier
qui contiendra le blog. Aucun autre accès au système n'est permis.

De plus, `forward` est très strict en terme de permissions.

Au pire, quelqu'un peut écrire un mail à votre place sur le compte
défini (`writer@domaine.tld` dans l'exemple), un spam par exemple. C'est
pourquoi:

* Gardez l'adresse de publication secrète.
* Définissez un bon mot de passe.

### Et les brouillons?
Un client mail supporte sûrement ça.

### J'ai fait une faute, comment la corriger?
Il faut directement éditer les fichiers (par ssh par exemple).
Ou bien laisser les choses ainsi : ça fait partie du jeu, vous rédigez
un blog, c'est spontané, c'est éphémère : il y a des erreurs c'est
normal.


### Que se passe-t-il s'il y a une erreur?
Le serveur mail va renvoyer un message contenant l'erreur. Par exemple,
si le mot de passe est mauvais:

```
Hi!

This is the MAILER-DAEMON, please DO NOT REPLY to this email.

An error has occurred while attempting to deliver a message for
the following list of recipients:

writer@domaine.tld: "prose: wrong password, exit: Undefined error: 0"

Below is a copy of the original message:
```

### Comment configurer httpd dans ce cas?

	mkdir /var/www/htdocs/blog
	chown writer:writer /var/www/htdocs/blog

/etc/httpd.conf:

server "blog.domain.tld" {
        listen on * port 80
        root "/htdocs/blog"
        directory index index.html
}


### Comment régénérer un blog tout entier?

Il suffit de faire passer chaque article brut dans `prose`. 
Voici par exemple un script pour ça, qui se lance à
l'intérieur du dossier contenant votre blog (dans l'exemple,
c'état `/home/writer/blog`). On déplace avant ça
les articles dans un dossier temporaire "regen". Pensez à
remplacer votre mot de passe dans le script si vous l'utilisez.


```
mkdir -p regen
mv *.txt regen/
find regen/ -iname "*.txt" -maxdepth 1 | while read -r i; do
	(echo "\n\n${PW}"
	cat $1) |\
	/home/prxblog/prose/prose /home/prxblog/blog/
	done
```

Supprimez le dossier "regen" ensuite.

Le script `regen-blog` est inclus à l'archive de `prose`.

---

<a href="#" id="en"></a>
prose is a little tool to write your own blog without worrying about
PHP, database or requiring a brower with complex CMS. 
It only require a working email server (`smtpd` :)) : send a message to a configured address and see
your new entry published.
It's goal is to stay focused on writing. Blogging is like a web diary
again, not a CMS-like.

It is writtend in C, pledged and unveiled.
It was developped under OpenBSD and might work on other UNIX with a few
adjustments.

Feel free to contribute and suggest improvements.

## Install and configure
It is supposed to be run by any user, not root, so we install prose in
user home directory. When the user will get an email, it will be parsed
by `prose`. Thus, it is advised to create a specific user to run the
blog. 
For the example, we use the user `writer` for this purpose (use
`adduser` to create the new account).

Next commands are run by the user `writer`:

	su writer

get prose:

	ftp https://si3t.ch/code/prose.tgz
	tar xvzf prose
	cd prose/

edit configuration : 

	vi config.h

Then compile:

	make prose

For now, we have prose binary in `$HOME/prose/prose`.

Create a directory to store your blog:

	cd $HOME
	mkdir wwwblog

Now make sure all email for `writer@yourdomain.tld` are managed by `prose`.
Edit `$HOME/.forward` (see `forward 5`) and add :

	|/home/writer/prose/prose /home/writer/wwwblog

`prose` takes as argument the output directory.

If the above don't work as expected, you can edit `/etc/mail/aliases` this way,
but it requires root access:

	writer: "|/home/writer/prose/prose /home/writer/wwwblog"

Then run `newaliases`.

You need to copy `wwwblog` to a place where it can be served by a http
server (like `httpd`). To do so, use a cronjob and rsync.

	@hourly /usr/bin/openrsync -r /home/writer/wwwblog/ /var/www/htdocs/blog/

Now, You're ready to publish your new article.

## Usage

Write a new note to `writer@yourdomain.tld`.
Remember:

* First line of your message must be the password defined in `config.h`.
Otherwise, the note is discarded.
* Following empty lines are ignored.
* Second line is the title of your note.

It is advised to write in plaintext, but do whatever you want after
all.

An atom feed will be created and a sitemap too.


## Configuration

### config.h
Most of `prose` is configured by editing source code.

You can change:

* `pw` : the password
* `ext` : file extension of raw articles
* `url` : url to your blog
* `markup` : path to executable that will convert your post to html
(such as markdown). If you don't need it, leave "`NULL`" and enjoy
harder `pledge` and `unveil` rules.
* `atomfp` : file name of atom feed.
* `maxentry` : number of atom entry.
* `headhtml`, `footerhtml`, `atom`, `atomentry` : templates to generate
html and atom pages. Take care to leave `%s` and `%d` so they are
replaced by url and page numbers.


### CSS
Some classes are used in pages:

* `id="page"` : page number, like in a diary.
* `class="arrow"` : arrows to see next and previous article.
* `class="next"` : next article arrow link.
* `class="prev"` : previous article arrow link.


## FAQ

### Isn't there any markup ?
Nope.
If you need to, write markdown and translate it to html (there are
converters online).

More seriously, you can set `markup` option in "config.h" file to call
external program that will convert your blog post.

### Is it secure?
It tries to. At least, it doesn't require PHP or python.
It is [pledged](http://man.openbsd.org/pledge).
It is [unveiled](http://man.openbsd.org/unveil).
`forward` is very strict about permission.

The worst that might happen is someone sending an email to
`writer@yourdomain.tld` guessing the right password. So:

* Don't publish this address online.
* Use a strong passphrase.

### How to keep drafts?
Your mail client can keep drafts, for sure.

### I made a mistake, how do I fix it?
ssh to your server and edit the file.

Or keep it this way : it's a diary, it has mistakes.


### What happens if there is an error?
You'll see the error in the returned mail. As example if you forgot to
create the output directory, you'll see:


```
Hi!

This is the MAILER-DAEMON, please DO NOT REPLY to this email.

An error has occurred while attempting to deliver a message for
the following list of recipients:

blabla@domain.tld: "prose: opendir '/home/writer/wwwblog':: No such file or directory"

Below is a copy of the original message:
```

### What if the password is wrong ?
Same as above, but the message will be:

```
blabla@domain.tld: "prose: wrong password, exit: Undefined error: 0"
```

### How to regenerate a whole blog ?

Just pipe every raw article to `prose`. A script `regen-blog` is
included to do so. It will copy every raw article into a "regen"
directory that you may delete after.

Edit this script to change the password according to yours.

```
mkdir -p regen
mv *.txt regen/
find regen/ -iname "*.txt" -maxdepth 1 | while read -r i; do
	(echo "\n\n${PW}"
	cat $i) |\
	/home/prxblog/prose/prose /home/prxblog/blog/
done
```

Replace `cat` with your markdown converter if needed:

```
mkdir -p regen
mv *.txt regen/
find regen/ -iname "*.txt" -maxdepth 1 | while read -r i; do
	(echo "\n\n${PW}"
	cmark -t html --smart --unsafe $i) |\
	/home/prxblog/prose/prose /home/prxblog/blog/
done
```

## Forewords

### useradd

	useradd -m /home writer
	passwd writer


### httpd

	mkdir /var/www/htdocs/blog
	chown writer:writer /var/www/htdocs/blog

/etc/httpd.conf:

    server "blog.domain.tld" {
        listen on * port 80
        root "/htdocs/blog"
        directory index index.html
    }

