rearange files and updateing files
This commit is contained in:
1 parent
20acb4bc9f
commit
2de2c461e2
28 files changed
+285
-188
No files matched your search
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import webbrowser
|
||||
from twitchAPI.twitch import Twitch
|
||||
from twitchAPI.oauth import UserAuthenticator
|
||||
from twitchAPI.type import AuthScope
|
||||
|
||||
SECRETS_FILE = "twitch_secrets.json"
|
||||
|
||||
def load_credentials():
|
||||
"""Loads existing Client ID and Secret from your JSON file."""
|
||||
if not os.path.exists(SECRETS_FILE):
|
||||
raise FileNotFoundError(f"Could not find {SECRETS_FILE} in this directory.")
|
||||
with open(SECRETS_FILE, "r") as f:
|
||||
data = json.load(f)
|
||||
return data.get("client_id"), data.get("client_secret")
|
||||
|
||||
def save_token_to_json(token):
|
||||
"""Saves the generated token into twitch_secrets.json under 'manual_token'."""
|
||||
with open(SECRETS_FILE, "r") as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Inject the new token
|
||||
data["manual_token"] = token
|
||||
|
||||
with open(SECRETS_FILE, "w") as f:
|
||||
json.dump(data, f, indent=4)
|
||||
print(f"\n[SUCCESS] Token saved inside '{SECRETS_FILE}' under 'manual_token'!")
|
||||
|
||||
async def main():
|
||||
try:
|
||||
client_id, client_secret = load_credentials()
|
||||
if not client_id or not client_secret:
|
||||
print("[ERROR] Please add your client_id and client_secret to the JSON file first.")
|
||||
return
|
||||
|
||||
print("Initializing local connection loop...")
|
||||
# Initialize official Twitch connection interface
|
||||
twitch = await Twitch(client_id, client_secret)
|
||||
|
||||
# Scopes: We leave this empty [] since VOD collection only requires basic public clearance
|
||||
scopes = []
|
||||
|
||||
# Create an authenticator that automatically sets up http://localhost:17563
|
||||
auth = UserAuthenticator(twitch, scopes, url="http://localhost:17563")
|
||||
|
||||
# Request authentication URL
|
||||
auth_url = auth.return_auth_url()
|
||||
print(f"\nIf your browser does not open automatically, copy and paste this URL into your browser:\n{auth_url}\n")
|
||||
|
||||
# Open your system default browser to let you manually click "Authorize"
|
||||
webbrowser.open(auth_url)
|
||||
|
||||
print("Waiting for you to click 'Authorize' in your web browser...")
|
||||
# The script halts here, running a local background server until you click authorize
|
||||
token, refresh_token = await auth.authenticate()
|
||||
|
||||
print(f"\nSuccessfully generated Token: {token}")
|
||||
|
||||
# Save it right back into your configuration file
|
||||
save_token_to_json(token)
|
||||
|
||||
# Gracefully shut down the library connection
|
||||
await twitch.close()
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n[ERROR] An error occurred: {e}")
|
||||
print("Double-check that http://localhost:17563 is added to your Twitch Dev Console.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run the asynchronous loop
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
from datetime import datetime, UTC
|
||||
|
||||
import package.database as database
|
||||
|
||||
DB = None
|
||||
|
||||
def has_no_timezone(dt_string: str) -> bool:
|
||||
try:
|
||||
# fromisoformat parses standard formats like YYYY-MM-DD HH:MM:SS
|
||||
dt = datetime.fromisoformat(dt_string)
|
||||
|
||||
# Check if tzinfo is completely missing OR if its offset is undefined
|
||||
return dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None
|
||||
except ValueError:
|
||||
print(f"Error: '{dt_string}' is not a valid date-time string.")
|
||||
return False
|
||||
|
||||
def fix_time():
|
||||
chats = DB.get_vods()
|
||||
#chats = DB.get_clips()
|
||||
|
||||
for chat in chats:
|
||||
(
|
||||
id,
|
||||
title,
|
||||
created_at,
|
||||
view_count,
|
||||
duration,
|
||||
url,
|
||||
thumbnail_url,
|
||||
game_id,
|
||||
game_name,
|
||||
stream_id,
|
||||
creator_name,
|
||||
clip_is,
|
||||
downloaded,
|
||||
uploaded_yt,
|
||||
uploaded_yt_chats,
|
||||
uploaded_yt_shorts,
|
||||
) = chat
|
||||
|
||||
if "T" in created_at:
|
||||
date_string = created_at.replace("T", " ")
|
||||
DB.update_datetime(id, date_string)
|
||||
|
||||
if has_no_timezone(created_at):
|
||||
dt_with_utc = datetime.fromisoformat(created_at).replace(tzinfo=UTC)
|
||||
date_string = dt_with_utc.isoformat().strftime('%Y-%m-%d %H:%M:%S %z')
|
||||
DB.update_datetime(id, date_string)
|
||||
|
||||
print("====================================================")
|
||||
print(f"✅ Processing: Times Fix.")
|
||||
print("====================================================")
|
||||
|
||||
def main():
|
||||
global DB
|
||||
DB = database.Database()
|
||||
|
||||
fix_time()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
from pathlib import Path
|
||||
|
||||
import package.database as database
|
||||
|
||||
DB = None
|
||||
|
||||
def fix_download():
|
||||
chats = DB.get_undownloaded()
|
||||
#chats = DB.get_clips()
|
||||
|
||||
for chat in chats:
|
||||
(
|
||||
id,
|
||||
title,
|
||||
created_at,
|
||||
view_count,
|
||||
duration,
|
||||
url,
|
||||
thumbnail_url,
|
||||
game_id,
|
||||
game_name,
|
||||
stream_id,
|
||||
creator_name,
|
||||
clip_is,
|
||||
downloaded,
|
||||
uploaded_yt,
|
||||
uploaded_yt_chats,
|
||||
uploaded_yt_shorts,
|
||||
) = chat
|
||||
|
||||
if clip_is:
|
||||
file_name = Path(f"download/clips/{id}/{id}.mp4")
|
||||
else:
|
||||
file_name = Path(f"download/videos/{id}/{id}.mp4")
|
||||
|
||||
if file_name.exists():
|
||||
DB.mark_as_downloaded(id)
|
||||
|
||||
|
||||
print("====================================================")
|
||||
print(f"✅ Processing: download Fix.")
|
||||
print("====================================================")
|
||||
|
||||
def main():
|
||||
global DB
|
||||
DB = database.Database()
|
||||
|
||||
fix_download()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import json
|
||||
import asyncio
|
||||
from pathlib import Path
|
||||
|
||||
import package.database as database
|
||||
import package.twitch.video_info as video_info
|
||||
|
||||
DB = None
|
||||
def format_to_hms(total_seconds):
|
||||
# Calculate hours, minutes, and seconds
|
||||
hours, remainder = divmod(int(total_seconds), 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
|
||||
# Return formatted string: e.g., 4h27m12s
|
||||
return f"{hours}h{minutes}m{seconds}s"
|
||||
|
||||
def read_json(file_path: str):
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as file:
|
||||
data = json.load(file)
|
||||
|
||||
# Extracting streamer info
|
||||
streamer_name = data.get("streamer", {}).get("name")
|
||||
|
||||
# Extracting video core details
|
||||
video_data = data.get("video", {})
|
||||
video_title = video_data.get("title")
|
||||
video_id = video_data.get("id")
|
||||
video_created_at = video_data.get("created_at")
|
||||
video_length_seconds = video_data.get("length")
|
||||
video_views = video_data.get("viewCount")
|
||||
video_game = video_data.get("game")
|
||||
|
||||
# Printing variables to verify
|
||||
print(f"Streamer: {streamer_name}")
|
||||
print(f"Title: {video_title}")
|
||||
print(f"Video ID: {video_id}")
|
||||
print(f"Created At: {video_created_at}")
|
||||
print(f"Duration: {video_length_seconds} seconds")
|
||||
print(f"Views: {video_views}")
|
||||
print(f"Game: {video_game}")
|
||||
|
||||
video_length = format_to_hms(video_length_seconds)
|
||||
|
||||
game_id = asyncio.run(video_info.get_game_id_by_name(video_game))
|
||||
|
||||
DB.insert_video_record(
|
||||
video_id,
|
||||
video_title,
|
||||
video_created_at,
|
||||
int(video_views),
|
||||
video_length,
|
||||
"",
|
||||
"",
|
||||
game_id,
|
||||
video_game,
|
||||
"",
|
||||
"",
|
||||
False
|
||||
)
|
||||
|
||||
id = video_id
|
||||
|
||||
source = Path(f"download/saveold/{id}")
|
||||
destination = Path(f"download/videos/{id}")
|
||||
|
||||
if source.exists() and source.is_dir():
|
||||
source.rename(destination)
|
||||
print("====================================================")
|
||||
print(f"🚀 VOD to moved: {video_title}")
|
||||
print("====================================================")
|
||||
|
||||
except FileNotFoundError:
|
||||
print(f"Error: The file at {file_path} was not found.")
|
||||
except json.JSONDecodeError:
|
||||
print(
|
||||
"Error: Failed to parse JSON. Make sure trailing cut-off text is removed."
|
||||
)
|
||||
|
||||
def main():
|
||||
global DB
|
||||
DB = database.Database()
|
||||
|
||||
|
||||
|
||||
# Set the path of the directory you want to walk through
|
||||
# Use "." for the current folder, or a full path like "C:/Users/Name/Documents"
|
||||
root_directory = "./download/saveold"
|
||||
|
||||
# os.walk yields a 3-item tuple for every single folder it finds
|
||||
for current_folder, subfolders, files in os.walk(root_directory):
|
||||
|
||||
print(f"\n📂 Current Folder: {current_folder}")
|
||||
|
||||
# List all subfolders inside the current folder
|
||||
if subfolders:
|
||||
print(f" 📁 Subfolders found: {', '.join(subfolders)}")
|
||||
|
||||
# List all files inside the current folder
|
||||
for file_name in files:
|
||||
# Construct the full absolute or relative path to the file
|
||||
full_file_path = os.path.join(current_folder, file_name)
|
||||
print(f" 📄 File: {file_name} ({full_file_path})")
|
||||
|
||||
if file_name.endswith(".json"):
|
||||
read_json(full_file_path)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
import sqlite3
|
||||
|
||||
# Connect to your database file
|
||||
db_name = "database.db" # Change to your actual file name
|
||||
conn = sqlite3.connect(db_name)
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
# 1. Create a temporary table with the new text-based game_id
|
||||
cursor.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS twitch_videos_temp (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
view_count INTEGER NOT NULL,
|
||||
duration TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
thumbnail_url TEXT NOT NULL,
|
||||
game_id TEXT NOT NULL,
|
||||
game_name TEXT NOT NULL,
|
||||
stream_id TEXT NOT NULL,
|
||||
creator_name TEXT NOT NULL,
|
||||
clip_is BOOLEAN NOT NULL DEFAULT 0,
|
||||
downloaded BOOLEAN NOT NULL DEFAULT 0,
|
||||
uploaded_yt BOOLEAN NOT NULL DEFAULT 0,
|
||||
uploaded_yt_chats BOOLEAN NOT NULL DEFAULT 0,
|
||||
uploaded_yt_shorts BOOLEAN NOT NULL DEFAULT 0
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
# 2. Copy and convert data to the temporary table
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO twitch_videos_temp (
|
||||
id, title, created_at, view_count, duration, url, thumbnail_url,
|
||||
game_id, game_name, stream_id, creator_name, clip_is, downloaded,
|
||||
uploaded_yt, uploaded_yt_chats, uploaded_yt_shorts
|
||||
)
|
||||
SELECT
|
||||
id, title, created_at, view_count, duration, url, thumbnail_url,
|
||||
CAST(game_id AS TEXT), game_name, stream_id, creator_name, clip_is, downloaded,
|
||||
uploaded_yt, uploaded_yt_chats, uploaded_yt_shorts
|
||||
FROM twitch_videos
|
||||
"""
|
||||
)
|
||||
|
||||
# 3. Drop the old table configuration
|
||||
cursor.execute("DROP TABLE twitch_videos")
|
||||
|
||||
# 4. Rename the temporary table to your exact original table name
|
||||
cursor.execute("ALTER TABLE twitch_videos_temp RENAME TO twitch_videos")
|
||||
|
||||
# Commit changes if everything succeeded
|
||||
conn.commit()
|
||||
print("Migration successful! 'twitch_videos' table updated.")
|
||||
|
||||
except sqlite3.Error as e:
|
||||
# Roll back changes if an error occurs
|
||||
conn.rollback()
|
||||
print(f"An error occurred: {e}")
|
||||
|
||||
finally:
|
||||
# Close database connection
|
||||
conn.close()
|
||||
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python3
|
||||
import package.database as database
|
||||
from pathlib import Path
|
||||
|
||||
DB = None
|
||||
|
||||
def remove_vods():
|
||||
chats = DB.get_vods()
|
||||
#chats = DB.get_clips()
|
||||
|
||||
for chat in chats:
|
||||
(
|
||||
id,
|
||||
title,
|
||||
created_at,
|
||||
view_count,
|
||||
duration,
|
||||
url,
|
||||
thumbnail_url,
|
||||
game_id,
|
||||
game_name,
|
||||
stream_id,
|
||||
creator_name,
|
||||
clip_is,
|
||||
downloaded,
|
||||
uploaded_yt,
|
||||
uploaded_yt_chats,
|
||||
uploaded_yt_shorts,
|
||||
) = chat
|
||||
|
||||
#shutil.rmtree(f"", ignore_errors=True)
|
||||
|
||||
if clip_is:
|
||||
source = Path(f"../saveoldold/clips/{id}")
|
||||
destination = Path(f"../savedup/clips/{id}")
|
||||
else:
|
||||
source = Path(f"../saveoldold/{id}")
|
||||
destination = Path(f"../savedup/{id}")
|
||||
|
||||
if source.exists() and source.is_dir():
|
||||
source.rename(destination)
|
||||
print("====================================================")
|
||||
print(f"🚀 VOD to remove: {title}")
|
||||
print("====================================================")
|
||||
|
||||
print("====================================================")
|
||||
print(f"✅ Processing: VOD removal Done.")
|
||||
print("====================================================")
|
||||
|
||||
def main():
|
||||
global DB
|
||||
DB = database.Database()
|
||||
|
||||
remove_vods()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python3
|
||||
import package.database as database
|
||||
|
||||
DB = None
|
||||
|
||||
def redownload_clips():
|
||||
clips = DB.get_clips()
|
||||
|
||||
for clip in clips:
|
||||
# Unpack variables clearly
|
||||
(
|
||||
id,
|
||||
title,
|
||||
created_at,
|
||||
view_count,
|
||||
duration,
|
||||
url,
|
||||
thumbnail_url,
|
||||
game_id,
|
||||
game_name,
|
||||
stream_id,
|
||||
creator_name,
|
||||
clip_is,
|
||||
downloaded,
|
||||
uploaded_yt,
|
||||
uploaded_yt_chats,
|
||||
uploaded_yt_shorts,
|
||||
) = clip
|
||||
|
||||
DB.unmark_as_download(id)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
DB = database.Database()
|
||||
redownload_clips()
|
||||
@@ -0,0 +1,72 @@
|
||||
import os
|
||||
|
||||
import package.database as database
|
||||
|
||||
DB = None
|
||||
|
||||
def remove_files():
|
||||
datas = DB.get_download()
|
||||
|
||||
top_txt = "TeamPGP Live on Twitch...\n Every Friday and Sunday @7:30 ET.\n twitch.tv/teampgp"
|
||||
|
||||
for data in datas:
|
||||
(
|
||||
id,
|
||||
title,
|
||||
created_at,
|
||||
view_count,
|
||||
duration,
|
||||
url,
|
||||
thumbnail_url,
|
||||
game_id,
|
||||
game_name,
|
||||
stream_id,
|
||||
creator_name,
|
||||
clip_is,
|
||||
downloaded,
|
||||
uploaded_yt,
|
||||
uploaded_yt_chats,
|
||||
uploaded_yt_shorts,
|
||||
) = data
|
||||
|
||||
if clip_is == 0:
|
||||
video_path = f"download/videos/{id}/{id}.mp4"
|
||||
else:
|
||||
video_path = f"download/clips/{id}/{id}.mp4"
|
||||
|
||||
temp_chat = video_path.replace(".mp4", "_temp_chat.mp4")
|
||||
temp_with_chat = video_path.replace(".mp4", "_temp_with_chat.mp4")
|
||||
video_chat = video_path.replace(".mp4", "_with_chat.mp4")
|
||||
video_chatSS = video_path.replace(".mp4", "_SS_with_chat.mp4")
|
||||
video_chat_over = video_path.replace(".mp4", "_over_with_chat.mp4")
|
||||
mask_path = video_path.replace(".mp4", "_temp_chat_mask.mp4")
|
||||
|
||||
shorts_gaussian_9_16 = ""#video_path.replace(".mp4", "_gaussian_9_16.mp4")
|
||||
shorts_9_16 = ""#video_path.replace(".mp4", "_9_16.mp4")
|
||||
|
||||
srt_file = ""#video_path.replace(".mp4", ".srt")
|
||||
|
||||
|
||||
files = [temp_chat, temp_with_chat, video_chatSS, video_chat_over, mask_path, shorts_gaussian_9_16, shorts_9_16, srt_file, video_chat]
|
||||
|
||||
for file in files:
|
||||
if os.path.exists(file):
|
||||
if file == video_path:
|
||||
print("❌ Error: trying to delete import file.")
|
||||
return
|
||||
else:
|
||||
os.remove(file)
|
||||
|
||||
def redownload():
|
||||
DB.unmark_as_download("2840110867")
|
||||
|
||||
|
||||
def main():
|
||||
global DB
|
||||
DB = database.Database()
|
||||
|
||||
remove_files()
|
||||
redownload()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user