diff --git a/README.md b/README.md index 722c2f0..befd06c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,75 @@ -# GSL Statique Littérateur +# GSL: Statique Littérateur +GSL is a multiple blogs/websites generator based on their domain, +written in bash, for minimal dependancies. The websites are nearly all +static, except for some includes that nginx can easily get, in your +webserver. + +# Dependancies +- bash +- coreutils + + +# GSL: Installation + +To avoid sudo, you should give permissions to USER + +## --Prefix for DOMAIN configuration (set according to user choice): +- HOME: ~/.config/gsl +- GLOBAL: /var/lib/gsl +- Folder: --Prefix/domains/ (created with $ gsl new) + +### DOMAIN Datas from Prefix: +- Folder: --Prefix/DOMAIN/ (Created by GSL) +- - Files: DOMAIN.conf, authors.db (Created by GSL) +- - Folder: --Prefix/DOMAIN/tmeplates/ (css, logos...) (Created by GSL) + +## Destination Folder: /etc/gsl/ +- File: gsl.conf + +## Destination Folder: /var/lib/gsl/ +- Folder: db (Created by GSL) +- Folder: helps +- Folder: scripts +- File: README.md + +## Destination Folder: /var/log/gsl +- File: gsl.log (Created and managed by GSL $ gsl log clean...) + +## Destination Folder: /usr/local/bin +- File: gsl + + +# How to configure a DOMAIN folder, and create a Post +## Set a DOMAIN +- add a DOMAIN name (if not alrady done) + +Follow instructions when adding DOMAIN or see them again with +``` +gsl help new +gsl help install +``` + +## Set a DOMAIN folder +if not already done: +- Create or go into your folder of choice +- Save into that folder a blank file named gsl.DOMAIN (gsl.example.org) +to tell GSL, this folder is for this DOMAIN website + +## Create a new Post +- Write a post in a file, using some "metas" that GSL will catch. +The engine is written from scratch and looks like a mix of markdown and +ReStructuredText. It's very easy to learn and use. +- Save your file with .gsl extension +- Start checking it, using: +``` +gsl check +``` +If your Post has no error, you will have some ready to deploy html +files and folders. You could install lightweight darkhttpd webserver on +your PC to preview the website + +# Create a Templates +You will have to create some CSS in your /DOMAIN/templates/ +- HOME: ~/.config/domains/DOMAIN/templates/ +- GLOBAL: /var/list/domains/DOMAIN/templates/ diff --git a/etc/gsl/gsl.conf b/etc/gsl/gsl.conf new file mode 100644 index 0000000..c7e076b --- /dev/null +++ b/etc/gsl/gsl.conf @@ -0,0 +1,161 @@ +# file: gsl.conf +# Folder: /etc/gsl +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + + +#======================================================================= +# Folders +#======================================================================= +# Librairies +gsl_dir_lib="/var/lib/gsl" +gsl_dir_scripts="$gsl_dir_lib/scripts" +gsl_dir_helps="$gsl_dir_lib/helps" + +# Management +gsl_dir_db="$gsl_dir_lib/db" +gsl_dir_global_domains="/var/lib/gsl/domains" + +# Logs +gsl_dir_logs="/var/log/gsl" + +# User +gsl_dir_user_domains="/home/$USER/.config/gsl/domains" + +#======================================================================= +# Files +#======================================================================= +# Logs +gsl_file_logs="$gsl_dir_logs/gsl.log" + +# Management +gsl_file_db_domains="$gsl_dir_db/domains.db" +gsl_file_db_posts="$gsl_dir_db/posts.db" +gsl_file_db_stats="$gsl_dir_db/stats.db" + +# Registred Authors filename +gsl_filename_auth="authors.db" + +#======================================================================= +# GSL Internal Configuration +#======================================================================= +# Reserved 10 posts ID (Home, about...) +gsl_post_min_ID=10 + +# minimum size to check a post +gsl_post_min_size=800 + +# Init log datas +gsl_log_a=' ~ ' +gsl_log_e='Err' +gsl_log_w='War' +gsl_log_i='Inf' + + +# Admin show +gsl_admin_sep_post='===============' + +# Date format +gsl_test_date='^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]+$' + +# Logs +gsl_log_act_title='POST TITLE' +gsl_log_act_author='REGISTRED NAME' +gsl_log_act_date='YYYY-MM-DD' +gsl_log_act_info='POST is ABOUT...' +gsl_log_act_slug='POST-TITLE' +gsl_log_act_code='NBR : FILENAME' +gsl_log_act_image='NBR : NAME : ALT TEXT' +gsl_log_act_abbr='SHORT : LONG' +gsl_log_act_h1='#1 POST CONTENT TITLE' +gsl_log_act_link='NAME : URL : ALT TEXT' +gsl_log_act_file='NAME : FILENAME : ALT TEXT' + +#----------------------------------------------------------------------- +# Set CONTENT POTST markers +#----------------------------------------------------------------------- +gsl_mo_p='(' +gsl_mo_link='\[_' +gsl_mo_em='/_' +gsl_mo_bold='\*_' +gsl_mo_strong='\*\*_' +gsl_mo_code='¤_' +gsl_mo_file='<_' + +gsl_mc_p=')' +gsl_mc_link='_\]' +gsl_mc_em='_/' +gsl_mc_bold='_\*' +gsl_mc_strong='_\*\*' +gsl_mc_code='_¤' +gsl_mc_file='_>' + +gsl_mark_image='_image_' +gsl_mark_code='_code_' +gsl_mark_title='#' +gsl_mark_hr='===' +gsl_mark_list1='=> ' +gsl_mark_list2='==> ' +gsl_mark_list3='===> ' + +gsl_mark_blockquote='---' +gsl_mark_blockquote_cite='_cite :' +gsl_mark_blockquote_year='_year :' +gsl_mark_blockquote_link='_link :' +gsl_mark_blockquote_book='_book :' +gsl_mark_blockquote_lang='_lang :' + +gsl_o_markers=( +$gsl_mo_link +$gsl_mo_em +$gsl_mo_strong +$gsl_mo_bold +$gsl_mo_code +$gsl_mo_file +) + +gsl_c_markers=( +$gsl_mc_link +$gsl_mc_em +$gsl_mc_strong +$gsl_mc_bold +$gsl_mc_code +$gsl_mc_file +) + +gsl_i_markers=( +Link +Italic +Strong +Bold +Code +File +) + +gsl_u_markers=( +'[_ _]' +'/_ _/' +'**_ _**' +'*_ _*' +'¤_ _¤' +'<_ _>' +) + +gsl_markers_nbr=$(( ${#gsl_o_markers[@]} - 1 )) + +#----------------------------------------------------------------------- +# Set HEADERS markers +#----------------------------------------------------------------------- +gsl_marker_ID=';; ID: ' +gsl_marker_title=';; title: ' +gsl_marker_slug=';; slug: ' +gsl_marker_info=';; info: ' +gsl_marker_author=';; author: ' +gsl_marker_date=';; date: ' + +#Optional (include brut text) +gsl_marker_code=';; code' +gsl_marker_image=';; image' +gsl_marker_abbr=';; abbr' +gsl_marker_link=';; link' +gsl_marker_file=';; file' diff --git a/usr/local/bin/gsl b/usr/local/bin/gsl new file mode 100755 index 0000000..a78ac95 --- /dev/null +++ b/usr/local/bin/gsl @@ -0,0 +1,179 @@ +#!/bin/bash + +#======================================================================= +# Checking Dependancies +#======================================================================= +# Get Tools +! [[ -f "/var/lib/gsl/scripts/gsl__tools" ]] \ + && echo "! Missing file: /var/lib/gsl/scripts/gsl__tools" \ + && return +source "/var/lib/gsl/scripts/gsl__tools" + +# Get conf +gsl__check_source "/etc/gsl/gsl.conf" || exit 1 + +# Get Logs Manager +gsl__check_source "$gsl_dir_scripts/gsl__log_manager" || exit 1 + +# Check/Create Files and Folders +gsl__create_ff + +#======================================================================= +# Main +#======================================================================= +case "$1" in + author|-A) + gsl__find_domain && exit 1 + gsl__check_source "$gsl_dir_scripts/gsl__auth_manager" || exit 1 + + echo "# Domain: $gsl_find_domain" + case "$2" in + "") + gsl__authors_list + ;; + add) + gsl__logs_print \ + "$gsl_log_i" \ + "Starting" \ + "Process" \ + "Add Author for domain $gsl_find_domain" \ + "Domain: $gsl_find_domain" + gsl__authors_add + gsl__logs_print \ + "$gsl_log_i" \ + "Stopping" \ + "Process" \ + "Add Author for domain $gsl_find_domain" \ + "Domain: $gsl_find_domain" + ;; + remove) + gsl__logs_print \ + "$gsl_log_i" \ + "Starting" \ + "Process" \ + "Remove Author for domain $gsl_find_domain" \ + "Domain: $gsl_find_domain" + gsl__authors_remove + gsl__logs_print \ + "$gsl_log_i" \ + "Stopping" \ + "Process" \ + "Remove Author for domain $gsl_find_domain" \ + "Domain: $gsl_find_domain" + ;; + esac + ;; + + new|-N) + gsl__check_source "$gsl_dir_scripts/gsl__new_website" || exit 1 + gsl__logs_print \ + "$gsl_log_i" \ + "Starting" \ + "Process" \ + "New Website" \ + "$gsl_dir_scripts/gsl__new_website" + + gsl__new_website + + gsl__logs_print \ + "$gsl_log_i" \ + "Stopping" \ + "Process" \ + "New Website" \ + "$gsl_dir_scripts/gsl__new_website" + + gsl author add + ;; + + log|-L) + [[ -z `grep '[^[:space:]]' "$gsl_file_logs"` ]] \ + && echo "# No logs to show. File is empty." \ + && exit + + while test "$2" + do + case "$2" in + clean|-C) + gsl_date_logs=`date +%F-%H-%M-%S` + mv "$gsl_file_logs" "$gsl_dir_logs/$gsl_date_logs.gsl.log" + rm -f "$gsl_file_logs" + printf '%s %s %s\n' \ + "# Logs saved to" \ + "$gsl_dir_logs/$gsl_date_logs.gsl.log" \ + "and cleaned" + exit + ;; + -s) gsl_logs_last_session=true ;; + -e) gsl_logs_err=true ;; + -i) gsl_logs_inf=true ;; + -w) gsl_logs_war=true ;; + *) gsl_logs_search="$2" ;; + esac + shift + done + gsl__logs_show + ;; + + check|-C) + gsl__find_domain && exit 1 + gsl__check_source "$gsl_dir_scripts/gsl__auth_manager" || exit 1 + gsl__authors_list check && exit 1 + gsl__check_source "$gsl_dir_scripts/gsl__post_manager" || exit 1 + gsl__check_source "$gsl_dir_scripts/gsl__post_checkers" || exit 1 + gsl__check_nbr_posts && exit 1 + gsl__check_source "$gsl_dir_scripts/gsl__db_manager" || exit 1 + + gsl__logs_print \ + "$gsl_log_i" \ + "Starting" \ + "Process" \ + "Check Post for domain $gsl_find_domain" \ + "${PWD}" + + gsl__logs_print \ + "$gsl_log_i" \ + "Found" \ + "Posts" \ + "$gsl_nbr_posts" \ + "${PWD}" + + gsl__loop_posts check + + gsl__logs_print \ + "$gsl_log_i" \ + "Stopping" \ + "Process" \ + "Check Post for domain $gsl_find_domain" \ + "${PWD}" + ;; + + readme) + if [[ -f "/var/lib/gsl/README.md" ]];then + clear + cat /var/lib/gsl/README.md + else + echo "! Missing file: /var/lib/gsl/README.md" + fi + ;; + + help|--help|-h) + gsl__check_file "$gsl_dir_helps/gsl_help" || exit 1 + + clear + case "$2" in + "") + cat "$gsl_dir_helps/gsl_help" + ;; + new) + gsl__check_file "$gsl_dir_helps/gsl_infos_new_website" \ + || exit 1 + cat "$gsl_dir_helps/gsl_infos_new_website" + ;; + install) + gsl__check_file "$gsl_dir_helps/gsl_help_install" \ + || exit 1 + cat "$gsl_dir_helps/gsl_help_install" + ;; + esac + ;; +esac diff --git a/var/lib/gsl/helps/gsl_help b/var/lib/gsl/helps/gsl_help new file mode 100644 index 0000000..e636a9b --- /dev/null +++ b/var/lib/gsl/helps/gsl_help @@ -0,0 +1,22 @@ +# GSL: Statique Littérateur + +$ gsl [ARG] + readme : Show README.md instructions + help | -h [OPT] : This Help. Add FULL [ARG] for specifics + install : Show process installation + + new | -N : Add and configure a new DOMAIN + + log | -L [OPTS] : Show logs from all sessions + clean | -C : Logs saved to {DATE}.gsl.log and cleaned + -i | -w | -e : from levels (infos, warnings, errors) + -s : from last session only + [TERM] : [TERM] : case insensitive, regex 'T1.*T2' + (i.e. $ gsl log -e -s code) + + author | -A [OPT] : List authors from DOMAIN set in PWD folder + add : Add author(s) for DOMAIN + remove : Remove author(s) for DOMAIN + + check | -C : Check Posts erors from PWD folder + diff --git a/var/lib/gsl/helps/gsl_help_install b/var/lib/gsl/helps/gsl_help_install new file mode 100644 index 0000000..546fc4a --- /dev/null +++ b/var/lib/gsl/helps/gsl_help_install @@ -0,0 +1,29 @@ +# GSL: Installation + +To avoid sudo, you should give permissions to USER + +## --Prefix for DOMAIN configuration (set according to user choice): +- HOME: ~/.config/gsl +- GLOBAL: /var/lib/gsl +- Folder: --Prefix/domains/ (created with $ gsl new) + +### DOMAIN Datas from Prefix: +- Folder: --Prefix/DOMAIN/ (Created by GSL) +- - Files: DOMAIN.conf, authors.db (Created by GSL) +- - Folder: --Prefix/DOMAIN/tmeplates/ (css, logos...) (Created by GSL) + +## Destination Folder: /etc/gsl/ +- File: gsl.conf + +## Destination Folder: /var/lib/gsl/ +- Folder: db (Created by GSL) +- Folder: helps +- Folder: scripts +- File: README.md + +## Destination Folder: /var/log/gsl +- File: gsl.log (Created and managed by GSL $ gsl log clean...) + +## Destination Folder: /usr/local/bin +- File: gsl + diff --git a/var/lib/gsl/helps/gsl_infos_new_website b/var/lib/gsl/helps/gsl_infos_new_website new file mode 100644 index 0000000..9e828a1 --- /dev/null +++ b/var/lib/gsl/helps/gsl_infos_new_website @@ -0,0 +1,18 @@ +# GSL: Statique Littérateur + + GSL can manage multiple websites, based on their DOMAIN Name + When adding, set your new DOMAIN, for Global or Home Use + + - Home case : Domain configuration saved to + : /home/USER/.config/gsl/domains/DOMAIN/DOMAIN.conf + + - Global case: Domain configuration saved to + : /var/lib/gsl/domains/DOMAIN/DOMAIN.conf + + - Your templates, where you give .css, logo, footer.html... must be put in + : --prefix_above/domains/DOMAIN/templates + +# Writing your Posts: + - Create or go into a folder (i.e. /home/USER/Documents/Mytexts) + - Set an empty file in this folder named gsl.DOMAIN (i.e. gsl.example.com) + - Save in this folder your posts in files with .gsl extension (i.e. mygreatpost.gsl) diff --git a/var/lib/gsl/scripts/gsl__auth_manager b/var/lib/gsl/scripts/gsl__auth_manager new file mode 100644 index 0000000..1b97c7d --- /dev/null +++ b/var/lib/gsl/scripts/gsl__auth_manager @@ -0,0 +1,109 @@ +#!/bin/bash +# file: gsl__auth_manager +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#======================================================================= +# Manage Authors from DOMAIN +#======================================================================= +gsl__authors_check() { +gsl_save_dir_ndd=`grep "$gsl_find_domain" "$gsl_file_db_domains"` +gsl_file_auth_ndd="$gsl_save_dir_ndd/$gsl_filename_auth" + +! [[ -f "$gsl_file_auth_ndd" ]] \ + && touch "$gsl_file_auth_ndd" +} + +#======================================================================= +# List Authors from DOMAIN +#======================================================================= +gsl__authors_list() { +gsl__authors_check + +[[ -z `grep '[^[:space:]]' "$gsl_file_auth_ndd"` ]] \ + && echo "! No Registred authors yet." \ + && return + +case "$1" in + check) + return + ;; +esac + +echo -e "\n# Authors Registred:" +while read -r "line_nbr" "author" +do + echo " $line_nbr: $author" +done < <(cat -n "$gsl_file_auth_ndd") +} + +#======================================================================= +# Add Author(s) for DOMAIN to authors.db in Profile User +#======================================================================= +gsl__authors_add() { +gsl__authors_check +gsl__authors_list + +printf '\n%s\n%s\n%s\n \n' \ + "# You can add one or more Authors" \ + " Use comma (,) delimiter (i.e. Joe Foo,Jane)" \ + " || empty field to cancel" + +echo -ne "# Add author(s) name : " && IFS="," read -a gsl_new_authors +[[ "$gsl_new_authors" ]] || return + +gsl_nbr_authors=${#gsl_new_authors[@]} +for i in `seq 0 $(( gsl_nbr_authors - 1 ))` +do + echo "${gsl_new_authors[i]}" >> "$gsl_file_auth_ndd" && \ + gsl__logs_print \ + "$gsl_log_i" \ + "Author" \ + "Added" \ + "${gsl_new_authors[i]} for domain $gsl_find_domain" \ + "$gsl_file_auth_ndd" +done + +gsl__authors_list +} + +#======================================================================= +# Remove Author(s) for DOMAIN from authors.db in Profile User +#======================================================================= +gsl__authors_remove() { +gsl__authors_check +gsl__authors_list + +printf '\n%s\n%s\n%s\n \n' \ + "# You can REMOVE one or more Authors" \ + " Enter numbers (space delimiter)" \ + " || empty field to cancel" + +read -rp "! Which numbers author to REMOVE ? " gsl_rm_authors +gsl_rm_authors=($gsl_rm_authors) + +gsl_nbr_authors=`cat $gsl_file_auth_ndd | wc -l` +for line in ${gsl_rm_authors[@]} +do + [[ $line =~ ^[0-9]+$ ]] || continue + (( $line < 1 )) && continue + (( $line > $gsl_nbr_authors )) && continue + + if [[ $rm_line ]];then + ! (( $line == 1 )) && line=$(( line - 1 )) + fi + gsl_rm_author=`awk -v n="$line" 'NR == n' "$gsl_file_auth_ndd"` + sed -i "${line}d" "$gsl_file_auth_ndd" && \ + gsl__logs_print \ + "$gsl_log_i" \ + "Author" \ + "Removed" \ + "$gsl_rm_author for domain $gsl_find_domain" \ + "$gsl_file_auth_ndd" + echo " - Removed > $gsl_rm_author <" + rm_line=true +done + +gsl__authors_list +} diff --git a/var/lib/gsl/scripts/gsl__db_manager b/var/lib/gsl/scripts/gsl__db_manager new file mode 100644 index 0000000..c7cf30d --- /dev/null +++ b/var/lib/gsl/scripts/gsl__db_manager @@ -0,0 +1,65 @@ +#!/bin/bash +# file: gsl__db_manager +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#======================================================================= +# Get Post Hash FROM DB posts.db +#======================================================================= +gsl__db_post_hash() { +gsl_db_post_hash=` +grep "$gsl_post" \ + "$gsl_file_db_posts" \ + | awk -F"|" '{print $3}'` +} + +#======================================================================= +# Check Post exists and get line NBR in DB +#======================================================================= +gsl__db_post_exists() { +gsl_db_post_exists=`grep -n "$gsl_post" "$1"` +gsl_db_post_line_nbr=`awk -F":" '{print $1}' <<< "$gsl_db_post_exists"` +gsl_db_post_status=`awk -F"|" '{print $4}' <<< "$gsl_db_post_exists"` +} + +#======================================================================= +# From gsl__loop_posts: Write DB +#======================================================================= +gsl__db_line_post() { +case "$gsl_process" in + Checked) + gsl_db_line=` + printf '%s%s%s%s%s\n' \ + "$gsl_post_ID 1|" \ + "$gsl_post|" \ + "$gsl_post_hash|" \ + "$gsl_post_size|" \ + "$gsl_process|"` + + # case if post exists in DB posts.db ? + gsl__db_post_exists "$gsl_file_db_posts" + if [[ "$gsl_db_post_exists" ]];then + sed -i "${gsl_db_post_line_nbr}s/.*/$gsl_db_line/" \ + "$gsl_file_db_posts" && \ + gsl__logs_print \ + "$gsl_log_w" \ + "DB" \ + "Post" \ + "$gsl_post - Replaced Hash: $gsl_post_hash" \ + "$gsl_file_db_posts" + gsl_checker_war=true + + else + echo "$gsl_db_line" \ + >> "$gsl_file_db_posts" && \ + gsl__logs_print \ + "$gsl_log_i" \ + "DB" \ + "Post" \ + "$gsl_post - New Line. Hash: $gsl_post_hash" \ + "$gsl_file_db_posts" + fi + ;; +esac +} diff --git a/var/lib/gsl/scripts/gsl__log_manager b/var/lib/gsl/scripts/gsl__log_manager new file mode 100644 index 0000000..ef250a9 --- /dev/null +++ b/var/lib/gsl/scripts/gsl__log_manager @@ -0,0 +1,80 @@ +#!/bin/bash +# file: gsl__log_manager +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#----------------------------------------------------------------------- +# Print in log file +#----------------------------------------------------------------------- +gsl__logs_print() { +#1: Level +#2: Type +#3: Process +#4: Infos +#5: File +printf '%s %s\t%s\t%s\t%s\t%s\n' \ + "`date +%F' ~ '%T`" \ + "$1" \ + "$2" \ + "$3" \ + "$4" \ + "$5" \ + >> "$gsl_file_logs" +} + +#----------------------------------------------------------------------- +# Show logs from file with filters +#----------------------------------------------------------------------- +gsl__logs_show() { +clear + +# Choices are important, but let's give priority +[[ "$gsl_logs_inf" ]] \ + && gsl_logs_filter="$gsl_log_i" +[[ "$gsl_logs_war" ]] \ + && gsl_logs_filter="$gsl_log_w" +[[ "$gsl_logs_err" ]] \ + && gsl_logs_filter="$gsl_log_e" + +[[ "$gsl_logs_last_session" ]] \ + && gsl_log_show_session="Last session" \ + || gsl_log_show_session="All" + +gsl_logs_infos=` +printf '%s\n%s\n%s\n' \ + "Logs : $gsl_log_show_session" \ + "Filter: $gsl_logs_filter" \ + "Search: $gsl_logs_search"` + +# Last session show or not +if [[ "$gsl_logs_last_session" ]];then + gsl_log_start_line=` + grep -n "Starting" "$gsl_file_logs" \ + | tail -1 \ + | awk -F: '{print $1}'` + + printf '%s\n \n' "$gsl_logs_infos" + + awk -v sl="$gsl_log_start_line" \ + 'NR >= sl' \ + "$gsl_file_logs" \ + | grep "$gsl_logs_filter" \ + | grep -Ei "$gsl_logs_search" \ + | column -t -s$'\t' +else + printf '%s\n' "$gsl_logs_infos" + + while read -r "gsl_log_content" + do + # Let's read clear sessions + [[ "$gsl_log_content" =~ "Starting" ]] \ + && echo + + echo "$gsl_log_content" + done < <(cat "$gsl_file_logs" \ + | grep "$gsl_logs_filter" \ + | grep -Ei "$gsl_logs_search" \ + | column -t -s$'\t') +fi +} diff --git a/var/lib/gsl/scripts/gsl__new_website b/var/lib/gsl/scripts/gsl__new_website new file mode 100644 index 0000000..4e20b7d --- /dev/null +++ b/var/lib/gsl/scripts/gsl__new_website @@ -0,0 +1,327 @@ +#!/bin/bash +# file: gsl__new_website +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + + +#======================================================================= +# +# Configure new WEBSITE from DOMAIN +# +#======================================================================= +gsl__new_website() { +gsl__check_file "$gsl_dir_helps/gsl_infos_new_website" || return + +clear +cat $gsl_dir_helps/gsl_infos_new_website +printf '\n%s\n%s\n%s\n' \ + "# Configuration of a new website..." \ + "# Cancel with empty field" \ + "# You will be asked to confirm at the end" + +#======================================================================= +# Webserver URI +#======================================================================= +echo -e "\n# Webserver: /var/www ! NO ending / (Or maybe elsewhere...)" +read -erp \ + ": Webserver URI ? " \ + gsl_set_server + +gsl__check_settings $gsl_set_server \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Domain URL +#======================================================================= +printf '\n%s %s\n' \ + "# URL: www.example.com !NO ending /" \ + "(https:// will be added if missing or force with http://)" +read -rp \ + ": Website URL ? " \ + gsl_set_url + +gsl__check_settings $gsl_set_url \ + && [[ "$gsl_process_stop" ]] \ + && return + +gsl_https='https://' +case "$gsl_set_url" in + "https://"*) + gsl_set_ndd=${gsl_set_url/$gsl_https/} + echo "D> Case: $gsl_set_ndd" + ;; + "http://"*) + gsl_http="http://" + gsl_set_ndd=${gsl_set_url/$gsl_http/} + ;; + *) + gsl_set_ndd="$gsl_set_url" + gsl_https+=$gsl_set_url + gsl_set_url=$gsl_https + ;; +esac + +# Domain NAME +gsl_set_ndd=`awk -F"." '{print $(NF-1)"."$NF}' <<< $gsl_set_ndd` +gsl_set_file_ndd="$gsl_set_ndd.conf" + +#======================================================================= +# Personal use or global use ? +#======================================================================= +echo -e "\n# Save Domain in Home or Global" +read -rp \ + ": Home Use (y/n) ? " \ + gsl_set_user_conf +case "$gsl_set_user_conf" in + y|Y) + gsl_save_dir_ndd="$gsl_dir_user_domains/$gsl_set_ndd" + gsl_save_conf_ndd="$gsl_save_dir_ndd/$gsl_set_file_ndd" + gsl_ask="# Save to $gsl_save_conf_ndd ? " + ;; + n|N) + gsl_save_dir_ndd="$gsl_dir_global_domains/$gsl_set_ndd" + gsl_save_conf_ndd="$gsl_save_dir_ndd/$gsl_set_file_ndd" + gsl_ask="# Save to $gsl_save_conf_ndd ? " + ;; + *) echo "! Abandon... Maybe next time" && return ;; +esac + +#======================================================================= +# Website Title +#======================================================================= +echo -e "\n# Title: My Compagny (or My beautiful website)" +read -rp \ + ": Website Title ? " \ + gsl_set_title + +gsl__check_settings $gsl_set_title \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Website Description +#======================================================================= +echo -e "\n# Description: writings about this website" +read -rp \ + ": Website Description ? " \ + gsl_set_about +gsl__check_settings $gsl_set_about\ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Contact Mail +#======================================================================= +echo -e "\n# Mail: contact@example.com" +read -rp \ + ": Contact Mail ? " \ + gsl_set_mail + +gsl__check_settings $gsl_set_mail \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Website Keywords +#======================================================================= +echo -e "\n# Keywords: geek,logiciels libre,friends (comma separated)" +read -rp \ + ": Website Keywords ? " \ + gsl_set_keys + +gsl__check_settings $gsl_set_keys \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Language +#======================================================================= +echo -e "\n# Language: fr (or en-GB...)" +read -rp \ + ": Website Lang ? " \ + gsl_set_lang + +gsl__check_settings $gsl_set_lang \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Copyright +#======================================================================= +echo -e "\n# Copyright: 2022 TITLE CC-BY-SA" +read -rp \ + ": Website Copyright ? " \ + gsl_set_cr + +gsl__check_settings $gsl_set_cr \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Website Logo +#======================================================================= +printf '\n%s %s\n' \ + "# logo: my-logo.png" \ + "(Put it in $gsl_save_dir_ndd/templates/)" +read -rp \ + ": Website logo file NAME ? " \ + gsl_set_logo + +gsl__check_settings $gsl_set_logo \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# CSS Acronym +#======================================================================= +printf '\n%s %s\n' \ + "# CSS (short) Acronym: myweb !No need to end with _" \ + "(Will create specific classes like myweb_paragraph)" +read -rp \ + ": CSS Acronym ? " \ + gsl_set_css + +gsl__check_settings $gsl_set_css \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Author Reference +#======================================================================= +printf '\n%s %s\n' \ + "# Author URL Profile: https://..." \ + "(Used for meta rel='me')" +read -rp \ + ": Author URL Profile ? " \ + gsl_set_auth_url + +gsl__check_settings $gsl_set_auth_url \ + && [[ "$gsl_process_stop" ]] \ + && return + +#======================================================================= +# Show Resume +#======================================================================= +clear +printf '%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n' \ + "# New Website configurations..." \ + ": Webserver|$gsl_set_server" \ + ": URL|$gsl_set_url" \ + ": Domain|$gsl_set_ndd" \ + ": Title|$gsl_set_title" \ + ": Description|$gsl_set_about" \ + ": Contact|$gsl_set_mail" \ + ": Keywords|$gsl_set_keys" \ + ": Language|$gsl_set_lang" \ + ": Copyright|$gsl_set_cr" \ + ": Logo File|$gsl_set_logo" \ + ": CSS Acro|$gsl_set_css" \ + ": Author URL|$gsl_set_auth_url" \ + | column -t -s'|' + +#======================================================================= +# Ask to Confirm +#======================================================================= +echo +if [[ -d "$gsl_save_dir_ndd" ]];then + printf '%s\n%s\n' \ + "! A profile already exists in $gsl_save_dir_ndd" \ + "- Remove (A)LL Directories: $gsl_save_dir_ndd" \ + "- Remove (F)ile configurations : $gsl_save_conf_ndd" \ + "- Any other key to cancel" && \ + gsl__logs_print \ + "$gsl_log_w" \ + "Found" \ + "Profile" \ + "Configuration from $gsl_set_ndd" \ + "$gsl_save_conf_ndd" + + read -rp "! Remove (A|F|*) ? " \ + gsl_ask_remove + + case "$gsl_ask_remove" in + A) + rm -rf "$gsl_save_dir_ndd" && \ + gsl__logs_print \ + "$gsl_log_i" \ + "Remove" \ + "Folders" \ + "Configuration from $gsl_set_ndd" \ + "$gsl_save_dir_ndd" + ;; + F) + rm -f "$gsl_save_conf_ndd" && \ + gsl__logs_print \ + "$gsl_log_i" \ + "Remove" \ + "File" \ + "Configuration from $gsl_set_ndd" \ + "$gsl_save_conf_ndd" + gsl_set_confirm="Y" + ;; + *) echo "# Canceled";return ;; + esac +fi + +! [[ "$gsl_set_confirm" ]] \ + && read -rp "$gsl_ask ?" gsl_set_confirm + +case "$gsl_set_confirm" in + y|Y) + ! [[ -d "$gsl_save_dir_ndd/templates" ]] \ + && mkdir -p "$gsl_save_dir_ndd/templates" \ + && gsl__logs_print \ + "$gsl_log_i" \ + "Create" \ + "Folder" \ + "Configuration from $gsl_set_ndd" \ + "$gsl_save_dir_ndd/templates" + ;; + *) + gsl__new_website && return + ;; +esac + +#======================================================================= +# Save config +#======================================================================= +printf '%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n' \ + "gsl_site_server=\"$gsl_set_server\"" \ + "gsl_site_url=\"$gsl_set_url\"" \ + "gsl_site_ndd=\"$gsl_set_ndd\"" \ + "gsl_site_title=\"$gsl_set_title\"" \ + "gsl_site_about=\"$gsl_set_about\"" \ + "gsl_site_mail=\"$gsl_set_mail\"" \ + "gsl_site_keys=\"$gsl_set_keys\"" \ + "gsl_site_lang=\"$gsl_set_lang\"" \ + "gsl_site_cr=\"$gsl_set_cr\"" \ + "gsl_site_logo=\"$gsl_set_logo\"" \ + "gsl_site_css=\"$gsl_set_css\"" \ + "gsl_site_auth_url=\"$gsl_set_auth_url\"" \ + > "$gsl_save_conf_ndd" + +if ! [[ `grep "$gsl_save_dir_ndd" "$gsl_file_db_domains"` ]];then + echo "$gsl_save_dir_ndd" >> "$gsl_file_db_domains" && \ + gsl__logs_print \ + "$gsl_log_i" \ + "Create" \ + "File" \ + "Configuration from $gsl_set_ndd" \ + "$gsl_file_db_domains" +fi +} + +#======================================================================= +# Check if no Response from $@ +#======================================================================= +gsl__check_settings() { + case "$@" in + "") + gsl_process_stop=true + echo "! Abandon... Maybe next time" + return + ;; + esac +} diff --git a/var/lib/gsl/scripts/gsl__post_checkers b/var/lib/gsl/scripts/gsl__post_checkers new file mode 100644 index 0000000..3a05762 --- /dev/null +++ b/var/lib/gsl/scripts/gsl__post_checkers @@ -0,0 +1,155 @@ +#!/bin/bash +# file: gsl__post_checkers +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#======================================================================= +# From: gsl__loop_posts | Check Post from modules +#======================================================================= +gsl__post_all_checkers() { +clear +unset gsl_check_done + +echo -n ": Searching for Headers..." +gsl__post_check_headers +echo -ne "\r\033[2K: Searching for #1..." +gsl__post_check_h1 + +echo + +# End of checkers : show logs for war and err +[[ "$gsl_checker_war" ]] \ + && gsl log -s -w + +[[ "$gsl_checker_err" ]] \ + && gsl log -s -e + +} + +#======================================================================= +# Check Post for VALID Content HEADERS +#======================================================================= +gsl__post_check_headers() { +# +# Check if Missing NEEDED HEADERS +# + +# Title +gsl_header_title=`gsl__get_header "$gsl_marker_title" "$gsl_post"` +! [[ "$gsl_header_title" ]] \ + && gsl__logs_print \ + "$gsl_log_e" \ + "Title" \ + "Post" \ + "Missing" \ + "${PWD}/$gsl_post" \ + && gsl_checker_err=true + +# Slug +gsl_header_slug=`gsl__get_header "$gsl_marker_slug" "$gsl_post"` +! [[ "$gsl_header_slug" ]] \ + && gsl__logs_print \ + "$gsl_log_e" \ + "Slug" \ + "Post" \ + "Missing" \ + "${PWD}/$gsl_post" \ + && gsl_checker_err=true + +# Author +gsl_header_author=`gsl__get_header "$gsl_marker_author" "$gsl_post"` +! [[ "$gsl_header_author" ]] \ + && gsl__logs_print \ + "$gsl_log_e" \ + "Author" \ + "Post" \ + "Missing" \ + "${PWD}/$gsl_post" \ + && gsl_checker_err=true + +# Date +gsl_header_date=`gsl__get_header "$gsl_marker_date" "$gsl_post"` +! [[ "$gsl_header_date" ]] \ + && gsl__logs_print \ + "$gsl_log_e" \ + "Date" \ + "Post" \ + "Missing" \ + "${PWD}/$gsl_post" \ + && gsl_checker_err=true + +# Description +gsl_header_info=`gsl__get_header "$gsl_marker_info" "$gsl_post"` +! [[ "$gsl_header_info" ]] \ + && gsl__logs_print \ + "$gsl_log_e" \ + "Infos" \ + "Post" \ + "Missing" \ + "${PWD}/$gsl_post" \ + && gsl_checker_err=true + +# +# Check for VALID Content HEADERS +# + +# Author registred +if ! [[ `grep "$gsl_header_author" "$gsl_file_auth_ndd"` ]];then + gsl__logs_print \ + "$gsl_log_e" \ + "Author" \ + "Post" \ + "$gsl_header_author not registred for domain $gsl_find_domain" \ + "${PWD}/$gsl_post" + gsl_checker_err=true +fi + +# Date Format YYYY-MM-DD +if ! [[ "$gsl_header_date" =~ $gsl_test_date ]];then + gsl__logs_print \ + "$gsl_log_e" \ + "Date" \ + "Post" \ + "$gsl_header_date not YYYY-MM-DD" \ + "${PWD}/$gsl_post" + gsl_checker_err=true +fi + +[[ "$gsl_checker_err" ]] && return + +# Slug format title-post +gsl_header_slug_test=${gsl_header_slug// /-} +if ! [[ "$gsl_header_slug" == "$gsl_header_slug_test" ]];then + gsl_new_header_slug="$gsl_marker_slug$gsl_header_slug_test" + sed -i "s|$gsl_marker_slug$gsl_header_slug|$gsl_new_header_slug" \ + "$gsl_post" && \ + gsl__logs_print \ + "$gsl_log_w" \ + "Slug" \ + "Post" \ + "Changed: $gsl_header_slug_test" \ + "${PWD}/$gsl_post" + gsl_checker_war=true +fi +} + +#======================================================================= +# Check Post for begining content +#======================================================================= +gsl__post_check_h1() { +gsl_post_begin=` +grep -n "#1" $gsl_post \ + | head -1 \ + | awk -F: '{print $1}'` + +if ! [[ "$gsl_post_begin" ]];then + gsl__logs_print \ + "$gsl_log_e" \ + "Begin" \ + "Post" \ + "Missing content: #1 TITLE" \ + "${PWD}/$gsl_post" + gsl_checker_err=true +fi +} diff --git a/var/lib/gsl/scripts/gsl__post_manager b/var/lib/gsl/scripts/gsl__post_manager new file mode 100644 index 0000000..3618dd3 --- /dev/null +++ b/var/lib/gsl/scripts/gsl__post_manager @@ -0,0 +1,104 @@ +#!/bin/bash +# file: gsl__post_manager +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#======================================================================= +# Check if posts from PWD folder +#======================================================================= +gsl__check_nbr_posts() { +gsl_nbr_posts=`ls -1 *.gsl 2>/dev/null | wc -l` +(( $gsl_nbr_posts == 0 )) \ + && echo "! No Posts found with .gsl extension" +} + +#======================================================================= +# Read from Post list +#======================================================================= +gsl__loop_posts() { +for gsl_post in `ls -1 *.gsl 2>/dev/null` +do + # Post too small + gsl__post_hash_size + if (( "$gsl_post_size" <= $gsl_post_min_size ));then + gsl__logs_print \ + "$gsl_log_e" \ + "Post" \ + "Size" \ + "Too small $gsl_post_size <= $gsl_post_min_size" \ + "${PWD}/$gsl_post" + continue + fi + + case "$1" in + check) + gsl__post_compare_hash && continue + gsl__logs_print \ + "$gsl_log_i" \ + "Reading" \ + "Post" \ + "$gsl_post" \ + "${PWD}" + gsl__post_all_checkers + + # No error: Check/Write to DB (posts.db) + if ! [[ "$gsl_checker_err" ]];then + gsl_process="Checked" + gsl__db_line_post + fi + ;; + + make) + gsl_process="Made" + gsl__db_post_exists "$gsl_file_db_posts" + if [[ "$gsl_db_post_status" == "Made" ]];then + gsl__logs_print + "$gsl_log_w" \ + "Post" \ + "Make" \ + "$gsl_post already Made (Converted)" \ + "$gsl_file_db_posts" + continue + fi + ;; + esac +done + +[[ "$gsl_check_done" ]] \ + && echo "# All posts already checked" +} + +#======================================================================= +# Get Post Hash +#======================================================================= +gsl__post_hash_size() { +gsl_post_csum=`cksum "$gsl_post"` +gsl_post_hash=`awk '{print $1}' <<< "$gsl_post_csum"` +gsl_post_size=`awk '{print $2}' <<< "$gsl_post_csum"` +} + +#======================================================================= +# Check if Post has same Hash +#======================================================================= +gsl__post_compare_hash() { +gsl__db_post_hash +if [[ "$gsl_db_post_hash" == "$gsl_post_hash" ]];then + gsl__logs_print \ + "$gsl_log_i" \ + "Post" \ + "Hash" \ + "$gsl_post already Checked from $gsl_post_hash" \ + "$gsl_file_db_posts" + gsl_check_done=true +fi +} + +#======================================================================= +# Get everything after the marker. $1: marker | $2: File +#======================================================================= +gsl__get_header() { +awk -F"$1" -v marker="$1" \ + '{if ($0 ~ marker) print $2}' \ + "$2" 2>/dev/null +} diff --git a/var/lib/gsl/scripts/gsl__tools b/var/lib/gsl/scripts/gsl__tools new file mode 100644 index 0000000..b9e6f9e --- /dev/null +++ b/var/lib/gsl/scripts/gsl__tools @@ -0,0 +1,89 @@ +#!/bin/bash +# file: gsl__tools +# Folder: /var/lib/gsl/scripts +# By echolib +# License: GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 + +#======================================================================= +# Tool: Source if found +#======================================================================= +gsl__check_source() { +if [[ -f "$1" ]];then + source "$1" +else + echo "! Missing file: $1" + return 1 +fi +} + +#======================================================================= +# Tool: Check needed file +#======================================================================= +gsl__check_file() { +if ! [[ -f "$1" ]];then + return 1 +fi +} + +#======================================================================= +# Check Needed Folders, and create needed files +#======================================================================= +# Folders +gsl__create_ff() { +for gsl_folder in "$gsl_dir_db" \ + "$gsl_dir_logs" +do + if ! [[ -d "$gsl_folder" ]];then + echo ": Creating $gsl_folder and give permissions to $USER" + sudo mkdir -p "$gsl_folder" && \ + sudo chown -R $USER:$USER "$gsl_folder" + fi +done + +# Files +for gsl_file in "$gsl_file_logs" \ + "$gsl_file_db_posts" \ + "$gsl_file_db_stats" \ + "$gsl_file_db_domains" +do + gsl__check_file "$gsl_file" || \ + touch "$gsl_file" +done +} + +#======================================================================= +# Check if PWD is configure for DOMAIN +#======================================================================= +gsl__find_domain() { +gsl_nbr_domains=` +find . -maxdepth 1 -not -type d -type f -iname "gsl.*.*" 2>/dev/null \ + | wc -l` +if (( $gsl_nbr_domains > 1 ));then + echo "! Too much domains registred here: Set only One per folder" + return +elif (( $gsl_nbr_domains == 0 ));then + echo "! No registred domain here: change or set folder. See help new" + return +fi + +gsl_find_domain=` +find . -maxdepth 1 -not -type d -type f -iname "gsl.*.*" 2>/dev/null` + +if [[ "$gsl_find_domain" ]];then + gsl_find_domain=` + awk -F"." '{print $(NF-1)"."$NF}' \ + <<< $gsl_find_domain` + gsl_find_domain=${gsl_find_domain,,} + + gsl__check_domain "$gsl_find_domain" +fi +} + +#======================================================================= +# Check and set domain from db +#======================================================================= +gsl__check_domain() { +gsl_this_conf_domain=`grep "$1" "$gsl_file_db_domains"` +! [[ "$gsl_this_conf_domain" ]] \ + && echo "! Domain Not found: $1" +}