From d789212b8788e7cb0c0c17e8c97b1f51d6c3b99f Mon Sep 17 00:00:00 2001 From: "Yann Esposito (Yogsototh)" Date: Thu, 25 Jul 2019 11:10:50 +0200 Subject: [PATCH] Updated the auto-load script --- .project.el | 204 -------------------- .project.el.gpg | Bin 0 -> 3154 bytes src/posts/2019-07-04-static-org-publish.org | 122 +++++++++--- 3 files changed, 95 insertions(+), 231 deletions(-) delete mode 100644 .project.el create mode 100644 .project.el.gpg diff --git a/.project.el b/.project.el deleted file mode 100644 index 9db8eb1..0000000 --- a/.project.el +++ /dev/null @@ -1,204 +0,0 @@ -(require 'org) -(require 'ox-publish) -(require 'ox-html) -(require 'org-element) -(require 'ox-rss) - -(setq org-link-file-path-type 'relative) - -(defun org-blog-prepare (project-plist) - "With help from `https://github.com/howardabrams/dot-files'. - Touch `index.org' to rebuilt it. - Argument `PROJECT-PLIST' contains information about the current project." - (let* ((base-directory (plist-get project-plist :base-directory)) - (buffer (find-file-noselect (expand-file-name "index.org" base-directory) t))) - (with-current-buffer buffer - (set-buffer-modified-p t) - (save-buffer 0)))) - -(defvar org-blog-head - (concat - "" - "" - "" - "")) - -(defun menu (lst) - "Blog menu" - (concat - "" - (mapconcat 'identity - (append - '("Home" - "Posts") - lst) - " | ") - "")) - - -(defun str-time-to-year-float (date-str) - (/ (float-time - (apply 'encode-time - (mapcar (lambda (x) (if (null x) 0 x)) - (parse-time-string date-str)))) - (* 365.25 24 60 60))) - -(defvar blog-creation-date "2019-07-01") - -(defun y-date (date-str) - "Number of year since the begining of this blog" - (let ((y (- (str-time-to-year-float date-str) - (str-time-to-year-float blog-creation-date)))) - (format "∆t=%.2f" y))) - -(defun org-blog-preamble (info) - "Pre-amble for whole blog." - (concat - "
" - (menu '("↓ bottom ↓")) - "

" - (format "%s" (car (plist-get info :title))) - (when-let ((date (get-from-info info :date))) - (format " - %s" date)) - "

" - "
")) - -(defun get-from-info (info k) - (let ((i (car (plist-get info k)))) - (when (and i (stringp i)) - i))) - -(defun rand-obfs (c) - (let ((r (% (random) 20))) - (cond ((eq 0 r) (format "%c" c)) - ((< 0 r 10) (format "&#%d;" c)) - (t (format "&#x%X;" c))))) - -(defun obfuscate-html (txt) - (apply 'concat - (mapcar 'rand-obfs txt))) - -(defun org-blog-postamble (info) - "Post-amble for whole blog." - (concat - "
" - "
" - (when-let ((author (get-from-info info :author))) - (if-let ((email (plist-get info :email))) - (format "
Author: %s
" - (obfuscate-html "mailto:") - (obfuscate-html email) - (obfuscate-html author)) - (format "
Author: %s
" author))) - (when-let ((date (get-from-info info :date))) - (format "
Created: %s (%s)
" date (y-date date))) - (when-let ((keywords (plist-get info :keywords))) - (format "
Keywords: %s
" keywords)) - (format "
Generated: %s
" - (format-time-string "%Y-%m-%d %H:%M:%S")) - (format (concat "
Generated with " - "Emacs %s, " - "Spacemacs %s, " - "Org Mode %s" - "
") - emacs-version spacemacs-version org-version) - "
" - (menu '("↑ Top ↑")) - "
")) - -(defun org-blog-sitemap-format-entry (entry _style project) - "Return string for each ENTRY in PROJECT." - (when (s-starts-with-p "posts/" entry) - (format "@@html:@@ %s: @@html:@@ [[file:%s][%s]] @@html:@@" - (format-time-string "%Y-%m-%d" - (org-publish-find-date entry project)) - entry - (org-publish-find-title entry project)))) - -(defun org-blog-sitemap-function (title list) - "Return sitemap using TITLE and LIST returned by `org-blog-sitemap-format-entry'." - (concat "#+TITLE: " title "\n" - "#+AUTHOR: Yann Esposito\n" - "#+EMAIL: yann.esposito@gmail.com\n" - "\n#+begin_archive\n" - (mapconcat (lambda (li) - (format "@@html:
  • @@ %s @@html:
  • @@" (car li))) - (seq-filter #'car (cdr list)) - "\n") - "\n#+end_archive\n")) - -(setq base-dir (concat (projectile-project-root) "src")) -(setq publish-dir (concat (projectile-project-root) "_site")) -(setq assets-dir (concat base-dir "/assets")) -(setq publish-assets-dir (concat publish-dir "/assets")) -(setq rss-dir base-dir) -(setq publish-rss-dir publish-dir) -(setq domainname "https://her.esy.fun") -(setq org-publish-project-alist - `(("orgfiles" - :base-directory ,base-dir - :exclude ".*drafts/.*" - :base-extension "org" - - :publishing-directory ,publish-dir - - :recursive t - :preparation-function org-blog-prepare - :publishing-function org-html-publish-to-html - - :with-toc nil - :with-title nil - :with-date t - :section-numbers nil - :html-doctype "html5" - :html-html5-fancy t - :html-head-include-default-style nil - :html-head-include-scripts nil - :htmlized-source t - :html-head-extra ,org-blog-head - :html-preamble org-blog-preamble - :html-postamble org-blog-postamble - - :auto-sitemap t - :sitemap-filename "archive.org" - :sitemap-title "Blog Posts" - :sitemap-style list - :sitemap-sort-files anti-chronologically - :sitemap-format-entry org-blog-sitemap-format-entry - :sitemap-function org-blog-sitemap-function) - - ("assets" - :base-directory ,assets-dir - :base-extension ".*" - :publishing-directory ,publish-assets-dir - :publishing-function org-publish-attachment - :recursive t) - - ("rss" - :base-directory ,rss-dir - :base-extension "org" - :html-link-home ,domainname - :html-link-use-abs-url t - :rss-extension "xml" - :publishing-directory ,publish-rss-dir - :publishing-function (org-rss-publish-to-rss) - :exclude ".*" - :include ("archive.org") - :section-numbers nil - :table-of-contents nil) - - ("blog" :components ("orgfiles" "assets" "rss")))) - -;; add target=_blank and rel="noopener noreferrer" to all links by default -(defun my-org-export-add-target-blank-to-http-links (text backend info) - "Add target=\"_blank\" to external links." - (when (and - (org-export-derived-backend-p backend 'html) - (string-match "href=\"http[^\"]+" text) - (not (string-match "target=\"" text)) - (not (string-match (concat "href=\"" domainname "[^\"]*") text))) - (string-match "ReC3POofcKvKQ<8zg3~fGY(4Ygk#B^&@0tn_iVuh~Lh(2g-t=Ok{pW zok!!d1B@1g35`|g zPVoM-Y9dDOag40p&m|?%5tT`bo!0N+V@qA_Jd(wh=f9{h#8Bx-rCGvpJfMhdx;*wV zt-XFREj^qA(F6AfWDgEB-?)_?HtgueZ+Fy7*tPQ8cqq8CwB&-ab%Gj)T5%5GW++gF zGg{ffCkLjy)-2p|t0{eiKa_iCm$rQt{uvzL!V{>jj3Ohz zUL;6tNMh|{|LsA0Ios7pe~<3APLV1L;_|%hw#phG8*V1g(+R9+8xv|ErENy>7(OWz zQn;m{SW&&7ih-R5X(lN}8r0-ps2~e&-#ycsozvJ>kbPLI)SvG+t^mQq)icNP7K5Y^kQA>EU({j7*Fv>1kKmE@lRs z@M-)CMro<{79b+et&N-;y4TY6X%a0oDj{IvnxVXxjNr0Uu`n(ZBz?5*YE&`m2;)Mti{Hu5}P}sTHiSI(LAzqo*$YoA&l69-F#>7Dqzk zG?DH@q3>y7H=1rtN_)7RjUTdO1xNQHUk*M=ynZG~Qu|YM4~H`A5k*(gZ5d&fmhJTY z%{R|+`9j44W(&a*3kYVHVopFeaL4mkfQ#ZSyU2B*0sEd2(O|hxhB%8+LVq(1!`x$* zPKh6&H#>@-HXsg#1TUAsTAsTmgH@-f*iRY>xxZ~_;Q#!UxHusnzn=)%f#S_ZPZ9&$ zFj^-uwPaUwvFlij1i0h=40`VqBm8uL4d)9b zVdGABDz~+vWPNB(;jJ4zam!Fw&nXvBtITD<)*N2d#U?QxNn|G`j3|J&O_U!>R^*o8 zP7cR`Pev4D3M8e+SHv*?!Ta$J3k5)NuCGsf(H#Rw#hOvg=db)AiE6yhOztTz zlGqp{HnKUsLoe2_T-#%s$VE!r3mX%&%y8;|cJvixdn3p+oHev?PScOM(Lk`rEl9_BXt>L}1%2r} z0TWOkxcw-(!S^>|A+%(Ltk>S+>pr>I%b8ewcz-Er=M2?t2i%W>tgRzMCCt3P?W@z= zre=7k7zWH~L`o1LIeE1SGekjtsMBn*bGSJ&9UTLMSFF~V9{K5}>=rv0g8;!bz zm97Q+m4$}BE(tlwR7hoWe>V$@fcxohZ)BlbQwJSXa8>`2^LnIBV5eCzWX`L*SC@lC zjTT(xoEc_07$sx-lk4;M{oa#v?5ZdNDpCno~hbY7fEx)T1CKf4SnZ)2A#hS2Qfx5)Z z$o?E|b?FCF!!08_`8gPZPKPHIz<^|~&}>ZR0{SZRxM2;X9B(Sr6J77;NycSn;Yv(P z)rqe_Hz#PyX#n%m(RyIb{EAdSV*o#{8YBChRF~~*XdBgft}8F(qos)T?^eshJaSnC zHV<}kZQ(-IDr*SpK`jAWH-6O2mCj?)al|$5CLGUVZ`|QW@FmX`zWBG#kvuk)Fj~*z z@`7cVejAmoe1SS`K{Hsg4-esU_4EN?05Q1fYcdmc2rxt$6`JN)XKUFz17a zYs<|5_Yp3`d%|_1%~I_0K!<@mU^6w*6Ht_yL4aFqbvv7?twa>LtFR!1|8enl<*iD4 zN$U0ljuDwRoyhT5-U0ZR#X>MjR=ETQ1jv*!CgqPGB;&dgMy z;cXDn$PfI5LAX=leuEfr!lWv76IazUcNqn)w?%*WVq^zUb<0Tg&wq>CwcLdF&gCcYW}_hR$n|$ssLMAFy({wS;Q3L|`qlgH_e2!2GCUQRXJ+ z?StJ*G}oXvcG{cV%sTb28w5pTor?(u69l6nXT#kk{Hm;*=~m@*^;5xNy{-mcdgArM z#6gXEb^vioc1gU2tv2ePFrfElo09wa?;1&ZmiKysw9wH>1hYsSQDmF6sO<0-yeT%5 zRkZv6oKW7bG(WR3x->x}f8X!j&ia~4VsI?vm>uV*y#EDh^CqJyDah+_rQ+CgO>OMMZEM2XR&x z24D$ab3)F`7$#LTuiGY#UrQbPO=K?OZ!LDj_GxfH$uf7--!j~tV7iN+ex9D#7S(FR z?N&eU<0oIkDxH#rN7KwWIR#$9BlX;f4`8ukfHY;Dpv$1#QBFTAk#W)Z(m+Ek6$rEVzDX+36G`6;r1TWd5*=PvKd{ sKE1^zfL})*;K7Ea*N)lO-wykW_1Ny(d@;=GXVVyKHOcuwMDYvgMeL^>{r~^~ literal 0 HcmV?d00001 diff --git a/src/posts/2019-07-04-static-org-publish.org b/src/posts/2019-07-04-static-org-publish.org index 96b0a40..8cc9592 100644 --- a/src/posts/2019-07-04-static-org-publish.org +++ b/src/posts/2019-07-04-static-org-publish.org @@ -68,9 +68,10 @@ You can add a task quite easily while doing other work in emacs. :CUSTOM_ID: basic-blog-a1fc :END: -I put the need minimal code in a =.project.el= file of my blog repository. -I used the solution given [[https://francismurillo.github.io/2017-02-15-Project-Script-Loader/][here]] (see direct link to the code snippet) to eval the -content of that file each time I enter into this project. +I put the need minimal code in a =.project.el.gpg= file of my blog repository. +Inspired by this [[https://francismurillo.github.io/2017-02-15-Project-Script-Loader/][blog post]] I enhanced this version to be both more user friendly +and secure (see [[#digression]]). + But even before that, I simply put the code in has an elisp code block of my =index.org= that I exectued with =C-c C-c=. @@ -180,30 +181,6 @@ images, etc...) ("blog" :components ("orgfiles" "assets")))) #+end_src - -#+begin_src elisp - (setq base-dir (concat (projectile-project-root) "src")) - (setq publish-dir (concat (projectile-project-root) "_site")) - (setq assets-dir (concat base-dir "/assets")) - (setq publish-assets-dir (concat publish-dir "/assets")) - (setq org-publish-project-alist - `(("orgfiles" - :base-directory ,base-dir - :exclude ".*drafts/.*" - :base-extension "org" - :publishing-directory ,publish-dir - :recursive t) - - ("assets" - :base-directory ,assets-dir - :base-extension ".*" - :publishing-directory ,publish-assets-dir - :publishing-function org-publish-attachment - :recursive t) - - ("blog" :components ("orgfiles" "assets")))) -#+end_src - With that you will copy the assets and export org file to html. You can do both by selecting `blog` when doing an `org-publish`. @@ -422,3 +399,94 @@ That's better. But for a blog you also generally want to have your own CSS. 'my-org-export-add-target-blank-to-http-links) #+end_src +* Digression + :PROPERTIES: + :CUSTOM_ID: digression + :END: + +Auto loading a =.el= file when entering in a project. +It should be easy and safe. + +The best solution I found. +Save your =.el= file as a =.el.gpg= file. +With =epa= emacs should encrypt the file for you using your own private key. +Great! Now we simply verify the file exists and load it only if it is encrypted +with one of you /trusted keys/. +The list of key fingerprint you trust is a configuration. + +When opening a new file via projectile or dired + +1. check the =.project.el.gpg= file is not already loaded for the current project +2. check the =.project.el.gpg= file exists +3. check the =.project.el.gpg= file is encrypted with a trusted key +4. decrypt and load =.project.el.gpg= + +That's it. + +You simply need to set the =y/trusted-gpg-key-fingerprints= variable with the +list of your own fingerprint. +You can get a list of them with =gpg --list-secret-keys=. + +Now you can be happy, this is really safe, in the sense that if you clone a new +project from the internet with a =.project.el.gpg= file in it. +That file won't be run on your system. + +Of course if you want to share that =.el= to other people, you need to adapt. +But for my use case, this is perfect. + +#+begin_src elisp + (defvar y/trusted-gpg-key-fingerprints + '("448E9FEF4F5B86DE79C1669B7B19A4C650D59646") + "The list of GPG fingerprint you trust when decrypting a gpg file. + You can retrieve the fingerprints of your own private keys with: + `gpg --list-secret-keys' (take care of removing the spaces when copy/pasting here)") + + (defun y/get-encryption-key (file) + "given a gpg encrypted file, returns the fingerprint of they + key that encrypted it" + (string-trim-right + (shell-command-to-string + (concat + "gpg --status-fd 1 --decrypt -o /dev/null " file " 2>/dev/null" + "|grep DECRYPTION_KEY" + "|awk '{print $4}'")))) + + (defun y/trusted-gpg-origin-p (file) + "Returns true if the file is encrypted with a trusted key" + (member (y/get-encryption-key file) y/trusted-gpg-key-fingerprints)) + + (defun y/project-el-auto-load () + (with-eval-after-load 'projectile + (defconst y/project-file ".project.el.gpg" + "Filename looked after to be loaded and evaluated.") + (defvar y/loaded-projects (list) + "Projects that have been loaded by `y/load-project-file'.") + (defun y/load-project-file () + "Loads the `y/project-file' for a project. This is run + once after the project is loaded signifying project setup." + (interactive) + (when (projectile-project-p) + (lexical-let* ((project-root (projectile-project-root)) + (project-init-file (expand-file-name y/project-file project-root))) + (when (and (not (member project-root y/loaded-projects)) ;; project file not already loaded + (file-exists-p project-init-file) ;; project file exists + (y/trusted-gpg-origin-p project-init-file)) ;; project file is tursted + (message "Loading project init file for %s" (projectile-project-name)) + (condition-case ex + (progn (load project-init-file) + (add-to-list 'y/loaded-projects project-root) + (message "%s loaded successfully" project-init-file)) + ('error + (message + "There was an error loading %s: %s" + project-init-file + (error-message-string ex)))))))) + ;; for some obscure reason there is not really a working hook + ;; to be used with projectile to launch the `y/load-project-file' + ;; only when switching to a new project. + ;; Thus the `y/loaded-projects' state. + (add-hook 'find-file-hook #'y/load-project-file t) + (add-hook 'dired-mode-hook #'y/load-project-file t))) +#+end_src + +