From 37e29989fe674e26f13a44b76a8a87fba7f14435 Mon Sep 17 00:00:00 2001 From: Bogomil Vasilev Date: Fri, 11 Feb 2022 14:36:10 +0200 Subject: [PATCH] add some more scripts Signed-off-by: Bogomil Vasilev --- archy-usb-ctl.sh | 111 ++++++++++++++++++++++++++++++++++++++++++ btfs.sh | 45 +++++++++++++++++ check-ip-seeds.py | 82 +++++++++++++++++++++++++++++++ clean_chroot_build.sh | 13 +++++ find_adb_device.py | 65 +++++++++++++++++++++++++ movie_list/index.py | 47 ++++++++++++------ movie_list/movie_list | 78 +++++++++++++++++++++++++++-- proton.sh | 35 +++++++++++++ 8 files changed, 455 insertions(+), 21 deletions(-) create mode 100755 archy-usb-ctl.sh create mode 100755 btfs.sh create mode 100755 check-ip-seeds.py create mode 100755 clean_chroot_build.sh create mode 100755 find_adb_device.py create mode 100755 proton.sh diff --git a/archy-usb-ctl.sh b/archy-usb-ctl.sh new file mode 100755 index 0000000..1ed9c92 --- /dev/null +++ b/archy-usb-ctl.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +if [[ $UID != 0 ]]; then + printf "You need root permissions to use this script!\n" + exit 1 +fi + +export LVM_SUPPRESS_FD_WARNINGS=true +ACTION=mount +RUN_CHROOT=true +USB_LUKS_PART= + +# Call getopt to validate the provided input. +options=$(getopt -o cmnu -l chroot,nochroot,mount,umount -- "$@") +eval set -- "$options" +while [ $# -gt 0 ]; do + case "$1" in + (-m|--mount) ACTION=mount ;; + (-u|--umount) ACTION=umount ;; + (-n|--nochroot) RUN_CHROOT=false ;; + (-c|--chroot) RUN_CHROOT=true ;; + (--) shift; break;; + (-*) echo "invalid option: $1" 1>&2; exit 1;; + (*) break;; + esac + shift +done +if [ "$#" -gt 1 ]; then + echo "Only 1 additional argument possible! Got $#: $*" + exit 1 +fi + +if [ "$1" ]; then + USB_LUKS_PART="$1" +fi + +get_archy_usb_dev_path() +{ + declare -A dev_map='([by-id]="usb-ADATA*part3" [by-uuid]="bbd2dd10-4209-4879-a1e2-5ee1eff8ff5c")' + for key in "${!dev_map[@]}"; do + dev_path=$(find -L "/dev/disk/${key}" -name "${dev_map[$key]}") + if [ -n "$dev_path" ]; then + echo "${dev_path}" + break + fi + done +} + +get_usb_efi_part() +{ + echo "/dev/$(lsblk -ndo pkname "$1")2" +} + +get_usb_root_part() +{ + lsblk -no path "$1" | grep root +} + +usb_mount() +{ + cryptsetup open "${USB_LUKS_PART}" adatausb || exit $? + vgchange -a y > /dev/null || exit $? + + usb_dev_root=$(get_usb_root_part "${USB_LUKS_PART}") + + echo -e "Mounting /\t${usb_dev_root}" + mount "${usb_dev_root}" /mnt/usb + exit_code=$? + if [ $exit_code -ne 0 ]; then + cryptsetup close "${USB_LUKS_PART}" + exit $exit_code + fi + + echo -e "Mounting /efi\t${USB_DEV_EFI}" + mount "${USB_DEV_EFI}" /mnt/usb/efi + exit_code=$? + if [ $exit_code -ne 0 ]; then + umount /mnt/usb + cryptsetup close "${USB_LUKS_PART}" + exit $exit_code + fi + if [ $RUN_CHROOT == true ]; then + arch-chroot /mnt/usb + fi +} + +usb_umount() +{ + usb_dev_root=$(get_usb_root_part "${USB_LUKS_PART}") + umount "${USB_DEV_EFI}" "${usb_dev_root}" # || exit $? + vgchange -a n --quiet adata > /dev/null # || exit $? + cryptsetup close adatausb +} + +# Auto-detect, in case we don't provide a device +if [ -z "${USB_LUKS_PART}" ]; then + USB_LUKS_PART=$(get_archy_usb_dev_path) + if [ -z "${USB_LUKS_PART}" ]; then + printf "Device not found!\nUse %s \n" "$0" + exit 1 + fi +fi + +USB_DEV_EFI=$(get_usb_efi_part "${USB_LUKS_PART}") +if [ -n "${usb_def_efi}" ]; then + echo "EFI device not found!" + exit 1 +fi + +usb_$ACTION + diff --git a/btfs.sh b/btfs.sh new file mode 100755 index 0000000..313e0ec --- /dev/null +++ b/btfs.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +function timestamp() { + date +"%Y%m%d%H%M%S" +} + +XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache} + +mountpoint="$XDG_CACHE_HOME/btfs-$(timestamp)" +[ ! -d "$mountpoint" ] && mkdir "$mountpoint" + +[ -z "$1" ] && printf "%s [magnet|*.torrent]\n" "$0" && exit 1 + +printf "Mounting %s to %s\n" "$1" "$mountpoint" +btfs "$1" "${mountpoint}" +btfs_status=$? +if [ $btfs_status != 0 ]; then + printf "Failed to mount torrent: %s\n" "$1" + exit $btfs_status +fi +while true; do + movie_dir_size=$(du -hs "$mountpoint"|awk '{print $1}') + printf "movie_dir_size: %s\n" "$movie_dir_size" + if [ "$movie_dir_size" != '4.0K' ] && [ "$movie_dir_size" != "0" ]; then + break; + else + sleep 5; + fi +done + +printf "Locating the largest file...\n" +movie="$(find "$mountpoint" -type f -exec du -hs '{}' +|sort -rh|grep -vi sample|head -n1| \ + awk '{$1=""; print $0}')" +movie=$(echo $movie|xargs) +[ -z "$movie" ] && printf "Could not locate the movie!\n" && exit 1 + +printf "Playing: %s\n" "$movie" +#smplayer -fullscreen "$movie" 1>/dev/null +#mpv --fs --volume=100 "$movie" # 1>/dev/null +vlc "$movie" 1>/dev/null +printf "Unmounting: %s\n" "$mountpoint" +fusermount -u "$mountpoint" +printf "Removing dir: %s\n" "$mountpoint" +rmdir "$mountpoint" + diff --git a/check-ip-seeds.py b/check-ip-seeds.py new file mode 100755 index 0000000..904cf4f --- /dev/null +++ b/check-ip-seeds.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +import sys +import json +import urllib +import urllib.request as urllib +from html.parser import HTMLParser +from termcolor import colored + +class MyHTMLParser(HTMLParser): + tbody = False + div = False + a_href = False + timestamp = False + timestamps = [] + category = False + category_value = None + + def handle_starttag(self, tag, attrs): + if tag == 'tbody': + self.tbody = True + elif tag == 'div' and self.tbody: + self.div = True + elif tag == 'a' and self.tbody and self.div: + self.a_href = True + if tag == 'td' and self.tbody: + for attr in attrs: + if len(attr) == 2 and attr[0] == 'class': + if attr[1] == 'date-column': + self.timestamp = True + elif attr[1] == 'category-column': + self.category = True + + def get_category(self): + colored_category = None + if self.category_value == 'Movies': + colored_category = colored(self.category_value, 'cyan', attrs=['bold']) + elif self.category_value == 'Books': + colored_category = colored(self.category_value, 'green', attrs=['bold']) + elif self.category_value == 'XXX': + colored_category = colored(self.category_value, 'magenta', attrs=['bold']) + else: + colored_category = self.category_value + return f'{colored_category}{(10-len(self.category_value)) * " "}' + + def store_category(self, data): + self.category_value = data.strip() + self.category = False + + def handle_endtag(self, tag): + if tag == 'tbody': + self.tbody = self.div = self.a_href = False + if tag == 'div': + self.div = self.a_href = False + if tag == 'a_href': + self.a_href = False + def handle_data(self, data): + if self.tbody and self.div and self.a_href: + print('\t| '.join(self.timestamps) + '\t| ' + self.get_category() + '| ' + data.strip()) + self.a_href = False + self.timestamps = [] + elif self.timestamp: + self.timestamps.append(data) + self.timestamp = False + elif self.category: + self.store_category(data) + +if len(sys.argv) != 2: + print(f'{sys.argv[0]} ') + sys.exit(1) +url = f'https://iknowwhatyoudownload.com/en/peer/?ip={sys.argv[1]}' +req = urllib.Request(url, headers={'User-Agent' : "Magic Browser"}) +fp = urllib.urlopen(req) +mybytes = fp.read() +mystr = mybytes.decode("utf8") +fp.close() + +ip = json.loads(urllib.urlopen(f'http://ipinfo.io/{sys.argv[1]}/json').read().decode('utf8')) +print(f'----- IP: {ip["ip"]} ----- Country: {ip["country"]} ----- City: {ip["city"]} -----') +# instantiate the parser and fed it some HTML +parser = MyHTMLParser() +parser.feed(mystr) diff --git a/clean_chroot_build.sh b/clean_chroot_build.sh new file mode 100755 index 0000000..309a7ee --- /dev/null +++ b/clean_chroot_build.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +CHROOT=$HOME/chroot +if [ ! -d "$CHROOT" ]; then + mkdir $CHROOT + mkarchroot $CHROOT/root base-devel + # mkarchroot $CHROOT/root base-devel zsh +else + arch-nspawn $CHROOT/root pacman -Syu + #arch-nspawn $CHROOT/root pacman -S --noconfirm +fi +makechrootpkg -c -r $CHROOT -- $@ + diff --git a/find_adb_device.py b/find_adb_device.py new file mode 100755 index 0000000..d5cf0f2 --- /dev/null +++ b/find_adb_device.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +from os import environ +import subprocess +import json +import sys +import re + +def main(): + adb_cmd = subprocess.Popen(['adb', 'devices', '-l'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE, universal_newlines=True) + adb_cmd.wait() + out, _ = adb_cmd.communicate() + for num, line in enumerate(out.strip().split('\n')): + if line == 'List of devices attached': + devices = out.strip().split('\n')[num+1:] + break + device = None + if len(sys.argv) == 1: + if len(devices) == 1: + device = devices[0].split()[0] + elif len(devices) > 1: + print(f'Please specify a device: {sys.argv[0]} ') + print('More than 1 device detected:') + print('\n'.join(devices)) + exit(1) + elif len(devices) == 0: + print('No devices available! Perhaps first try: adb connect ') + exit(1) + elif len(sys.argv) == 2: + device = sys.argv[1] + if device not in devices: + print(f'Device not in list, connecting to: {device}') + adb_cmd = subprocess.run(['adb', 'connect', device]) + else: + print('Unexpected argument count!') + exit(1) + + adb_cmd_string = ['adb', '-s', device, 'shell', 'dumpsys', 'location'] + print(f'Running: {adb_cmd_string}') + adb_cmd = subprocess.Popen( + adb_cmd_string, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True) + adb_cmd.wait() + out, err = adb_cmd.communicate() + if adb_cmd.returncode != 0: + print("adb failed:\n{err}") + exit(1) + gps = {} + for line in out.split('\n'): + if 'Gnss Location Data' in line: + gps_data = re.sub('.*Gnss Location Data:: ', '', line) + for attr in gps_data.split(','): + gps[attr.split()[0].replace(':', '')] = attr.split()[1] + + # url = f'https://www.google.com/maps/place/{gps["LatitudeDegrees"]},{gps["LongitudeDegrees"]}' + url = f'http://www.openstreetmap.org/?mlat={gps["LatitudeDegrees"]}&mlon={gps["LongitudeDegrees"]}&zoom=17' + if environ.get('DISPLAY'): + subprocess.run(['xdg-open', url]) + else: + print(url) + +main() + diff --git a/movie_list/index.py b/movie_list/index.py index aa5bd0a..c3d14f1 100755 --- a/movie_list/index.py +++ b/movie_list/index.py @@ -20,7 +20,8 @@ from imdb import IMDb class MovieList: """ Class to generate a movie list HTML table """ - def __init__(self, src=None): + def __init__(self, src=None, dst=None): + self.prev_html = [] self.html = """ My Movie List @@ -49,9 +50,12 @@ class MovieList: """ self.src = src + self.dst = Path(dst) if dst else Path(os.path.dirname(sys.argv[0])) / 'index.html' self.movie_list = [] self.status_list = [] self.threads = [] + self.read_prev_output() + self.html_table = None def _worker(self, arg, index): # Scan IMDb for a given movie and append it to the html @@ -81,8 +85,8 @@ class MovieList: rating = movie['rating'] genres = ', '.join(movie['genres']) status = self.status_list[index] - self.html += ( - f'\n\t{index + 1}' + self.html_table[index] = ( + f'\n{" "*8}{index + 1}' f'{title}' f'{year}{rating}' f'{genres}' @@ -106,37 +110,48 @@ class MovieList: tmp_status = re.sub(r'\]|.*\[', '', tmp_status) self.movie_list = tmp_names.splitlines() self.status_list = tmp_status.splitlines() + self.html_table = [None] * len(self.movie_list) # Progress bar. Enough said pbar = progressbar.ProgressBar(max_value=len(self.movie_list)) for idx, val in enumerate(self.movie_list): - thread = threading.Thread(target=self._worker, args=(val, idx,)) - self.threads.append(thread) - thread.start() - pbar.update(idx+1) - time.sleep(0.2) - if len(self.threads) % 16 == 0: - time.sleep(6) + match = [line for line in self.prev_html if re.sub(r' \(.*\)', '', val) in line] + if match: + # Update movies as DONE in case of change + match = match[0].replace('*', self.status_list[idx]) + # Directly insert the current HTML line from the older output + self.html_table[idx] = f'\n{" "*8}{idx + 1}{match[match.find("") + 5:]}' + pbar.update(idx + 1) + else: + thread = threading.Thread(target=self._worker, args=(val, idx)) + self.threads.append(thread) + thread.start() + pbar.update(idx+1) + time.sleep(0.2) + if len(self.threads) % 16 == 0: + time.sleep(6) for thread in self.threads: thread.join() + self.html += ''.join(self.html_table) return True def write(self, dst=None): """ Write the HTML list to index.html """ - if not dst: - dst = Path(os.path.dirname(sys.argv[0])) / 'index.html' - else: - dst = Path(dst) + out_path = dst if dst else self.dst # Just a fancy scrollbar for the html scroll = '' self.html += ('\n\t\n\n' + '\nGenerated on: ' + time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) + ' by ' + sys.argv[0] + scroll + '\n') - with open(dst, 'wb') as fp_handle: + with open(out_path, 'wb') as fp_handle: fp_handle.write(self.html.encode('utf8')) + def read_prev_output(self): + with open(self.dst, 'rb') as fp_handle: + self.prev_html = fp_handle.read().decode('utf8').split('\n') + def main(): """ Default run """ @@ -150,7 +165,7 @@ def main(): if len(sys.argv) == 3: dst = sys.argv[2] - mlist = MovieList(src=src) + mlist = MovieList(src=src, dst=dst) if mlist.gen(): mlist.write(dst=dst) diff --git a/movie_list/movie_list b/movie_list/movie_list index b6534d1..4c47c7b 100644 --- a/movie_list/movie_list +++ b/movie_list/movie_list @@ -108,6 +108,7 @@ Pirates of the Caribbean: The Curse of the Black Pearl (2003) [DONE] Pirates of the Caribbean: Dead Man's Chest (2006) [DONE] Pirates of the Caribbean: At World's End (2007) [DONE] Pirates of the Caribbean: On Stranger Tides (2011) [DONE] +Pirates of the Caribbean: Dead Men Tell No Tales (2017) [*] Star Wars: Episode I - The Phantom Menace (1999) [DONE] Star Wars: Episode II - Attack of the Clones (2002) [DONE] Star Wars: Episode III - Revenge of the Sith (2005) [DONE] @@ -289,16 +290,16 @@ Spider-Man: Homecoming (2017) [DONE] Rememory (2017) [DONE] Wristcutters: A Love Story (2006) [DONE] Bohemian Rhapsody (2018) [DONE] -Killer's Bodyguard (2017) [*] +Killer's Bodyguard (2017) [DONE] Danny Collins (2015) [DONE] Annabelle: Creation (2017) [DONE] Secrets of State (2008) [*] -Sleepers (1996) [*] -The Disaster Artist (2017) [*] +Sleepers (1996) [DONE] +The Disaster Artist (2017) [DONE] Slumdog Millionaire (2008) [DONE] Ready Player One (2018) [DONE] Dorian Gray (2009) [DONE] -Serenity (2018) [*] +Serenity (2019) [DONE] Death Wish (2018) [DONE] Loving Pablo (2017) [DONE] Get Out (2017) [DONE] @@ -338,5 +339,72 @@ Man on a Ledge (2012) [DONE] The Highwaymen (2019) [DONE] Cold War (2018) [*] Cold Pursuit (2019) [DONE] -Ad Astra (2019) [*] +Ad Astra (2019) [DONE] Storm Boy (2019) [DONE] +Extremely Wicked, Shockingly Evil and Vile (2019) [DONE] +The Post (2017) [DONE] +Angel Has Fallen (2019) [DONE] +The Irishman (2019) [DONE] +The Nightingale (2018) [DONE] +Code 8 (2019) [DONE] +Togo (2019) [*] +Knives Out (2019) [DONE] +Children of Men (2006) [DONE] +Bogowie (2014) [DONE] +Spiral (2021) [*] +Ip Man 4 (2019) [DONE] +The Collini Case (2019) [DONE] +The Traitor (2019) [DONE] +Motherless Brooklyn (2019) [DONE] +The Banker (2020) [DONE] +The Gentlemen (2020) [DONE] +The Platform (2019) [DONE] +Radioactive (2019) [DONE] +Radium Girls (2020) [DONE] +The Stanford Prison Experiment (2015) [DONE] +Red Dragon (2002) [DONE] +The Silence of the Lambs (1991) [DONE] +Hannibal (2001) [DONE] +Parasite (2019) [DONE] +Rounds (2019) [DONE] +Murder On The Orient Express (2017) [DONE] +Pinocchio (2019) [DONE] +The Professor and the Madman (2019) [DONE] +Andhadhun (2018) [DONE] +Archive (2020) [DONE] +The Silencing (2020) [DONE] +Underwater (2020) [DONE] +Love and Monsters (2020) [DONE] +Marshall (2017) [DONE] +The Invisible Man (2020) [DONE] +Greenland (2020) [DONE] +Lean on Me (1989) [DONE] +Let Him Go (2020) [DONE] +Super Lopez (2018) [DONE] +Midnight Special (2016) [DONE] +The Father (2020) [DONE] +Another Round (2020) [DONE] +Promising Young Woman (2021) [DONE] +La Daronne (2020) [DONE] +Tangerines (2013) [DONE] +Bridge of Spies (2015) [DONE] +Glass (2019) [DONE] +The Hunt (2020) [DONE] +The Father (2020) [DONE] +The Dry (2020) [DONE] +The Little Things (2021) [DONE] +Arrival (2016) [DONE] +Duel (1971) [DONE] +The Courier (2020) [DONE] +The Bone Collector (1999) [DONE] +Oslo (2021) [DONE] +Wrath of Man (2021) [DONE] +Nobody (2021) [DONE] +Голата истина за група Жигули (2021) [DONE] +Wild Tales (2014) [DONE] +My Son (2021) [DONE] +The Guilty (2021) [DONE] +Finch (2021) [DONE] +Last Night in Soho (2021) [DONE] +Deepwater Horizon (2016) [DONE] +Boss Level (2020) [DONE] diff --git a/proton.sh b/proton.sh new file mode 100755 index 0000000..df7877c --- /dev/null +++ b/proton.sh @@ -0,0 +1,35 @@ +#!/usr/bin/zsh + +# Run Windows programs through Proton from Steams installation, without +# starting the main Steam client. +# +# Create a directory for the Proton environment to run in. As an example make +# a folder "proton" in your home and point to it in the "env_dir" variable. +# Then look in the "steamapps/common/" folder in your Steam installation for +# available Proton versions to use. Pick one and point the variable +# "install_dir" to that directory. Optionally install this script in a +# directory that is in your $PATH, so you can run it easily from any place. +# +# Usage: +# proton ./program.exe + +# Path to the directory where the actual Proton from Steam is installed in. +# install_dir="$HOME/.steam/steam/steamapps/common/Proton - Experimental" +install_dir="$HOME/gamez/steam-linux/steamapps/common/Proton - Experimental" +# Steam / Client path +export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.steam/steam" + +# Data folder for Proton/WINE environment. Folder must exist. +env_dir=$HOME/proton + +# Proton modes to run +# run = start target app +# waitforexitandrun = wait for wineserver to shut down +# getcompatpath = linux -> windows path +# getnativepath = windows -> linux path +mode=run + +# EXECUTE +export STEAM_COMPAT_DATA_PATH=$env_dir +"$install_dir/proton" $mode $* +