diff --git a/grpoppro b/grpoppro index a816924..8684928 100755 --- a/grpoppro +++ b/grpoppro @@ -1,23 +1,22 @@ #!/usr/bin/env bash -GRPOPPRO_DATA_DIR=${XDG_DATA_HOME:-$HOME/.local/share}/grpoppro -GRPOPPRO_DATA_FILE=$GRPOPPRO_DATA_DIR/lastPlayedSeries -GRPOPPRO_PLAYLIST_FILE=$GRPOPPRO_DATA_DIR/lastPlaylistPlayed -GRPOPPRO_COOKIE_FILE=$GRPOPPRO_DATA_DIR/cookies.txt +## Definitions +GRPOPPRO_DATA_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/grpoppro" +GRPOPPRO_DATA_FILE="$GRPOPPRO_DATA_DIR/lastPlayedSeries" +GRPOPPRO_PLAYLIST_FILE="$GRPOPPRO_DATA_DIR/lastPlaylistPlayed" +GRPOPPRO_COOKIE_FILE="$GRPOPPRO_DATA_DIR/cookies.txt" +GRPOPPRO_HISTORY_FILE="$GRPOPPRO_DATA_DIR/history" INTERACTIVE="on" menu="fuzzel -d -p " #menu="fzf -i --prompt=" apiurl="https://coverapi.store" player="mpv" +## End of definitions -mkdir -p "$GRPOPPRO_DATA_DIR" - -if [[ "$OSTYPE" == "linux-gnu" ]]; then - if nmcli connection show --active | grep -i -q wireguard; then - echo "Exiting because a vpn connection is active" - exit 0 - fi -fi +function usage { + echo -e "\n\tUsage:\n\n\t$(basename "$0") \"name of film or show\" [season] [episode(ex 01 02 .. 10 11)]\n\tOr $(basename "$0") [--menu|--resume|--select|--finish]\n\tOr $(basename "$0") --open \"name of film or show\"" + exit 0 +} function getFzfForTermux { if command -v fzf >/dev/null 2>&1; then @@ -35,7 +34,41 @@ function message { fi } -[[ "$OSTYPE" != "linux-gnu" ]] && INTERACTIVE="off" && menu="fzf -i --prompt=seasonXepisode" && player="am start -n is.xyz.mpv/.MPVActivity -a android.intent.action.VIEW -d" && getFzfForTermux +function getIMDBID { + imdbid="$(curl -s -L -c "$GRPOPPRO_COOKIE_FILE" -b "$GRPOPPRO_COOKIE_FILE" \ + -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0" \ + -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" \ + "https://www.imdb.com/find/?q=$title" | grep -io ' href=['"'"'"][^"'"'"']*['"'"'"]' | grep 'href="/title/'| head -n1 | sed -e 's/href="\/title\///' -e 's/\/?.*//' -e 's/^ //' + )" + # imdbid="$(curl -s "http://imdb.konsthol.eu/find?q=$title" | grep -io ' href=['"'"'"][^"'"'"']*['"'"'"]' | grep title | head -n1 | sed -e 's/^ //' -e 's/href="\/title\///' -e 's/"//')" + if ! [[ "$imdbid" == *"tt"* ]]; then + message "Film or show not found in imdb" + exit 0 + fi +} + +function basics() { + title="$1" + title="${title// /%20}" + getIMDBID "$title" + simpleurl="$apiurl/embed/$imdbid/" +} + +function getInternalID { + response="$(curl -s -L -c "$GRPOPPRO_COOKIE_FILE" -b "$GRPOPPRO_COOKIE_FILE" \ + -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0" \ + -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" \ + -H "Accept-Language: en-US,en;q=0.5" \ + -H "Connection: keep-alive" \ + -H "Upgrade-Insecure-Requests: 1" \ + "$simpleurl" + )" + if echo "$response" | grep -q "id='el-content'>"; then + message "No file found" + exit 0 + fi + internalid="$(echo "$response" | grep news_id | awk '{print $5}' | awk -F\' '{print $2}')" +} function getMovieStreamUrl { PHPSESSID="$(grep 'PHPSESSID' "$GRPOPPRO_COOKIE_FILE" | awk '{print $NF}')" @@ -61,43 +94,22 @@ function getMovieStreamUrl { )" } -function getInternalID { - response="$(curl -s -L -c "$GRPOPPRO_COOKIE_FILE" -b "$GRPOPPRO_COOKIE_FILE" \ - -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0" \ - -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" \ - -H "Accept-Language: en-US,en;q=0.5" \ - -H "Connection: keep-alive" \ - -H "Upgrade-Insecure-Requests: 1" \ - "$simpleurl" - )" - if echo "$response" | grep -q "id='el-content'>"; then - message "No file found" - exit 0 - fi - internalid="$(echo "$response" | grep news_id | awk '{print $5}' | awk -F\' '{print $2}')" -} - -function getIMDBID { - imdbid="$(curl -s -L -c "$GRPOPPRO_COOKIE_FILE" -b "$GRPOPPRO_COOKIE_FILE" \ - -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0" \ - -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" \ - "https://www.imdb.com/find/?q=$title" | grep -io ' href=['"'"'"][^"'"'"']*['"'"'"]' | grep 'href="/title/'| head -n1 | sed -e 's/href="\/title\///' -e 's/\/?.*//' -e 's/^ //' - )" - # imdbid="$(curl -s "http://imdb.konsthol.eu/find?q=$title" | grep -io ' href=['"'"'"][^"'"'"']*['"'"'"]' | grep title | head -n1 | sed -e 's/^ //' -e 's/href="\/title\///' -e 's/"//')" - if ! [[ "$imdbid" == *"tt"* ]]; then - message "Film or show not found in imdb" - exit 0 - fi -} - -function usage { - echo -e "\n\tUsage:\n\n\t$(basename "$0") \"name of film or show\" [season] [episode(ex 01 02 .. 10 11)]\n\tOr $(basename "$0") [--menu|--resume|--finish]\n\tOr $(basename "$0") --open \"name of film or show\"" - exit 0 -} - function play { - [[ "$player" == "mpv" ]] && player="mpv --save-position-on-quit --fs" + if [[ "$player" == "mpv" ]]; then + MPV_OPTS="--vo=gpu \ + --gpu-api=opengl \ + --opengl-es=yes \ + --really-quiet \ + --msg-level=all=no \ + --no-load-scripts \ + --profile=sw-fast \ + --no-ytdl" + MPVPID="$(pidof mpv | cut -d' ' -f1)" + [[ -n "$MPVPID" ]] && kill -s SIGTERM "$MPVPID" + player="mpv --save-position-on-quit --fs ${MPV_OPTS}" + fi [[ "$OSTYPE" != "linux-gnu" ]] && INTERACTIVE="off" && streamurl="${streamurl//https/http}" + # No setsid -f here because menu function goes from play to resume eval "$player" "$streamurl" } @@ -106,6 +118,8 @@ function dumpData { echo "$seasonEpisode" >> "$GRPOPPRO_DATA_FILE" echo "$streamurl" >> "$GRPOPPRO_DATA_FILE" message "Last Played -> $seasonEpisode" + echo "$title|$seasonEpisode|$streamurl" >> "$GRPOPPRO_HISTORY_FILE" + tac "$GRPOPPRO_HISTORY_FILE" | awk -F'|' '!seen[$1]++' | tac > "${GRPOPPRO_DATA_DIR}/temp.txt" && mv "${GRPOPPRO_DATA_DIR}/temp.txt" "$GRPOPPRO_HISTORY_FILE" } function sourceData { @@ -116,18 +130,6 @@ function sourceData { fi } -[[ "$#" -lt 1 ]] && usage -[[ "$#" -gt 3 ]] && usage - -#Standard Stuff - -function basics() { - title="$1" - title="${title// /%20}" - getIMDBID "$title" - simpleurl="$apiurl/embed/$imdbid/" -} - function menuSearch { # Two requests to the api [[ "$INTERACTIVE" == "on" ]] && title=$(echo "" | wofi --dmenu --insensitive --prompt="Search Series" --width=300 --height=50) @@ -151,7 +153,7 @@ function menuSearch { echo "$response" > "$GRPOPPRO_PLAYLIST_FILE" title="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | head -n1 | awk -F/ '{print $(NF-1)}')" title="${title//_/ }" - seasonEpisode="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | awk -F\" '{print $8}' | awk -F/ '{print $NF}' | awk -F. '{print $1}' | eval "$menu"\""$title"\")" + seasonEpisode="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | awk -F\" '{print $8}' | awk -F/ '{print $NF}' | awk -F. '{print $1}' | eval "$menu"\""$title" \")" if [[ -z "$seasonEpisode" ]]; then message "Nothing Selected" exit 0 @@ -173,7 +175,7 @@ function resume { while true do sourceData - seasonEpisode="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | awk -F\" '{print $8}' | awk -F/ '{print $NF}' | awk -F. '{print $1}' | sed -n -e "0,/$lastSeasonEpisodePlayed/!p" | eval "$menu"\""$title"\")" + seasonEpisode="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | awk -F\" '{print $8}' | awk -F/ '{print $NF}' | awk -F. '{print $1}' | sed -n -e "0,/$lastSeasonEpisodePlayed/!p" | eval "$menu"\""$title" \")" if [[ -z "$seasonEpisode" ]]; then message "Nothing Selected" exit 0 @@ -184,6 +186,48 @@ function resume { done } +function resumeSeries { + if [[ ! -f "$GRPOPPRO_HISTORY_FILE" ]]; then + message "No history found" + exit 0 + fi + + resume_series=$(awk -F'|' '{print $1}' "$GRPOPPRO_HISTORY_FILE" | sort | uniq | eval "$menu"\"Select Series \") + if [[ -z "$resume_series" ]]; then + message "No series selected" + exit 0 + fi + + # resume_episode=$(grep "^$resume_series|" "$GRPOPPRO_HISTORY_FILE" | awk -F'|' '{print $2}' | eval "$menu"\"Select Episode \") + resume_episode="$(grep "^$resume_series|" "$GRPOPPRO_HISTORY_FILE" | awk -F'|' '{print $2}')" + if [[ -n "$resume_episode" ]]; then + message "Continuing $resume_series from $resume_episode" + fi + + resume_streamurl=$(grep "^$resume_series|$resume_episode|" "$GRPOPPRO_HISTORY_FILE" | awk -F'|' '{print $3}') + title="$resume_series" + title="${title// /%20}" + getIMDBID "$title" + simpleurl="$apiurl/embed/$imdbid/" + getInternalID "$simpleurl" + response="$(curl -s -L -c "$GRPOPPRO_COOKIE_FILE" -b "$GRPOPPRO_COOKIE_FILE" \ + -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0" \ + -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" \ + -H "Accept-Language: en-US,en;q=0.5" \ + -H "Connection: keep-alive" \ + -H "Upgrade-Insecure-Requests: 1" \ + "$apiurl/uploads/playlists/$internalid.txt" + )" + echo "$response" > "$GRPOPPRO_PLAYLIST_FILE" + title="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | head -n1 | awk -F/ '{print $(NF-1)}')" + title="${title//_/ }" + seasonEpisode="$resume_episode" + streamurl="$resume_streamurl" + dumpData "$title" "$seasonEpisode" + play + resume +} + function resumeUnfinishedEpisode { # Zero requests to the api if [[ ! -f "$GRPOPPRO_DATA_FILE" ]]; then @@ -192,8 +236,21 @@ function resumeUnfinishedEpisode { fi sourceData streamurl="$lastEpisodePlayedURL" + if [[ "$player" == "mpv" ]]; then + MPV_OPTS="--vo=gpu \ + --gpu-api=opengl \ + --opengl-es=yes \ + --really-quiet \ + --msg-level=all=no \ + --no-load-scripts \ + --profile=sw-fast \ + --no-ytdl" + MPVPID="$(pidof mpv | cut -d' ' -f1)" + [[ -n "$MPVPID" ]] && kill -s SIGTERM "$MPVPID" + player="mpv --resume-playback --fs ${MPV_OPTS}" + fi [[ "$OSTYPE" != "linux-gnu" ]] && INTERACTIVE="off" && streamurl="${streamurl//https/http}" - [[ "$player" == "mpv" ]] && player="mpv --resume-playback --fs" + # No setsid -f here because menu function goes from play to resume eval "$player" "$streamurl" resume } @@ -206,14 +263,31 @@ function openInBrowser { exit 0 } +### Program starts here ### + +mkdir -p "$GRPOPPRO_DATA_DIR" + +if [[ "$OSTYPE" == "linux-gnu" ]]; then + if nmcli connection show --active | grep -i -q wireguard; then + echo "Exiting because a vpn connection is active" + exit 0 + fi +fi + +[[ "$OSTYPE" != "linux-gnu" ]] && INTERACTIVE="off" && menu="fzf -i --prompt=seasonXepisode" && player="am start -n is.xyz.mpv/.MPVActivity -a android.intent.action.VIEW -d" && getFzfForTermux + +[[ "$#" -lt 1 ]] && usage +[[ "$#" -gt 3 ]] && usage + [[ "$1" == "--open" ]] && openInBrowser "$@" [[ "$1" == "--menu" ]] && menuSearch [[ "$1" == "--resume" ]] && resume [[ "$1" == "--finish" ]] && resumeUnfinishedEpisode +[[ "$1" == "--select" ]] && resumeSeries # One arguement and it contains the imdb id # Two requests to the api -if [[ "$1" == *"tt"* ]] && [[ "$#" -eq 1 ]] && [[ "$1" != "--menu" ]] && [[ "$1" != "--resume" ]]; then +if [[ "$1" == *"tt"* ]] && [[ "$#" -eq 1 ]] && [[ "$1" != "--menu" ]] && [[ "$1" != "--resume" ]] && [[ "$1" != "--select" ]]; then simpleurl="$1" getInternalID "$simpleurl" getMovieStreamUrl "$internalid" @@ -240,7 +314,7 @@ if [[ "$#" -eq 3 ]]; then fi # Movies URL -if [[ "$#" -eq 1 ]] && [[ "$1" != "--menu" ]] && [[ "$1" != "--resume" ]]; then +if [[ "$#" -eq 1 ]] && [[ "$1" != "--menu" ]] && [[ "$1" != "--resume" ]] && [[ "$1" != "--select" ]]; then # Two requests to the api basics "$1" # Gets the title, performs one request to imdb and gets the complete url getInternalID "$simpleurl" # Gets the complete url and performs one request to get the internal id or inform us it does not exist