hbbs

[archived] bbs.hlirc.net
git clone https://hhvn.uk/hbbs
git clone git://hhvn.uk/hbbs
Log | Files | Refs | README | LICENSE

interface.sh (12625B)


      1 #!/bin/sh
      2 
      3 . $cwd/include/userinfo.sh
      4 . $cwd/include/permissions.sh
      5 
      6 k=$(tput setaf $key___colour)
      7 e=$(tput setaf $error_colour)
      8 N=$(tput setaf $new___colour)
      9 U=$(tput setaf $num___colour)
     10 D=$(tput setaf $date__colour)
     11 s=$(tput sgr0)
     12 
     13 set_mode(){
     14 	mode=$1
     15 	page=0
     16 }
     17 
     18 parse_in(){
     19 	cmd=$(echo "$1" | grep -o '^.')
     20 	arg=$(echo "$1" | sed 's/^.[[:space:]]*//')
     21 }
     22 
     23 pager(){
     24 	rows=$(echo "$term_height - 4" | bc)
     25 	head -n $(($rows*($page+1))) | tail -n +$((($rows*$page)+1))
     26 }
     27 
     28 menu_boards(){
     29 	clear
     30 	echo "$banner"
     31 	echo
     32 	printf '%- 20s Posts  Description\n' 'Board'
     33 	echo ================================================================================
     34 	for b in $boards
     35 	do
     36 		b2=$(echo "$b" | tr '[:upper:]' '[:lower:]')
     37 		new=$(awk -v "user=$user" -F"	" '{for (i=8; i<=NF; i++) if ($i == user) print}' < $datadir/boards/$b2/list | wc -l)
     38 		printf '%- 20s [%s% 4d%s] %s\n' \
     39 			"$b" \
     40 			"$([ $new -ne 0 ] && printf "$N" || printf "$U")" \
     41 			"$(awk '$4 != "root"' < $datadir/boards/$b2/list | wc -l)" \
     42 			"${s}" \
     43 			"$(eval "echo \$board_${b2}_desc")"
     44 	done | pager 5 $(echo "$banner" | wc -l)
     45 	printf '=======================================================================Page:%- 3d=\n' "$page"
     46 	while prompt "Ne${k}x${s}t ${k}$([ $page -eq 0 ] && printf "${e}")p${s}revious ${k}u${s}sers ${k}s${s}elect rel${k}o${s}ad intro${k}d${s}uction mar${k}k${s} ${k}h${s}elp" input
     47 	do
     48 		oldprompt "$input"
     49 		parse_in "$input"
     50 		case "$cmd" in
     51 			x|"") page=$(($page+1)); break ;;
     52 			p)
     53 				[ $page -eq 0 ] && {
     54 					error "already on first page"
     55 				} || {
     56 					page=$(($page-1))
     57 					break
     58 				}
     59 				;;
     60 			s) 
     61 				[ "$arg" = "" ] && prompt "board" arg
     62 				board=$(echo "$boards" | tr ' ' '\n' | grep -i "$arg" | head -n 1 | tr '[:upper:]' '[:lower:]')
     63 				[ "$board" = "" ] && error "no such board" || {
     64 					set_mode list
     65 					break 
     66 				}
     67 				;;
     68 			d) cat $cwd/etc/intro ;;
     69 			u) set_mode users; break ;;
     70 			o) break ;;
     71 			k) 
     72 				[ "$arg" = "" ] && markread_all "$user" && break
     73 				[ "$arg" != "" ] && board=$(echo "$boards" | tr ' ' '\n' | grep -i "$arg" | head -n 1 | tr '[:upper:]' '[:lower:]')
     74 				[ "$board" = "" ] && error "no such board" || {
     75 					markread_board "$board" "$user"
     76 					break
     77 				}
     78 				;;
     79 			h) cat <<- EOF
     80 				<cmd> <arg>
     81 
     82 				x - go to the next page
     83 				p - go to the previous page
     84 				s - select <arg> as board
     85 				d - veiw introduction
     86 				u - go to the users menu
     87 				o - reload the current menu
     88 				k - mark read all or <arg> board
     89 				h - show this help
     90 
     91 				(help varies depending on current menu)
     92 				EOF
     93 				;;
     94 			*) error "unrecognized command" ;;
     95 		esac
     96 	done
     97 }
     98 
     99 menu_list(){
    100 	clear
    101 	echo "$banner"
    102 	echo
    103 	[ ! -f $datadir/boards/$board/list ] && echo "1	0	01-Jan-1970	root	empty" > $datadir/boards/$board/list
    104 	echo "  ID    Date          User         Subject                                      "
    105 	echo ================================================================================
    106 	awk -v "n=1" -v "c0=${s}" -v "c1=${U}" -v "c2=${D}" -v "c3=${N}" -v "user=$user" -F"	" '
    107 		$1 != n {print "--------------------------------------------------------------------------------"}
    108 		$4 != "root" {
    109 			n = ""
    110 			for (i=8; i<=NF; i++)
    111 				if ($i == user)
    112 					n = c3
    113 
    114 			printf("%s% 3s.%- 3s%s [%s%s%s] %- 10s | %s%s%s\n", c1, $1, $2, c0, c2, $3, c0, $4, n, $5, c0);
    115 			n = $1
    116 		}
    117 		$4 == "root" {print ""}' < $datadir/boards/$board/list | pager
    118 	printf '=%- 10s============================================================Page:%- 3d=\n' "$(echo "$board" | tr '[:lower:]' '[:upper:]')" "$page" | tr ' ' '=' | sed 's/==$/ =/;s/:=/: /' 
    119 	while prompt "Ne${k}x${s}t ${k}$([ $page -eq 0 ] && printf "${e}")p${s}revious ${k}b${s}oards rel${k}o${s}ad ${k}r${s}ead ${k}$(check_post_perm $board $user noprint || printf "${e}")n${s}ew ${k}h${s}elp" input
    120 	do
    121 		oldprompt "$input"
    122 		parse_in "$input"
    123 		case "$cmd" in
    124 			x|"") page=$(($page+1)); break ;;
    125 			p)
    126 				[ $page -eq 0 ] && {
    127 					error "already on first page"
    128 				} || {
    129 					page=$(($page-1))
    130 					break
    131 				}
    132 				;;
    133 			b) set_mode boards; break ;;
    134 			o) break ;;
    135 			r)
    136 				[ "$arg" = "" ] && prompt "id" arg
    137 				echo "$arg" | grep '.' >/dev/null || {
    138 					arg="$arg.0"
    139 				}
    140 				grep "^${arg%%.*}	${arg##*.}" < $datadir/boards/$board/list >/dev/null && {
    141 					id=$arg
    142 					set_mode "read"
    143 					clear
    144 					break
    145 				} || error "no such id"
    146 				;;
    147 			n)
    148 				check_post_perm $board $user || continue
    149 				[ "$arg" = "" ] && prompt "Subject" subject || subject="$arg"
    150 				info "Type a full stop (.) on a line to end the post"
    151 				file="$datadir/boards/$board/$(echo "$(find $datadir/boards/$board/ -type f | wc -l) + 1" | bc).post"
    152 				sed '/^\.$/q' > $file
    153 				save=""
    154 				prompt "Save mesage (${k}y${s}/${k}n${s})" save
    155 				[ "$save" != "y" ] && {
    156 					info "didn't save message"
    157 					anykey
    158 					break
    159 				}
    160 				lock $datadir/boards/$board/list
    161 				awk -v "data=1	0	$(date +%d-%b-%Y)	$user	$subject	$(basename $file)	$(basename $file)	$(userlist "$user")" -F"	" \
    162 					'BEGIN {print data}
    163 					$4 != "root" {
    164 						ul=""
    165 						for (i=8; i<=NF; i++)
    166 							ul = sprintf("%s\t%s", ul, $i)
    167 						print $1 + 1 "\t" $2 "\t" $3 "\t" $4 "\t" $5 "\t" $6 "\t" $7 ul
    168 					}' \
    169 					< $datadir/boards/$board/list > $datadir/boards/$board/list.new
    170 				mv $datadir/boards/$board/list.new $datadir/boards/$board/list
    171 				unlock $datadir/boards/$board/list
    172 				ok "message sent"
    173 				add_log "post" "$user"
    174 				check_post_throttle "$user"
    175 				anykey
    176 				break
    177 				;;
    178 			h) cat <<- EOF
    179 				<cmd> <arg>
    180 
    181 				x - go to the next page
    182 				p - go to the previous page
    183 				b - go to the boards menu
    184 				o - reload
    185 				r - read the message/thread with <arg> id
    186 				n - create new thread with <arg> subject
    187 				h - show this help
    188 
    189 				(help varies depending on current menu)
    190 				EOF
    191 				;;
    192 			*) error "unrecognized command" ;;
    193 		esac
    194 	done
    195 }
    196 
    197 menu_read(){
    198 	markread "$board" "$user" "$id"
    199 	id2=${id##*.}
    200 	file=$(awk -v "id1=${id%%.*}" -v "id2=${id2}" -F"	" '$1 == id1 && $2 == id2 {print $6 " " $7}' < $datadir/boards/$board/list)
    201 	from=$(awk -v "id1=${id%%.*}" -v "id2=${id2}" -F"	" '$1 == id1 && $2 == id2 {print $4}' < $datadir/boards/$board/list)
    202 	fromf=$([ "$(userget $from realname)" != "$from" ] && echo "From: $(userget $from realname) <$from>" || echo "From: $from")
    203 	printf '\n\n%s\n\n' "$fromf" | cat /dev/stdin $datadir/boards/$board/$(echo "$file" | sed -E 's/.* (.)/\1/') | sed 's/^\.$/ /'
    204 	total_in_thread=$(awk -v "file=$(echo "$file" | sed 's/ .*//')" -F"	" '$6 == file' < $datadir/boards/$board/list | wc -l)
    205 	while prompt "($(($id2+1))/$total_in_thread) Ne${k}$([ $(($id2+1)) -eq $total_in_thread ] && printf "${e}")x${s}t ${k}$([ $id2 -eq 0 ] && printf "${e}")p${s}revious rep${k}$(check_reply_perm $board $user noprint)l${s}y ${k}b${s}oards b${k}a${s}ck ${k}h${s}elp" input
    206 	do
    207 		oldprompt "$input"
    208 		parse_in "$input"
    209 		case "$cmd" in
    210 			x) 
    211 				oldid="$id"
    212 				id=$(awk -v "file=$(echo "$file" | sed 's/ .*//')" -v "id2=$id2" -F"	" '$6 == file && ($2 - 1) == id2 {print $1"."$2}' < $datadir/boards/$board/list)
    213 				[ "$id" = "" ] && {
    214 					error "already on last message in thread"
    215 					id="$oldid"
    216 				} || break
    217 				;;
    218 			p) 
    219 				oldid="$id"
    220 				id=$(awk -v "file=$(echo "$file" | sed 's/ .*//')" -v "id2=$id2" -F"	" '$6 == file && ($2 + 1) == id2 {print $1"."$2}' < $datadir/boards/$board/list)
    221 				[ "$id" = "" ] && {
    222 					error "already on first message in thread"
    223 					id="$oldid"
    224 				} || break
    225 				;;
    226 			b) set_mode boards; break ;;
    227 			l)
    228 				check_reply_perm $board $user || continue
    229 				info "Type a full stop (.) on a line to end the post"
    230 				ofile="$file"
    231 				file="$datadir/boards/$board/$(echo "$(find $datadir/boards/$board/ -type f | wc -l) + 1" | bc).post"
    232 				sed '/^\.$/q' > $file
    233 				save=""
    234 				prompt "Save mesage (${k}y${s}/${k}n${s})" save
    235 				[ "$save" != "y" ] && {
    236 					info "didn't save message"
    237 					anykey
    238 					break
    239 				}
    240 				lnum=$(echo "$(awk -v "file=$(echo "$ofile" | sed 's/ .*//')" -F"	" '$6 == file' < $datadir/boards/$board/list | wc -l) - 1" | bc)
    241 				lock $datadir/boards/$board/list
    242 				awk \
    243 					-v "n=1" \
    244 					-v "file=$(basename "$file")" \
    245 					-v "lnum=$lnum" \
    246 					-v "user=$user" \
    247 					-v "date=$(date +%d-%b-%Y)" \
    248 					-v "ofile=$(echo "$ofile" | sed 's/ .*//')" \
    249 					-v "ul=$(userlist "$user")" -F"	" '
    250 					$6 == ofile && $2 != lnum {print}
    251 					$6 == ofile && $2 == lnum {
    252 						print
    253 						print $1 "\t" lnum + 1 "\t" date "\t" user "\t-->\t" ofile "\t" file "\t" ul
    254 					}
    255 					$6 != ofile
    256 				' < $datadir/boards/$board/list > $datadir/boards/$board/list.new
    257 				mv $datadir/boards/$board/list.new $datadir/boards/$board/list
    258 				unlock $datadir/boards/$board/list
    259 				set_mode list
    260 				ok "message sent"
    261 				add_log "post" "$user"
    262 				check_post_throttle "$user"
    263 				anykey
    264 				break
    265 				;;
    266 			a) set_mode list; break ;;
    267 			h) cat <<- EOF
    268 				<cmd> <arg>
    269 
    270 				x - go to the next page
    271 				p - go to the previous page
    272 				b - go to the boards menu
    273 				l - reply to the thread
    274 				a - go back to $board listing
    275 				h - show this help
    276 
    277 				(help varies depending on current menu)
    278 				EOF
    279 				;;
    280 			"")
    281 				oldid="$id"
    282 				id=$(awk -v "file=$(echo "$file" | sed 's/ .*//')" -v "id2=$id2" -F"	" '$6 == file && ($2 - 1) == id2 {print $1"."$2}' < $datadir/boards/$board/list)
    283 				[ "$id" = "" ] && set_mode list
    284 				break
    285 				;;
    286 			*) error "unrecognized command" ;;
    287 		esac
    288 	done
    289 }
    290 
    291 menu_users(){
    292 	clear
    293 	echo "$banner"
    294 	echo
    295 	echo ================================================================================
    296 	ls $datadir/users/ | pager 4 $(echo "$banner" | wc -l)
    297 	printf '=======================================================================Page:%- 3d=\n' "$page"
    298 	while prompt "Ne${k}x${s}t ${k}$([ $page -eq 0 ] && printf "${e}")p${s}revious ${k}b${s}oards ${k}i${s}nfo ${k}e${s}dit ${k}h${s}elp" input
    299 	do
    300 		oldprompt "$input"
    301 		parse_in "$input"
    302 		case "$cmd" in
    303 			x|"") page=$(($page+1)); break ;;
    304 			p)
    305 				[ $page -eq 0 ] && {
    306 					error "already on first page"
    307 				} || {
    308 					page=$(($page-1))
    309 					break
    310 				}
    311 				;;
    312 			i)
    313 				[ ! -f $datadir/users/${arg:-$user} ] && error "no such user" && break
    314 				clear
    315 				[ "$verify_email" = "yes" ] && {
    316 					[ "$(userget "${arg:-$user}" expiry)" = "" ] && \
    317 						echo "Verified: yes" || \
    318 						echo "Verified: no"
    319 				}
    320 				echo "Created:  $(userget "${arg:-$user}" creation)"
    321 				echo "Email:    $(userget "${arg:-$user}" email)"
    322 				echo "Realname: $(userget "${arg:-$user}" realname)"
    323 				[ "$(userget "${arg:-$user}" nick)" != "" ] && echo "Nick:     $(userget "${arg:-$user}" nick)"
    324 				echo
    325 				cat $datadir/profile/${arg:-$user}
    326 				tput sgr0
    327 				anykey
    328 				break
    329 				;;
    330 			e)
    331 				info "leave prompts empty to let value remain unchanged"
    332 				prompt "email (currently: $(userget $user email))" email
    333 				prompt "usual nick on irc (currently: $(userget $user nick))" nick
    334 				prompt "\"realname\" (currently: $(userget $user realname))" realname
    335 				prompt "password" passwd
    336 				[ "$password" != "" ] && {
    337 					prompt "confirm password" passwd2
    338 					[ "$passwd" = "$passwd2" ] && {
    339 						userset "$user" passwd "$(echo "$passwd" | sha512sum)"
    340 						ok "password updated"
    341 					} || error "passwords do not match"
    342 				}
    343 				[ "$email" != "" ] && checknmail "$email" && userset "$user" email "$email"
    344 				[ "$nick" != "" ] && userset "$user" nick "$nick"
    345 				[ "$realname" != "" ] && userset "$user" realname "$realname"
    346 				prompt "Edit bio (${k}y${s}es/${k}n${s}o/from ${k}u${s}ri)" edit
    347 				[ "$edit" = "y" ] && {
    348 					info "Type a full stop (.) on a line to finish the profile"
    349 					sed '/^\.$/d'  > $datadir/profile/$user.new
    350 					save=""
    351 					while [ "$save" != "y" ] && [ "$save" != "n" ]
    352 					do
    353 						prompt "Save mesage (${k}y${s}/${k}n${s})" save
    354 					done
    355 					[ "$save" = "n" ] && {
    356 						info "didn't save profile"
    357 						anykey
    358 						break
    359 					}
    360 					cp $datadir/profile/$user.new $datadir/profile/$user
    361 				}
    362 				[ "$(echo "$edit" | grep -o '^.')" = "u" ] && {
    363 					[ "$(echo "$edit" | sed 's/^.//' | tr -d ' ')" = "" ] && prompt "uri:" url || uri=$(echo "$edit" | sed 's/^.//' | tr -d ' ')
    364 					curl "$uri" > $datadir/profile/$user
    365 				}
    366 				ok "profile updated"
    367 				anykey
    368 				break
    369 				;;
    370 			b) set_mode boards; break ;;
    371 			h) cat <<- EOF
    372 				<cmd> <arg>
    373 
    374 				x - go to the next page
    375 				p - go to the previous page
    376 				i - view information about yourself, or <arg>
    377 				e - edit your profile
    378 				b - go to the boards menu
    379 				h - show this help
    380 
    381 				(help varies depending on current menu)
    382 				EOF
    383 				;;
    384 		esac
    385 	done
    386 }
    387 
    388 interface(){
    389 	clear
    390 	while true
    391 	do
    392 		case "$mode" in
    393 			boards) menu_boards ;;
    394 			users) menu_users ;;
    395 			list) menu_list ;;
    396 			read) menu_read ;;
    397 			*) set_mode "boards"
    398 		esac
    399 	done
    400 }