169 lines
5.0 KiB
Python
169 lines
5.0 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import json
|
|
import urllib.request
|
|
import urllib.error
|
|
from typing import Dict, Set, Any
|
|
from pathlib import Path
|
|
|
|
API_URL = "https://library.cufiy.net/api/modules.min.json"
|
|
INDEX_FILE = "index.json"
|
|
AUTHOR_TO_SYNC = "50/50"
|
|
|
|
|
|
def fetch_api_data() -> list:
|
|
try:
|
|
print(f"Fetching data from {API_URL}")
|
|
req = urllib.request.Request(
|
|
API_URL,
|
|
headers={
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
|
|
}
|
|
)
|
|
with urllib.request.urlopen(req) as response:
|
|
data = json.loads(response.read().decode('utf-8'))
|
|
print(f"Successfully fetched {len(data)} modules from API")
|
|
return data
|
|
except urllib.error.URLError as e:
|
|
print(f"Error fetching API data: {e}")
|
|
raise
|
|
except json.JSONDecodeError as e:
|
|
print(f"Error parsing API response: {e}")
|
|
raise
|
|
|
|
|
|
def extract_manifest_path(manifest_url: str) -> str:
|
|
parts = manifest_url.split('/')
|
|
try:
|
|
main_index = parts.index('main')
|
|
path = '/'.join(parts[main_index + 1:])
|
|
return path
|
|
except (ValueError, IndexError):
|
|
return '/'.join(parts[-2:])
|
|
|
|
|
|
def filter_author_modules(api_data: list, author: str) -> Set[str]:
|
|
author_paths = set()
|
|
|
|
for module in api_data:
|
|
module_author = module.get('author', {})
|
|
author_name = module_author.get('name') if isinstance(module_author, dict) else module_author
|
|
|
|
if author_name == author:
|
|
manifest_url = module.get('manifestUrl', '')
|
|
if manifest_url:
|
|
path = extract_manifest_path(manifest_url)
|
|
author_paths.add(path)
|
|
|
|
print(f"Found {len(author_paths)} modules from author '{author}' in API")
|
|
return author_paths
|
|
|
|
|
|
def load_index() -> Dict[str, Any]:
|
|
try:
|
|
with open(INDEX_FILE, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
print(f"Loaded {len(data)} modules from {INDEX_FILE}")
|
|
return data
|
|
except FileNotFoundError:
|
|
print(f"✗Error: {INDEX_FILE} not found")
|
|
raise
|
|
except json.JSONDecodeError as e:
|
|
print(f"Error parsing {INDEX_FILE}: {e}")
|
|
raise
|
|
|
|
|
|
def is_manga_module(module_type: str) -> bool:
|
|
return module_type in ("manga", "mangas")
|
|
|
|
|
|
def update_index(index_data: Dict[str, Any], api_paths: Set[str], author: str) -> Dict[str, Any]:
|
|
updated_index = {}
|
|
removed_count = 0
|
|
kept_count = 0
|
|
manga_protected = 0
|
|
|
|
for path, module_data in index_data.items():
|
|
module_author = module_data.get('author', {})
|
|
author_name = module_author.get('name') if isinstance(module_author, dict) else module_author
|
|
module_type = module_data.get('type', '')
|
|
should_keep = False
|
|
reason = ""
|
|
|
|
# ALWAYS protect manga modules FIRST (highest priority)
|
|
if is_manga_module(module_type):
|
|
should_keep = True
|
|
reason = f"manga module (protected, type: {module_type})"
|
|
manga_protected += 1
|
|
elif author_name != author:
|
|
should_keep = True
|
|
reason = f"different author ({author_name})"
|
|
elif path in api_paths:
|
|
should_keep = True
|
|
reason = "exists in API"
|
|
else:
|
|
reason = f"not in API (author: {author})"
|
|
|
|
if should_keep:
|
|
updated_index[path] = module_data
|
|
kept_count += 1
|
|
else:
|
|
print(f" - Removing: {path} ({reason})")
|
|
removed_count += 1
|
|
|
|
print(f"\nKept {kept_count} modules")
|
|
if manga_protected > 0:
|
|
print(f"Protected {manga_protected} manga modules from removal")
|
|
if removed_count > 0:
|
|
print(f"Removed {removed_count} modules")
|
|
else:
|
|
print(f"No modules needed to be removed")
|
|
|
|
return updated_index
|
|
|
|
|
|
def save_index(index_data: Dict[str, Any]) -> None:
|
|
try:
|
|
with open(INDEX_FILE, 'w', encoding='utf-8') as f:
|
|
json.dump(index_data, f, indent=2, ensure_ascii=False)
|
|
print(f"\nSuccessfully saved updated {INDEX_FILE}")
|
|
except Exception as e:
|
|
print(f"Error saving {INDEX_FILE}: {e}")
|
|
raise
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("INDEX.JSON UPDATE SCRIPT")
|
|
print("=" * 60)
|
|
print(f"Syncing author: {AUTHOR_TO_SYNC}")
|
|
print(f"Protected types: manga, mangas")
|
|
print("=" * 60)
|
|
print()
|
|
|
|
try:
|
|
api_data = fetch_api_data()
|
|
|
|
api_paths = filter_author_modules(api_data, AUTHOR_TO_SYNC)
|
|
|
|
index_data = load_index()
|
|
|
|
print(f"\nProcessing modules")
|
|
updated_index = update_index(index_data, api_paths, AUTHOR_TO_SYNC)
|
|
|
|
save_index(updated_index)
|
|
|
|
print("\n" + "=" * 60)
|
|
print("UPDATE COMPLETE")
|
|
print("=" * 60)
|
|
|
|
except Exception as e:
|
|
print(f"\nScript failed: {e}")
|
|
return 1
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
exit(main())
|