Adds two managed system overlays (l4d2center-maps, cedapug-maps) that fetch curated map archives from upstream sources and reconcile addons symlinks for non-Steam maps. A daily systemd timer enqueues a coalesced refresh_global_overlays worker job; downloads, extraction, and rebuilds run in the existing job worker and surface in the job log UI. Schema: GlobalOverlaySource / GlobalOverlayItem / GlobalOverlayItemFile plus nullable Job.user_id so system jobs render as "system" in the UI. The new builder reconciles symlinks against the per-source vpk cache and leaves foreign symlinks untouched. Initialize-time guard refuses to mount a partial overlay if any expected vpk is missing from cache. Refresh service uses shutil.move to handle EXDEV when /tmp and the cache live on different filesystems. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
65 lines
2 KiB
Python
65 lines
2 KiB
Python
from l4d2web.services.global_map_sources import (
|
|
GlobalMapManifestItem,
|
|
parse_cedapug_custom_html,
|
|
parse_l4d2center_csv,
|
|
)
|
|
|
|
|
|
def test_parse_l4d2center_csv_semicolon_manifest():
|
|
raw = """Name;Size;md5;Download link
|
|
carriedoff.vpk;128660532;0380e12c57156574e17a96da1252cf21;https://l4d2center.com/maps/servers/carriedoff.7z
|
|
"""
|
|
|
|
items = parse_l4d2center_csv(raw)
|
|
|
|
assert items == [
|
|
GlobalMapManifestItem(
|
|
item_key="carriedoff.vpk",
|
|
display_name="carriedoff.vpk",
|
|
download_url="https://l4d2center.com/maps/servers/carriedoff.7z",
|
|
expected_vpk_name="carriedoff.vpk",
|
|
expected_size=128660532,
|
|
expected_md5="0380e12c57156574e17a96da1252cf21",
|
|
)
|
|
]
|
|
|
|
|
|
def test_parse_l4d2center_rejects_missing_header():
|
|
try:
|
|
parse_l4d2center_csv("bad,data\n")
|
|
except ValueError as exc:
|
|
assert "Name;Size;md5;Download link" in str(exc)
|
|
else:
|
|
raise AssertionError("bad header must fail")
|
|
|
|
|
|
def test_parse_cedapug_custom_html_extracts_relative_zip_links():
|
|
html = """
|
|
<script>renderCustomMapDownloads([
|
|
["c1m1_hotel","<span style='color: #977d4c;'>Dead Center<\\/span>"],
|
|
["l4d2_ff01_woods","<span style='color: #854C34;'>Fatal Freight<\\/span>","\\/maps\\/FatalFreight.zip"],
|
|
["external","External","https://steamcommunity.com/sharedfiles/filedetails/?id=123"]
|
|
])</script>
|
|
"""
|
|
|
|
items = parse_cedapug_custom_html(html)
|
|
|
|
assert items == [
|
|
GlobalMapManifestItem(
|
|
item_key="FatalFreight.zip",
|
|
display_name="Fatal Freight",
|
|
download_url="https://cedapug.com/maps/FatalFreight.zip",
|
|
expected_vpk_name="",
|
|
expected_size=None,
|
|
expected_md5="",
|
|
)
|
|
]
|
|
|
|
|
|
def test_parse_cedapug_custom_html_rejects_missing_data():
|
|
try:
|
|
parse_cedapug_custom_html("<html></html>")
|
|
except ValueError as exc:
|
|
assert "renderCustomMapDownloads" in str(exc)
|
|
else:
|
|
raise AssertionError("missing embedded data must fail")
|