Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/clients/stremio/addon_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,14 @@ def parse_torrent_description(self, desc: str) -> Dict[str, Any]:
"languages": [],
}
# Extract size
size_pattern = r"💾 ([\d.]+ (?:GB|MB))"
size_match = re.search(size_pattern, desc)
size_pattern = r"💾 ([\d.,]+ (?:GB|MB|Go|Mo))"
size_match = re.search(size_pattern, desc, re.IGNORECASE)
size = size_match.group(1) if size_match else None
if size:
size = convert_size_to_bytes(size)

# Extract seeders
seeders_pattern = r"👤 (\d+)"
seeders_pattern = r"[👥👤] (\d+)"
seeders_match = re.search(seeders_pattern, desc)
seeders = int(seeders_match.group(1)) if seeders_match else None

Expand Down
20 changes: 15 additions & 5 deletions lib/utils/kodi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,18 +518,28 @@ def bytes_to_human_readable(size: int, unit: str = "B") -> str:


def convert_size_to_bytes(size_str: str) -> int:
"""Convert size string to bytes."""
match = re.match(r"(\d+(?:\.\d+)?)\s*(GB|MB|KB|B)", size_str, re.IGNORECASE)
"""Convert size string to bytes.

Supports:
- Standard units: GB, MB, KB, B
- European units: Go, Mo, Ko (Gigaoctet, Megaoctet, Kilooctet)
- European decimal comma: 1,5 GB → treated as 1.5 GB
"""
# Normalize European decimal comma (only between digits, not a thousands separator)
size_str = re.sub(r"(\d),(\d)", r"\1.\2", size_str)
match = re.match(
r"(\d+(?:\.\d+)?)\s*(GB|MB|KB|B|Go|Mo|Ko)", size_str, re.IGNORECASE
)

if match:
size, unit = match.groups()
size = float(size)
unit = unit.upper()
if unit == "GB":
if unit in ("GB", "GO"):
return int(size * 1024**3)
if unit == "MB":
if unit in ("MB", "MO"):
return int(size * 1024**2)
if unit == "KB":
if unit in ("KB", "KO"):
return int(size * 1024)
return int(size)
return 0
Expand Down
52 changes: 52 additions & 0 deletions tests/unit/test_kodi_utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import pytest
from unittest.mock import patch

from lib.utils.kodi import utils
Expand Down Expand Up @@ -42,3 +43,54 @@ def test_is_youtube_addon_enabled_returns_false_when_addon_is_disabled():

get_cond_visibility.assert_called_once_with(f"System.HasAddon({utils.YOUTUBE_ADDON_ID})")
addon_cls.assert_called_once_with(utils.YOUTUBE_ADDON_ID)


@pytest.mark.parametrize(
("input_str", "expected"),
[
# Standard English units
("1 GB", 1 * 1024**3),
("2.5 GB", int(2.5 * 1024**3)),
("500 MB", 500 * 1024**2),
("100 KB", 100 * 1024),
("42 B", 42),
# Case insensitivity
("1.5 gb", int(1.5 * 1024**3)),
("200 mb", 200 * 1024**2),
("50 kb", 50 * 1024),
# European units (Go = GB, Mo = MB, Ko = KB)
("1 Go", 1 * 1024**3),
("1.5 Go", int(1.5 * 1024**3)),
("500 Mo", 500 * 1024**2),
("100 Ko", 100 * 1024),
# Case insensitivity for European units
("2 go", 2 * 1024**3),
("300 mo", 300 * 1024**2),
("75 ko", 75 * 1024),
# European decimal comma → normalised to dot
("1,5 GB", int(1.5 * 1024**3)),
("2,5 Go", int(2.5 * 1024**3)),
("500,5 MB", int(500.5 * 1024**2)),
# Edge cases
("0 GB", 0),
("0 MB", 0),
("0 B", 0),
# Precision edge case – int truncation, not rounding
("1.9 GB", int(1.9 * 1024**3)),
],
)
def test_convert_size_to_bytes(input_str, expected):
assert utils.convert_size_to_bytes(input_str) == expected


@pytest.mark.parametrize(
("input_str",),
[
("",),
("not a size",),
("ABC",),
("1.5",), # missing unit
],
)
def test_convert_size_to_bytes_invalid(input_str):
assert utils.convert_size_to_bytes(input_str) == 0