How do I write this website?
I use Emacs Org-mode to write this website. I deploy the site to s3.
Here is the code.
Makefile
aziz.tn/dev: ./dev.sh aziz.tn/deploy: docker build -t aziz_site_deploy -f Dockerfile.deploy . && docker run -t aziz_site_deploy
dev.sh
#!/bin/bash rebuild_container() { docker stop azizsite docker rm azizsite docker build -t aziz_site -f Dockerfile.dev . docker run --rm -d --name azizsite -p 8080:80 -t aziz_site } while true; do rebuild_container inotifywait -r -e modify,create,delete . done
Dockerfile.dev
FROM ubuntu:20.04 as builder RUN apt-get update && apt-get install emacs-nox -y COPY . /app/ WORKDIR /app/src/ RUN emacs -Q --script ./site.el FROM httpd:2.4 COPY --from=builder /app/publish/ /usr/local/apache2/htdocs/
Dockerfile.deploy
FROM ubuntu:20.04 RUN apt-get update && apt-get install emacs-nox -y RUN apt-get install awscli -y COPY . /app/ WORKDIR /app/src/ RUN emacs -Q --script ./site.el COPY keys/credentials /root/.aws/credentials CMD aws s3 sync /app/publish/ s3://xxxxxxx/
downsize.py
(script to downsize images and strip metadata)
from PIL import Image from PIL import ImageOps import os import piexif def resize_image(filename, max_size): with Image.open(filename) as img: img = ImageOps.exif_transpose(img) width, height = img.size if width > max_size or height > max_size: if width > height: ratio = max_size / width new_size = (max_size, int(height * ratio)) else: ratio = max_size / height new_size = (int(width * ratio), max_size) img = img.resize(new_size, Image.ANTIALIAS) img.save(filename, optimize=True, quality=95) def strip_exif(image_path): exif_dict = piexif.load(image_path) if exif_dict: exif_dict.pop("Exif", None) exif_dict.pop("GPS", None) exif_dict.pop("Interop", None) exif_dict.pop("1st", None) exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, image_path) def main(): # Set the maximum image size max_size = 1000 # Loop through all the image files in the current directory for filename in os.listdir('src/static/photos'): if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')): # Resize the image if it's larger than the maximum size resize_image('src/static/photos/' + filename, max_size) strip_exif('src/static/photos/' + filename) if __name__ == '__main__': main()
site.el
(script to generate the website)
(setq user-full-name "Aziz Knani" user-mail-address "me@aziz.tn") (add-to-list 'load-path "/app/elisp/") (require 'ox-publish) (require 'ox-rss) (if (file-exists-p "../publish") (delete-directory "../publish" t)) (setq org-html-htmlize-output-type 'css) (setq org-html-htmlize-font-prefix "org-") (defun my/org-publish-sitemap (title list) "Default site map, as a string. TITLE is the the title of the site map. LIST is an internal representation for the files to include, as returned by `org-list-to-lisp'. PROJECT is the current project." (concat "#+TITLE: " title "\n\n" (org-list-to-org (cadar (delq nil (mapcar (lambda (x) (member "blog" x)) (cdr list))))))) (defun my/org-publish-sitemap-entry (entry style project) "Default format for site map ENTRY, as a string. ENTRY is a file name. STYLE is the style of the sitemap. PROJECT is the current project." (cond ((not (directory-name-p entry)) (format "[[file:%s][(%s) %s]]" entry (format-time-string "%d/%m/%Y" (org-publish-find-date entry project)) (org-publish-find-title entry project))) ((eq style 'tree) ;; Return only last subdir. (file-name-nondirectory (directory-file-name entry))) (t entry))) (setq org-publish-project-alist `(("aziz.tn-org" :base-directory "." :base-extension "org" :publishing-directory "../publish/" :recursive t :html-doctype "html5" :with-date t :html-html5-fancy t :section-numbers nil :with-toc nil :publishing-function org-html-publish-to-html :auto-sitemap t :sitemap-function my/org-publish-sitemap :sitemap-filename "journal.org" :sitemap-title "Journal" :sitemap-sort-files anti-chronologically :sitemap-format-entry my/org-publish-sitemap-entry :headline-levels 4 :html-preamble " <ul class=\"menu\"> <li><a href=\"/\">Home</a></li> <li><a href=\"/about.html\">About</a></li> <li><a href=\"/journal.html\">Journal</a></li> <li><a href=\"/photos.html\">Photos</a></li> </ul>" :html-postamble " <hr> <p class=\"author\">Author: %a </p>\n<p class=\"date\">Date: %T </p>\n<p class=\"creator\">%c</p> <a style=\"display:block; text-align:center; \" href='https://www.discovertunisia.com/en/'> <img id=\"tunisia\"style='width: auto;height: 50px; opacity: 35%%;' src='/static/img/tn_flag.svg' alt='Tunisian flag' /></a>" :html-head-extra ,(concat "<style>" (with-temp-buffer (insert-file-contents "./static/css/theme.css") (buffer-string)) "</style>" "<link href=\"https://fonts.googleapis.com/css?family=Source+Code+Pro&display=swap\" rel=\"stylesheet\">" )) ("aziz.tn-static" :base-directory "." :base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf\\|el\\|py\\|c\\|sh\\|txt\\|svg" :publishing-directory "../publish/" :recursive t :publishing-function org-publish-attachment) ("aziz.tn-tangle" :base-directory "." :publishing-directory "static/files" :recursive t :publishing-function org-babel-tangle-publish) ("aziz.tn-rss" :base-directory "." :base-extension "org" :exclude ".*" :publishing-directory "../publish/" :publishing-function org-rss-publish-to-rss :include ("journal.org")) ("aziz.tn" :components ("aziz.tn-org" "aziz.tn-static" ;; "aziz.tn-rss" "aziz.tn-tangle")))) (org-publish "aziz.tn" t)