логотипы каналов, тест 2

This commit is contained in:
2026-07-02 14:47:37 +03:00
parent e32fdcb74e
commit 03a68ee8ca
9 changed files with 130 additions and 72 deletions

13
app.py
View File

@@ -34,7 +34,7 @@ from parsers.parser_players import run_parser_players
from parsers.parser_schedule import run_parser_schedule from parsers.parser_schedule import run_parser_schedule
from parsers.parser_standings import run_parser_standings from parsers.parser_standings import run_parser_standings
from parsers.parser_teams import run_parser_teams from parsers.parser_teams import run_parser_teams
from parsers.parser_sources import build_empty_photo_path, list_parser_sources, get_default_source_key, get_parser_source from parsers.parser_sources import build_empty_photo_path, build_channel_logo_path, build_empty_channel_logo_path, list_parser_sources, get_default_source_key, get_parser_source
from services.project_settings_service import build_project_settings_context, save_project_settings from services.project_settings_service import build_project_settings_context, save_project_settings
from repositories.project_settings_repository import ensure_project_settings_tables from repositories.project_settings_repository import ensure_project_settings_tables
@@ -1681,11 +1681,12 @@ def vmix_schedule(session_token: str):
"#FFFFFF00" if row[2] is None and row[3] is None else "#FFFFFF" "#FFFFFF00" if row[2] is None and row[3] is None else "#FFFFFF"
), ),
"channel": ( "channel": (
(rf"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Лого каналов\{row[7]}.png" if row[-1] != "RUSSIAN_CUP" else rf"D:\Графика\ФУТБОЛ\ЖФЛ Кубок России 2026\Лого каналов\{row[7]}.png") build_channel_logo_path(row[8] if len(row) > 8 else None, row[7])
# if row[7] and row[5] == "scheduled" if str(row[7] or "").strip()
if row[2] is None and row[3] is None else build_empty_channel_logo_path(row[8] if len(row) > 8 else None)
else (r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Лого каналов\EMPTY.png" if row[-1] != "RUSSIAN_CUP" else r"D:\Графика\ФУТБОЛ\ЖФЛ Кубок России 2026\Лого каналов\EMPTY.png")
), ),
"channel_value": row[7] or "",
"source_key": row[8] if len(row) > 8 else "",
} }
for row in rows for row in rows
] ]
@@ -2299,12 +2300,14 @@ def render_admin_db_index(
"title": "Суперлига 2026", "title": "Суперлига 2026",
"logo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Teams Logos", "logo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Teams Logos",
"photo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo", "photo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo",
"channel_logo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Лого каналов",
}, },
{ {
"key": "RUSSIAN_CUP", "key": "RUSSIAN_CUP",
"title": "Кубок России 2026", "title": "Кубок России 2026",
"logo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Teams Logos", "logo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Teams Logos",
"photo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Photo", "photo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Photo",
"channel_logo_base_path": r"D:\Графика\ФУТБОЛ\ЖФЛ Кубок России 2026\Лого каналов",
}, },
] ]
default_parser_source_key = "SUPERLEAGUE" default_parser_source_key = "SUPERLEAGUE"

View File

@@ -228,3 +228,45 @@ def build_photo_path(source_key: str | None, filename: str | None) -> str:
def build_empty_photo_path(source_key: str | None = None) -> str: def build_empty_photo_path(source_key: str | None = None) -> str:
"""Путь к пустой картинке фото для выбранного источника.""" """Путь к пустой картинке фото для выбранного источника."""
return build_photo_path(source_key, "EMPTY.png") return build_photo_path(source_key, "EMPTY.png")
def extract_channel_logo_filename(value: str | None) -> str:
"""Возвращает имя файла логотипа телеканала из старого полного пути или нового значения."""
value = str(value or "").strip().strip('"').strip("'")
if not value:
return ""
normalized = value.replace("/", "\\")
filename = normalized.split("\\")[-1].strip()
return filename
def ensure_channel_logo_extension(filename: str) -> str:
filename = extract_channel_logo_filename(filename)
if not filename:
return ""
if "." not in filename.rsplit("\\", 1)[-1]:
return f"{filename}.png"
return filename
def get_channel_logo_base_path(source_key: str | None = None) -> str:
source = get_parser_source(source_key)
return str(source.get("channel_logo_base_path") or "").rstrip("\\/")
def build_channel_logo_path(source_key: str | None, filename: str | None) -> str:
"""Собирает полный путь к логотипу телеканала по источнику турнира."""
logo_file = ensure_channel_logo_extension(filename)
if not logo_file:
return ""
base_path = get_channel_logo_base_path(source_key)
if not base_path:
return logo_file
return f"{base_path}\\{logo_file}"
def build_empty_channel_logo_path(source_key: str | None = None) -> str:
return build_channel_logo_path(source_key, "EMPTY.png")

View File

@@ -355,7 +355,7 @@ def get_tour_schedule_by_match_id(match_id: int) -> list[dict]:
with conn.cursor() as cur: with conn.cursor() as cur:
cur.execute( cur.execute(
""" """
SELECT m.tour SELECT m.tour, m.season, m.source_key
FROM matches m FROM matches m
WHERE m.id = %s WHERE m.id = %s
""", """,
@@ -366,6 +366,8 @@ def get_tour_schedule_by_match_id(match_id: int) -> list[dict]:
return [] return []
tour = row[0] tour = row[0]
season = row[1]
source_key = resolve_match_source_key(match_id, row[2] if len(row) > 2 else None)
cur.execute( cur.execute(
""" """
@@ -384,11 +386,13 @@ def get_tour_schedule_by_match_id(match_id: int) -> list[dict]:
LEFT JOIN teams ht ON ht.id = m.home_team_id LEFT JOIN teams ht ON ht.id = m.home_team_id
LEFT JOIN teams at ON at.id = m.away_team_id LEFT JOIN teams at ON at.id = m.away_team_id
WHERE m.tour = %s WHERE m.tour = %s
AND (%s IS NULL OR m.season = %s)
AND COALESCE(NULLIF(m.source_key, ''), %s) = %s
ORDER BY ORDER BY
m.match_date NULLS LAST, m.match_date NULLS LAST,
m.id m.id
""", """,
(tour,), (tour, season, season, source_key, source_key),
) )
rows = cur.fetchall() rows = cur.fetchall()

View File

@@ -21,6 +21,7 @@ DEFAULT_PARSER_SOURCES = [
"calendar_type": "tours", "calendar_type": "tours",
"logo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Teams Logos", "logo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Teams Logos",
"photo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo", "photo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo",
"channel_logo_base_path": r"D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Лого каналов",
"teams_url": "https://wfl.rfs.ru/tournament/1061879/teams", "teams_url": "https://wfl.rfs.ru/tournament/1061879/teams",
"schedule_url": "https://wfl.rfs.ru/tournament/1061879/calendar?round_id=1117550&type=tours", "schedule_url": "https://wfl.rfs.ru/tournament/1061879/calendar?round_id=1117550&type=tours",
"standings_url": "https://wfl.rfs.ru/tournament/1061879/tables", "standings_url": "https://wfl.rfs.ru/tournament/1061879/tables",
@@ -38,6 +39,7 @@ DEFAULT_PARSER_SOURCES = [
"calendar_type": "stages", "calendar_type": "stages",
"logo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Teams Logos", "logo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Teams Logos",
"photo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Photo", "photo_base_path": r"D:\Графика\ФУТБОЛ\Кубок России 2026\Photo",
"channel_logo_base_path": r"D:\Графика\ФУТБОЛ\ЖФЛ Кубок России 2026\Лого каналов",
"teams_url": "https://wfl.rfs.ru/tournament/1064908/teams", "teams_url": "https://wfl.rfs.ru/tournament/1064908/teams",
"schedule_url": "https://wfl.rfs.ru/tournament/1064908/calendar?round_id=1125159&type=stages", "schedule_url": "https://wfl.rfs.ru/tournament/1064908/calendar?round_id=1125159&type=stages",
"standings_url": "https://wfl.rfs.ru/tournament/1064908/tables", "standings_url": "https://wfl.rfs.ru/tournament/1064908/tables",
@@ -49,6 +51,15 @@ DEFAULT_PARSER_SOURCES = [
] ]
SOURCE_SELECT_SQL = """
SELECT key, title, tournament_id, round_id, season, calendar_type,
logo_base_path, photo_base_path, channel_logo_base_path,
teams_url, schedule_url, standings_url,
match_base_url, base_url, sort_order, is_active
FROM parser_sources
"""
def _row_to_source(row: tuple) -> dict[str, Any]: def _row_to_source(row: tuple) -> dict[str, Any]:
return { return {
"key": row[0] or "", "key": row[0] or "",
@@ -59,13 +70,14 @@ def _row_to_source(row: tuple) -> dict[str, Any]:
"calendar_type": row[5] or "tours", "calendar_type": row[5] or "tours",
"logo_base_path": row[6] or "", "logo_base_path": row[6] or "",
"photo_base_path": row[7] or "", "photo_base_path": row[7] or "",
"teams_url": row[8] or "", "channel_logo_base_path": row[8] or "",
"schedule_url": row[9] or "", "teams_url": row[9] or "",
"standings_url": row[10] or "", "schedule_url": row[10] or "",
"match_base_url": row[11] or "", "standings_url": row[11] or "",
"base_url": row[12] or "https://wfl.rfs.ru", "match_base_url": row[12] or "",
"sort_order": row[13] or 0, "base_url": row[13] or "https://wfl.rfs.ru",
"is_active": bool(row[14]), "sort_order": row[14] or 0,
"is_active": bool(row[15]),
} }
@@ -94,6 +106,7 @@ def ensure_project_settings_tables() -> None:
calendar_type VARCHAR(50) NOT NULL DEFAULT 'tours', calendar_type VARCHAR(50) NOT NULL DEFAULT 'tours',
logo_base_path TEXT, logo_base_path TEXT,
photo_base_path TEXT, photo_base_path TEXT,
channel_logo_base_path TEXT,
teams_url TEXT, teams_url TEXT,
schedule_url TEXT, schedule_url TEXT,
standings_url TEXT, standings_url TEXT,
@@ -107,6 +120,7 @@ def ensure_project_settings_tables() -> None:
""" """
) )
cur.execute("ALTER TABLE parser_sources ADD COLUMN IF NOT EXISTS photo_base_path TEXT;") cur.execute("ALTER TABLE parser_sources ADD COLUMN IF NOT EXISTS photo_base_path TEXT;")
cur.execute("ALTER TABLE parser_sources ADD COLUMN IF NOT EXISTS channel_logo_base_path TEXT;")
for key, value in DEFAULT_APP_SETTINGS.items(): for key, value in DEFAULT_APP_SETTINGS.items():
cur.execute( cur.execute(
@@ -122,25 +136,12 @@ def ensure_project_settings_tables() -> None:
cur.execute( cur.execute(
""" """
INSERT INTO parser_sources ( INSERT INTO parser_sources (
key, key, title, tournament_id, round_id, season, calendar_type,
title, logo_base_path, photo_base_path, channel_logo_base_path,
tournament_id, teams_url, schedule_url, standings_url, match_base_url, base_url,
round_id, sort_order, is_active, created_at, updated_at
season,
calendar_type,
logo_base_path,
photo_base_path,
teams_url,
schedule_url,
standings_url,
match_base_url,
base_url,
sort_order,
is_active,
created_at,
updated_at
) )
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW()) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
ON CONFLICT (key) DO NOTHING; ON CONFLICT (key) DO NOTHING;
""", """,
( (
@@ -152,6 +153,7 @@ def ensure_project_settings_tables() -> None:
source["calendar_type"], source["calendar_type"],
source["logo_base_path"], source["logo_base_path"],
source["photo_base_path"], source["photo_base_path"],
source["channel_logo_base_path"],
source["teams_url"], source["teams_url"],
source["schedule_url"], source["schedule_url"],
source["standings_url"], source["standings_url"],
@@ -172,6 +174,15 @@ def ensure_project_settings_tables() -> None:
""", """,
(source.get("photo_base_path") or "", source["key"]), (source.get("photo_base_path") or "", source["key"]),
) )
cur.execute(
"""
UPDATE parser_sources
SET channel_logo_base_path = %s, updated_at = NOW()
WHERE key = %s
AND (channel_logo_base_path IS NULL OR TRIM(channel_logo_base_path) = '');
""",
(source.get("channel_logo_base_path") or "", source["key"]),
)
conn.commit() conn.commit()
except Exception: except Exception:
conn.rollback() conn.rollback()
@@ -223,26 +234,9 @@ def list_parser_sources_from_db(active_only: bool = True) -> list[dict[str, Any]
try: try:
with conn.cursor() as cur: with conn.cursor() as cur:
if active_only: if active_only:
cur.execute( cur.execute(SOURCE_SELECT_SQL + " WHERE is_active = TRUE ORDER BY sort_order ASC, title ASC;")
"""
SELECT key, title, tournament_id, round_id, season, calendar_type,
logo_base_path, photo_base_path, teams_url, schedule_url, standings_url,
match_base_url, base_url, sort_order, is_active
FROM parser_sources
WHERE is_active = TRUE
ORDER BY sort_order ASC, title ASC;
"""
)
else: else:
cur.execute( cur.execute(SOURCE_SELECT_SQL + " ORDER BY sort_order ASC, title ASC;")
"""
SELECT key, title, tournament_id, round_id, season, calendar_type,
logo_base_path, photo_base_path, teams_url, schedule_url, standings_url,
match_base_url, base_url, sort_order, is_active
FROM parser_sources
ORDER BY sort_order ASC, title ASC;
"""
)
rows = cur.fetchall() rows = cur.fetchall()
return [_row_to_source(row) for row in rows] return [_row_to_source(row) for row in rows]
finally: finally:
@@ -257,17 +251,7 @@ def get_parser_source_from_db(source_key: str) -> dict[str, Any] | None:
conn = get_connection() conn = get_connection()
try: try:
with conn.cursor() as cur: with conn.cursor() as cur:
cur.execute( cur.execute(SOURCE_SELECT_SQL + " WHERE key = %s LIMIT 1;", (source_key,))
"""
SELECT key, title, tournament_id, round_id, season, calendar_type,
logo_base_path, photo_base_path, teams_url, schedule_url, standings_url,
match_base_url, base_url, sort_order, is_active
FROM parser_sources
WHERE key = %s
LIMIT 1;
""",
(source_key,),
)
row = cur.fetchone() row = cur.fetchone()
return _row_to_source(row) if row else None return _row_to_source(row) if row else None
finally: finally:
@@ -292,6 +276,7 @@ def update_parser_source(source_key: str, values: dict[str, str]) -> None:
"calendar_type": "tours", "calendar_type": "tours",
"logo_base_path": "", "logo_base_path": "",
"photo_base_path": "", "photo_base_path": "",
"channel_logo_base_path": "",
"teams_url": "", "teams_url": "",
"schedule_url": "", "schedule_url": "",
"standings_url": "", "standings_url": "",
@@ -313,10 +298,11 @@ def update_parser_source(source_key: str, values: dict[str, str]) -> None:
""" """
INSERT INTO parser_sources ( INSERT INTO parser_sources (
key, title, tournament_id, round_id, season, calendar_type, key, title, tournament_id, round_id, season, calendar_type,
logo_base_path, photo_base_path, teams_url, schedule_url, standings_url, logo_base_path, photo_base_path, channel_logo_base_path,
teams_url, schedule_url, standings_url,
match_base_url, base_url, sort_order, is_active, created_at, updated_at match_base_url, base_url, sort_order, is_active, created_at, updated_at
) )
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW()) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
ON CONFLICT (key) ON CONFLICT (key)
DO UPDATE SET DO UPDATE SET
title = EXCLUDED.title, title = EXCLUDED.title,
@@ -326,6 +312,7 @@ def update_parser_source(source_key: str, values: dict[str, str]) -> None:
calendar_type = EXCLUDED.calendar_type, calendar_type = EXCLUDED.calendar_type,
logo_base_path = EXCLUDED.logo_base_path, logo_base_path = EXCLUDED.logo_base_path,
photo_base_path = EXCLUDED.photo_base_path, photo_base_path = EXCLUDED.photo_base_path,
channel_logo_base_path = EXCLUDED.channel_logo_base_path,
teams_url = EXCLUDED.teams_url, teams_url = EXCLUDED.teams_url,
schedule_url = EXCLUDED.schedule_url, schedule_url = EXCLUDED.schedule_url,
standings_url = EXCLUDED.standings_url, standings_url = EXCLUDED.standings_url,
@@ -344,6 +331,7 @@ def update_parser_source(source_key: str, values: dict[str, str]) -> None:
merged.get("calendar_type") or "tours", merged.get("calendar_type") or "tours",
merged.get("logo_base_path") or "", merged.get("logo_base_path") or "",
merged.get("photo_base_path") or "", merged.get("photo_base_path") or "",
merged.get("channel_logo_base_path") or "",
merged.get("teams_url") or "", merged.get("teams_url") or "",
merged.get("schedule_url") or "", merged.get("schedule_url") or "",
merged.get("standings_url") or "", merged.get("standings_url") or "",

View File

@@ -87,6 +87,7 @@ def build_project_settings_context() -> dict[str, Any]:
), ),
_field(_source_field_key(source_key, "LOGO_BASE_PATH"), "Папка логотипов", source.get("logo_base_path", ""), wide=True), _field(_source_field_key(source_key, "LOGO_BASE_PATH"), "Папка логотипов", source.get("logo_base_path", ""), wide=True),
_field(_source_field_key(source_key, "PHOTO_BASE_PATH"), "Папка фотографий", source.get("photo_base_path", ""), wide=True), _field(_source_field_key(source_key, "PHOTO_BASE_PATH"), "Папка фотографий", source.get("photo_base_path", ""), wide=True),
_field(_source_field_key(source_key, "CHANNEL_LOGO_BASE_PATH"), "Папка логотипов каналов", source.get("channel_logo_base_path", ""), wide=True),
_field(_source_field_key(source_key, "TEAMS_URL"), "Ссылка на команды", source.get("teams_url", ""), wide=True), _field(_source_field_key(source_key, "TEAMS_URL"), "Ссылка на команды", source.get("teams_url", ""), wide=True),
_field(_source_field_key(source_key, "SCHEDULE_URL"), "Ссылка на расписание", source.get("schedule_url", ""), wide=True), _field(_source_field_key(source_key, "SCHEDULE_URL"), "Ссылка на расписание", source.get("schedule_url", ""), wide=True),
_field(_source_field_key(source_key, "STANDINGS_URL"), "Ссылка на турнирку", source.get("standings_url", ""), wide=True), _field(_source_field_key(source_key, "STANDINGS_URL"), "Ссылка на турнирку", source.get("standings_url", ""), wide=True),
@@ -123,6 +124,7 @@ def save_project_settings(form_values: dict[str, str]) -> list[str]:
"CALENDAR_TYPE": "calendar_type", "CALENDAR_TYPE": "calendar_type",
"LOGO_BASE_PATH": "logo_base_path", "LOGO_BASE_PATH": "logo_base_path",
"PHOTO_BASE_PATH": "photo_base_path", "PHOTO_BASE_PATH": "photo_base_path",
"CHANNEL_LOGO_BASE_PATH": "channel_logo_base_path",
"TEAMS_URL": "teams_url", "TEAMS_URL": "teams_url",
"SCHEDULE_URL": "schedule_url", "SCHEDULE_URL": "schedule_url",
"STANDINGS_URL": "standings_url", "STANDINGS_URL": "standings_url",

View File

@@ -460,27 +460,29 @@ def get_vmix_schedule(session_row):
m.match_date, m.match_date,
m.status, m.status,
m.id, m.id,
m.channel COALESCE(m.channel, '') AS channel,
COALESCE(NULLIF(m.source_key, ''), %s) AS source_key
FROM matches m FROM matches m
LEFT JOIN teams t1 ON m.home_team_id = t1.id LEFT JOIN teams t1 ON m.home_team_id = t1.id
LEFT JOIN teams t2 ON m.away_team_id = t2.id LEFT JOIN teams t2 ON m.away_team_id = t2.id
WHERE m.tour = %s WHERE m.tour = %s
AND (%s IS NULL OR m.season = %s) AND (%s IS NULL OR m.season = %s)
AND COALESCE(m.source_key, %s) = %s AND COALESCE(NULLIF(m.source_key, ''), %s) = %s
ORDER BY m.match_date, m.id ORDER BY m.match_date, m.id
""" """
conn = get_connection() conn = get_connection()
try: try:
with conn.cursor() as cur: with conn.cursor() as cur:
cur.execute(query, (tour, season, season, source_filter, source_filter)) cur.execute(query, (source_filter, tour, season, season, source_filter, source_filter))
rows = cur.fetchall() rows = cur.fetchall()
result = [] result = []
for row in rows: for row in rows:
row = list(row) row = list(row)
row[0] = build_logo_variant_path(source_key, row[0], "white") row_source_key = row[8] if len(row) > 8 else source_key
row[1] = build_logo_variant_path(source_key, row[1], "white") row[0] = build_logo_variant_path(row_source_key, row[0], "white")
row[1] = build_logo_variant_path(row_source_key, row[1], "white")
result.append(tuple(row)) result.append(tuple(row))
return result return result
finally: finally:

View File

@@ -0,0 +1,12 @@
ALTER TABLE parser_sources
ADD COLUMN IF NOT EXISTS channel_logo_base_path TEXT;
UPDATE parser_sources
SET channel_logo_base_path = 'D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Лого каналов'
WHERE key = 'SUPERLEAGUE'
AND (channel_logo_base_path IS NULL OR TRIM(channel_logo_base_path) = '');
UPDATE parser_sources
SET channel_logo_base_path = 'D:\Графика\ФУТБОЛ\ЖФЛ Кубок России 2026\Лого каналов'
WHERE key = 'RUSSIAN_CUP'
AND (channel_logo_base_path IS NULL OR TRIM(channel_logo_base_path) = '');

View File

@@ -542,18 +542,19 @@
<select class="field-select" id="parserSource" name="parser_source" required> <select class="field-select" id="parserSource" name="parser_source" required>
{% if sources %} {% if sources %}
{% for source in sources %} {% for source in sources %}
<option value="{{ source.key }}" data-logo-base-path="{{ source.logo_base_path or '' }}" data-photo-base-path="{{ source.photo_base_path or '' }}" {% if source.key == default_parser_source_key %}selected{% endif %}> <option value="{{ source.key }}" data-logo-base-path="{{ source.logo_base_path or '' }}" data-photo-base-path="{{ source.photo_base_path or '' }}" data-channel-logo-base-path="{{ source.channel_logo_base_path or '' }}" {% if source.key == default_parser_source_key %}selected{% endif %}>
{{ source.title }} {{ source.title }}
</option> </option>
{% endfor %} {% endfor %}
{% else %} {% else %}
<option value="SUPERLEAGUE" data-logo-base-path="D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Teams Logos" data-photo-base-path="D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo" selected>Суперлига 2026</option> <option value="SUPERLEAGUE" data-logo-base-path="D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Teams Logos" data-photo-base-path="D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Photo" data-channel-logo-base-path="D:\Графика\ФУТБОЛ\Женская Суперлига 2026\Лого каналов" selected>Суперлига 2026</option>
<option value="RUSSIAN_CUP" data-logo-base-path="D:\Графика\ФУТБОЛ\Кубок России 2026\Teams Logos" data-photo-base-path="D:\Графика\ФУТБОЛ\Кубок России 2026\Photo">Кубок России 2026</option> <option value="RUSSIAN_CUP" data-logo-base-path="D:\Графика\ФУТБОЛ\Кубок России 2026\Teams Logos" data-photo-base-path="D:\Графика\ФУТБОЛ\Кубок России 2026\Photo" data-channel-logo-base-path="D:\Графика\ФУТБОЛ\ЖФЛ Кубок России 2026\Лого каналов">Кубок России 2026</option>
{% endif %} {% endif %}
</select> </select>
<div class="helper-text">Список источников хранится в <b>базе данных</b> и редактируется в настройках проекта.</div> <div class="helper-text">Список источников хранится в <b>базе данных</b> и редактируется в настройках проекта.</div>
<div class="helper-text">Путь к логотипам: <b id="selectedLogoBasePath"></b></div> <div class="helper-text">Путь к логотипам: <b id="selectedLogoBasePath"></b></div>
<div class="helper-text">Путь к фотографиям: <b id="selectedPhotoBasePath"></b></div> <div class="helper-text">Путь к фотографиям: <b id="selectedPhotoBasePath"></b></div>
<div class="helper-text">Путь к логотипам каналов: <b id="selectedChannelLogoBasePath"></b></div>
</div> </div>
<div> <div>
@@ -851,6 +852,7 @@
const parserSourceSelect = document.getElementById("parserSource"); const parserSourceSelect = document.getElementById("parserSource");
const selectedLogoBasePath = document.getElementById("selectedLogoBasePath"); const selectedLogoBasePath = document.getElementById("selectedLogoBasePath");
const selectedPhotoBasePath = document.getElementById("selectedPhotoBasePath"); const selectedPhotoBasePath = document.getElementById("selectedPhotoBasePath");
const selectedChannelLogoBasePath = document.getElementById("selectedChannelLogoBasePath");
const openCreateAccountBtn = document.getElementById("openCreateAccountBtn"); const openCreateAccountBtn = document.getElementById("openCreateAccountBtn");
const closeCreateAccountBtn = document.getElementById("closeCreateAccountBtn"); const closeCreateAccountBtn = document.getElementById("closeCreateAccountBtn");
const accountModal = document.getElementById("accountModal"); const accountModal = document.getElementById("accountModal");
@@ -1000,6 +1002,9 @@
if (selectedPhotoBasePath) { if (selectedPhotoBasePath) {
selectedPhotoBasePath.textContent = option?.dataset?.photoBasePath || "—"; selectedPhotoBasePath.textContent = option?.dataset?.photoBasePath || "—";
} }
if (selectedChannelLogoBasePath) {
selectedChannelLogoBasePath.textContent = option?.dataset?.channelLogoBasePath || "—";
}
} }
document.addEventListener("click", (event) => { document.addEventListener("click", (event) => {

BIN
vMix.zip

Binary file not shown.