diff options
-rwxr-xr-x | bits24-certs.sh | 16 | ||||
-rwxr-xr-x | gfz | 22 | ||||
-rwxr-xr-x | syncclg | 8 | ||||
-rwxr-xr-x | vartak-results-data | 176 | ||||
-rwxr-xr-x | vartak-results-final.awk | 68 | ||||
-rwxr-xr-x | vartak-results-show | 60 | ||||
-rwxr-xr-x | vartak-results.sh | 73 |
7 files changed, 423 insertions, 0 deletions
diff --git a/bits24-certs.sh b/bits24-certs.sh new file mode 100755 index 0000000..118c422 --- /dev/null +++ b/bits24-certs.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +[ -f certificate.jpg ] || exit + +for file in *Participants.csv; do + event="${file%Participants.csv}" + mkdir -pv "$event" + + while IFS=\| read -r email name; do echo + # [ -f "$event/$email" ] && continue + convert -verbose certificate.jpg \ + -pointsize 200 -fill white -font MesloLGL-Nerd-Font-Bold \ + -annotate +3700+2550 "$name" -annotate +3700+3100 "$event" \ + "$event/$email.jpg" + done < "$file" +done @@ -0,0 +1,22 @@ +#!/bin/sh + +FILESDIR="$HOME/GDrive/vartak/CS/practical-files" +ZIPDIR="$HOME/GDrive/vartak/CS/practical-zip" +alias zip='zip -FSr' + +cd "$FILESDIR" || exit +# zip "$ZIPDIR/sem4" sem4 +zip "$ZIPDIR/sem5" sem5 + +# cd "$FILESDIR/sem4" || exit +# zip "$ZIPDIR/sem4/AAD" AAD -x AAD/P04_Flutter/firebase/\* AAD/P04_Flutter/Flutter/\* +# zip "$ZIPDIR/sem4/Android" Android +# zip "$ZIPDIR/sem4/CN" CN +# zip "$ZIPDIR/sem4/IOT" IOT +# zip "$ZIPDIR/sem4/SE" SE +# zip "$ZIPDIR/sem4/TOC" TOC + +cd "$FILESDIR/sem5" || exit +zip "$ZIPDIR/sem5/AI" AI +zip "$ZIPDIR/sem5/INS" INS +zip "$ZIPDIR/sem5/STQA" STQA @@ -0,0 +1,8 @@ +#!/bin/sh + +cd ~/GDrive/vartak/CS/practical-files/sem5 || exit +gfz +gitpush + +printf "\nSyncing Drive..." +syncdrive diff --git a/vartak-results-data b/vartak-results-data new file mode 100755 index 0000000..2e63f44 --- /dev/null +++ b/vartak-results-data @@ -0,0 +1,176 @@ +#!/bin/sh + +help() { echo "vartak-results-data - convert vartak results pdf into CSV data files + +USAGE: + vartak-results-data [OPTION]... <FILE> + +OPTIONS: + -d DEST produce data in the specified DESTination path/directory + -t top header + -h show this help message"; } + +warn() { printf "WARNING: %s\n" "$@" >&2; } +err() { printf "vartak-result-data: %b\n" "$@" >&2; exit 1; } + +while getopts 'td:h' o; do case "$o" in + d) export DEST="$OPTARG" ;; + t) tflag=1 ;; + h) help; exit ;; + *) err "invalid option -- '$OPTARG'" ;; +esac done +shift $((OPTIND - 1)) + +[ "$#" -lt 1 ] && help >&2 && exit 1 + +[ "${1#*ATKT}" != "$1" ] && err "ATKT files are not supported" + +filetype="$(file --mime-type --brief "$1")" +case "$filetype" in + application/pdf) pdftotext -layout "$1"; file="${1%.pdf}.txt"; tmp=1 ;; + text/plain) file="$1" ;; + *) err "only PDF and text files are supported\n$1 :-\n\t$filetype" ;; +esac + +file="$(realpath "$file")" +printf "\n:: Preparing data in : %s\n" "${DEST:=$PWD}" +mkdir -pv "$DEST" +cd "$DEST" || exit + +if [ "$tflag" = 1 ]; then + header="$(sed -nE "0,/^Seat .*Name \s{2,}(.*Total).*$/ s//\1/p" "$file" | + sed -E 's/\s?\[ [0-9]+(\s\])?\s*/,/g; s/,$//')" +else + header="$(sed -nE '0,/^[0-9]{5} [/A-Z ]*\s{2,}(.*)/ s//\1/p' "$file" | + sed -E 's/\s?\[ [0-9]+(\s\])?\s*/,/g; s/,$//')" +fi + +if [ -f names.csv ]; then + echo "names.csv already exists, skipping..." +else + echo "Seat No,Name" >> names.csv + awk -f - "$file" >> names.csv << EOF + /^[0-9]{5}/ { + name = "" + for (i = 2; \$i !~ /^(${header%%[ ,]*}|INTER|TW)/; i++) { name = name " " \$i } + sub(/^\s*/, "", name) + print \$1 "," name + } +EOF +fi + +header="Seat No,$header" + +if [ -f marks.csv ]; then + echo "marks.csv already exists, skipping..." +else + echo "$header" > marks.csv + awk ' + /^[0-9]{5}/ { printf("%d", $1) } + !/^[0-9]/ && !/Seat/ && !/Total\s*\[/ && /Total/ { + start = 1 + while ($start != "Total") start++ + start++ + for (i = start; i <= NF; i++) { + if ($i ~ /^AB$/) { + printf(",%s", "0") + } else if ($i ~ /^[0-9]+$/) { + printf(",%d", $i) + } + } + printf("\n") + } + ' "$file" >> marks.csv +fi + +if [ -f GP.csv ]; then + echo "GP.csv already exists, skipping..." +else + echo "${header%,Total}" > GP.csv + awk ' + /^[0-9]{5}/ { printf("%d", $1) } + / GP / { + start = 1 + while ($start != "GP") start++ + start++ + for (i = start; i <= NF; i++) { + if ($i ~ /F/) { + printf(",%s", "0") + } else if ($i ~ /^[0-9]+$/) { + printf(",%d", $i) + } + } + printf("\n") + } + ' "$file" >> GP.csv +fi + +if [ -f CGP.csv ]; then + echo "CGP.csv already exists, skipping..." +else + echo "$header,CGPA" > CGP.csv + awk ' + /^[0-9]{5}/ { printf("%d", $1) } + / GPA / { gpa = $NF } + / CG / { + start = 1 + while ($start != "CG") start++ + start++ + for (i = start; i <= NF; i++) { + if ($i ~ /F/) { + printf(",%s", "0") + } else if ($i ~ /^[0-9]+$/) { + printf(",%d", $i) + } + } + printf(",%.2f\n", gpa) + } + ' "$file" >> CGP.csv +fi + +rows() { + [ -z "$(sed -n '1!d; /^Seat No,/p' "$1")" ] && + warn "missing header in file: $1"; + grep -cv 'Seat No' "$1" +} + +# no. of rows for each files +nr_names="$(rows names.csv)" +nr_marks="$(rows marks.csv)" +nr_GP="$(rows GP.csv)" +nr_CGP="$(rows CGP.csv)" + +if [ "$nr_names" != "$nr_marks" ] || + [ "$nr_names" != "$nr_GP" ] || + [ "$nr_names" != "$nr_CGP" ]; then + warn "inconsitent number of rows" +fi + +cols() { awk -F, ' + NR == 1 { min = NF } + { if (NF > max) max = NF; if (NF < min) min = NF } + END { + if (max != min) + print "WARNING: inconsitent columns in file: " FILENAME > "/dev/stderr" + print max + } + ' "$1"; } + +# no. of columns for each file +nc_names="$(cols names.csv)" +nc_marks="$(cols marks.csv)" +nc_GP="$(cols GP.csv)" +nc_CGP="$(cols CGP.csv)" + +[ "$nc_names" != 2 ] && + warn "names data doesn't have exactly 2 columns" +[ "$nc_marks" != "$(( nc_GP + 1))" ] && + warn "marks data doesn't have an additional column GP data" +[ "$nc_CGP" != "$(( nc_marks + 1 ))" ] && + warn "CGP data doesn't have an additional column to marks data" + +printf ":: Finished\n" + +# clean up +[ "$tmp" = 1 ] && rm -f "$file" + diff --git a/vartak-results-final.awk b/vartak-results-final.awk new file mode 100755 index 0000000..a156277 --- /dev/null +++ b/vartak-results-final.awk @@ -0,0 +1,68 @@ +#!/bin/awk -f + +BEGIN { FS="," } +FNR == 1 { next } +FILENAME ~ /\/?names.csv$/ { names[$1] = $NF; next } +FILENAME ~ /\/?marks.csv$/ { marks[$1] = $NF; next } +FILENAME ~ /\/?CGP.csv$/ { gpas[$1] = $NF; next } + +END { + i = 1 + for (sn in names) { + order[i++] = sn + if (marks[sn] == 0) { marks[sn] = ""; results[sn] = "AB" } + else if (gpas[sn] == 0) results[sn] = "F" + else results[sn] = gpas[sn] + } + + if (sort == "yes") { + rank="\n\t\t\t<th>Rank</th>\n" + n = length(order) + for (i in order) { + max = i + for (j = i; j <= n; j++) { + sn1 = order[max]; sn2 = order[j] + if (results[sn1] == results[sn2]) { + if (marks[sn1] < marks[sn2]) max = j + } + else if (results[sn1] == "AB") max = j + else if (results[sn1] == "F") { + if (results[sn2] != "AB") max = j + } + else if (gpas[sn1] < gpas[sn2]) max = j + } + if (max != i) { t = order[i]; order[i] = order[max]; order[max] = t } + } + } + + print("<table>\n\ + <thead>\n\ + <tr>\n" rank\ +" <th>Seat<br>No.</th>\n\ + <th>Name</th>\n\ + <th>Total<br>Marks</th>\n\ + <th>GPA</th>\n\ + </tr>\n\ + </thead>\n\ + <tbody>") + for (i in order) { + sn = order[i] + if (results[sn] == "AB") { + print("\t\t<tr class=\"absent\">") + } else if (results[sn] == "F") { + print("\t\t<tr class=\"fail\">") + } else if (gpas[sn] >= 9) { + print("\t\t<tr class=\"pass notable\">") + } else { + print("\t\t<tr class=\"pass\">") + } + if (sort == "yes") printf("\t\t\t<td class=\"numeric\">%s</td>\n", i) + printf("\t\t\t<td class=\"numeric\">%s</td>\n", sn) + printf("\t\t\t<td class=\"name\">%s</td>\n", names[sn]) + printf("\t\t\t<td class=\"numeric\">%s</td>\n", marks[sn]) + printf("\t\t\t<td class=\"numeric\">%s</td>\n", results[sn]) + print("\t\t</tr>") + } + print("\t</tbody>") + print("</table>") +} diff --git a/vartak-results-show b/vartak-results-show new file mode 100755 index 0000000..6872943 --- /dev/null +++ b/vartak-results-show @@ -0,0 +1,60 @@ +#!/bin/sh + +help() { echo "vartak-results-show - display results with names of students + +USAGE: + vartak-results-show [OPTION]... <FILE> + +OPTIONS: + -s FIELD sort by FIELD name + -S FIELD sort by FIELD name (reversed) + -N NAMES path to file that has student names data + -h show this help message + +FILE is the CSV file that contains scores of each student. +FIELD name is one of the field from CSV header. + +NAMES data is the file containing the names of student. By default, it's +assumed that this file is named as 'names.csv' and is present in the current +directory. This file should have seat no in first column and names in the +second."; } + +err() { printf 'vartak-results-show: %s\n' "$@" >&2; exit 1; } +while getopts 'ns:S:N:h' o; do case "$o" in + s) SORTFIELD="$OPTARG" ;; + S) SORTFIELD="$OPTARG" SORTOPTS="$SORTOPTS -r" ;; + N) NAMEFILE="$OPTARG" ;; + h) help; exit ;; + *) err "invalid option -- '$OPTARG'" ;; +esac done +shift $((OPTIND - 1)) + +[ ! -f "${NAMEFILE:=names.csv}" ] && err "file not found: $NAMEFILE" + +[ "$(awk -F, '{print NF; exit}' "$NAMEFILE")" != 2 ] && + err "NAMES data doesn't have exactly 2 columns" + +[ "$#" -lt 1 ] && help >&2 && exit 1 + +data="$(awk -F, ' + FNR == NR { a[$1] = $2; next; } + { + printf("%s%s%s", $1, FS, a[$1]) + for (i = 2; i <= NF; i++) { + printf("%s%s", FS, $i) + } + print "" + } + ' "$NAMEFILE" "$1")" + +header="$(echo "$data" | head -1)" +data="$(echo "$data" | tail +2)" + +if [ -n "$SORTFIELD" ]; then + FIELDINDEX="$(echo "$header" | sed -n 's/,/\n/gp' | + grep -nx "$SORTFIELD" | cut -d: -f1)" + data="$(echo "$data" | sort -n "$SORTOPTS" -t, -k "$FIELDINDEX")" || exit +fi + +(printf "Sr. No,%s\n" "$header"; echo "$data" | nl -s, -w1) | + column --table --separator ',' --table-right 1,2,4-20 diff --git a/vartak-results.sh b/vartak-results.sh new file mode 100755 index 0000000..2953fb2 --- /dev/null +++ b/vartak-results.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +export RESULT_DIR="$HOME/GDrive/vartak/results" +export SITE_BASE_DIR="$HOME/Dev/csstudent41.github.io" +export DATA_DIR="$SITE_BASE_DIR/data/results" +export CONTENT_DIR="$SITE_BASE_DIR/content/results" + +hugo_new() { + mkdir -p "$(dirname "$1")" + echo "+++ +title = \"${2:-$1}\" +date = $(date +%Y-%m-%dT%H:%M:%S%:::z) ++++" > "$1" && + echo "Content \"$1\" created" +} + +# rm -r "$CONTENT_DIR" +# rm "$CONTENT_DIR/_index.md" +# rm -r "$CONTENT_DIR/2022-23/fycs-sem2" + +cd "$SITE_BASE_DIR" || exit +[ ! -f "$CONTENT_DIR/_index.md" ] && { + hugo_new "$CONTENT_DIR/_index.md" "📝 Vartak Exam Results" +} + + +find "$RESULT_DIR" -type f -iwholename "*$1*" -name '*-REGULAR-*.pdf' \ + -printf '%P\n' | while read -r file; do + dir="$DATA_DIR/${file%.pdf}" + outdir="$(echo "${file%.pdf}" | sed 's/-\(REGULAR\|ATKT\)-.*$//; s/\(.*\)/\L\1/')" + outdir="$CONTENT_DIR/${outdir%-*}$(echo "${outdir##*-}" | + sed 's/iv/iiii/; s/v/iiiiii/' | tr -d \\n | wc -m)" + + [ -d "$dir" ] || { + case "${file%%/*}" in + 2022-23) + case "${file##*/}" in + SYIT*) vartak-results-data -td "$dir" "$RESULT_DIR/$file" ;; + *) vartak-results-data -d "$dir" "$RESULT_DIR/$file" ;; + esac + ;; + + 2023-24) + case "${file##*/}" in + SYBCOM*|SYBBI*|FYBCOM*|FYBBI*) + vartak-results-data -td "$dir" "$RESULT_DIR/$file" ;; + FYBMS*|SYBMS*) continue ;; + *) vartak-results-data -d "$dir" "$RESULT_DIR/$file" ;; + esac + ;; + + *) vartak-results-data -d "$dir" "$RESULT_DIR/$file" ;; + esac + [ -d "$dir" ] && rm -rf "$outdir" + } + + [ -f "$outdir/_index.html" ] && continue + title="$(echo "${dir##*/}" | + sed 's/-\(REGULAR\|ATKT\)-.*$//; s/SEM/Sem/; s/-/ /g;')" + hugo_new "$outdir/_index.html" "📜 $title" + echo "<p style=\"text-align: center\">Checkout <a href=\"toppers\">top scorers</a> 🚀</p>" >> "$outdir/_index.html" + vartak-results-final.awk "$dir/names.csv" "$dir/marks.csv" "$dir/CGP.csv" >> "$outdir/_index.html" + + [ -f "$outdir/toppers.html" ] && continue + hugo_new "$outdir/toppers.html" "🎓 $title" + vartak-results-final.awk sort=yes "$dir/names.csv" "$dir/marks.csv" "$dir/CGP.csv" >> "$outdir/toppers.html" +done + + +find "$CONTENT_DIR" -mindepth 1 -maxdepth 1 -type d | while read -r dir; do + [ -f "$dir/_index.md" ] && continue + hugo_new "$dir/_index.md" "🗓️ ${dir##*/}" +done |