Compare commits
12 Commits
e70d6063e5
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| f7f4bf66e8 | |||
| 1ca024226e | |||
| 6da4cb891b | |||
| b2b8089320 | |||
| 3e7dafb4b2 | |||
| 4bfc45c100 | |||
| 481fa5886a | |||
| 37e29989fe | |||
| 570014c240 | |||
| db8f4e1479 | |||
| aac410f1e1 | |||
| 391ae02488 |
131
archy-usb-ctl.sh
Executable file
131
archy-usb-ctl.sh
Executable file
@@ -0,0 +1,131 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This script is indended to decrypt, mount and chroot in a LUKS+EFI+LVM USB
|
||||||
|
|
||||||
|
if [[ $UID != 0 ]]; then
|
||||||
|
printf "You need root permissions to use this script!\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
echo -e "\nUsage: $(basename "$0") [options] [luks_device]\n\n" \
|
||||||
|
"Options:\n" \
|
||||||
|
"\t-m, --mount Mount the LUKS device (Default)\n" \
|
||||||
|
"\t-u, --umount Unmount the LUKS device\n" \
|
||||||
|
"\t-n, --nochroot Don't run arch-chroot\n" \
|
||||||
|
"\t-c, --chroot Run arch-chroot (Default)\n" \
|
||||||
|
"\t-h, --help Display this message\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mute lvm utilities
|
||||||
|
export LVM_SUPPRESS_FD_WARNINGS=true
|
||||||
|
|
||||||
|
# Some sane defaults
|
||||||
|
ACTION=mount
|
||||||
|
RUN_CHROOT=true
|
||||||
|
USB_LUKS_PART=
|
||||||
|
|
||||||
|
# Call getopt to validate the provided input.
|
||||||
|
if ! options=$(getopt -o chmnu -l chroot,nochroot,mount,umount,help -- "$@"); then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
eval set -- "$options"
|
||||||
|
while true; do
|
||||||
|
case "$1" in
|
||||||
|
(-m|--mount) ACTION=mount ;;
|
||||||
|
(-u|--umount) ACTION=umount ;;
|
||||||
|
(-n|--nochroot) RUN_CHROOT=false ;;
|
||||||
|
(-c|--chroot) RUN_CHROOT=true ;;
|
||||||
|
(-h|--help) usage; exit 1;;
|
||||||
|
(--) shift; break;;
|
||||||
|
(*) usage; break;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
if [ "$#" -gt 1 ]; then
|
||||||
|
echo "error: Only 1 device argument possible! Got $#: $*"
|
||||||
|
usage
|
||||||
|
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 </dev/path/to/LUKS_device>\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
|
||||||
|
|
||||||
46
btfs.sh
Executable file
46
btfs.sh
Executable file
@@ -0,0 +1,46 @@
|
|||||||
|
#!/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
|
||||||
|
#kodi "$movie" 1>/dev/null
|
||||||
|
printf "Unmounting: %s\n" "$mountpoint"
|
||||||
|
fusermount -u "$mountpoint"
|
||||||
|
printf "Removing dir: %s\n" "$mountpoint"
|
||||||
|
rmdir "$mountpoint"
|
||||||
|
|
||||||
82
check-ip-seeds.py
Executable file
82
check-ip-seeds.py
Executable file
@@ -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]} <ip_addr>')
|
||||||
|
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)
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
#checkpatch --no-tree -f
|
|
||||||
checkpatch="/usr/lib/modules/$(uname -r)/build/scripts/checkpatch.pl"
|
|
||||||
|
|
||||||
if [ -z "$1" ]; then
|
|
||||||
project_dir="$PWD"
|
|
||||||
elif [ -d "$1" ]; then
|
|
||||||
project_dir="$1"
|
|
||||||
else
|
|
||||||
source_file="$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$project_dir" ]; then
|
|
||||||
"${checkpatch}" --no-tree -f "${source_file}"
|
|
||||||
else
|
|
||||||
find "${project_dir}" -regex '.*\.\(c\|h\)' -exec "${checkpatch}" --no-tree -f '{}' +
|
|
||||||
fi
|
|
||||||
|
|
||||||
13
clean_chroot_build.sh
Executable file
13
clean_chroot_build.sh
Executable file
@@ -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 -- $@
|
||||||
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Capture screen script
|
|
||||||
prefix=`date +"%G.%m.%d_%H.%M.%S"`
|
|
||||||
|
|
||||||
ffmpeg -y -f x11grab \
|
|
||||||
-video_size 1920x1080 \
|
|
||||||
-r 30 \
|
|
||||||
-i $DISPLAY \
|
|
||||||
-f pulse \
|
|
||||||
-ac 2 \
|
|
||||||
-i default \
|
|
||||||
-c:v libx264 \
|
|
||||||
-crf 0 \
|
|
||||||
-pix_fmt yuv420p \
|
|
||||||
-preset ultrafast \
|
|
||||||
-threads 0 \
|
|
||||||
$prefix.mp4
|
|
||||||
# -f alsa \
|
|
||||||
# -i hw:2,1 \
|
|
||||||
#-an \
|
|
||||||
65
find_adb_device.py
Executable file
65
find_adb_device.py
Executable file
@@ -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]} <device>')
|
||||||
|
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 <device>')
|
||||||
|
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()
|
||||||
|
|
||||||
2
movie_list/.gitignore
vendored
Normal file
2
movie_list/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
index.html
|
||||||
|
jquery.dataTables.min.js
|
||||||
571
movie_list/gen_movie_list.py
Executable file
571
movie_list/gen_movie_list.py
Executable file
@@ -0,0 +1,571 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
1. Import a movie_list txt file
|
||||||
|
2. Query IMDb for each entry, retrieving actual movie name, rating and genres
|
||||||
|
3. Generate an HTML table from the IMDb data
|
||||||
|
4. Store the HTML in index.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
from pathlib import Path
|
||||||
|
import progressbar
|
||||||
|
from imdb import IMDb
|
||||||
|
from imdb._exceptions import IMDbParserError, IMDbDataAccessError
|
||||||
|
|
||||||
|
|
||||||
|
class MovieList:
|
||||||
|
""" Class to generate a movie list HTML table """
|
||||||
|
def __init__(self, src=None, dst=None):
|
||||||
|
self.prev_html = []
|
||||||
|
self.html = """<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>My Movie List</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css">
|
||||||
|
<script src="../jquery-3.7.1.min.js"></script>
|
||||||
|
<script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||||
|
background: transparent;
|
||||||
|
height: 100vh;
|
||||||
|
padding: 0.5rem;
|
||||||
|
color: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
padding: 0.75rem;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_filter {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
text-align: right;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_filter label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_filter input {
|
||||||
|
padding: 0.4rem 0.75rem;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 6px;
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_filter input::placeholder {
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_filter input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: rgba(255, 255, 255, 0.4);
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_info {
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_scroll {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_scrollHead {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_scrollBody {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_scrollBody::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_scrollBody::-webkit-scrollbar-track {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_scrollBody::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper::-webkit-scrollbar-track {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataTables_wrapper::-webkit-scrollbar-thumb {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable.stripe tbody tr.odd,
|
||||||
|
table.dataTable.display tbody tr.odd,
|
||||||
|
table.dataTable tbody tr {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable.hover tbody tr:hover,
|
||||||
|
table.dataTable.display tbody tr:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.dataTable tbody td {
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead {
|
||||||
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead th {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead th:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead th.sorting,
|
||||||
|
#sortable thead th.sorting_asc,
|
||||||
|
#sortable thead th.sorting_desc {
|
||||||
|
padding-right: 1.5rem;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead th.sorting:after {
|
||||||
|
content: '⇅';
|
||||||
|
position: absolute;
|
||||||
|
right: 0.5rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead th.sorting_asc:after {
|
||||||
|
content: '↑';
|
||||||
|
position: absolute;
|
||||||
|
right: 0.5rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable thead th.sorting_desc:after {
|
||||||
|
content: '↓';
|
||||||
|
position: absolute;
|
||||||
|
right: 0.5rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody tr {
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||||
|
transition: background 0.15s ease;
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody tr:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.1) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody td {
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
background: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody td:first-child {
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody td a {
|
||||||
|
color: rgba(135, 206, 250, 0.9);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody td a:hover {
|
||||||
|
color: rgba(135, 206, 250, 1);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody td p[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable tbody td:nth-child(4) {
|
||||||
|
color: rgba(255, 193, 7, 0.9);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timestamp {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
padding-top: 0.5rem;
|
||||||
|
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
try {
|
||||||
|
$('#sortable').DataTable({
|
||||||
|
"paging": false,
|
||||||
|
"info": true,
|
||||||
|
"searching": true,
|
||||||
|
"ordering": true,
|
||||||
|
"order": [[0, "desc"]],
|
||||||
|
"language": {
|
||||||
|
"search": "Search:",
|
||||||
|
"info": "Showing _TOTAL_ movies",
|
||||||
|
"infoEmpty": "No movies",
|
||||||
|
"infoFiltered": "(filtered from _MAX_)"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch(e) {
|
||||||
|
console.error("DataTables init error:", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<base target="_parent" />
|
||||||
|
<div class="container">
|
||||||
|
<h1>🎬 My Movie Collection</h1>
|
||||||
|
<table id="sortable" class="sortable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Rating</th>
|
||||||
|
<th>Genre</th>
|
||||||
|
<th>Status</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>"""
|
||||||
|
self.src = src
|
||||||
|
self.dst = Path(dst) if dst else Path(os.path.dirname(sys.argv[0])) / 'index.html'
|
||||||
|
self.movie_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
|
||||||
|
# This collects rating, genres, official name and a hyperlink
|
||||||
|
imdb = IMDb()
|
||||||
|
first_run = True
|
||||||
|
while True:
|
||||||
|
if not first_run:
|
||||||
|
time.sleep(10)
|
||||||
|
else:
|
||||||
|
first_run = False
|
||||||
|
try:
|
||||||
|
query = imdb.search_movie(f'{arg["title"]} {arg["year"]}')
|
||||||
|
break
|
||||||
|
except IMDbDataAccessError as imdb_data_exc:
|
||||||
|
exc = str(imdb_data_exc)
|
||||||
|
if '503' in exc:
|
||||||
|
sys.stderr.write('503 - Service Unavailable, retrying...')
|
||||||
|
elif '403' in exc:
|
||||||
|
sys.stderr.write('403 - Forbidden, retrying...\n')
|
||||||
|
query = []
|
||||||
|
time.sleep(10)
|
||||||
|
except IMDbParserError as imdb_parser_exc:
|
||||||
|
query = []
|
||||||
|
break
|
||||||
|
except Exception as exc:
|
||||||
|
time.sleep(10)
|
||||||
|
|
||||||
|
movie = None
|
||||||
|
for entry in query:
|
||||||
|
try:
|
||||||
|
imdb.update(entry)
|
||||||
|
except Exception as e:
|
||||||
|
sys.stderr.write('update err')
|
||||||
|
# in case any of these keys is missing in the query, continue
|
||||||
|
if not all(key in entry.keys() for key in ['kind', 'year', 'title']):
|
||||||
|
continue
|
||||||
|
if arg['status'] == 'DONE' and 'rating' not in entry.keys():
|
||||||
|
continue
|
||||||
|
# Try to eliminate episode results
|
||||||
|
if [i for i in entry.keys() if 'episode' in i.lower()] or (
|
||||||
|
'episode' in entry['title'].lower() and \
|
||||||
|
'episode' not in arg['title'].lower()):
|
||||||
|
continue
|
||||||
|
if entry['kind'].lower() == arg['kind'].lower():
|
||||||
|
movie = entry
|
||||||
|
break
|
||||||
|
if not movie:
|
||||||
|
movie = {
|
||||||
|
'title': arg['title'],
|
||||||
|
'kind': arg['kind'],
|
||||||
|
'year': arg['year'],
|
||||||
|
'dummy': None
|
||||||
|
}
|
||||||
|
if 'genres' not in movie.keys():
|
||||||
|
movie['genres'] = ['N/A']
|
||||||
|
if 'rating' not in movie.keys():
|
||||||
|
movie['rating'] = 'N/A'
|
||||||
|
|
||||||
|
html_title_td = movie['title'] if 'dummy' in movie.keys() else \
|
||||||
|
f'<a href="https://www.imdb.com/title/tt{movie.movieID}" target="_blank">{movie["title"]}</a>'
|
||||||
|
|
||||||
|
self.html_table[index] = (
|
||||||
|
f'\n <tr>'
|
||||||
|
f'<td data-label="#">{index + 1}</td>'
|
||||||
|
f'<td data-label="Title"><p hidden>{arg["title"]}</p>{html_title_td}</td>'
|
||||||
|
f'<td data-label="Year">{movie["year"]}</td>'
|
||||||
|
f'<td data-label="Rating" align="center">{movie["rating"]}</td>'
|
||||||
|
f'<td data-label="Genre">{", ".join(movie["genres"])}</td>'
|
||||||
|
f'<td data-label="Status" align="center">{arg["status"]}</td>'
|
||||||
|
f'</tr>'
|
||||||
|
)
|
||||||
|
|
||||||
|
def gen(self):
|
||||||
|
""" Generate an HTML list based on input, using a threaded worker """
|
||||||
|
if not self.src:
|
||||||
|
self.src = Path(os.path.dirname(sys.argv[0])) / 'movie_list'
|
||||||
|
else:
|
||||||
|
self.src = Path(self.src)
|
||||||
|
if not self.src.exists():
|
||||||
|
sys.stderr.write(f'error: input does not exist - {self.src}\n')
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.movie_list = {}
|
||||||
|
seen_titles = set() # Track unique titles
|
||||||
|
|
||||||
|
# Open the movie list & split the columns
|
||||||
|
with open(self.src, 'r', encoding='utf-8') as fp_handle:
|
||||||
|
mlist_raw = fp_handle.read()
|
||||||
|
idx = 0
|
||||||
|
for raw_line in mlist_raw.splitlines():
|
||||||
|
# In case the line is empty
|
||||||
|
if not raw_line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
title = raw_line[0:next((i for i, ch in enumerate(raw_line) if ch in {'<', '('}), None) - 1]
|
||||||
|
|
||||||
|
# Skip if we've already seen this title
|
||||||
|
if title in seen_titles:
|
||||||
|
continue
|
||||||
|
|
||||||
|
seen_titles.add(title)
|
||||||
|
self.movie_list.update({
|
||||||
|
idx: {
|
||||||
|
'title': title,
|
||||||
|
'kind': raw_line[raw_line.find('<')+1:raw_line.rfind('>')+1].strip('<>') or 'movie',
|
||||||
|
'year': raw_line[raw_line.find('(')+1:raw_line.find(')')],
|
||||||
|
'status': raw_line[raw_line.find('[')+1:raw_line.find(']')],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
self.html_table = [None] * len(self.movie_list)
|
||||||
|
|
||||||
|
# Progress bar
|
||||||
|
pbar = progressbar.ProgressBar(max_value=len(self.movie_list))
|
||||||
|
for idx, movie in self.movie_list.items():
|
||||||
|
# More precise matching - look for the hidden <p> tag with exact title
|
||||||
|
match = [html_row for html_row in self.prev_html
|
||||||
|
if f'<p hidden>{movie["title"]}</p>' in html_row
|
||||||
|
and 'N/A' not in html_row]
|
||||||
|
if match:
|
||||||
|
# Update the index and status from the cached row
|
||||||
|
match_str = match[0]
|
||||||
|
# Replace the status (* -> DONE or vice versa)
|
||||||
|
match_str = match_str.replace('*', movie['status']).replace('DONE', movie['status'])
|
||||||
|
# Update the index number
|
||||||
|
if '<td data-label="#">' in match_str:
|
||||||
|
# Extract everything after the index cell
|
||||||
|
after_index = match_str.split('</td>', 1)[1] if '</td>' in match_str else match_str
|
||||||
|
self.html_table[idx] = f'\n <tr><td data-label="#">{idx + 1}</td>{after_index}'
|
||||||
|
else:
|
||||||
|
self.html_table[idx] = match_str
|
||||||
|
pbar.increment()
|
||||||
|
else:
|
||||||
|
thread = threading.Thread(target=self._worker, args=(movie, idx))
|
||||||
|
self.threads.append(thread)
|
||||||
|
|
||||||
|
max_threads = 10
|
||||||
|
while self.threads:
|
||||||
|
threads_alive = self.get_alive_threads()
|
||||||
|
threads_to_be_started = [i for i in self.threads if i not in threads_alive]
|
||||||
|
for idx in range(max_threads if max_threads < len(threads_to_be_started) else len(threads_to_be_started)):
|
||||||
|
threads_to_be_started[idx].start()
|
||||||
|
pbar.increment()
|
||||||
|
time.sleep(2)
|
||||||
|
time.sleep(2)
|
||||||
|
self.delete_finished_threads()
|
||||||
|
|
||||||
|
# Don't append to self.html here - we'll do it in write()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def delete_finished_threads(self):
|
||||||
|
for idx, thread in enumerate(self.threads):
|
||||||
|
if not thread.is_alive() and thread._started.is_set():
|
||||||
|
thread.join()
|
||||||
|
self.threads[idx] = None
|
||||||
|
self.threads = list(filter(lambda a: a is not None, self.threads))
|
||||||
|
|
||||||
|
def get_alive_threads(self):
|
||||||
|
threads = []
|
||||||
|
for thread in self.threads:
|
||||||
|
if thread.is_alive() or thread._started.is_set():
|
||||||
|
threads.append(thread)
|
||||||
|
return threads
|
||||||
|
|
||||||
|
def write(self, dst=None):
|
||||||
|
""" Write the HTML list to index.html """
|
||||||
|
out_path = dst if dst else self.dst
|
||||||
|
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
|
||||||
|
|
||||||
|
# Build the final HTML - don't append, rebuild from scratch
|
||||||
|
final_html = self.html.split('<tbody>')[0] + '<tbody>'
|
||||||
|
final_html += ''.join([row for row in self.html_table if row is not None])
|
||||||
|
final_html += f'''
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="timestamp">Generated {timestamp} UTC</div>
|
||||||
|
</body>
|
||||||
|
</html>'''
|
||||||
|
|
||||||
|
with open(out_path, 'wb') as fp_handle:
|
||||||
|
fp_handle.write(final_html.encode('utf8'))
|
||||||
|
|
||||||
|
def read_prev_output(self):
|
||||||
|
""" Import a previous HTML table """
|
||||||
|
if self.dst.exists():
|
||||||
|
with open(self.dst, 'rb') as fp_handle:
|
||||||
|
self.prev_html = fp_handle.read().decode('utf8').split('\n')
|
||||||
|
|
||||||
|
def deduplicate_html(self):
|
||||||
|
""" Remove duplicate entries from html_table based on movie titles """
|
||||||
|
seen_titles = set()
|
||||||
|
deduplicated = []
|
||||||
|
|
||||||
|
for idx, row in enumerate(self.html_table):
|
||||||
|
if row is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Extract the hidden title from the row
|
||||||
|
if '<p hidden>' in row and '</p>' in row:
|
||||||
|
start = row.find('<p hidden>') + 10
|
||||||
|
end = row.find('</p>', start)
|
||||||
|
title = row[start:end]
|
||||||
|
|
||||||
|
if title not in seen_titles:
|
||||||
|
seen_titles.add(title)
|
||||||
|
deduplicated.append(row)
|
||||||
|
else:
|
||||||
|
# Skip duplicate
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
# If we can't find the hidden title, keep the row anyway
|
||||||
|
deduplicated.append(row)
|
||||||
|
|
||||||
|
# Update html_table with deduplicated content
|
||||||
|
self.html_table = deduplicated
|
||||||
|
return len(self.html_table)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
""" Default run """
|
||||||
|
src = dst = None
|
||||||
|
if len(sys.argv) > 3:
|
||||||
|
sys.stderr.write(f'error: max 2 variables, {len(sys.argv)-1} given!\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
src = sys.argv[1]
|
||||||
|
if len(sys.argv) == 3:
|
||||||
|
dst = sys.argv[2]
|
||||||
|
|
||||||
|
mlist = MovieList(src=src, dst=dst)
|
||||||
|
if mlist.gen():
|
||||||
|
mlist.write(dst=dst)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
469
movie_list/movie_list
Normal file
469
movie_list/movie_list
Normal file
@@ -0,0 +1,469 @@
|
|||||||
|
Edge of Tomorrow (2014) [DONE]
|
||||||
|
Third Person (2013) [DONE]
|
||||||
|
Outbreak (1995) [DONE]
|
||||||
|
Hanna (2011) [DONE]
|
||||||
|
School Ties (1992) [DONE]
|
||||||
|
I Am Legend (2007) [DONE]
|
||||||
|
Life Is Beautiful (1997) [DONE]
|
||||||
|
Hitch (2005) [DONE]
|
||||||
|
The Curious Case of Benjamin Button (2008) [DONE]
|
||||||
|
The Pursuit of Happyness (2006) [DONE]
|
||||||
|
Pay It Forward (2000) [DONE]
|
||||||
|
American Gangster (2007) [DONE]
|
||||||
|
Mr. Nobody (2009) [DONE]
|
||||||
|
The Jacket (2005) [DONE]
|
||||||
|
Two Night Stand (2014) [DONE]
|
||||||
|
Chef (2014) [DONE]
|
||||||
|
Mary and Max (2009) [DONE]
|
||||||
|
Lucky Number Slevin (2006) [DONE]
|
||||||
|
The Road (2009) [DONE]
|
||||||
|
Magnolia (1999) [DONE]
|
||||||
|
The Monster (1994) [DONE]
|
||||||
|
The Tiger and the Snow (2005) [DONE]
|
||||||
|
Lucy (2014) [DONE]
|
||||||
|
End of Watch (2012) [DONE]
|
||||||
|
The Prestige (2006) [DONE]
|
||||||
|
Léon (1994) [DONE]
|
||||||
|
Reservoir Dogs (1992) [DONE]
|
||||||
|
Ratatouille (2007) [DONE]
|
||||||
|
Cloud Atlas (2012) [DONE]
|
||||||
|
Office Space (1999) [DONE]
|
||||||
|
Life of Pi (2012) [DONE]
|
||||||
|
The Intouchables (2011) [DONE]
|
||||||
|
The Pianist (2002) [DONE]
|
||||||
|
Stand by Me (1986) [DONE]
|
||||||
|
Coach Carter (2005) [DONE]
|
||||||
|
Law Abiding Citizen (2009) [DONE]
|
||||||
|
The Butterfly Effect (2004) [DONE]
|
||||||
|
Devil's Advocate (1997) [DONE]
|
||||||
|
Braveheart (1995) [DONE]
|
||||||
|
Body of Lies (2008) [DONE]
|
||||||
|
Midnight in Paris (2011) [DONE]
|
||||||
|
Ghost Town (2008) [DONE]
|
||||||
|
RED (2010) [DONE]
|
||||||
|
The Fountain (2006) [DONE]
|
||||||
|
The Boy in the Striped Pajamas (2008) [DONE]
|
||||||
|
Ip Man (2008) [DONE]
|
||||||
|
The Bourne Identity (2002) [DONE]
|
||||||
|
The Bourne Supremacy (2004) [DONE]
|
||||||
|
The Bourne Ultimatum (2007) [DONE]
|
||||||
|
Heat (1995) [DONE]
|
||||||
|
A Beautiful Mind (2001) [DONE]
|
||||||
|
Sin City (2005) [DONE]
|
||||||
|
Fargo (1996) [DONE]
|
||||||
|
Snatch (2000) [DONE]
|
||||||
|
Blood Diamond (2006) [DONE]
|
||||||
|
The Departed (2006) [DONE]
|
||||||
|
Forrest Gump (1994) [DONE]
|
||||||
|
Schindler's List (1993) [DONE]
|
||||||
|
The Shawshank Redemption (1994) [DONE]
|
||||||
|
Limitless (2011) [DONE]
|
||||||
|
Seven Pounds (2008) [DONE]
|
||||||
|
I, Robot (2004) [DONE]
|
||||||
|
The Usual Suspects (1995) [DONE]
|
||||||
|
The Sixth Sense (1999) [DONE]
|
||||||
|
The Mechanic (2011) [DONE]
|
||||||
|
The King's Speech (2010) [DONE]
|
||||||
|
The Green Mile (1999) [DONE]
|
||||||
|
The Game (1997) [DONE]
|
||||||
|
The Edge (1997) [DONE]
|
||||||
|
Taken (2008) [DONE]
|
||||||
|
Taken 2 (2012) [DONE]
|
||||||
|
Taken 3 (2014) [DONE]
|
||||||
|
Shutter Island (2010) [DONE]
|
||||||
|
Scent of a Woman (1992) [DONE]
|
||||||
|
Papillon (1973) [DONE]
|
||||||
|
Oliver Twist (2005) [DONE]
|
||||||
|
Memento (2000) [DONE]
|
||||||
|
Lock, Stock and Two Smoking Barrels (1998) [DONE]
|
||||||
|
The Crimson Rivers (2000) [DONE]
|
||||||
|
Inception (2010) [DONE]
|
||||||
|
Headhunters (2011) [DONE]
|
||||||
|
Fearless (2006) [DONE]
|
||||||
|
Unleashed (2005) [DONE]
|
||||||
|
Catch Me If You Can (2002) [DONE]
|
||||||
|
Sweeney Todd: The Demon Barber of Fleet Street (2007) [DONE]
|
||||||
|
King of California (2007) [DONE]
|
||||||
|
Pulp Fiction (1994) [DONE]
|
||||||
|
The Godfather (1972) [DONE]
|
||||||
|
The Matrix (1999) [DONE]
|
||||||
|
The Matrix Reloaded (2003) [DONE]
|
||||||
|
The Matrix Revolutions (2003) [DONE]
|
||||||
|
Se7en (1995) [DONE]
|
||||||
|
The Rock (1996) [DONE]
|
||||||
|
Saving Private Ryan (1998) [DONE]
|
||||||
|
A Time to Kill (1996) [DONE]
|
||||||
|
The Hobbit: An Unexpected Journey (2012) [DONE]
|
||||||
|
The Hobbit: The Desolation of Smaug (2013) [DONE]
|
||||||
|
The Hobbit: The Battle of the Five Armies (2014) [DONE]
|
||||||
|
The Lord of the Rings: The Fellowship of the Ring (2001) [DONE]
|
||||||
|
The Lord of the Rings: The Two Towers (2002) [DONE]
|
||||||
|
The Lord of the Rings: The Return of the King (2003) [DONE]
|
||||||
|
The Machinist (2004) [DONE]
|
||||||
|
The Imaginarium of Doctor Parnassus (2009) [DONE]
|
||||||
|
Transcendence (2014) [DONE]
|
||||||
|
Dark Shadows (2012) [DONE]
|
||||||
|
The Rum Diary (2011) [DONE]
|
||||||
|
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]
|
||||||
|
Star Wars: Episode IV - A New Hope (1977) [DONE]
|
||||||
|
Star Wars: Episode V - The Empire Strikes Back (1980) [DONE]
|
||||||
|
Star Wars: Episode VI - Return of the Jedi (1983) [DONE]
|
||||||
|
Star Wars: Episode VII: The Force Awakens (2015) [DONE]
|
||||||
|
Rogue One: A Star Wars Story (2016) [DONE]
|
||||||
|
Men in Black (1997) [DONE]
|
||||||
|
Men in Black II (2002) [DONE]
|
||||||
|
Men in Black 3 (2012) [DONE]
|
||||||
|
Hancock (2008) [DONE]
|
||||||
|
Silver Linings Playbook (2012) [DONE]
|
||||||
|
Meet the Parents (2000) [DONE]
|
||||||
|
Meet the Fockers (2004) [DONE]
|
||||||
|
Showtime (2002) [DONE]
|
||||||
|
Analyze This (1999) [DONE]
|
||||||
|
Jackie Brown (1997) [DONE]
|
||||||
|
The Untouchables (1987) [DONE]
|
||||||
|
Rango (2011) [DONE]
|
||||||
|
Lord of War (2005) [DONE]
|
||||||
|
Alice in Wonderland (2010) [DONE]
|
||||||
|
Public Enemies (2009) [DONE]
|
||||||
|
Corpse Bride (2005) [DONE]
|
||||||
|
Finding Neverland (2004) [DONE]
|
||||||
|
Secret Window (2004) [DONE]
|
||||||
|
Once Upon a Time in Mexico (2003) [DONE]
|
||||||
|
Blow (2001) [DONE]
|
||||||
|
Chocolat (2000) [DONE]
|
||||||
|
Sleepy Hollow (1999) [DONE]
|
||||||
|
The Man Who Cried (2000) [DONE]
|
||||||
|
The Ninth Gate (1999) [DONE]
|
||||||
|
Donnie Brasco (1997) [DONE]
|
||||||
|
Platoon (1986) [DONE]
|
||||||
|
One Flew Over the Cuckoo's Nest (1975) [DONE]
|
||||||
|
Goodfellas (1990) [DONE]
|
||||||
|
City of God (2002) [DONE]
|
||||||
|
Once Upon a Time in the West (1968) [DONE]
|
||||||
|
Gladiator (2000) [DONE]
|
||||||
|
300 (2006) [DONE]
|
||||||
|
Django Unchained (2012) [DONE]
|
||||||
|
American Beauty (1999) [DONE]
|
||||||
|
Black Swan (2010) [DONE]
|
||||||
|
WALL·E (2008) [DONE]
|
||||||
|
Amélie (2001) [DONE]
|
||||||
|
Eternal Sunshine of the Spotless Mind (2004) [DONE]
|
||||||
|
Inglourious Basterds (2009) [DONE]
|
||||||
|
Unforgiven (1992) [DONE]
|
||||||
|
Scarface (1983) [DONE]
|
||||||
|
Die Hard (1988) [DONE]
|
||||||
|
Die Hard 2 (1990) [DONE]
|
||||||
|
Die Hard with a Vengeance (1995) [DONE]
|
||||||
|
Live Free or Die Hard (2007) [DONE]
|
||||||
|
A Good Day to Die Hard (2013) [DONE]
|
||||||
|
Die Another Day (2002) [DONE]
|
||||||
|
A Long Way Down (2014) [DONE]
|
||||||
|
Remember Me (2010) [DONE]
|
||||||
|
Automata (2014) [DONE]
|
||||||
|
The World Is Not Enough (1999) [DONE]
|
||||||
|
The Thomas Crown Affair (1999) [DONE]
|
||||||
|
Tomorrow Never Dies (1997) [DONE]
|
||||||
|
GoldenEye (1995) [DONE]
|
||||||
|
Mrs. Doubtfire (1993) [DONE]
|
||||||
|
Dracula Untold (2014) [DONE]
|
||||||
|
Interstellar (2014) [DONE]
|
||||||
|
Fury (2014) [DONE]
|
||||||
|
The Maze Runner (2014) [DONE]
|
||||||
|
Ender's Game (2013) [DONE]
|
||||||
|
Stonehearst Asylum (2014) [DONE]
|
||||||
|
Predestination (2014) [DONE]
|
||||||
|
Jurassic World (2015) [DONE]
|
||||||
|
Pan (2015) [DONE]
|
||||||
|
The Cobbler (2014) [DONE]
|
||||||
|
The Conjuring (2013) [DONE]
|
||||||
|
Starred Up (2013) [DONE]
|
||||||
|
In Order of Disappearance (2014) [DONE]
|
||||||
|
The Imitation Game (2014) [DONE]
|
||||||
|
Begin Again (2013) [DONE]
|
||||||
|
A Walk Among the Tombstones (2014) [DONE]
|
||||||
|
Detachment (2011) [DONE]
|
||||||
|
Identity (2003) [DONE]
|
||||||
|
Force Majeure (2014) [DONE]
|
||||||
|
Gone Girl (2014) [DONE]
|
||||||
|
The Equalizer (2014) [DONE]
|
||||||
|
The Equalizer 2 (2018) [DONE]
|
||||||
|
Desert Flower (2009) [DONE]
|
||||||
|
I Origins (2014) [DONE]
|
||||||
|
Whiplash (2014) [DONE]
|
||||||
|
Redirected (2014) [DONE]
|
||||||
|
Nightcrawler (2014) [DONE]
|
||||||
|
The Judge (2014) [DONE]
|
||||||
|
I Am Sam (2001) [DONE]
|
||||||
|
The Bank Job (2008) [DONE]
|
||||||
|
Child 44 (2015) [DONE]
|
||||||
|
Big Hero 6 (2014) [DONE]
|
||||||
|
Rise of the Guardians (2012) [DONE]
|
||||||
|
De vrais mensonges (2010) [DONE]
|
||||||
|
Unbroken (2014) [DONE]
|
||||||
|
Kingsman: The Secret Service (2014) [DONE]
|
||||||
|
Kidnapping Mr. Heineken (2015) [DONE]
|
||||||
|
The Blind Side (2009) [DONE]
|
||||||
|
Leviafan (2014) [DONE]
|
||||||
|
The Rewrite (2014) [DONE]
|
||||||
|
Focus (2015) [DONE]
|
||||||
|
The Wedding Ringer (2015) [DONE]
|
||||||
|
The Forger (2014) [DONE]
|
||||||
|
Project Almanac (2014) [DONE]
|
||||||
|
Run All Night (2015) [DONE]
|
||||||
|
The Age of Adaline (2015) [DONE]
|
||||||
|
Tomorrowland (2015) [DONE]
|
||||||
|
Before We Go (2014) [DONE]
|
||||||
|
John Doe: Vigilante (2014) [DONE]
|
||||||
|
Blown Away (1994) [DONE]
|
||||||
|
The Man from U.N.C.L.E. (2016) [DONE]
|
||||||
|
Southpaw (2015) [DONE]
|
||||||
|
Concussion (2015) [DONE]
|
||||||
|
Spy (2015) [DONE]
|
||||||
|
Gravity (2013) [DONE]
|
||||||
|
The Revenant (2015) [DONE]
|
||||||
|
Ex Machina (2014) [DONE]
|
||||||
|
The Martian (2015) [DONE]
|
||||||
|
Shelter (2014) [DONE]
|
||||||
|
Criminal Activities (2015) [DONE]
|
||||||
|
The Walk (2015) [DONE]
|
||||||
|
The Finest Hours (2016) [DONE]
|
||||||
|
Gods of Egypt (2016) [DONE]
|
||||||
|
The Terminal (2004) [DONE]
|
||||||
|
In The Heart of the Sea (2015) [DONE]
|
||||||
|
Secret in Their Eyes (2015) [DONE]
|
||||||
|
Zootopia (2016) [DONE]
|
||||||
|
Ip Man 3 (2015) [DONE]
|
||||||
|
Miss Peregrine's Home for Peculiar Children (2016) [DONE]
|
||||||
|
Deadpool (2016) [DONE]
|
||||||
|
Assassin's Creed (2016) [DONE]
|
||||||
|
John Q (2002) [DONE]
|
||||||
|
Now You See Me (2013) [DONE]
|
||||||
|
Up (2009) [DONE]
|
||||||
|
The Shallows (2016) [DONE]
|
||||||
|
Boychoir (2014) [DONE]
|
||||||
|
Same Kind of Different as Me (2017) [DONE]
|
||||||
|
Allied (2016) [DONE]
|
||||||
|
Mad Max: Fury Road (2015) [DONE]
|
||||||
|
Blood Father (2016) [DONE]
|
||||||
|
Citizenfour (2014) [DONE]
|
||||||
|
Kon-Tiki (2012) [DONE]
|
||||||
|
Our Kind of Traitor (2016) [DONE]
|
||||||
|
Inferno (2016) [DONE]
|
||||||
|
En man som heter Ove (2015) [DONE]
|
||||||
|
Ghost In The Shell (2017) [DONE]
|
||||||
|
War Dogs (2016) [DONE]
|
||||||
|
Equals (2015) [DONE]
|
||||||
|
The Outsiders (1983) [DONE]
|
||||||
|
Fantastic Beasts and Where to Find Them (2016) [DONE]
|
||||||
|
Joy (2015) [DONE]
|
||||||
|
Coherence (2013) [DONE]
|
||||||
|
The Elephant Man (1980) [DONE]
|
||||||
|
The Jungle Book (2016) [DONE]
|
||||||
|
The Girl on the Train (2016) [DONE]
|
||||||
|
Passengers (2016) [DONE]
|
||||||
|
Arrival (2016) [DONE]
|
||||||
|
Rust and Bone (2012) [DONE]
|
||||||
|
Jack Reacher (2012) [DONE]
|
||||||
|
At The End of The Tunnel (2016) [DONE]
|
||||||
|
The Town (2010) [DONE]
|
||||||
|
The Giver (2014) [DONE]
|
||||||
|
John Wick (2014) [DONE]
|
||||||
|
John Wick: Chapter 2 (2017) [DONE]
|
||||||
|
Lost in Translation (2003) [DONE]
|
||||||
|
The Graduate (1967) [DONE]
|
||||||
|
Logan (2017) [DONE]
|
||||||
|
K-PAX (2001) [DONE]
|
||||||
|
The Best Offer (2013) [DONE]
|
||||||
|
Fences (2016) [DONE]
|
||||||
|
Inside I'm Dancing (2004) [DONE]
|
||||||
|
My Name Is Khan (2010) [DONE]
|
||||||
|
Life (2017) [DONE]
|
||||||
|
Gifted (2017) [DONE]
|
||||||
|
Spider-Man: Homecoming (2017) [DONE]
|
||||||
|
Rememory (2017) [DONE]
|
||||||
|
Wristcutters: A Love Story (2006) [DONE]
|
||||||
|
Bohemian Rhapsody (2018) [DONE]
|
||||||
|
The Hitmans's Bodyguard (2017) [DONE]
|
||||||
|
Danny Collins (2015) [DONE]
|
||||||
|
Annabelle: Creation (2017) [DONE]
|
||||||
|
Secrets of State (2008) [*]
|
||||||
|
Sleepers (1996) [DONE]
|
||||||
|
The Disaster Artist (2017) [DONE]
|
||||||
|
Slumdog Millionaire (2008) [DONE]
|
||||||
|
Ready Player One (2018) [DONE]
|
||||||
|
Dorian Gray (2009) [DONE]
|
||||||
|
Serenity (2019) [DONE]
|
||||||
|
Death Wish (2018) [DONE]
|
||||||
|
Loving Pablo (2017) [DONE]
|
||||||
|
Get Out (2017) [DONE]
|
||||||
|
Orphan (2009) [DONE]
|
||||||
|
Upgrade (2018) [DONE]
|
||||||
|
Dangal (2016) [DONE]
|
||||||
|
BlacKkKlansman (2018) [DONE]
|
||||||
|
The Shape of Water (2017) [DONE]
|
||||||
|
What Women Want (2000) [DONE]
|
||||||
|
What's Love Got to Do with It (1993) [DONE]
|
||||||
|
Spotlight (2015) [DONE]
|
||||||
|
First Man (2018) [DONE]
|
||||||
|
Halloween (2018) [*]
|
||||||
|
Catch-22 (1970) [*]
|
||||||
|
The Nun (2018) [DONE]
|
||||||
|
Into The White (2012) [DONE]
|
||||||
|
Trash (2014) [DONE]
|
||||||
|
First Man (2018) [DONE]
|
||||||
|
Full Metal Jacket (1987) [*]
|
||||||
|
Roman J. Israel, Esq. (2017) [DONE]
|
||||||
|
Venom (2018) [DONE]
|
||||||
|
Moby Dick (1998) <TV Mini Series> [DONE]
|
||||||
|
The Help (2011) [DONE]
|
||||||
|
Hidden Figures (2016) [DONE]
|
||||||
|
The Guilty (2018) [DONE]
|
||||||
|
Green Book (2018) [DONE]
|
||||||
|
The Road Within (2014) [DONE]
|
||||||
|
King of Thieves (2018) [DONE]
|
||||||
|
The House That Jack Built (2018) [DONE]
|
||||||
|
Captain Marvel (2019) [DONE]
|
||||||
|
Miss Sloane (2016) [DONE]
|
||||||
|
The Bra (2018) [DONE]
|
||||||
|
The Mule (2018) [DONE]
|
||||||
|
Escape Room (2019) [DONE]
|
||||||
|
Man on a Ledge (2012) [DONE]
|
||||||
|
The Highwaymen (2019) [DONE]
|
||||||
|
Cold War (2018) [*]
|
||||||
|
Cold Pursuit (2019) [DONE]
|
||||||
|
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]
|
||||||
|
Ip Man 4 (2019) [DONE]
|
||||||
|
The Collini Case (2019) [DONE]
|
||||||
|
The Traitor (2019) [DONE]
|
||||||
|
Motherless Brooklyn (2019) [DONE]
|
||||||
|
The Banker (2020) [DONE]
|
||||||
|
The Gentlemen (2019) [DONE]
|
||||||
|
The Platform (2019) [DONE]
|
||||||
|
Radioactive (2019) [DONE]
|
||||||
|
Radium Girls (2018) [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]
|
||||||
|
Another Round (2020) [DONE]
|
||||||
|
Promising Young Woman (2020) [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 <TV Movie> (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]
|
||||||
|
Boite Noire (2021) [DONE]
|
||||||
|
Fresh (2022) [DONE]
|
||||||
|
Death on the Nile (2022) [DONE]
|
||||||
|
All Quiet on the Western Front (2022) [DONE]
|
||||||
|
Triangle of Sadness (2022) [DONE]
|
||||||
|
Jerry and Marge Go Large (2022) [DONE]
|
||||||
|
Fighting With My Family (2019) [DONE]
|
||||||
|
The Woman King (2022) [DONE]
|
||||||
|
Capernaum (2018) [DONE]
|
||||||
|
The Menu (2022) [DONE]
|
||||||
|
Rye Lane (2023) [DONE]
|
||||||
|
Sisu (2022) [DONE]
|
||||||
|
Zodiac (2007) [DONE]
|
||||||
|
Legend (2015) [DONE]
|
||||||
|
Luther The Fallen Sun (2023) [DONE]
|
||||||
|
Mr. Morgan's Last Love (2013) [DONE]
|
||||||
|
Sweet November (2001) [DONE]
|
||||||
|
The Debt (2010) [DONE]
|
||||||
|
Don Jon (2013) [DONE]
|
||||||
|
Nefarious (2023) [DONE]
|
||||||
|
Oppenhaimer (2023) [DONE]
|
||||||
|
No Hard Feelings (2023) [DONE]
|
||||||
|
Powder (1995) [DONE]
|
||||||
|
The Life of David Gale (2003) [DONE]
|
||||||
|
Crazy, Stupid, Love. (2011) [DONE]
|
||||||
|
Before We Go (2014) [DONE]
|
||||||
|
The Banshees of Inisherin (2022) [DONE]
|
||||||
|
Three Thousand Years of Longing (2022) [DONE]
|
||||||
|
Hardcore Henry (2015) [DONE]
|
||||||
|
Chalga (2023) [DONE]
|
||||||
|
Dumb Money (2023) [DONE]
|
||||||
|
Society of the Snow (2023) [DONE]
|
||||||
|
The Aviator's Wife (1981) [*]
|
||||||
|
Past Lives (2023) [DONE]
|
||||||
|
Comandante (2023) [DONE]
|
||||||
|
The Lost Boys (1987) [DONE]
|
||||||
|
Blade Runner (2049) [DONE]
|
||||||
|
The Lunchbox (2013) [DONE]
|
||||||
|
Half Nelson (2006) [DONE]
|
||||||
|
The Dirt (2019) [DONE]
|
||||||
|
Manchester by the Sea (2016) [DONE]
|
||||||
|
The Perks of Being a Wallflower (2012) [DONE]
|
||||||
|
The Ministry of Ungentlemanly Warfare (2024) [DONE]
|
||||||
|
Wings of Desire (1987) [*]
|
||||||
|
Cadillac Records (2008) [DONE]
|
||||||
|
The Substance (2024) [DONE]
|
||||||
|
Don't Look Up (2021) [DONE]
|
||||||
|
La Vie en Rose (2007) [DONE]
|
||||||
|
The Peanut Butter Falcon (2019) [DONE]
|
||||||
|
One Battle After Another (2025) [DONE]
|
||||||
|
The Master and Margarita (2024) [DONE]
|
||||||
|
Woman at War (2018) [DONE]
|
||||||
|
Good Fortune (2025) [DONE]
|
||||||
|
The Age of Disclosure (2025) [*]
|
||||||
|
Evil Does Not Exist (2023) [DONE]
|
||||||
|
Black Cat, White Cat (1998) [DONE]
|
||||||
|
Nuremberg (2025) [DONE]
|
||||||
|
Poor Things (2023) [*]
|
||||||
|
The French Dispatch (2021) [DONE]
|
||||||
|
Sentimental Value (2025) [DONE]
|
||||||
|
28 Years Later: The Bone Temple (2026) [*]
|
||||||
|
Youth (2015) [DONE]
|
||||||
35
proton.sh
Executable file
35
proton.sh
Executable file
@@ -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 $*
|
||||||
|
|
||||||
Reference in New Issue
Block a user