#!/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 INTERACTIVE="on" menu="fuzzel -d -p " #menu="fzf -i --prompt=" apiurl="https://coverapi.store" player="mpv" 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 getFzfForTermux { if command -v fzf >/dev/null 2>&1; then echo -e "\n" else apt install -y fzf 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 getMovieStreamUrl() { PHPSESSID="$(grep 'PHPSESSID' "$GRPOPPRO_COOKIE_FILE" | awk '{print $NF}')" streamurl="$(curl -s -L -c "$GRPOPPRO_COOKIE_FILE" -b "$GRPOPPRO_COOKIE_FILE" "$apiurl/engine/ajax/controller.php" --compressed -X POST \ -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0' \ -H 'Accept: application/json, text/javascript, */*; q=0.01' \ -H 'Accept-Language: en-US,en;q=0.5' \ -H 'Accept-Encoding: gzip, deflate, br, zstd' \ -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \ -H 'X-Requested-With: XMLHttpRequest' \ -H "Origin: $apiurl" \ -H 'DNT: 1' \ -H 'Sec-GPC: 1' \ -H 'Connection: keep-alive' \ -H "Referer: $simpleurl" \ -H "Cookie: PHPSESSID=$PHPSESSID" \ -H 'Sec-Fetch-Dest: empty' \ -H 'Sec-Fetch-Mode: cors' \ -H 'Sec-Fetch-Site: same-origin' \ -H 'TE: trailers' \ --data-raw "mod=players&news_id=$internalid" \ | sed 's/\\//g' | grep -oP 'file:"\K[^"]+' )" } 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 [[ "$INTERACTIVE" == "on" ]] && notify-send -t 2000 "No file found" || echo -e "\n\tNo file found" && exit 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 [[ "$INTERACTIVE" == "on" ]] && notify-send -t 2000 "Film or show not found in imdb" || echo -e "\n\tFilm or show not found in imdb" exit fi } function usage { echo -e "\n\tUsage: $(basename "$0") \"name of film or show\" [season] [episode(ex 01 02 .. 10 11)]\n\tOr $(basename "$0") [--menu|--resume|--finish]" exit } function play { [[ "$player" == "mpv" ]] && player="mpv --save-position-on-quit --fs" [[ "$OSTYPE" != "linux-gnu" ]] && INTERACTIVE="off" && streamurl="${streamurl//https/http}" eval "$player" "$streamurl" } function dumpData() { echo "$title" > "$GRPOPPRO_DATA_FILE" echo "$seasonEpisode" >> "$GRPOPPRO_DATA_FILE" echo "$streamurl" >> "$GRPOPPRO_DATA_FILE" [[ "$INTERACTIVE" == "on" ]] && notify-send -t 2000 "Last Played -> $seasonEpisode" || echo "Last Played -> $seasonEpisode" } function sourceData { [ -f "$GRPOPPRO_DATA_FILE" ] && lastSeasonEpisodePlayed="$(sed -n 2p "$GRPOPPRO_DATA_FILE")" && lastSeriesPlayed="$(sed -n 1p "$GRPOPPRO_DATA_FILE")" && lastEpisodePlayedURL="$(sed -n 3p "$GRPOPPRO_DATA_FILE")" } [[ "$#" -lt 1 ]] && usage [[ "$#" -gt 3 ]] && usage [[ "$#" -eq 2 ]] && 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) [[ "$INTERACTIVE" == "off" ]] && [[ -z "$title" ]] && read -r -p "Search Series: " title [[ -z "$title" ]] && exit 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="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | awk -F\" '{print $8}' | awk -F/ '{print $NF}' | awk -F. '{print $1}' | eval "$menu"\""$title"\")" if [[ -z "$seasonEpisode" ]]; then [[ "$INTERACTIVE" == "on" ]] && notify-send -t 2000 "Nothing Selected" || echo "Nothing Selected" exit fi streamurl="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | grep "${seasonEpisode}" | head -n1 | awk -F\" '{print $8}')" dumpData "$title" "$seasonEpisode" play resume } function resume { # Zero requests to the api [ ! -f "$GRPOPPRO_DATA_FILE" ] && echo "Nothing to resume" && exit sourceData title=$lastSeriesPlayed 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"\")" if [[ -z "$seasonEpisode" ]]; then [[ "$INTERACTIVE" == "on" ]] && notify-send -t 2000 "Nothing Selected" || echo "Nothing Selected" exit fi streamurl="$(grep "mp4" "$GRPOPPRO_PLAYLIST_FILE" | grep "${seasonEpisode}" | head -n1 | awk -F\" '{print $8}')" dumpData "$title" "$seasonEpisode" play done } function resumeUnfinishedEpisode { # Zero requests to the api [ ! -f "$GRPOPPRO_DATA_FILE" ] && echo "Nothing to resume" && exit sourceData streamurl="$lastEpisodePlayedURL" [[ "$OSTYPE" != "linux-gnu" ]] && INTERACTIVE="off" && streamurl="${streamurl//https/http}" [[ "$player" == "mpv" ]] && player="mpv --resume-playback --fs" eval "$player" "$streamurl" resume } [[ "$1" == "--menu" ]] && menuSearch [[ "$1" == "--resume" ]] && resume [[ "$1" == "--finish" ]] && resumeUnfinishedEpisode # One arguement and it contains the imdb id if [[ "$1" == *"tt"* ]] && [[ "$#" -eq 1 ]] && [[ "$1" != "--menu" ]] && [[ "$1" != "--resume" ]]; then simpleurl="$1" getInternalID "$simpleurl" getMovieStreamUrl "$internalid" play exit fi # Series URL if [[ "$#" -eq 3 ]]; then # Two requests to the api basics "$1" getInternalID "$simpleurl" season="$2" episode="$3" streamurl="$(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" | grep "mp4" | grep "${season}x${episode}" | head -n1 | awk -F\" '{print $8}')" play exit fi # Movies URL if [[ "$#" -eq 1 ]] && [[ "$1" != "--menu" ]] && [[ "$1" != "--resume" ]]; 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 getMovieStreamUrl "$internalid" # Gets the internal id and performs one request to get the stream url play # It uses mpv to stream the file exit fi