mirror of
https://github.com/Dictionarry-Hub/database.git
synced 2025-12-11 16:26:58 +00:00
New Profile: 2160p Quality (#19)
create(script): Add tierCreator script for generating group tier custom formats + release group regex patterns fix(tierCreator): Update YAML handling and improve template processing for group tiers remove(template): release group condition placeholder create(format): 2160p Quality Tiers - 69 new release group regex patterns - 6 new tiers for 2160p Quality create(data): Add 2160p Quality Tiers JSON file with detailed statistics and scoring docs(README): Update README to include utility scripts and tier creator usage instructions fix(tierCreator): Improve output message to indicate whether a file is being created or overwritten feat(tierCreator): Add show_preview option for dry run mode to display regex patterns and custom formats add(tier): more data for 2160p Quality add(tiers): new regex patterns for various groups, tweaks to 2160p quality tiers tweak(format): add WOU and MALUS to unwanted x265 tweak(format): Seperate streaming services into 1080p / 2160p - Existing ones still exist, there are just needed for the 2160p Quality profile since it needs different scores based on the resolution create(format): Standard Dynamic Range create(format): Match x265 only for 1080p - Used to get rid of 1080p x265 encodes for 2160p Quality (since x265 is needed for 2160p Encodes) tweak(regex): DTS & X can now be seperated by a colon tweak(format): Add STRiKE to missing HDR Groups create(profile): Initialise 2160p Quality tweak(tier): adjustments to scoring algorithm - hard limits on efficiency delta / num releases for tier 3+ tweaks(tier): new groups / tier adjustments for 2160p quality add(format): x264 (1080p) - Match x264 2160p encodes tweak(profile): Various improvements - Remove UHD Bluray scores, they bloat the scoring logic - Reduce SDR WEBs to below tier ~4 - Add some notes on scoring logic to description fix(tier): Remove bad data fix(tier): remove groups added via bad data tweak(tier): target 55% efficiency, new data for SA89, Mainframe add(profile): x265 (Missing 2160p) - Append x265 to 2160 Blu-ray encodes that are not explicitly labelled x264 tweak(profile): Various improvements / tweaks - Remove required groups for HDR missing CF - New CF for unknown lossless audio - New 2160p Balanced tiers - Normalise lossless audio / quality tier scores tweak(profile): Adjust fallbacks / improve descriptions - Removed HDTV for 1080p profiles - Renamed 'fallbacks' to 'SD' tweak(profile): Finalise 2160p Quality v1 - Set upgrade until to 2160p Transparent, score = 800, min score increment = 5 - Add comprehensive description
This commit is contained in:
210
scripts/tierCreator.py
Normal file
210
scripts/tierCreator.py
Normal file
@@ -0,0 +1,210 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
|
||||
|
||||
def load_template(template_path):
|
||||
"""Load a YAML template file."""
|
||||
try:
|
||||
with open(template_path, 'r') as f:
|
||||
return yaml.safe_load(f)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Template file not found: {template_path}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def create_regex_pattern(group_name,
|
||||
template_dir,
|
||||
output_dir,
|
||||
dry_run=False,
|
||||
show_preview=False):
|
||||
"""Create a regex pattern file for a release group if it doesn't exist."""
|
||||
output_path = output_dir / f"{group_name}.yml"
|
||||
|
||||
# Skip if pattern already exists
|
||||
if output_path.exists():
|
||||
print(f"Skipping existing regex pattern: {output_path}")
|
||||
return
|
||||
|
||||
print(
|
||||
f"{'Would create' if dry_run else 'Creating'} regex pattern: {output_path}"
|
||||
)
|
||||
|
||||
# Load and fill template
|
||||
template = load_template(template_dir / "releaseGroup.yml")
|
||||
template['name'] = group_name
|
||||
template['pattern'] = f"(?<=^|[\\s.-]){group_name}\\b"
|
||||
|
||||
# Show preview in dry run mode if this is the first pattern
|
||||
if dry_run and show_preview:
|
||||
print("\nPreview of first regex pattern:")
|
||||
print("---")
|
||||
print(
|
||||
yaml.dump(template,
|
||||
sort_keys=False,
|
||||
default_flow_style=False,
|
||||
indent=2))
|
||||
print("---\n")
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Write pattern file if not dry run
|
||||
if not dry_run:
|
||||
with open(output_path, 'w') as f:
|
||||
yaml.dump(template, f, sort_keys=False)
|
||||
|
||||
|
||||
def create_tier_format(tier,
|
||||
resolution,
|
||||
type_name,
|
||||
groups,
|
||||
template_dir,
|
||||
output_dir,
|
||||
dry_run=False,
|
||||
show_preview=False):
|
||||
"""Create a custom format file for a specific tier."""
|
||||
# Get groups for this tier
|
||||
tier_groups = [group["name"] for group in groups if group["tier"] == tier]
|
||||
if not tier_groups:
|
||||
return
|
||||
|
||||
# Load and fill template
|
||||
template = load_template(template_dir / "groupTier.yml")
|
||||
|
||||
# Replace template variables
|
||||
template['name'] = f"{resolution} {type_name} Tier {tier}"
|
||||
template[
|
||||
'description'] = f"Matches release groups who fall under {resolution} {type_name} Tier {tier}"
|
||||
|
||||
# Find and update resolution condition
|
||||
for condition in template['conditions']:
|
||||
if condition.get('resolution'):
|
||||
condition['name'] = resolution
|
||||
condition['resolution'] = resolution
|
||||
|
||||
# Add release group conditions
|
||||
for group_name in tier_groups:
|
||||
release_group_condition = {
|
||||
'name': group_name,
|
||||
'negate': False,
|
||||
'pattern': group_name,
|
||||
'required': False,
|
||||
'type': 'release_group'
|
||||
}
|
||||
template['conditions'].append(release_group_condition)
|
||||
|
||||
# Ensure tests is an empty list, not null
|
||||
template['tests'] = []
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Write custom format file
|
||||
output_path = output_dir / f"{resolution} {type_name} Tier {tier}.yml"
|
||||
existing = "Overwriting" if output_path.exists() else "Creating"
|
||||
print(
|
||||
f"{'Would ' + existing.lower() if dry_run else existing} custom format: {output_path} (includes {len(tier_groups)} groups)"
|
||||
)
|
||||
|
||||
# Show preview in dry run mode if this is the first format
|
||||
if dry_run and show_preview:
|
||||
print("\nPreview of first custom format:")
|
||||
print("---")
|
||||
print(
|
||||
yaml.dump(template,
|
||||
sort_keys=False,
|
||||
default_flow_style=False,
|
||||
indent=2))
|
||||
print("---\n")
|
||||
|
||||
if not dry_run:
|
||||
with open(output_path, 'w') as f:
|
||||
yaml.dump(template,
|
||||
f,
|
||||
sort_keys=False,
|
||||
default_flow_style=False,
|
||||
indent=2)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Create Radarr custom formats for release group tiers')
|
||||
parser.add_argument('json_file',
|
||||
help='Input JSON file containing tier data')
|
||||
parser.add_argument('--resolution',
|
||||
choices=['SD', '720p', '1080p', '2160p'],
|
||||
required=True,
|
||||
help='Resolution for custom formats')
|
||||
parser.add_argument('--type',
|
||||
choices=['Quality', 'Balanced'],
|
||||
required=True,
|
||||
help='Type of custom format')
|
||||
parser.add_argument(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
help='Show what would be done without making any changes')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Setup paths
|
||||
script_dir = Path(__file__).parent
|
||||
template_dir = script_dir.parent / "templates"
|
||||
regex_dir = script_dir.parent / "regex_patterns"
|
||||
format_dir = script_dir.parent / "custom_formats"
|
||||
|
||||
# Load and parse input JSON
|
||||
try:
|
||||
with open(args.json_file, 'r') as f:
|
||||
data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Input JSON file not found: {args.json_file}")
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError:
|
||||
print(f"Error: Invalid JSON file: {args.json_file}")
|
||||
sys.exit(1)
|
||||
|
||||
# Print summary of what we found
|
||||
print(f"\nAnalyzing input file: {args.json_file}")
|
||||
print(
|
||||
f"Found {len(data['tiered_groups'])} release groups across {len(set(group['tier'] for group in data['tiered_groups']))} tiers"
|
||||
)
|
||||
|
||||
if args.dry_run:
|
||||
print("\nDRY RUN - No files will be created or modified\n")
|
||||
|
||||
# Create regex patterns for all groups
|
||||
print("\nProcessing regex patterns:")
|
||||
for i, group in enumerate(data["tiered_groups"]):
|
||||
create_regex_pattern(group["name"],
|
||||
template_dir,
|
||||
regex_dir,
|
||||
args.dry_run,
|
||||
show_preview=(i == 0))
|
||||
|
||||
# Create tier formats
|
||||
print("\nProcessing custom formats:")
|
||||
unique_tiers = sorted(set(group["tier"]
|
||||
for group in data["tiered_groups"]))
|
||||
for i, tier in enumerate(unique_tiers):
|
||||
create_tier_format(tier,
|
||||
args.resolution,
|
||||
args.type,
|
||||
data["tiered_groups"],
|
||||
template_dir,
|
||||
format_dir,
|
||||
args.dry_run,
|
||||
show_preview=(i == 0))
|
||||
|
||||
print(
|
||||
f"\nSuccessfully {'simulated' if args.dry_run else 'created'} custom formats for {args.resolution} {args.type}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user