sbrs

Simple blog and RSS system
git clone git://git.christosmarg.xyz/sbrs.git
Log | Files | Refs | README | LICENSE

commit bd7e6c00af3c79a870d0510b23924c4865232ff5
parent 5f22043e342ec5eafb0cfecee4ce487e1a0000ae
Author: Christos Margiolis <christos@margiolis.net>
Date:   Fri, 16 Oct 2020 00:46:19 +0300

added -c option, added automatic blogindex dating, added a few more error checks, pending code beautification and simplification

Diffstat:
MMakefile | 9+++++++--
MREADME.md | 36+++++++++++++++++++++---------------
Mautoblog | 223+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mblogindex.html | 5+----
Mrss.xml | 8--------
5 files changed, 162 insertions(+), 119 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,3 +1,5 @@ +# See LICENSE file for copyright and license details. + BIN = autoblog VERSION = 0.1 DIST = ${BIN}-${VERSION} @@ -28,11 +30,14 @@ install: all ${CP} ${BIN} ${DESTDIR}${BIN_DIR} ${CP} ${MAN1} ${DESTDIR}${MAN_DIR} sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MAN_DIR}/${MAN1} - chmod 644 ${DESTDIR}${BIN_DIR}/${BIN} + chmod 755 ${DESTDIR}${BIN_DIR}/${BIN} chmod 644 ${DESTDIR}${MAN_DIR}/${MAN1} uninstall: all ${RM} ${DESTDIR}${BIN_DIR}/${BIN} ${RM} ${DESTDIR}${MAN_DIR}/${MAN1} -.PHONY: all dist install uninstall +clean: + ${RM} ${DIST}.tar.gz + +.PHONY: all clean dist install uninstall diff --git a/README.md b/README.md @@ -2,17 +2,19 @@ A small and simple blog and RSS shell script inspired by [Luke Smith's lb](https://github.com/LukeSmithxyz/lb) but -with a few modifications to match my own workflow. +with many modifications and additions to match my own workflow. ## Features `autoblog` can do the following: -* Define a `blog` directory where all blog posts will be stored -* Set up a seperate `HTML` blog page with CSS styling -* Add the blog post on the website's main page and on the blog's index -* Add the blog post to an RSS feed -* Revise or delete an already published post +* Define a `blog` directory where all blog posts will be stored. +* Set up a seperate `HTML` blog page with CSS styling of your choosing. +* Add the blog post on the website's main and blog index pages. +* Add the blog post to a specified RSS feed. +* Revise, delete, or change the title of a published post. + +Read the `man` page for more. ## Installation @@ -25,7 +27,7 @@ $ cd path/to/autoblog/ $ sudo make install ``` -You must **always** run the script inside the website's +You must **always** run the script inside your website's main directory. Alternatively, you can store the script inside your website's @@ -33,19 +35,23 @@ main directory. ## Preparation -Inside the script, change the `website` and `author` variables +The following files have to exist +* `index.html` +* `blogindex.html` +* `rss.xml` +* `template.html` +* `styles.css` + +Inside the `autoblog` script, change the `website` and `author` variables to your website's URL and your name and make sure the rest of the variables are properly set to match your website's structure. By default, all blog posts are stored in `blog/`. -`autoblog` will search for `<!--BLOG-->` inside `index.html` and -`rss.xml` in order to put the blog post listings and RSS feed -respectively. Inside `blogindex.html` however, it will search for -`<!--BLOG [Month Year]-->` (e.g `<!-- BLOG January 1800-->`). +`autoblog` will search for `<!--BLOG-->` inside `index.html`, +`blogindex.html` and `rss.xml` in order to put the blog post +listings and RSS feed below it. -A `template.html` file needs to exist in your main directory -in order for the script to run properly. -That file is how you want your blog post's page to look like. See +The `template.html` file is how you want your blog post's page to look like. See my own `template.html` for more. The `TITLE`, `HEADER` and `AUTHOR` fields must exist and be left as is. diff --git a/autoblog b/autoblog @@ -1,4 +1,5 @@ #!/bin/sh +# See LICENSE file for copyright and license details. website="https://christosmarg.xyz" author="Christos Margiolis" @@ -10,111 +11,153 @@ rssfile="rss.xml" template="template.html" [ -z "$EDITOR" ] && EDITOR="nano" -confirm_action() -{ - read -erp "$1" confirm && [ "$confirm" = "$2" ] || exit +confirm_action() { + read -erp "$1" confirm && [ "$confirm" = "$2" ] || exit } -listposts() -{ - printf "Listing posts in %s (Total: %d)\n" "$1" "$(ls $1 -I "*final*" | wc -l)" - ls -rc $1 -I "*-final*" | awk -F '/' '{print $NF}' | nl - [ $(($(ls $1 | wc -l))) -eq 0 ] && echo "No posts available in $1" && exit - read -erp "Choose a post to by number: " num && - [ -z "$(echo $num | grep -E "^[1-9]+$")" ] || - [ $(($(echo "$blogpost" | wc -l))) -gt 1 ] || - [ $(($num)) -gt $(($(ls $1 | wc -l))) ] || - [ -z "$num" ] && - echo "No post selected." && exit - blogpost=$(ls -rc $1 -I "*-final*" | nl | grep -w " $num" | awk '{print $2}' | sed "s/\..*//") +listposts() { + printf "Listing posts in %s (total: %d)\n" "$1" "$(ls $1 -I "*final*" | wc -l)" + ls -rc $1 -I "*-final*" | awk -F '/' '{print $NF}' | nl + [ $(($(ls $1 | wc -l))) -eq 0 ] && echo "No posts available in $1" && exit + read -erp "Choose a post to by number: " num \ + && [ -z "$(echo $num | grep -E "^[1-9]+$")" ] \ + || [ $(($(echo "$blogpost" | wc -l))) -gt 1 ] \ + || [ $(($num)) -gt $(($(ls $1 | wc -l))) ] \ + || [ -z "$num" ] \ + && echo "No post selected." && exit + blogpost=$(ls -rc $1 -I "*-final*" | nl | grep -w " $num" | awk '{print $2}' | sed "s/\..*//") } -newpost() -{ - mkdir -p $draftdir - read -erp "Title: " title && [ -z "$title" ] && echo "Please specify a title." && exit - blogpost=$(echo $title | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-') - [ -f "$blogdir/$blogpost.html" ] && echo "File exists already." && exit - $EDITOR "$draftdir/$blogpost.html" - sed -i "s/^/\ \ \ \ \ \ \ \ /" $draftdir/$blogpost.html # bad? - sed "s/TITLE/$title/g;s/HEADER/$title/g;s/AUTHOR/$author/g;" $template > $draftdir/$blogpost-final.html +newpost() { + mkdir -p $draftdir + read -erp "Title: " title && [ -z "$title" ] && echo "Please specify a title." && exit + blogpost=$(echo $title | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-') + [ -f "$blogdir/$blogpost.html" ] && echo "File exists already." && exit + $EDITOR "$draftdir/$blogpost.html" + sed -i "s/^/\ \ \ \ \ \ \ \ /" $draftdir/$blogpost.html # bad? + sed "s/TITLE/$title/g;s/HEADER/$title/g;s/AUTHOR/$author/g;" $template > $draftdir/$blogpost-final.html } -publish() -{ - confirm_action "Publish post (y/N)? " "y" - title=$(grep "<title>" $draftdir/$blogpost-final.html | sed "s/<title>//;s/<\/title>//;s/ *//;") - sed -i "/<\!--BLOG-->/r $draftdir/$blogpost.html" $draftdir/$blogpost-final.html - sed "s/</\&lt;/g;s/>/\&gt;/g;" "$draftdir/$blogpost.html" > $draftdir/$blogpost.xml - cp $draftdir/$blogpost-final.html $blogdir && mv $blogdir/$blogpost-final.html $blogdir/$blogpost.html - printf "\t\t\t\t<li>%s &ndash; <a href=\"%s\">%s</a></li>\n" "$(date '+%Y %b %d')" "$blogdir/$blogpost.html" "$title" | expand -t4 > $draftdir/$blogpost-htmlentry - printf "<item>\n\t<title>%s</title>\n\t<guid>%s</guid>\n\t<pubDate>%s</pubDate>\n\t<description>\n\t\t%s\n\t</description>\n</item>\n" "$title" "$website/$blogdir/$blogpost.html" "$(date '+%a, %d %b %Y')" "$(cat $draftdir/$blogpost.xml)" | expand -t4 > $draftdir/$blogpost-rssentry - - #dateid=$(date '+%b %Y' | sed 's/\ //' | tr '[:upper:]' '[:lower:]') - #[ -z "$(grep "$dateid" $blogindex)" ] && update_blogindex - - sed -i "/<\!--BLOG $(date '+%B %Y')-->/r $draftdir/$blogpost-htmlentry" $blogindex && echo "Blogindex... done." - sed -i "/<\!--BLOG-->/r $draftdir/$blogpost-htmlentry" $index && echo "Index... done" - sed -i "/<\!--BLOG-->/r $draftdir/$blogpost-rssentry" $rssfile && echo "RSS... done" - remove_last_index_entry && echo "Removing last entry from index file... done" - remove_contents $draftdir && echo "Cleaning up .drafts... done" - echo "Published $blogpost." +publish() { + confirm_action "Publish post (y/N)? " "y" + title=$(grep "<title>" $draftdir/$blogpost-final.html | sed "s/<title>//;s/<\/title>//;s/ *//;") + sed -i "/<\!--BLOG-->/r $draftdir/$blogpost.html" $draftdir/$blogpost-final.html + sed "s/</\&lt;/g;s/>/\&gt;/g;" "$draftdir/$blogpost.html" > $draftdir/$blogpost.xml + cp $draftdir/$blogpost-final.html $blogdir && mv $blogdir/$blogpost-final.html $blogdir/$blogpost.html + + printf "\t\t\t\t<li>%s &ndash; <a href=\"%s\">%s</a></li>\n" "$(date '+%Y %b %d')" "$blogdir/$blogpost.html" "$title" | expand -t4 > $draftdir/$blogpost-htmlentry + printf "<item>\n\t<title>%s</title>\n\t<guid>%s</guid>\n\t<pubDate>%s</pubDate>\n\t<description>\n\t\t%s\n \t</description>\n</item>\n" "$title" "$website/$blogdir/$blogpost.html" "$(date '+%a, %d %b %Y')" "$(cat $draftdir/$blogpost.xml)" | expand -t4 > $draftdir/$blogpost-rssentry + + blogindex_update + sed -i "/<\!--BLOG $(date '+%B %Y')-->/r $draftdir/$blogpost-htmlentry" $blogindex && echo "Blogindex... done." + sed -i "/<\!--BLOG-->/r $draftdir/$blogpost-htmlentry" $index && echo "Index... done" + sed -i "/<\!--BLOG-->/r $draftdir/$blogpost-rssentry" $rssfile && echo "RSS... done" + remove_last_index_entry && echo "Removing last entry from index file... done" + remove_contents $draftdir && echo "Cleaning up .drafts... done" + echo "Published $blogpost." +} + +# i dont like how this looks... +blogindex_update() { + dateid=$(date '+%b %Y' | sed 's/\ //' | tr '[:upper:]' '[:lower:]') + if [ -z "$(grep "$dateid" $blogindex)" ]; then + datename=$(date '+%B %Y') + monthheader=$(printf "\\ +<h2 id=\"%s\">%s<\/h2> \\ +<ul> \\ +\t<\!--BLOG %s--> \\ +<\/ul>" \ + "$dateid" "$datename" "$datename" | sed 's/^/\t\t\t/' | expand -t4) + + sed -i "/<\!--BLOG-->/a $monthheader" $blogindex + fi +} + +delete() { + [ $(($(echo "$blogpost" | wc -l))) -gt 1 ] && echo "Invalid choice" && exit + confirm_action "Are you sure you want to delete \"$blogpost\" (y/N)? " "y" + [ "$1" = "$blogdir" ] && + sed -i "/$blogpost/d" $index $blogindex && + sed -ni "/<item>/{ :loop; N; s/<\\/item>/&/; T loop; s/$blogpost/&/; T keep; d }; :keep; p" $rssfile + remove_contents $1 && echo "Removed $blogpost." } -delete() -{ - [ $(($(echo "$blogpost" | wc -l))) -gt 1 ] && echo "Invalid choice" && exit - confirm_action "Are you sure you want to delete \"$blogpost\" (y/N)? " "y" - [ "$1" = "$blogdir" ] && - sed -i "/$blogpost/d" $index $blogindex && - sed -ni "/<item>/{ :loop; N; s/<\\/item>/&/; T loop; s/$blogpost/&/; T keep; d }; :keep; p" $rssfile - remove_contents $1 && echo "Removed $blogpost." +view() { + cat $draftdir/$blogpost-final.html > $draftdir/$blogpost-final-view.html + title=$(grep "<title>" $draftdir/$blogpost-final-view.html | sed "s/<title>//;s/<\/title>//;s/ *//;") + sed -i "/<\!--BLOG-->/r $draftdir/$blogpost.html" $draftdir/$blogpost-final-view.html + $BROWSER $draftdir/$blogpost-final-view.html } -view() -{ - cat $draftdir/$blogpost-final.html > $draftdir/$blogpost-final-view.html - title=$(grep "<title>" $draftdir/$blogpost-final-view.html | sed "s/<title>//;s/<\/title>//;s/ *//;") - sed -i "/<\!--BLOG-->/r $draftdir/$blogpost.html" $draftdir/$blogpost-final-view.html - $BROWSER $draftdir/$blogpost-final-view.html +title_change() { + read -erp "Give post a new title: " newtitle && confirm_action "Are you sure (y/N)? " "y" + oldtitle=$(grep "<title>" $blogdir/$blogpost.html | sed "s/<title>//;s/<\/title>//;s/ *//;") + newtitle_fmt=$(echo $newtitle | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-') + sed -i "s/$blogpost/$newtitle_fmt/g;s/$oldtitle/$newtitle/g" $blogdir/$blogpost.html $index $blogindex $rssfile && + mv $blogdir/$blogpost.html $blogdir/$newtitle_fmt.html && + echo "Title changed successfully: $oldtitle -> $newtitle" } -# TEST -update_blogindex() -{ - #dateid=$(date '+%b %Y' | sed 's/\ //' | tr '[:upper:]' '[:lower:]') - datename=$(date '+%B %Y') - monthheader=$(echo -e "<h2 id=\"$dateid\">$datename<\/h2>\n<ul>\n\t<\!--BLOG $datename-->\n<\/ul>" | sed 's/^/\t\t\t/' | expand -t4) - sed "/<\!--BLOG-->/a $monthheader" $blogindex +remove_contents() { + ls $1 | grep -w $blogpost | sed "s/^/$1\//" | xargs rm +} + +remove_last_index_entry() { + indexentries=$(sed "1,/<\!--BLOG-->/d" $index | grep "<li>") && + [ $(($(echo "$indexentries" | wc -l))) -gt 7 ] && + lastentry=$(echo "$indexentries" | tail -2 | head -1) && + sed -i "s|$lastentry||;" $index +} + +err() { + echo "$1 file is missing. . ." + missing=true +} + +missing_check() { + missing=false + [ -f "$template" ] || err $template + [ -f "$index" ] || err $index + [ -f "$rssfile" ] || err $rssfile + [ -f "$blogindex" ] || err $blogindex + [ "$missing" = "true" ] && exit + + [ ! -d "$blogdir" ] && + confirm_action "Blog directory doesn't exist. Intialize it here (y/n)? " "y" && + mkdir -pv $blogdir } -remove_contents() -{ - ls $1 | grep -w $blogpost | sed "s/^/$1\//" | xargs rm +usage() { + printf "Usage: autoblog [OPTION]\n\n" + printf "Options:\n" + printf " -n\t\tNew post\n" + printf " -p\t\tPublish draft post\n" + printf " -e\t\tEdit draft post\n" + printf " -v\t\tView draft post in browser\n" + printf " -t\t\tDelete draft post\n" + printf " -r\t\tRevise published post\n" + printf " -c\t\tChange title\n" + printf " -o\t\tView published post in browser\n" + printf " -d\t\tDelete published post\n" + printf " -l\t\tList all published posts\n" } -remove_last_index_entry() -{ - indexentries=$(sed "1,/<\!--BLOG-->/d" $index | grep "<li>") && - [ $(($(echo "$indexentries" | wc -l))) -gt 7 ] && - lastentry=$(echo "$indexentries" | tail -2 | head -1) && - sed -i "s|$lastentry||;" $index +# Script begins here +main() { + missing_check + case $1 in + -n*) newpost ;; + -p*) listposts $draftdir && publish ;; + -e*) listposts $draftdir && $EDITOR $draftdir/$blogpost.html ;; + -v*) listposts $draftdir && view ;; + -t*) listposts $draftdir && delete $draftdir ;; + -r*) listposts $blogdir && $EDITOR $blogdir/$blogpost.html ;; + -c*) listposts $blogdir && title_change ;; + -o*) listposts $blogdir && $BROWSER $blogdir/$blogpost.html ;; + -d*) listposts $blogdir && delete $blogdir ;; + -l*) listposts $blogdir ;; + *) usage ;; + esac } -[ ! -d "$blogdir" ] && - confirm_action "Blog directory doesn't exist. Intialize it here (y/n)? " "y" && - mkdir -pv $blogdir - -case $1 in - -n*) newpost ;; - -p*) listposts $draftdir && publish ;; - -e*) listposts $draftdir && $EDITOR $draftdir/$blogpost.html ;; - -v*) listposts $draftdir && view ;; - -t*) listposts $draftdir && delete $draftdir ;; - -r*) listposts $blogdir && $EDITOR $blogdir/$blogpost.html ;; - -c*) listposts $blogdir && exit ;; - -o*) listposts $blogdir && $BROWSER $blogdir/$blogpost.html ;; - -d*) listposts $blogdir && delete $blogdir ;; - -l*) listposts $blogdir ;; - *) printf "Usage: autoblog [OPTION]\n\nOptions:\n -n\t\tNew post\n -p\t\tPublish draft post\n -e\t\tEdit draft post\n -v\t\tView draft post in browser\n -t\t\tDelete draft post\n -r\t\tRevise published post\n -c\t\tChange title\n -o\t\tView published post in browser\n -d\t\tDelete published post\n -l\t\tList all published posts\n" ;; -esac +main "$1" diff --git a/blogindex.html b/blogindex.html @@ -7,9 +7,6 @@ </head> <body> - <h2>Month Year</h2> - <ul> - <!--BLOG [Month Year]--> - </ul> + <!--BLOG--> </body> </html> diff --git a/rss.xml b/rss.xml @@ -7,14 +7,6 @@ <link>https://yourwebsite.com/rss.xml</link> <!--BLOG--> -<item> - <title>Sample post</title> - <guid>https://yourwebsite.com/sample-post.html</guid> - <pubDate>Wed, 11 Aug 1900</pubDate> - <description> - &lt;p&gt;Sample post.&lt;/p&gt; - </description> -</item> </channel> </rss>