Browse Source

Merge branch 'develop' of lcmstaff/lcmlog into master

Wew, was this week long! Felt like almost two. As promised, merging with master.
Alessandro De Gennaro 4 years ago
parent
commit
1078aae9cc
2 changed files with 442 additions and 47 deletions
  1. 50 0
      README.md
  2. 392 47
      lcmlog

+ 50 - 0
README.md

@@ -1,2 +1,52 @@
 # lcmlog
+Client side of a tool for reading and writing the lcm staff logs (both admins and 150). Requests are sent via ssh using user's account.
 
+## TL;DR: Installation and basic usage
+To install this software, simply clone this repository to your preferred machine; the machine doesn't have to be in the same subnet as the log server, the only requirement being that the server is reachable via SSH (through jumps, if needed).
+
+Usage: `lcmlog [-g] [-p]`. Currently supported methods are GET (`-g`) to print stored logs and POST (`-p`) to add new logs to the server.
+When running the software for the first time, regardless of the selected method, you will be prompted to open and edit a new configuration file with the editor corresponding to your `EDITOR` environment variable (default: `nano`).
+Write it as an SSH-config file (`~/.ssh/config`); this is used by the software to contact your log server.
+
+For any further questions, either run `lcmlog -h` or read the rest of this README.
+
+## Methods
+
+#### GET
+The `GET` method is called with the `-g` option and is used to print all the logs that meet the required criteria.
+
+#### POST
+The `POST` method is called with the `-p` option and is used to add a log to the database. Accented characters are allowed and automatically transformed using quotation marks or backticks.
+
+#### UPDATE
+The `UPDATE` method is called with the `-u` option and is used to regenerate the internal server database. It should only be called if a log file is added by hand, or if some of the log files get renamed or corrupted. It assumes that all the log files are correctly formatted. **CURRENTLY NOT WORKING**.
+
+## Configuration file
+To choose the server to communicate with, ssh uses a config file located in `~/.config/lcmlog`. The configuration file is named `config` and is a ssh config file: so, for more help, refer to ssh\_config manuals (i.e. run `man ssh_config` on your terminal).
+
+The script always checks if the config file exist: if false, it asks you if you want to generate it. Here the config file template generated by the program (`~/.config/lcmlog/config`):
+
+```
+# lcmlog config file
+
+# Write this file as a ssh_config file.
+# For more info, run the command 'man ssh_config'.
+
+# Host is 'server': do not change the name.
+Host server
+        HostName
+        # User and Port parameters should be used only out of the lcm cluster.
+        #User
+        #Port
+```
+
+After the generation, you should edit the file and add the correct `HostName` (and eventually also `User` and `Port`). This script automatically open the config file after its generation using `nano` editor.
+
+You can't use this program until the config file is generated in the default folder (`~/.config/lcmlog`).
+
+## Editor
+The default editor is `nano`. If you want to use another editor, your best shot is `export`ing the `EDITOR` variable from your shell (e.g. `export EDITOR=vim`). In a future update, this customization will be included in the configuration file.
+
+## TODO
+- [ ] Implement custom editor in the configuration file.
+- [ ] Implement the `UPDATE` method

+ 392 - 47
lcmlog

@@ -1,118 +1,463 @@
 #!/bin/bash
 
-DIR='/usr/local/src/lcm-unimi/lcmlog'
+DIR="/var/local/log/lcmlog-data"
+
+EDITOR="${EDITOR:-nano}"
+
+######################
+# AUXILIARY FUNCTION #
+######################
+
 
 usage()
 {
-	echo "$0 -gpu"
+	echo "Usage: $0 [-g|-p|-u]"
+	echo "Use -h option to show the help message."
 }
 
+
+######
+
+
+method_help()
+{
+	echo "lcmlog: client side of a tool for reading and writing the lcm staff logs."
+	echo
+	echo "Usage: $0 [option]"
+	echo
+	echo "Options:"
+	echo "  -g  Method GET: print all the logs that meet the required criteria"
+	echo "  -p  Method POST: add a log to the database"
+	echo "  -u  Method UPDATE: regenerate the internal server database"
+	echo "  -h  Show this help"
+}
+
+
+######
+
+
 method_get()
 {
 	pipe=$1
-	while true; do	# The user must say if he is looking for 150 or Admin logs
-		echo "Search for admin logs (a) or 150 logs (1)?"
+
+
+	# KIND
+	# The user must say if he's looking for 150 or Admin logs
+	echo "Search for admin logs [a] or 150 logs [1]?"
+	read CHAR
+	while [ -z $CHAR ]; do
+		echo "Retry, admin logs [a] or 150 logs [1]?"
 		read CHAR
-		if [ -z $CHAR ]; then continue; fi
-		if [ $CHAR == "a" ]; then
-			KIND="ADMIN"
-			break
-		elif [ $CHAR == "1" ]; then
-			KIND="150"
-			break
-		fi
 	done
+	while [ $CHAR != "a" ] && [ $CHAR != "1" ]; do
+		echo "Retry, admin logs [a] or 150 logs [1]?"
+		read CHAR
+		while [ -z $CHAR ]; do
+			echo "Retry, admin logs [a] or 150 logs [1]?"
+			read CHAR
+		done
+	done
+
+	# Select the correct kind
+	if [ $CHAR == "a" ]; then
+		KIND="Admin"
+	elif [ $CHAR == "1" ]; then
+		KIND="150"
+	fi
 
-	echo "Search for which user?"
+	# USER
+	echo
+	echo "Search for which user? (optional)"
 	read USER
 
-	echo "Search for which date?"
+	# DATE
+	echo
+	echo "Search for which date? (yyyy-mm-dd) (optional)"
 	read DATE
+	while ! [ -z $DATE ]; do
+		if [ ${DATE:4:1} != '-' ] || [ ${DATE:7:1} != '-' ] || (( ${#DATE} != 10 )); then
+			echo "Format: yyyy-mm-dd (i.e. 9 is 09). Reinsert."	
+			read DATE
+		else
+			break
+		fi
+	done
 
-	echo "Search for which tags? (insert comma separated tags)"
+	# TAGS
+	echo
+	echo "Search for which tags? (insert comma separated tags) (optional)"
 	read TAGS
 
+
+	# Update pipe
 	printf "%s\n" "GET" >> $pipe
 	printf "%s\n" "${KIND}" >> $pipe
 	printf "%s\n" "${DATE}" >> $pipe
 	printf "%s\n" "${TAGS}" >> $pipe
 	printf "%s\n" "${USER}" >> $pipe
-	
 }
 
+
+######
+
+
 method_post()
 {
 	pipe=$1
-	while true; do
-		echo "Post for admin logs (a) or 150 logs (1)?"
+
+
+	# KIND
+	AUX="n"
+	while [ $AUX == n ]; do
+		echo "Send an admin log [a] or 150 log [1]?"
 		read CHAR
+		while [ -z $CHAR ]; do
+			echo "Retry, admin logs [a] or 150 logs [1]?"
+			read CHAR
+		done
+		while [ $CHAR != "a" ] && [ $CHAR != "1" ]; do
+			echo "Retry, admin logs [a] or 150 logs [1]?"
+			read CHAR
+			while [ -z $CHAR ]; do
+				echo "Retry, admin logs [a] or 150 logs [1]?"
+				read CHAR
+			done
+		done
+		# Select the correct kind
 		if [ $CHAR == "a" ]; then
-			KIND="ADMIN"
-			break
+			KIND="Admin"
 		elif [ $CHAR == "1" ]; then
 			KIND="150"
-			break
 		fi
+		echo "Confirm $KIND log? [y|n] "
+		read AUX
+		while [ -z $AUX ]; do
+			echo "Yes (y) or no (n)? "
+			read AUX
+		done
+		while [ $AUX != "y" ] && [ $AUX != "n" ]; do
+			echo "Yes (y) or no (n)? "
+			read AUX
+			while [ -z $AUX ]; do
+				echo  "Yes (y) or no (n)? "
+				read AUX
+			done
+		done
 	done
 
-	while true; do
-		echo "Date?"
-		read DATE
-		if [ ! -z $DATE ]; then
-			break;
-		fi
+
+	# DATE
+	echo
+	echo "Insert the date."
+
+	# Year
+	echo "Year? (yyyy)"
+	read YEAR
+	YEAR=$((10#$YEAR))
+	re='^[0-9]+$'
+	while ! [[ $YEAR =~ $re ]]; do
+	   echo "Wrong, not a number: reinsert."
+		 read YEAR
+		 YEAR=$((10#$YEAR))
+	done
+	while (( ${#YEAR} != 4 )); do
+		echo "Wrong year, reinsert."
+		read YEAR
+		YEAR=$((10#$YEAR))
+		while ! [[ $YEAR =~ $re ]]; do
+		   echo "Wrong, not a number: reinsert."
+			 read YEAR
+			 YEAR=$((10#$YEAR))
+		done
 	done
 
-	while true; do
-		echo "Tags? (insert comma separated tags)"
-		read TAGS
-		if [ ! -z $DATE ]; then
-			break;
+	# Month
+	echo "Month? (mm)"
+	read MONTH
+	MONTH=$((10#$MONTH))
+	re='^[0-9]+$'
+	while ! [[ $MONTH =~ $re ]]; do
+	   echo "Wrong, not a number: reinsert."
+		 read MONTH
+		 MONTH=$((10#$MONTH))
+	done
+	while (( $MONTH < 1 )) || (( $MONTH > 12 )); do
+		echo "Wrong month, reinsert."
+		read MONTH
+		MONTH=$((10#$MONTH))
+		while ! [[ $MONTH =~ $re ]]; do
+		   echo "Wrong, not a number: reinsert."
+			 read MONTH
+			 MONTH=$((10#$MONTH))
+		done
+	done
+
+	# Day
+	echo "Day? (dd)"
+	if (( $MONTH == 2 )); then
+		echo "Be careful about the day! There is no check about leap years."
+	fi
+	read DAY
+	DAY=$((10#$DAY))
+	re='^[0-9]+$'
+	while ! [[ $DAY =~ $re ]]; do
+	   echo "Wrong, not a number: reinsert."
+		 read DAY
+		 DAY=$((10#$DAY))
+	done
+	# Month with 31 day
+	if (( $MONTH == 1 )) || (( $MONTH == 3 )) || (( $MONTH == 5 )) || (( $MONTH == 7 )) || (( $MONTH == 8 )) || (( $MONTH == 10 )) || (( $MONTH == 12 )); then
+		while (( $DAY < 1 )) || (( $DAY > 31 )); do
+			echo "Wrong day, reinsert."
+			read DAY
+			DAY=$((10#$DAY))
+			while ! [[ $DAY =~ $re ]]; do
+				echo "Wrong, not a number: reinsert."
+				read DAY
+				DAY=$((10#$DAY))
+			done
+		done
+	# Month with 30 day
+	elif (( $MONTH == 4 )) || (( $MONTH == 6 )) || (( $MONTH == 9 )) || (( $MONTH == 11 )); then
+		while (( $DAY < 1 )) || (( $DAY > 30 )); do
+			echo "Wrong day, reinsert."
+			read DAY
+			DAY=$((10#$DAY))
+			while ! [[ $DAY =~ $re ]]; do
+				echo "Wrong, not a number: reinsert."
+				read DAY
+				DAY=$((10#$DAY))
+			done
+		done
+	# Month with 29 day
+	elif (( $MONTH == 2 )); then
+		while (( $DAY < 1 )) || (( $DAY > 29 )); do
+			echo "Wrong day, reinsert."
+			read DAY
+			DAY=$((10#$DAY))
+			while ! [[ $DAY =~ $re ]]; do
+				echo "Wrong, not a number: reinsert."
+				read DAY
+				DAY=$((10#$DAY))
+			done
+		done
+	fi
+
+	## Turn month and day in correctly strings
+	if (( ${#MONTH} == 1 )); then
+		MONTH=0$MONTH
+	fi
+
+	if (( ${#DAY} == 1 )); then
+		DAY="0$DAY"
+		#DAY=$((10#$DAY))
+	fi
+
+	# Morning or afternoon shift
+	if [ $KIND == "150" ]; then
+		echo "Morning [m] or afternoon [p] shift?"
+		read CHAR
+		while [ -z $CHAR ]; do
+			echo "Retry, morning [m] or afternoon [p] shift?"
+			read CHAR
+		done
+		while [ $CHAR != "m" ] && [ $CHAR != "p" ]; do
+			echo "Retry, morning [m] or afternoon [p] shift?"
+			read CHAR
+			while [ -z $CHAR ]; do
+				echo "Retry, morning [m] or afternoon [p] shift?"
+				read CHAR
+			done
+		done
+
+		# Select the correct kind
+		if [ $CHAR == "m" ]; then
+			MP="mat"
+		elif [ $CHAR == "p" ]; then
+			MP="pom"
 		fi
+		
+		DATE=$YEAR"-"$MONTH"-"$DAY"_"$MP
+	else
+		DATE=$YEAR"-"$MONTH"-"$DAY
+	fi
+
+
+	# TAGS
+	echo
+	echo "Tags? (insert comma separated tags)"
+	read TAGS
+	while [ -z $TAGS ]; do
+		echo "Insert tags."
+		read TAGS
 	done
 
+
+	# Update of the pipe
 	printf "%s\n" "POST" >> $pipe
 	printf "%s\n" "${KIND}" >> $pipe
 	printf "%s\n" "${DATE}" >> $pipe
 	printf "%s\n" "${TAGS}" >> $pipe
 
-	printf "Please write your log\n\n"
 
-	cat - >> $pipe
+	# Write log
+	echo
+	echo "Please write your log:"
+	echo
+#	cat - >> $pipe
+	FILE_NAME=$(mktemp)
+	$EDITOR $FILE_NAME
+	cat $FILE_NAME >> $pipe
+	rm $FILE_NAME
 }
 
-# Entry point
-while getopts ":gpu" o; do
+
+###############
+# MAIN SCRIPT #
+###############
+
+
+## ENTRY POINT - INITIALIZATION
+
+# Check number of arguments
+if (( $# != 1 )); then
+	usage
+	exit 1
+fi
+
+# Check that the option is only one
+# -->   -g   OK
+#       -gp  NO
+if (( ${#1} != 2 )); then
+	usage
+	exit 1
+fi
+
+# Select method from the option
+while getopts ":gpuh" o; do
 	case $o in
-	g) METHOD="GET";;
-	p) METHOD="POST";;
-	u) METHOD="UPDATE";;
-	\?) usage && exit;;
+		g) METHOD="GET";;
+		p) METHOD="POST";;
+		u) METHOD="UPDATE";;
+		h) method_help && exit 0;;
+		#*) usage;;
+		\?) usage && exit 1;;
 	esac
 done
+
+# You must reset of the correct $OPTIND
 shift $(( $OPTIND -1 ))
 
-if [ -z "${METHOD}" ] ; then
-	usage && exit
+# Security control
+if [ -z "${METHOD}" ]; then usage; fi
+
+
+## CHECK CONFIG FILE
+if ! [ -f ~/.config/lcmlog/config ]; then
+	echo "Config file not found. The config file must be generated in order to use this program."
+	echo "Do you want to generate it? (folder: ~/.config/lcmlog) [y|n]"
+	read AUX
+	while [ -z $AUX ]; do
+		echo "Yes (y) or no (n)? "
+		read AUX
+	done
+	while [ $AUX != "y" ] && [ $AUX != "n" ]; do
+		echo "Yes (y) or no (n)? "
+		read AUX
+		while [ -z $AUX ]; do
+			echo  "Yes (y) or no (n)? "
+			read AUX
+		done
+	done
+	if [ $AUX == "y" ]; then
+		mkdir -p ~/.config/lcmlog
+		echo \
+"# lcmlog config file
+
+# Write this file as a ssh_config file.
+# For more info, run the command 'man ssh_config'.
+
+# Host is 'server': do not change the name.
+Host server
+	HostName
+	# User and Port parameters should be used only out of the lcm cluster.
+	#User
+	#Port" \
+		> ~/.config/lcmlog/config
+		echo "Done. Now you should edit the file and add HostName (and, in case, User and Port)."
+		echo "Opening file with $EDITOR in 4 seconds..."
+		sleep 4
+		$EDITOR ~/.config/lcmlog/config
+		echo
+	else
+		echo "Exit."
+		exit 0
+	fi
 fi
 
+
+## APPLY METHOD
+
 # Temporary pipe to send input to the server
 pipe=$(mktemp)
 
+# Use the correct method
+# Method UPDATE
 if [ "$METHOD" == "UPDATE" ]; then
+	echo "The UPDATE method is used to regenerate the internal server database."
+	echo "It should only be called if a log file is added by hand,"
+	echo "or if some of the log files get renamed or corrupted."
+	echo "It assumes that all the log files are correctly formatted."
+	echo
+	echo "Are you sure? [y|n] "
+	read ANSWER
+
+	while [ -z $ANSWER ]; do
+		printf "Yes (y) or no (n)? "
+		read ANSWER
+	done
+
+	while [ $ANSWER != "y" ] && [ $ANSWER != "n" ]; do
+		printf "Yes (y) or no (n)? "
+		read ANSWER
+
+		while [ -z $ANSWER ]; do
+			printf  "Yes (y) or no (n)? "
+			read ANSWER
+		done
+	done
+
+	if [ $ANSWER == "n" ]; then exit 0; fi
+
 	printf "UPDATE\n" >> $pipe
+	# Method GET
 elif [ "$METHOD" == "GET" ]; then
 	method_get $pipe
+	# Method POST
 elif [ "$METHOD" == "POST" ]; then
 	method_post $pipe
 fi
-	
+
+# Remove accents
+pipe2=$(mktemp)
+sed -e 's/à/a`/g' -e 's/è/e`/g' -e "s/é/e'/g" -e 's/ì/i`/g' -e 's/ò/o`/g' -e 's/ù/u`/g' -e 's/È/E`/g' < $pipe > $pipe2
+
 # Call the server
-ssh -s log@tuc lcmlog < $pipe
+echo
+ssh -F ~/.config/lcmlog/config -s server lcmlog < $pipe2
+
+
+### ENDING
 
+# Remove temporary pipe
+rm $pipe $pipe2
+
+# Check success or error
 RET=$?
-if [ $RET -ne 0 ]; then
+if (( $RET == 0 )); then
+	echo "Operation $METHOD completed successfully."
+	exit 0
+else
 	printf "Server error: $RET\n" >&2
+	exit $RET
 fi
-
-rm $pipe