7 Commits

Author SHA1 Message Date
Andy
b16610ac63 fix(progress): bind per-track bars and force terminal completion 2026-02-04 12:55:02 -07:00
Andy
5fae23eb99 feat(proxy): add specific server selection for WindscribeVPN 2026-02-04 19:49:52 +00:00
Andy
6186ff764b fix(progress): force track bar completion on terminal states 2026-02-04 12:31:49 -07:00
Sp5rky
207756c090 Merge pull request #69 from CodeName393/HDR-Vivid-File-Name-Processing
Fixed HDR Vivid showing the file name Range as 'None'
2026-02-04 12:24:24 -07:00
CodeName393
9e194f4868 Fix 2026-02-05 02:51:24 +09:00
CodeName393
5b50a6cd79 HDR Vivid 2026-02-05 02:50:03 +09:00
CodeName393
289c8a3b23 HDR Vivid 2026-02-05 02:49:50 +09:00
4 changed files with 72 additions and 3 deletions

View File

@@ -47,6 +47,7 @@ class WindscribeVPN(Proxy):
Supports:
- Country code: "us", "ca", "gb"
- Specific server: "sg007", "us150"
- City selection: "us:seattle", "ca:toronto"
"""
query = query.lower()
@@ -64,7 +65,17 @@ class WindscribeVPN(Proxy):
elif query in self.server_map and not city:
hostname = self.server_map[query]
else:
if re.match(r"^[a-z]+$", query):
server_match = re.match(r"^([a-z]{2})(\d+)$", query)
if server_match:
# Specific server selection, e.g., sg007, us150
country_code, server_num = server_match.groups()
hostname = self.get_specific_server(country_code, server_num)
if not hostname:
raise ValueError(
f"No WindscribeVPN server found matching '{query}'. "
f"Check the server number or use just '{country_code}' for a random server."
)
elif re.match(r"^[a-z]+$", query):
hostname = self.get_random_server(query, city)
else:
raise ValueError(f"The query provided is unsupported and unrecognized: {query}")
@@ -75,6 +86,38 @@ class WindscribeVPN(Proxy):
hostname = hostname.split(':')[0]
return f"https://{self.username}:{self.password}@{hostname}:443"
def get_specific_server(self, country_code: str, server_num: str) -> Optional[str]:
"""
Find a specific server by country code and server number.
Matches against hostnames like "sg-007.totallyacdn.com" for query "sg007".
Tries both the raw number and zero-padded variants.
Args:
country_code: Two-letter country code (e.g., "sg", "us")
server_num: Server number as string (e.g., "007", "7", "150")
Returns:
The matching hostname, or None if not found.
"""
num_stripped = server_num.lstrip("0") or "0"
candidates = {
f"{country_code}-{server_num}.",
f"{country_code}-{num_stripped}.",
f"{country_code}-{server_num.zfill(3)}.",
}
for location in self.countries:
if location.get("country_code", "").lower() != country_code:
continue
for group in location.get("groups", []):
for host in group.get("hosts", []):
hostname = host.get("hostname", "")
if any(hostname.startswith(prefix) for prefix in candidates):
return hostname
return None
def get_random_server(self, country_code: str, city: Optional[str] = None) -> Optional[str]:
"""
Get a random server hostname for a country, optionally filtered by city.

View File

@@ -218,6 +218,8 @@ class Episode(Title):
for indicator in ["HDR10", "SMPTE ST 2086"]
):
name += " HDR"
elif "HDR Vivid" in hdr_format:
name += " HDR"
else:
name += f" {DYNAMIC_RANGE_MAP.get(hdr_format)} "
elif "HLG" in trc or "Hybrid Log-Gamma" in trc or "ARIB STD-B67" in trc or "arib-std-b67" in trc.lower():

View File

@@ -153,6 +153,8 @@ class Movie(Title):
for indicator in ["HDR10", "SMPTE ST 2086"]
):
name += " HDR"
elif "HDR Vivid" in hdr_format:
name += " HDR"
else:
name += f" {DYNAMIC_RANGE_MAP.get(hdr_format)} "
elif "HLG" in trc or "Hybrid Log-Gamma" in trc or "ARIB STD-B67" in trc or "arib-std-b67" in trc.lower():

View File

@@ -95,7 +95,7 @@ class Tracks:
return rep
def tree(self, add_progress: bool = False) -> tuple[Tree, list[partial]]:
def tree(self, add_progress: bool = False) -> tuple[Tree, list[Callable[..., None]]]:
all_tracks = [*list(self), *self.chapters, *self.attachments]
progress_callables = []
@@ -121,7 +121,29 @@ class Tracks:
speed_estimate_period=10,
)
task = progress.add_task("", downloaded="-")
progress_callables.append(partial(progress.update, task_id=task))
state = {"total": 100.0}
def update_track_progress(
task_id: int = task,
_state: dict[str, float] = state,
_progress: Progress = progress,
**kwargs,
) -> None:
"""
Ensure terminal status states render as a fully completed bar.
Some downloaders can report completed slightly below total
before emitting the final "Downloaded" state.
"""
if "total" in kwargs and kwargs["total"] is not None:
_state["total"] = kwargs["total"]
downloaded_state = kwargs.get("downloaded")
if downloaded_state in {"Downloaded", "Decrypted", "[yellow]SKIPPED"}:
kwargs["completed"] = _state["total"]
_progress.update(task_id=task_id, **kwargs)
progress_callables.append(update_track_progress)
track_table = Table.grid()
track_table.add_row(str(track)[6:], style="text2")
track_table.add_row(progress)