add sync database option

Added option to sync the history databases for the same user
across devices on the same network (or the internet if that is set up on
the machines)
This commit is contained in:
ksyasuda 2021-11-11 14:13:11 -08:00
parent 3169872eac
commit 4853dea3d5
3 changed files with 398 additions and 192 deletions

310
ani-cli
View File

@ -118,6 +118,10 @@ run_stmt() {
printf "%s\n" "$1" | sqlite3 -noheader "$HISTORY_DB"
}
#####################
## Database Code ##
#####################
check_db() {
# Return number of matches for anime/episode in db
# echo "$1 $2"
@ -186,6 +190,47 @@ insert_history() {
fi
}
sync_search_history() {
cnt=0
while read -r line; do
anime_name=$(awk -F '|' '{print $2}' <<<"$line")
res=$(sqlite3 -noheader "$HISTORY_DB" <<<"SELECT anime_name FROM search_history WHERE anime_name = '$anime_name'")
if [[ "${res/ //}" == "" ]]; then
printf "%s\n" "Adding $line to search history..."
search_date=$(awk -F '|' '{print $3}' <<<"$line")
sqlite3 "$HISTORY_DB" <<<"INSERT INTO search_history(anime_name, search_date) VALUES('$anime_name', '$search_date')"
if [[ "$?" -ne 0 ]]; then
err "Error inserting row $line"
fi
((++cnt))
fi
done <<<"$(sqlite3 -noheader "$temp_db" <<<"SELECT DISTINCT * FROM search_history")"
printf "%s\n" "Inserted $cnt rows into search_history table"
}
sync_watch_history() {
cnt=0
while read -r line; do
anime_name=$(awk -F '|' '{print $2}' <<<"$line")
res=$(sqlite3 -noheader "$HISTORY_DB" <<<"SELECT anime_name FROM watch_history WHERE anime_name = '$anime_name'")
if [[ "${res/ //}" == "" ]]; then
printf "%s\n" "Adding $line to watch history..."
episode_num=$(awk -F '|' '{print $3}' <<<"$line")
watch_date=$(awk -F '|' '{print $NF}' <<<"$line")
sqlite3 "$HISTORY_DB" <<<"INSERT INTO watch_history(anime_name, episode_number, watch_date) VALUES('$anime_name', '$episode_num', '$watch_date')"
if [[ "$?" -ne 0 ]]; then
err "Error inserting row $line"
fi
((++cnt))
fi
done <<<"$(sqlite3 -noheader "$temp_db" <<<"SELECT DISTINCT * FROM watch_history")"
printf "%s\n" "Inserted $cnt rows into watch_history table"
}
#####################
## END of db code ##
#####################
# get query
get_search_query() {
# Query the anime to stream/download
@ -399,17 +444,17 @@ open_episode() {
video_url=$(get_links "$dpage_url")
case $video_url in
*streamtape*)
# If direct download not available then scrape streamtape.com
BROWSER=${BROWSER:-firefox}
printf "scraping streamtape.com\n"
video_url=$(curl -s "$video_url" | sed -n -E '
*streamtape*)
# If direct download not available then scrape streamtape.com
BROWSER=${BROWSER:-firefox}
printf "scraping streamtape.com\n"
video_url=$(curl -s "$video_url" | sed -n -E '
/^<script>document/{
s/^[^"]*"([^"]*)" \+ '\''([^'\'']*).*/https:\1\2\&dl=1/p
q
}
')
;;
;;
esac
if [ $is_download -eq 0 ]; then
@ -454,47 +499,84 @@ is_playlist=0
playlist_remove=0
playlist_add=0
playlist_file="$CFG_DIR/playlists/playlist.txt"
while getopts 'hd:HlpadP:' OPT; do
case $OPT in
h)
help_text
exit 0
;;
d)
is_download=1
download_dir="$OPTARG"
while getopts 'hd:HlpadP:s' OPT; do
case "$OPT" in
h)
help_text
exit 0
;;
d)
is_download=1
download_dir="$OPTARG"
if [ "$VERBOSE" -eq 1 ]; then
echo "DOWNLOAD DIR: $download_dir"
fi
;;
H)
scrape=history
;;
l)
list_history=1
;;
p)
scrape=playlist
is_playlist=1
;;
a)
is_add=1
scrape=add
;;
d)
is_delete=1
scrape=delete
;;
P)
is_playlist=1
# remove spaces from $OPTARG
playlist_file="${OPTARG/ //}"
[ -z "$playlist_file" ] && die "Enter in path to playlist"
[ "$VERBOSE" -eq 1 ] && printf "%s\n" "$playlist_file"
$player_fn "$playlist_file"
exit 0
;;
if [ "$VERBOSE" -eq 1 ]; then
printf "%s\n" "DOWNLOAD DIR: $download_dir"
fi
;;
H)
scrape=history
;;
l)
list_history=1
;;
p)
scrape=playlist
is_playlist=1
;;
a)
is_add=1
scrape=add
;;
d)
is_delete=1
scrape=delete
;;
P)
is_playlist=1
# remove spaces from $OPTARG
playlist_file="${OPTARG/ //}"
[ -z "$playlist_file" ] && die "Enter in path to playlist"
[ "$VERBOSE" -eq 1 ] && printf "%s\n" "$playlist_file"
$player_fn "$playlist_file"
exit 0
;;
s)
printf "%s" "Enter username for remote user: "
read -r username
printf "%s" "Enter host for remote user: "
read -r host
# printf "%s" "Enter connection string for remote user in the form user@host: "
# read -r connection_str
connection_str="$username@$host"
printf "%s" "Enter port to connect to remote host with or leave blank for default (22): "
read -r port
if [[ "${port/ //}" == "" ]]; then
PORT=22
else
PORT="$port"
fi
if [[ ! "@" != *"$connection_str" ]]; then
printf "%s\n" "Enter in full connection string to remote user in the form: user@host"
exit 1
fi
printf "%s\n" "Syncing database with: $connection_str on port $PORT"
temp_db="/tmp/aniwrapper_tmp_history.sqlite3"
scp -P "$PORT" "$connection_str:$XDG_CONFIG_HOME/aniwrapper/history.sqlite3" "$temp_db"
if [[ "$?" -ne 0 ]]; then
printf "%s\n" "Error getting database file from remote host"
exit 1
fi
sync_search_history && sync_watch_history
exit 0
;;
*)
printf "%s\n" "Invalid option"
exit 1
;;
esac
done
shift $((OPTIND - 1))
@ -515,63 +597,63 @@ if [[ "$list_history" -eq 1 ]]; then
fi
case $scrape in
query)
query)
get_search_query "$*"
search_results=$(search_anime "$query")
[ -z "$search_results" ] && die "No search results found"
anime_selection "$search_results"
[ $? -ne 0 ] && die "No anime selection found"
episode_selection
;;
history)
# search_results=$(sed -n -E 's/\t[0-9]*//p' "$logfile")
stmt="SELECT DISTINCT anime_name FROM watch_history ORDER BY watch_date DESC"
search_results=$(printf "%s\n" "$stmt" | sqlite3 -noheader "$HISTORY_DB")
[ -z "$search_results" ] && die "History is empty"
anime_selection "${search_results[@]}"
[ $? -ne 0 ] && die "No anime selection found"
stmt="SELECT episode_number FROM watch_history ORDER BY watch_date DESC LIMIT 1"
run_stmt "$stmt"
ep_choice_start=$?
echo "EPISODE: $ep_choice_start"
# ep_choice_start=$(sed -n -E "s/${selection_id}\t//p" "$logfile")
;;
playlist)
lines=$(cat "$playlist_file" | wc -l)
[ "$VERBOSE" -eq 1 ] && printf "%s%d\n" "Num lines in playlist: " "$lines"
if [[ "$lines" -eq 0 ]]; then
get_search_query "$*"
search_results=$(search_anime "$query")
[ -z "$search_results" ] && die "No search results found"
anime_selection "$search_results"
[ $? -ne 0 ] && die "No anime selection found"
episode_selection
else
line=($(sed '1q;d' "$playlist_file"))
if [[ "${#line[@]}" -ne 2 ]]; then
die "Something went wrong with the playlist file... exiting"
;;
history)
# search_results=$(sed -n -E 's/\t[0-9]*//p' "$logfile")
stmt="SELECT DISTINCT anime_name FROM watch_history ORDER BY watch_date DESC"
search_results=$(printf "%s\n" "$stmt" | sqlite3 -noheader "$HISTORY_DB")
[ -z "$search_results" ] && die "History is empty"
anime_selection "${search_results[@]}"
[ $? -ne 0 ] && die "No anime selection found"
stmt="SELECT episode_number FROM watch_history ORDER BY watch_date DESC LIMIT 1"
run_stmt "$stmt"
ep_choice_start=$?
echo "EPISODE: $ep_choice_start"
# ep_choice_start=$(sed -n -E "s/${selection_id}\t//p" "$logfile")
;;
playlist)
lines=$(cat "$playlist_file" | wc -l)
[ "$VERBOSE" -eq 1 ] && printf "%s%d\n" "Num lines in playlist: " "$lines"
if [[ "$lines" -eq 0 ]]; then
get_search_query "$*"
search_results=$(search_anime "$query")
[ -z "$search_results" ] && die "No search results found"
anime_selection "$search_results"
[ $? -ne 0 ] && die "No anime selection found"
episode_selection
else
line=($(sed '1q;d' "$playlist_file"))
if [[ "${#line[@]}" -ne 2 ]]; then
die "Something went wrong with the playlist file... exiting"
fi
selection_id="${line[0]}"
episodes=($selection_id)
ep_choice_start="${line[1]}"
ep_choice_end=""
read last_ep_number <<-EOF
$(search_eps "$selection_id")
EOF
[ "$VERBOSE" -eq 1 ] && printf "Anime: %s Episode: %d\n" "$episodes" "$ep_choice_start"
[ "$VERBOSE" -eq 1 ] && printf "Episodes: %s\n" "${episodes[@]}"
fi
selection_id="${line[0]}"
episodes=($selection_id)
ep_choice_start="${line[1]}"
ep_choice_end=""
read last_ep_number <<-EOF
$(search_eps "$selection_id")
EOF
[ "$VERBOSE" -eq 1 ] && printf "Anime: %s Episode: %d\n" "$episodes" "$ep_choice_start"
[ "$VERBOSE" -eq 1 ] && printf "Episodes: %s\n" "${episodes[@]}"
fi
;;
add)
get_search_query "$*"
search_results=$(search_anime "$query")
[ -z "$search_results" ] && die "No search results found"
anime_selection "$search_results"
[ $? -ne 0 ] && die "No anime selection found"
episode_selection
;;
delete) ;;
;;
add)
get_search_query "$*"
search_results=$(search_anime "$query")
[ -z "$search_results" ] && die "No search results found"
anime_selection "$search_results"
[ $? -ne 0 ] && die "No anime selection found"
episode_selection
;;
delete) ;;
esac
@ -622,29 +704,29 @@ while :; do
printf "$c_reset"
case $choice in
n)
episode=$((episode + 1))
;;
p)
episode=$((episode - 1))
;;
n)
episode=$((episode + 1))
;;
p)
episode=$((episode - 1))
;;
s)
printf "${c_blue}Choose episode $c_cyan[1-%d]$c_reset:$c_green " $last_ep_number
read episode
printf "$c_reset"
[ "$episode" -eq "$episode" ] 2>/dev/null || die "Invalid number entered"
;;
s)
printf "${c_blue}Choose episode $c_cyan[1-%d]$c_reset:$c_green " $last_ep_number
read episode
printf "$c_reset"
[ "$episode" -eq "$episode" ] 2>/dev/null || die "Invalid number entered"
;;
r) ;;
r) ;;
q)
break
;;
q)
break
;;
*)
die "invalid choice"
;;
*)
die "invalid choice"
;;
esac
open_episode "$selection_id" "$episode" "$download_dir"
done

View File

@ -9,11 +9,28 @@ CFG_DIR="$XDG_CONFIG_HOME/aniwrapper"
CFG_FILE="meh.rasi"
VERBOSE=0
# printf "%s\n" "CONFIG DIR: $CFG_DIR"
while getopts 'vh' OPT; do
case "$OPT" in
h)
help_text
;;
v)
VERBOSE=1
;;
*)
log "Invalid option"
exit 1
;;
esac
done
options="1. Stream|2. Download|3. Continue|4. Playlist|5. Quit"
quit="6. Quit"
options="1. Stream|2. Download|3. Continue|4. Playlist|5. Sync History|$quit"
choice=$(echo "${options[@]}" | rofi -dmenu -sep '|' -config "$CFG_DIR/$CFG_FILE" -l 5 -i -p "Aniwrapper")
[ "$VERBOSE" -eq 1 ] && printf "%s\n" "CONFIG DIR: $CFG_DIR"
choice=$(echo "${options[@]}" | rofi -dmenu -sep '|' \
-config "$CFG_DIR/$CFG_FILE" -l 6 -i -p "Aniwrapper")
seppuku() {
printf "%s\n" "$*"
@ -35,90 +52,135 @@ log() {
fi
}
[ "$choice" == "5. Quit" ] && quit
[ "$choice" == "$quit" ] && quit
selection=$(printf "%s\n" "$choice" | awk '{ print $1 }')
if [[ "$selection" == "1." ]]; then
# ---------------------------------------------------------------------------
# streaming
# ---------------------------------------------------------------------------
log "Streaming mode"
run
elif [[ "$selection" == "2." ]]; then
# ---------------------------------------------------------------------------
# download
# ---------------------------------------------------------------------------
log "Download anime"
dl_dir=$(rofi -dmenu -config "$CFG_DIR/$CFG_FILE" \
-l 1 -p "Enter download dir:")
# if dl_dir is none set to current directory
[ "$dl_dir" == "" ] && dl_dir="$DEFAULT_DOWNLOAD"
run -d "$dl_dir"
elif [[ "$selection" == "3." ]]; then
# ---------------------------------------------------------------------------
# continue
# ---------------------------------------------------------------------------
log "Continue watching"
run -H
elif [[ "$selection" == "4." ]]; then
# ---------------------------------------------------------------------------
# playlist mode
# ---------------------------------------------------------------------------
log "Playlist mode"
options="1. Play playlist|2. Add to playlist|3. Delete from playlist|4. Quit"
choice=$(printf "%s\n" "${options[@]}" |
rofi -dmenu -sep '|' \
-config "$CFG_DIR/$CFG_FILE" -l 4 -i -p "Enter choice:")
[ -z "$choice" ] && seppuku "No choice selected"
[ "$choice" == "5. Quit" ] && quit
selection=$(printf "%s\n" "$choice" | awk '{ print $1 }')
if [[ "$selection" == "1." ]]; then
# -----------------------------------------------------------------------
# watch playlist
# -----------------------------------------------------------------------
case "$selection" in
1.)
# ---------------------------------------------------------------------------
# streaming
# ---------------------------------------------------------------------------
log "Streaming mode"
run
;;
2.)
# ---------------------------------------------------------------------------
# download
# ---------------------------------------------------------------------------
log "Download anime"
dl_dir=$(rofi -dmenu -config "$CFG_DIR/$CFG_FILE" \
-l 1 -p "Enter download dir:")
# if dl_dir is none set to current directory
[ "$dl_dir" == "" ] && dl_dir="$DEFAULT_DOWNLOAD"
run -d "$dl_dir"
;;
3.)
# ---------------------------------------------------------------------------
# continue
# ---------------------------------------------------------------------------
log "Continue watching"
run -H
;;
4.)
# ---------------------------------------------------------------------------
# playlist mode
# ---------------------------------------------------------------------------
log "Playlist mode"
options="1. From file|2. Streaming|3. Quit"
options="1. Play playlist|2. Add to playlist|3. Delete from playlist|4. Quit"
choice=$(printf "%s\n" "${options[@]}" |
rofi -dmenu -sep '|' \
-config "$CFG_DIR/$CFG_FILE" -l 4 -i -p "Enter choice:")
[ -z "$choice" ] && seppuku "No choice selected"
[ "$choice" == "5. Quit" ] && quit
log "Selection: $choice"
[ "$choice" == "$quit" ] && quit
selection=$(printf "%s\n" "$choice" | awk '{ print $1 }')
if [[ "$selection" == "1." ]]; then
# -------------------------------------------------------------------
# watch playlist from file (downloaded videos)
# -------------------------------------------------------------------
# TODO: Change directory to variable set at install
log "Watching playlist from file"
PLAYLIST_DIR="$HOME/Videos/sauce"
log "Default playlist directory: $PLAYLIST_DIR"
choice=$(cd "$PLAYLIST_DIR" && find . -mindepth 1 -type d |
cut -c 3- |
rofi -dmenu \
-config "$CFG_DIR/$CFG_FILE" -l 5 -i -p "Choose playlist:")
# -----------------------------------------------------------------------
# watch playlist
# -----------------------------------------------------------------------
log "Playlist mode"
options="1. From file|2. Streaming|3. Quit"
choice=$(printf "%s\n" "${options[@]}" |
rofi -dmenu -sep '|' \
-config "$CFG_DIR/$CFG_FILE" -l 4 -i -p "Enter choice:")
[ -z "$choice" ] && seppuku "No choice selected"
log "Choice" "$choice"
run -P "$PLAYLIST_DIR/$choice"
[ "$choice" == "$quit" ] && quit
log "Selection: $choice"
selection=$(printf "%s\n" "$choice" | awk '{ print $1 }')
if [[ "$selection" == "1." ]]; then
# -------------------------------------------------------------------
# watch playlist from file (downloaded videos)
# -------------------------------------------------------------------
log "Watching playlist from file"
PLAYLIST_DIR="$HOME/Videos/sauce"
log "Default playlist directory: $PLAYLIST_DIR"
choice=$(cd "$PLAYLIST_DIR" && find . -mindepth 1 -type d |
cut -c 3- |
rofi -dmenu \
-config "$CFG_DIR/$CFG_FILE" -l 5 -i -p "Choose playlist:")
[ -z "$choice" ] && seppuku "No choice selected"
log "Choice" "$choice"
run -P "$PLAYLIST_DIR/$choice"
elif [[ "$selection" == "2." ]]; then
# -------------------------------------------------------------------
# watch playlist of 'queued' videos to stream
# -------------------------------------------------------------------
log "Watching from 'queue'"
run -p
fi
elif [[ "$selection" == "2." ]]; then
# -------------------------------------------------------------------
# watch playlist of 'queued' videos to stream
# -------------------------------------------------------------------
log "Watching from 'queue'"
run -p
# -----------------------------------------------------------------------
# add to playlist
# -----------------------------------------------------------------------
log "Add to playlist"
run -a
elif [[ "$selection" == "3." ]]; then
# -----------------------------------------------------------------------
# delete from playlist
# -----------------------------------------------------------------------
log "Not implemented yet"
run -r
fi
elif [[ "$selection" == "2." ]]; then
# -----------------------------------------------------------------------
# add to playlist
# -----------------------------------------------------------------------
log "Add to playlist"
run -a
elif [[ "$selection" == "3." ]]; then
# -----------------------------------------------------------------------
# delete from playlist
# -----------------------------------------------------------------------
log "Not implemented yet"
run -r
fi
fi
;;
5.)
log "Sync history database"
username=$(rofi -dmenu -config "$CFG_DIR/$CFG_FILE" \
-l 1 -p "Enter the username of the remote user:")
if [[ -z "$username" ]] || [[ "$username" == "" ]]; then
log "No username provided... exiting"
exit 1
fi
host=$(rofi -dmenu -config "$CFG_DIR/$CFG_FILE" \
-l 1 -p "Enter the host for the remote machine (eg 192.168.1.99):")
if [[ -z "$host" ]] || [[ "$host" == "" ]]; then
log "No host provided... exiting"
exit 1
fi
port=$(rofi -dmenu -config "$CFG_DIR/$CFG_FILE" \
-l 1 -p "Enter in the ssh port for remote machine or leave blank for default [22]:")
if [[ -z "$port" ]] || [[ "$port" == "" ]]; then
port=22
fi
printf "%s\n%s\n%d\n" "$username" "$host" "$port" | ani-cli -s
if [[ "$?" -ne 0 ]]; then
log "Aniwrapper was unable to sync the databases..."
exit 1
else
log "Databases synced successfully"
exit 0
fi
;;
6.)
# ---------------------------------------------------------------------------
# get out
# ---------------------------------------------------------------------------
printf "%s\n" "Quitting..."
exit 0
;;
*)
log "Invalid choice..."
exit 1
;;
esac

64
db.sh
View File

@ -9,7 +9,46 @@ log() {
printf "%s\n" "$1"
}
while getopts 'cdrqC' OPT; do
sync_search_history() {
cnt=0
temp_db="/tmp/aniwrapper_tmp_history.sqlite3"
while read -r line; do
anime_name=$(awk -F '|' '{print $2}' <<<"$line")
res=$(sqlite3 -noheader "$DIR/$DB" <<<"SELECT anime_name FROM search_history WHERE anime_name = '$anime_name'")
if [[ "${res/ //}" == "" ]]; then
log "Adding $line to search history..."
search_date=$(awk -F '|' '{print $3}' <<<"$line")
sqlite3 "$DIR/$DB" <<<"INSERT INTO search_history(anime_name, search_date) VALUES('$anime_name', '$search_date')"
if [[ "$?" -ne 0 ]]; then
log "Error inserting row $line"
fi
((++cnt))
fi
done <<<"$(sqlite3 -noheader "$temp_db" <<<"SELECT DISTINCT * FROM search_history")"
log "Inserted $cnt rows into search_history table"
}
sync_watch_history() {
cnt=0
temp_db="/tmp/aniwrapper_tmp_history.sqlite3"
while read -r line; do
anime_name=$(awk -F '|' '{print $2}' <<<"$line")
res=$(sqlite3 -noheader "$DIR/$DB" <<<"SELECT anime_name FROM watch_history WHERE anime_name = '$anime_name'")
if [[ "${res/ //}" == "" ]]; then
log "Adding $line to watch history..."
episode_num=$(awk -F '|' '{print $3}' <<<"$line")
watch_date=$(awk -F '|' '{print $NF}' <<<"$line")
sqlite3 "$DIR/$DB" <<<"INSERT INTO watch_history(anime_name, episode_number, watch_date) VALUES('$anime_name', '$episode_num', '$watch_date')"
if [[ "$?" -ne 0 ]]; then
log "Error inserting row $line"
fi
((++cnt))
fi
done <<<"$(sqlite3 -noheader "$temp_db" <<<"SELECT DISTINCT * FROM watch_history")"
log "Inserted $cnt rows into watch_history table"
}
while getopts 'cdrqCs' OPT; do
case "$OPT" in
c)
log "Creating database..."
@ -48,6 +87,29 @@ while getopts 'cdrqC' OPT; do
log "Cleaning up watch history..."
sqlite3 "$DIR/$DB" <<<"$stmt"
;;
s)
printf "%s" "Enter connection string for remote user in the form user@host: "
read -r connection_str
printf "%s" "Enter port to connect to remote host with or leave blank for default (22): "
read -r port
if [[ ! "${port/ //}" == "" ]]; then
PORT="$port"
fi
if [[ ! "@" != *"$connection_str" ]]; then
log "Enter in full connection string to remote user in the form: user@host"
exit 1
fi
log "Syncing database with: $connection_str on port $PORT"
scp -P "$PORT" "$connection_str:$DIR/$DB" "$temp_db"
if [[ "$?" -ne 0 ]]; then
printf "%s\n" "Error getting database file from remote host"
exit 1
fi
sync_search_history && sync_watch_history
;;
*)
log "Does not exist or not implemented yet..."
exit 1