#! /bin/bash localdir=~/.local/share/iris [[ -d $localdir/.fultmod ]] || mkdir -p $localdir [[ -f $localdir/.fultmod ]] || touch -d '2000-01-01' $localdir/.fultmod # fultmod: fecha y hora desde la que hay que cargar nuevos mensajes fultmod=$localdir/.fultmod fultmod2=$localdir/.fultmod2 mensajes=$localdir/mensajes.txt leidos=$localdir/leidos.txt bd=$localdir/iris.sqlite function update { # Actualizar la base de datos echo "Updating database..." >&2 # .fultmod2: fecha y hora de esta actualización touch $fultmod2 # Obtener la lista de mensajes y guardarla en $mensajes echo "hash|edit_hash|is_deleted|author|parent|timestamp|message" > $mensajes find /home/*/.iris.messages -newer $fultmod | while read mensajes; do jq '.[] | .hash + "|" + .edit_hash + "|" + ( .is_deleted | tostring ) + "|" + .data.author + "|" + .data.parent + "|" + .data.timestamp + "|" + (.data.message | gsub("\\|"; ":pipe:"))' "$mensajes" done | tr -d '"' >> $mensajes # Obtener la lista de mensajes leídos y guardarla en leidos echo "hash" > $leidos jq '.[]' ~/.iris.messages.read | tr -d '"' >> $leidos # Guardar la información en sqlite sqlite3 $bd <<< " CREATE TABLE IF NOT EXISTS 'mensajes'( 'hash' TEXT, 'edit_hash' TEXT, 'is_deleted' TEXT, 'author' TEXT, 'parent' TEXT, 'timestamp' TEXT, 'message' TEXT ); CREATE TABLE IF NOT EXISTS 'leidos'( 'hash' TEXT ); CREATE INDEX IF NOT EXISTS mensajes_idx_00014b4c ON mensajes(hash); CREATE INDEX IF NOT EXISTS leidos_idx_00014b4c ON leidos(hash); .import $mensajes mensajes .import $leidos leidos create temporary table duplicados as select rowid as id from mensajes a where exists ( select 1 from mensajes b where b.hash = a.hash and b.rowid < a.rowid ); delete from mensajes where rowid in (select id from duplicados); delete from mensajes where timestamp = 'timestamp'; drop table duplicados; create temporary table duplicados as select rowid as id from leidos a where exists ( select 1 from leidos b where b.hash = a.hash and b.rowid < a.rowid ); delete from leidos where rowid in (select id from duplicados); " && { mv $fultmod2 $fultmod rm $mensajes $leidos } } function ls_all { # Listar todos los hilos sqlite3 $bd <<< " select distinct rowid , substr(timestamp,1,10) , substr(author,1,instr(author, '@')-1) , case when instr(message, '\n') > 0 then substr(message,1,instr(message, '\n')-1) else message end as message from mensajes where is_deleted <> 'true' and parent = '' and edit_hash = '' order by timestamp desc" } function search { # Buscar hilos por palabras mencionadas en los mensajes sqlite3 $bd <<< " select distinct rowid , substr(timestamp,1,10) , substr(author,1,instr(author, '@')-1) , case when instr(message, '\n') > 0 then substr(message,1,instr(message, '\n')-1) else message end as message from mensajes where ( is_deleted <> 'true' and parent = '' and edit_hash = '' and message like '%$1%' ) or ( hash = ( select parent from mensajes where is_deleted <> 'true' and parent <> '' and edit_hash = '' and message like '%$1%' ) ) order by timestamp desc" } function ls_unread { # Listar hilos con mensajes sin leer sqlite3 $bd <<< " select distinct rowid , substr(timestamp,1,10) , substr(author,1,instr(author, '@')-1) , case when instr(message, '\n') > 0 then substr(message,1,instr(message, '\n')-1) else message end as message from mensajes a where is_deleted <> 'true' and parent = '' and edit_hash = '' and ( hash not in ( select hash from leidos ) or exists ( select 1 from mensajes b where parent = a.hash and b.hash not in ( select hash from leidos ) ) ) order by timestamp desc" } function t { # Menú para elegir un hilo de la lista completa while : ; do update mensaje="$(ls_all | menu "Filter: (Esc to go back) ")" [[ -z $mensaje ]] && break show $mensaje done unset mensaje } function u { # Menú para elegir un hilo entre los que tienen mensajes sin leer while : ; do update [[ $(ls_unread | wc -l) -gt 0 ]] || { echo "All messages read. Press any key to continue" >&2 read -sn1 break } mensaje="$(ls_unread | menu "Filter: (Esc to go back) ")" && [[ -z $mensaje ]] && break show $mensaje done unset mensaje } function s { # Buscar un hilo por palabras update lista="$(search "$1")" [[ -z "$lista" ]] && { echo "\"$1\" not found. Press any key to continue" >&2 read -sn1 return } unset mensaje mensaje="$(search "$1" | menu)" && [[ -n $mensaje ]] && show $mensaje unset mensaje } function menu { column -t -s'|' | fzf -e --reverse --no-sort --info=hidden --prompt="$1" | cut -d' ' -f1 } function thread { # Obtener el hash del mensaje inicial del hilo hash=$(sqlite3 $bd <<< " select hash from mensajes where rowid = '$1'") { sqlite3 $bd <<< " select substr(timestamp,1,10), author, message from mensajes where rowid = '$1'" sqlite3 $bd <<< " select substr(timestamp,1,10), author, message from mensajes where is_deleted <> 'true' and parent = '$hash' and edit_hash = '' order by timestamp" } | sed 's/\\n/:nl:/g' } function show { # Mostrar los mensajes de un hilo # Obtener el hash del mensaje inicial del hilo hash=$(sqlite3 $bd <<< " select hash from mensajes where rowid = '$1'") # Obtener la anchura del terminal anchura=$(tput cols) margen=0 [[ $anchura -gt 80 ]] && margen=$(( ($anchura - 80)/2 )) && anchura=80 && [[ $margen -gt 3 ]] && margen=3 # Mostrar los mensajes del hilo clear { echo "<<< Press q to go back" thread "$1" | while IFS='|' read fecha autor mensaje; do echo; echo -e "\033[0;32m$fecha $autor\033[0m"; echo "$mensaje" | sed 's/:nl:/\n/g; s/:pipe:/|/g' | fold -s -w $anchura; done | awk -v margen=$margen '{for (i=0; i1){ sep="," } } { printf sep "\"" $1 "\""; } END { print "]" } ' > "$HOME/.iris.messages.read" } # Show TUI only if first parameter is null # Useful for source the functions: # . path/to/iris-search silent [[ -z $1 ]] && while true; do clear res="$(echo "1 Unread 2 All topics 3 Search 4 Quit" | menu "Iris forum: " | cut -d' ' -f1)" [[ -z $res ]] && break case $res in 1) u ;; 2) t ;; 3) clear read -p "Search word: " word s "$word" ;; 4) break ;; *) : ;; esac done && clear