TwitchDownloader/twitch-archive.py

308 lines
24 KiB
Python
Raw Normal View History

2022-12-15 13:14:44 -05:00
import requests, os, time, json, sys, subprocess, getopt, smtplib, pathlib, socket
2022-12-06 10:52:44 -05:00
from colorama import Fore, Style
2022-12-05 11:21:39 -05:00
from datetime import datetime, timedelta
2022-12-03 08:57:56 -05:00
from pytz import timezone
from dotenv import load_dotenv, find_dotenv
2022-12-05 11:21:39 -05:00
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
2022-12-03 08:57:56 -05:00
class TwitchArchive:
def __init__(self):
# user configuration
2023-02-19 17:03:49 -05:00
self.username = "dogzilar123" # Twitch streamer username
self.quality = "best" # Qualities options: best/source high/720p medium/540p low/360p audio_only
2022-12-03 08:57:56 -05:00
# global configuration
self.root_path = r"archive" # Path where this script saves everything (livestream,VODs,chat,metadata)
2022-12-15 13:14:44 -05:00
self.rclone_path = "remote:path" # Path to rclone remote storage
2022-12-09 06:10:02 -05:00
self.refresh = 5.0 # Time between checking (5.0 is recommended), avoid less than 1.0
2022-12-16 09:48:28 -05:00
self.streamlink_ttvlol = 0 # 0 - disable blocking ads with ttvlol, 1 - enable blocking ads with ttvlol, Uses this repo: https://github.com/2bc4/streamlink-ttvlol to block ads with ttvlol. Follows the steps on the repo to enable it.
2022-12-15 13:14:44 -05:00
self.notifications = 0 # 0 - disable email notification of current seccion, 1 - enable email notification of current seccion
2022-12-03 08:57:56 -05:00
self.downloadMETADATA = 1 # 0 - disable metadata downloading, 1 - enable metadata downloading
self.downloadVOD = 1 # 0 - disable VOD downloading after stream finished, 1 - enable VOD downloading after stream finished (this option downloads the latest public vod)
self.downloadCHAT = 1 # 0 - disable chat downloading and rendering, 1 - enable chat downloading and rendering
2022-12-15 13:29:18 -05:00
self.uploadCloud = 0 # 0 - disable upload to remote cloud, 1 - enable upload to remote cloud
2022-12-15 13:14:44 -05:00
self.deleteFiles = 0 # 0 - disable the deleting of files from current seccion after being uploaded to the cloud, 1 - enable the deleting files of files from current seccion after being uploaded to the cloud (BE CAREFUL WITH THIS OPTION)
2022-12-16 09:48:28 -05:00
self.onlyRaw = 0 # 0 - disable the converting of ts files to mp3/mp4, 1 - enable the converting of ts files to mp3/mp4 (only works for recording, the vod will still be downloaded to mp3/mp4)
self.cleanRaw = 0 # 0 - disable the deleting of raw (.ts) files, 1 - enable the deleteing of raw (.ts) files (if upload enable they will be deleted before)
2022-12-03 08:57:56 -05:00
self.hls_segments = 3 # 1-10 for live stream, it's possible to use multiple threads to potentially increase the throughput. 2-3 is enough
self.hls_segmentsVOD = 10 # 1-10 for downloading vod, it's possible to use multiple threads to potentially increase the throughput
2022-12-09 06:10:02 -05:00
def run(self):
2022-12-09 15:06:59 -05:00
self.os = self.get_OS()
2022-12-15 13:14:44 -05:00
if load_dotenv(find_dotenv()): load_dotenv(find_dotenv())
else:
print(f'{Fore.RED}\033[1mCREATE .env file with variables{Style.RESET_ALL}')
quit()
self.correct_user()
2022-12-03 08:57:56 -05:00
print('Twitch-Archive')
print('Configuration:')
2022-12-05 11:21:39 -05:00
print(f'Root path: {Fore.GREEN}' + str(pathlib.Path(self.root_path).resolve()) + f'{Style.RESET_ALL}')
2022-12-03 08:57:56 -05:00
print(f'Refresh rate: {Fore.GREEN} {str(self.refresh)}{Style.RESET_ALL}')
if self.notifications == 1: print(f'Email notifications: {Fore.GREEN}Enabled{Style.RESET_ALL}')
else: print(f'Email notifications: {Fore.RED}Disabled{Style.RESET_ALL}')
if self.downloadMETADATA == 1: print(f'Metada downloading {Fore.GREEN}Enabled{Style.RESET_ALL}')
else: print(f'Metada downloading: {Fore.RED}Disabled{Style.RESET_ALL}')
if self.downloadVOD == 1: print(f'VOD downloading {Fore.GREEN}Enabled{Style.RESET_ALL}')
else: print(f'VOD downloading: {Fore.RED}Disabled{Style.RESET_ALL}')
if self.downloadCHAT == 1: print(f'Chat downloading {Fore.GREEN}Enabled{Style.RESET_ALL}')
else: print(f'Chat downloading: {Fore.RED}Disabled{Style.RESET_ALL}')
2022-12-09 06:10:02 -05:00
if self.uploadCloud == 1: print(f'Upload to cloud storage: {Fore.GREEN}Enabled{Style.RESET_ALL}')
else: print(f'Upload to cloud storage: {Fore.RED}Disabled{Style.RESET_ALL}')
2022-12-03 08:57:56 -05:00
if self.deleteFiles == 1: print(f'{Fore.RED}'+'\033[1m'+f'CAREFUL FILES ARE CONFIGURATED TO BE DELETED{Style.RESET_ALL}')
2022-12-05 11:21:39 -05:00
else: print(f'{Fore.GREEN}'+'\033[1m'+f'Files will NOT be deleted{Style.RESET_ALL}')
2022-12-03 08:57:56 -05:00
if self.uploadCloud == 0 and self.deleteFiles == 1: print(f'{Fore.RED}'+'\033[1m'+f'FILES WILL BE DELETED AND NO UPLOADED {Style.RESET_ALL}{Fore.GREEN}\n"CTRL + C"{Style.RESET_ALL}{Fore.RED}'+'\033[1m'+f' TO STOP AND CHANGED CONFIGURATION{Style.RESET_ALL}')
2022-12-06 10:52:44 -05:00
2022-12-09 06:10:02 -05:00
self.raw_path = str(pathlib.Path(os.path.join(self.root_path,self.username,"video", "raw")).absolute())
self.video_path = str(pathlib.Path(os.path.join(self.root_path, self.username, "video")).absolute())
2022-12-06 10:52:44 -05:00
self.chatJSON_path = str(pathlib.Path(os.path.join(self.root_path, self.username, "chat", "json")).absolute())
2022-12-09 06:10:02 -05:00
self.chatMP4_path = str(pathlib.Path(os.path.join(self.root_path, self.username, "chat")).absolute())
2022-12-06 10:52:44 -05:00
self.metadata_path = str(pathlib.Path(os.path.join(self.root_path, self.username, "metadata")).absolute())
2022-12-03 08:57:56 -05:00
2022-12-09 06:10:02 -05:00
if(os.path.isdir(self.raw_path) is False): os.makedirs(self.raw_path)
if(os.path.isdir(self.video_path) is False): os.makedirs(self.video_path)
2022-12-03 08:57:56 -05:00
if(os.path.isdir(self.chatJSON_path) is False): os.makedirs(self.chatJSON_path)
if(os.path.isdir(self.chatMP4_path) is False): os.makedirs(self.chatMP4_path)
if(os.path.isdir(self.metadata_path) is False): os.makedirs(self.metadata_path)
2022-12-15 13:14:44 -05:00
if not os.path.exists(os.path.join(self.root_path, ".log")):
2022-12-09 06:10:02 -05:00
with open(os.path.join(self.root_path, ".log"), 'w'): pass
2022-12-03 08:57:56 -05:00
print(f"Checking for {Fore.GREEN}{self.username}{Style.RESET_ALL} every {Fore.GREEN}{self.refresh}{Style.RESET_ALL} seconds. Record with {Fore.GREEN}{self.quality}{Style.RESET_ALL} quality.")
self.sendNotif("TWITCH ARCHIVE", f"Checking for {self.username} every {self.refresh} seconds. Record with {self.quality} quality.")
self.loopcheck()
2022-12-06 10:52:44 -05:00
2022-12-09 06:10:02 -05:00
def get_OS(self):
if sys.platform.startswith('win32'):
2022-12-09 15:06:59 -05:00
return 'windows'
2022-12-09 06:10:02 -05:00
elif sys.platform.startswith('linux'):
2022-12-09 15:06:59 -05:00
return 'linux'
2022-12-09 06:10:02 -05:00
else:
2022-12-15 13:14:44 -05:00
print(f'{Fore.RED}\033[1mOS no supported{Style.RESET_ALL}')
quit()
2022-12-09 06:10:02 -05:00
2022-12-15 13:14:44 -05:00
def get_oauth_token(self):
try:
return requests.post(f"https://id.twitch.tv/oauth2/token?client_id={os.getenv('CLIENT-ID')}&client_secret={os.getenv('CLIENT-SECRET')}&grant_type=client_credentials").json()['access_token']
except:
print(f'{Fore.RED}\033[1mCheck your client-id and secret{Style.RESET_ALL}')
quit()
def correct_user(self):
try:
url = f'https://api.twitch.tv/helix/users?login={self.username}'
response = requests.get(url,headers = {"Authorization" : "Bearer " + self.get_oauth_token(), "Client-ID": os.getenv('CLIENT-ID')}, timeout = 15).json()
if response['data'] == []:
print(f'{Fore.RED}\033[1mUse a correct username{Style.RESET_ALL}')
quit()
except requests.exceptions.RequestException as e:
print(e)
2022-12-03 08:57:56 -05:00
def check_user(self):
2022-12-15 13:14:44 -05:00
query = 'query{user(login: "' + self.username + '") {stream{archiveVideo{id}title createdAt}}}'
try:
response = requests.post('https://gql.twitch.tv/gql',json={'query': query},headers={"Client-ID": "kimne78kx3ncx6brgo4mv6wki5h1ko"})
return json.loads(response.text)
except requests.exceptions.RequestException as e:
print(e)
quit()
2022-12-11 10:09:52 -05:00
def get_vod(self):
2022-12-15 13:14:44 -05:00
query = 'query {user(login: "' + self.username + '") {videos(first: 1) {edges {node {id title description recordedAt lengthSeconds animatedPreviewURL previewThumbnailURL(height: 1280, width: 720) thumbnailURLs(height: 1280, width: 720)}}}}}'
try:
response = requests.post('https://gql.twitch.tv/gql', json={'query': query}, headers={"Client-ID": "kimne78kx3ncx6brgo4mv6wki5h1ko"})
return json.loads(response.text)
except requests.exceptions.RequestException as e:
print(e)
2022-12-03 08:57:56 -05:00
def sendNotif(self, subject, content):
if self.notifications == 1:
2022-12-15 13:14:44 -05:00
try:
sender = os.getenv("SENDER")
receiver = os.getenv("RECEIVER")
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = self.username + " _ " + subject
body = "Current seccion is for " + self.username + "\n\n\n\n" + content
msg.attach(MIMEText((body), 'plain'))
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(sender, os.getenv("PASSWD"))
txt = msg.as_string()
server.sendmail(sender, receiver, txt)
server.quit()
except socket.error as e:
print(e)
2022-12-06 10:52:44 -05:00
2022-12-03 08:57:56 -05:00
def loopcheck(self):
while True:
2022-12-11 10:09:52 -05:00
is_live = self.check_user()['data']['user']['stream']
if is_live is not None:
is_live_ready = self.check_user()['data']['user']['stream']['title']
if is_live_ready is not None:
2022-12-15 13:14:44 -05:00
bin_path = str(pathlib.Path(__file__).parent.resolve())+"/bin"
2022-12-11 10:09:52 -05:00
live_date = datetime.strptime(is_live["createdAt"],'%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone('UTC')).astimezone(tz=None).replace(tzinfo=None)
2022-12-15 13:14:44 -05:00
live_raw_filename = datetime.strftime(live_date,'%Y%m%d_%Hh%Mm%Ss')
2022-12-11 10:09:52 -05:00
live_raw_path = os.path.join(self.raw_path, "LIVE_" + live_raw_filename + ".ts")
live_proc_path = os.path.join(self.video_path, "LIVE_" + live_raw_filename + ".mp4")
2022-12-15 13:14:44 -05:00
with open(os.path.join(self.root_path, ".log"), encoding="utf-8") as logs:
2022-12-11 10:09:52 -05:00
logs = logs.read()
log_id = is_live["createdAt"] + " - " + self.username + " - " + is_live["title"]
if log_id in logs:
time.sleep(self.refresh)
2022-12-09 06:10:02 -05:00
2022-12-15 13:14:44 -05:00
with open(os.path.join(self.root_path, ".log"), "r+", encoding="utf-8") as logs:
2022-12-11 10:09:52 -05:00
log_id = is_live["createdAt"] + " - " + self.username + " - " + is_live["title"]
for line in logs:
if log_id in line:
2022-12-16 09:48:28 -05:00
time.sleep(self.refresh)
2022-12-11 10:09:52 -05:00
else:
logs.write(is_live["createdAt"] + " - " + self.username + " - " + is_live["title"] +"\n")
2022-12-16 09:48:28 -05:00
if self.streamlink_ttvlol == 1:ttvlol = ['--twitch-proxy-playlist=https://api.ttv.lol']
else: ttvlol = ''.split()
if self.quality == 'audio_only':
live_proc_path = os.path.join(self.video_path, "LIVE_" + live_raw_filename + ".mp3")
2023-02-19 17:03:49 -05:00
if (os.getenv("OAUTH-PRIVATE-TOKEN") != "" or os.getenv("OAUTH-PRIVATE-TOKEN") is not None or os.getenv("OAUTH-PRIVATE-TOKEN") != "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"):
auth = ['--twitch-api-header', 'Authorization=OAuth ' + os.getenv('OAUTH-PRIVATE-TOKEN')]
else: auth = ''.split()
2022-12-11 10:09:52 -05:00
self.sendNotif('Stream - ' + live_raw_filename, 'Streamer went live: ' + is_live["title"])
2023-02-19 17:03:49 -05:00
subprocess.call(['streamlink', 'twitch.tv/'+ self.username, self.quality, '--hls-segment-threads', str(self.hls_segments), '--hls-live-restart', '--retry-streams', str(self.refresh), '--twitch-disable-reruns', '-o', live_raw_path] + ttvlol + auth)
2022-12-16 09:48:28 -05:00
if(os.path.exists(live_raw_path) is True and self.onlyRaw == 0):
ffmpeg_settings = ['-y', '-i', live_raw_path, '-analyzeduration', '2147483647', '-probesize', '2147483647', '-c:v', 'copy', '-c:a', 'copy', '-start_at_zero', '-copyts', live_proc_path]
if self.quality == 'audio_only': ffmpeg_settings = ['-i', live_raw_path, '-vn', '-ar', '44100', '-ac', '2', '-b:a', '192k', live_proc_path]
if self.os == 'windows': subprocess.call([str(pathlib.Path(__file__).parent.resolve())+'/bin/ffmpeg.exe']+ ffmpeg_settings, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
elif self.os == 'linux': subprocess.call([str(pathlib.Path(__file__).parent.resolve())+'/bin/ffmpeg']+ ffmpeg_settings, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
2022-12-11 10:09:52 -05:00
else:
print("Skip fixing. File not found.")
current_vod = self.get_vod()['data']['user']['videos']['edges'][0]['node']
live_date_min = live_date - timedelta(minutes=1)
live_date_max = live_date + timedelta(minutes=1)
vod_date = datetime.strptime(current_vod["recordedAt"],'%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone('UTC')).astimezone(tz=None).replace(tzinfo=None)
2022-12-09 06:10:02 -05:00
2022-12-11 10:09:52 -05:00
if live_date_min <= vod_date <= live_date_max:
vod_proc_path = os.path.join(self.video_path, "VOD_" + live_raw_filename + ".mp4")
2022-12-16 09:48:28 -05:00
chat_json_path = os.path.join(self.chatJSON_path, "CHAT_" + live_raw_filename + ".json")
chat_video_path = os.path.join(self.chatMP4_path, "CHAT_" + live_raw_filename + ".mp4")
2022-12-11 10:09:52 -05:00
if self.downloadMETADATA == 1:
self.sendNotif('Metadata - ' + live_raw_filename,'Downloading and saving metadata:\n' + json.dumps(current_vod, indent=4))
with open(os.path.join(self.metadata_path, "METADA_" + live_raw_filename + ".json"), 'w', encoding='utf-8') as f:
json.dump(current_vod, f, ensure_ascii=False, indent=4)
2022-12-09 06:10:02 -05:00
2022-12-16 09:48:28 -05:00
if self.quality == 'audio_only':
vod_proc_path = os.path.join(self.video_path, "VOD_" + live_raw_filename + ".mp3")
2022-12-11 10:09:52 -05:00
if self.downloadVOD == 1:
print('Downloading VOD: ' + current_vod["title"])
self.sendNotif('VOD - ' + live_raw_filename,'Downloading VOD: ' + current_vod["title"])
try:
2022-12-15 13:14:44 -05:00
if self.os == 'windows':subprocess.call([bin_path+"/TwitchDownloaderCLI.exe", 'videoDownload', '-u', str(current_vod["id"]), '-q', self.quality, "-t", str(self.hls_segmentsVOD), "--ffmpeg-path", bin_path +"/ffmpeg.exe", '--temp-path', bin_path+"/temp", "-o", vod_proc_path])
elif self.os == 'linux':subprocess.call([bin_path+"/TwitchDownloaderCLI", 'videoDownload', '-u', str(current_vod["id"]), '-q', self.quality, "-t", str(self.hls_segmentsVOD), "--ffmpeg-path", bin_path +"/ffmpeg.exe", '--temp-path', bin_path+"/temp", "-o", vod_proc_path])
2022-12-11 10:09:52 -05:00
except Exception as e:
print('Error', 'A ERROR has ocurred and the VOD will not be downloaded.\n')
self.sendNotif('ERROR - ' + live_raw_filename, 'A ERROR has ocurred and the VOD will not be downloaded.\n')
if self.downloadCHAT == 1:
print('Downloading and rendering CHAT: ' + current_vod["title"])
self.sendNotif('CHAT - ' + live_raw_filename,'Downloading JSON and rendering chat logs from VOD:\n' + current_vod["title"])
2022-12-15 13:14:44 -05:00
chat_settings = ["--background-color", "#FF111111", "-w", "500", "-h", "1080", "--outline", "true", "-f", "Arial", "--font-size", "22", "--update-rate", "1.0", "--offline", "--ffmpeg-path", f"{bin_path}/ffmpeg.exe", "--temp-path", f"{bin_path}/temp"]
2022-12-11 10:09:52 -05:00
try:
2022-12-15 13:14:44 -05:00
if self.os == 'windows':
subprocess.call([bin_path + '/TwitchDownloaderCLI.exe', 'chatdownload', '--id', current_vod["id"], '-o', chat_json_path, '-E'])
print('Rendering CHAT: ' + current_vod["title"])
subprocess.call([bin_path + '/TwitchDownloaderCLI.exe', 'chatrender', '-i', chat_json_path, '-o', chat_video_path] + chat_settings)
elif self.os == 'linux':
subprocess.call([bin_path + '/TwitchDownloaderCLI', 'chatdownload', '--id', current_vod["id"], '-o', chat_json_path, '-E'])
subprocess.call([bin_path + '/TwitchDownloaderCLI', 'chatrender', '-i', chat_json_path, '-o', chat_video_path] + chat_settings)
2022-12-11 10:09:52 -05:00
except Exception as e:
self.sendNotif('ERROR - ' + live_raw_filename, "A ERROR has ocurred and chat will need to be downloaded and rendered manually.\n")
print("A ERROR has ocurred and chat will need to be downloaded and rendered manually\n")
else:
print('not VOD associated with stream found')
if self.cleanRaw == 1:
print('Deleting raw files')
if(os.path.exists(live_raw_path) is True): os.remove(live_raw_path)
if self.uploadCloud == 1:
with open(str(pathlib.Path(__file__).parent.resolve())+"/bin/temp/upload.txt", "a") as myfile:
myfile.write("LIVE_" + live_raw_filename + ".ts\n"+"VOD_" + live_raw_filename + ".ts\n"+"LIVE_" + live_raw_filename + ".mp4\n"+"VOD_" + live_raw_filename + ".mp4\n"+"METADATA_" + live_raw_filename + ".json\n"+"CHAT_" + live_raw_filename + ".json\n"+"CHAT_" + live_raw_filename + ".mp4\n")
print('Uploading files')
self.sendNotif("UPLOADING - " + live_raw_filename, 'The files are being uploaded')
2022-12-15 13:14:44 -05:00
subprocess.call(['rclone', 'copy', str(pathlib.Path(self.root_path).resolve()), self.rclone_path, '--include-from', bin_path + '/temp/upload.txt'])
2022-12-11 10:09:52 -05:00
os.remove(str(pathlib.Path(__file__).parent.resolve())+"/bin/temp/upload.txt")
if self.deleteFiles == 1:
self.sendNotif("DELETING - " + live_raw_filename, "Deleting the files from current seccion.")
print(f'{Fore.RED}DELETING FILES{Style.RESET_ALL}')
if self.cleanRaw == 0:
print(f'{Fore.RED}Deleting ' + live_raw_path + f'{Style.RESET_ALL}')
os.remove(live_raw_path)
print(f'{Fore.RED}Deleting ' + live_proc_path + f'{Style.RESET_ALL}')
os.remove(live_proc_path)
if self.downloadVOD == 1:
if(os.path.exists(os.path.join(self.raw_path, "VOD_" + live_raw_filename + ".ts")) is True):
if self.cleanRaw == 0:
print(f'{Fore.RED}Deleting ' + os.path.join(self.raw_path, "VOD_" + live_raw_filename + ".ts") + f'{Style.RESET_ALL}')
os.remove(os.path.join(self.raw_path, "VOD_" + live_raw_filename + ".ts"))
if(os.path.exists(os.path.join(self.video_path, "VOD_" + live_raw_filename + ".mp4")) is True):
print(f'{Fore.RED}Deleting ' + os.path.join(self.video_path, "VOD_" + live_raw_filename + ".mp4") + f'{Style.RESET_ALL}')
os.remove(os.path.join(self.video_path, "VOD_" + live_raw_filename + ".mp4"))
if self.downloadCHAT == 1:
if(os.path.exists(os.path.join(self.chatJSON_path, "CHAT_"+live_raw_filename + ".json")) is True):
print(f'{Fore.RED}Deleting ' + os.path.join(self.chatJSON_path, "CHAT_"+live_raw_filename + ".json") + f'{Style.RESET_ALL}')
os.remove(os.path.join(self.chatJSON_path, "CHAT_"+live_raw_filename + ".json"))
if(os.path.exists(os.path.join(self.chatMP4_path, "CHAT_"+live_raw_filename + ".mp4")) is True):
print(f'{Fore.RED}Deleting ' + os.path.join(self.chatMP4_path, "CHAT_"+live_raw_filename + ".mp4") + f'{Style.RESET_ALL}')
os.remove(os.path.join(self.chatMP4_path, "CHAT_"+live_raw_filename + ".mp4"))
if self.downloadMETADATA == 1:
if(os.path.exists(os.path.join(self.metadata_path, "METADA_"+live_raw_filename+".json")) is True):
print(f'{Fore.RED}Deleting ' + os.path.join(self.metadata_path, "METADA_"+live_raw_filename+".json") + f'{Style.RESET_ALL}')
os.remove(os.path.join(self.metadata_path, "METADA_"+live_raw_filename+".json"))
print('CURRENT SECCION HAVE FINISHED GOING BACK TO CHECKING')
self.sendNotif("SECCION DONE - " + live_raw_filename, 'CURRENT SECCION HAVE FINISHED GOING BACK TO CHECKING')
time.sleep(self.refresh)
else: time.sleep(self.refresh)
else: time.sleep(self.refresh)
2022-12-03 08:57:56 -05:00
def main(argv):
2022-12-09 06:10:02 -05:00
twitch_archive = TwitchArchive()
2022-12-16 09:48:28 -05:00
help_msg = '''
Twitch-Archive
Python script to record twitch live stream, download the VOD, metadata, chat and render it, and uploads them to any cloud storage.
-h, --help Display this information
-u, --username <username> Twitch channel username
-q, --quality <quality> best/source high/720p medium/480p worst/360p
-a, --ttv-lol <1/0> Block ads with ttv-lol https://github.com/2bc4/streamlink-ttvlol
-v, --vod <1/0> Download vod
-c, --chat <1/0> Download chat and render it
-m, --metadata <1/0> Download metadata
-r, --upload <1/0> Upload to cloud storage
-d, --delete <1/0> Delete all files after upload (CAREFUL with this arg)
-n, --notifications <1/0> Receive email notification of the proccess through gmail
'''
2022-12-03 08:57:56 -05:00
try:
2022-12-09 06:10:02 -05:00
opts, args = getopt.getopt(argv,"h:u:q:v:c:m:r:d:n",["username=","quality=","vod=","chat=","metadata=","upload=","delete=","notifications="])
2022-12-03 08:57:56 -05:00
except getopt.GetoptError:
2022-12-09 06:10:02 -05:00
print (help_msg)
2022-12-03 08:57:56 -05:00
sys.exit(2)
for opt, arg in opts:
2022-12-09 06:10:02 -05:00
if opt in ('-h', '--help'):
print(help_msg)
2022-12-03 08:57:56 -05:00
sys.exit()
2022-12-09 06:10:02 -05:00
elif opt in ("-u", "--username"): twitch_archive.username = arg
elif opt in ("-q", "--quality"): twitch_archive.quality = arg
2022-12-16 09:48:28 -05:00
elif opt in ("-a", "--ttv-lol"): twitch_archive.streamlink_ttvlol = int(arg)
2022-12-09 18:21:59 -05:00
elif opt in ("-v", "--vod"): twitch_archive.downloadVOD = int(arg)
elif opt in ("-c", "--chat"): twitch_archive.downloadCHAT = int(arg)
elif opt in ("-m", "--metadata"): twitch_archive.downloadMETADATA = int(arg)
elif opt in ("-r", "--upload"): twitch_archive.uploadCloud = int(arg)
elif opt in ("-d", "--delete"): twitch_archive.deleteFiles = int(arg)
elif opt in ("-n", "--notifications"): twitch_archive.notifications = int(arg)
2022-12-09 06:10:02 -05:00
twitch_archive.run()
2022-12-03 08:57:56 -05:00
if __name__ == "__main__":
2022-12-06 10:52:44 -05:00
main(sys.argv[1:])