diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a6d28d..fb2857b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased — targeting v0.1.0 +- Added a PNG export of the existing community artwork and switched template/profile + icon URLs to PNG for Docker Manager compatibility. Original SVG preserved. - Changed the default host WebUI/API port to `6969` for CPU, CUDA 12 and CUDA 13 installations. Internal port `8080` and WebUI port resolution remain unchanged; existing installations retain their configured host port. diff --git a/assets/README.md b/assets/README.md index b6a296f..22a9a1e 100644 --- a/assets/README.md +++ b/assets/README.md @@ -4,6 +4,18 @@ the white waveform on a blue/violet tile. Only a final newline was added; artwork and original SVG metadata are preserved. It requires no external font. +`icon.png` is a 256 × 256 raster export of that same artwork for the Community +Apps profile and Docker template. Docker Manager uses PNG-oriented icon caching +and rendering; the SVG remains the unchanged source asset. From the repository +root, export with: + +```sh +rsvg-convert --width 256 --height 256 --output assets/icon.png assets/icon.svg +``` + +The raster export does not carry the SVG's embedded provenance metadata; that +metadata remains in the original SVG. No artwork was regenerated or redesigned. + On 2026-09-06, the project owner (`lozenge0`) confirmed that the artwork was generated from scratch using their own prompts with Claude/AI, without supplied third-party images or assets. This records the owner's provenance statement; @@ -13,7 +25,7 @@ it is not an independent originality, copyright or trademark clearance. On 2026-09-12, the project owner (`lozenge0`) approved applying [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) to -`icon.svg`, to the extent they hold copyright and related rights in it. +`icon.svg` and its `icon.png` export, to the extent they hold copyright and related rights in them. The [CC0 legal code](https://creativecommons.org/publicdomain/zero/1.0/legalcode.en) governs this dedication, including its waiver, fallback licence and disclaimers. SPDX identifier: `CC0-1.0`. @@ -21,7 +33,7 @@ SPDX identifier: `CC0-1.0`. This does not assert that AI-generated artwork necessarily has copyright protection, clear third-party rights, or grant trademark rights. This is community integration artwork, not official audio.cpp branding or endorsement. The root MIT -licence covers integration code/docs; `icon.svg` is separately covered by CC0. +licence covers integration code/docs; both icon formats are separately covered by CC0. ## Maintainer presentation checks diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..33d35c7 Binary files /dev/null and b/assets/icon.png differ diff --git a/ca_profile.xml b/ca_profile.xml index b31082d..1e6b5f8 100644 --- a/ca_profile.xml +++ b/ca_profile.xml @@ -1,6 +1,6 @@ audio.cpp for Unraid: community-maintained templates using unmodified upstream Docker images. This project maintains the Unraid integration, not audio.cpp itself, and is not an official upstream endorsement. Installation support belongs in this repository's issues. Beta integration: see the README for tested hardware and remaining deployment checks. - https://raw.githubusercontent.com/lozenge0/audio-cpp-unraid/main/assets/icon.svg + https://raw.githubusercontent.com/lozenge0/audio-cpp-unraid/main/assets/icon.png https://github.com/lozenge0/audio-cpp-unraid diff --git a/docs/RELEASE-REVIEW.md b/docs/RELEASE-REVIEW.md index cd5f7d1..bbf40fe 100644 --- a/docs/RELEASE-REVIEW.md +++ b/docs/RELEASE-REVIEW.md @@ -104,6 +104,7 @@ LICENSE README.md SECURITY.md assets/README.md +assets/icon.png assets/icon.svg ca_profile.xml docs/CONFIGURATION.md diff --git a/templates/audio-cpp.xml b/templates/audio-cpp.xml index da44279..5bfcbbe 100644 --- a/templates/audio-cpp.xml +++ b/templates/audio-cpp.xml @@ -9,7 +9,7 @@ true AI Tools: http://[IP]:[PORT:8080]/ - https://raw.githubusercontent.com/lozenge0/audio-cpp-unraid/main/assets/icon.svg + https://raw.githubusercontent.com/lozenge0/audio-cpp-unraid/main/assets/icon.png https://github.com/0xShug0/audio.cpp https://github.com/lozenge0/audio-cpp-unraid/issues https://raw.githubusercontent.com/lozenge0/audio-cpp-unraid/main/templates/audio-cpp.xml diff --git a/tests/test_publication.py b/tests/test_publication.py index b7a514a..3a9812b 100644 --- a/tests/test_publication.py +++ b/tests/test_publication.py @@ -8,7 +8,7 @@ '.github/dependabot.yml', '.github/workflows/validate.yml', '.gitignore', 'CHANGELOG.md', 'LICENSE', 'README.md', 'CONTRIBUTING.md', 'SECURITY.md', - 'assets/README.md', 'assets/icon.svg', 'ca_profile.xml', + 'assets/README.md', 'assets/icon.svg', 'assets/icon.png', 'ca_profile.xml', 'docs/CONFIGURATION.md', 'docs/MAINTAINER.md', 'docs/CPU-RETEST-20260912.md', 'docs/FIRST-RUN-FINDINGS.md', 'docs/PLAN.md', 'docs/PUBLISHING.md', 'docs/RECREATION-TEST.md', 'docs/RELEASE-REVIEW.md', @@ -98,7 +98,8 @@ def test_no_selected_private_data_patterns_in_public_content(self): r'\bgithub_pat_[A-Za-z0-9_]{30,}\b', ) for name in sorted(EXPECTED): - if name.startswith('tests/'): + if name.startswith('tests/') or name == 'assets/icon.png': + # PNG structure/chunk allowlist is checked by test_template. continue text = (ROOT / name).read_text() for pattern in patterns: diff --git a/tests/test_template.py b/tests/test_template.py index f5d981a..3e069c4 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -129,6 +129,32 @@ def test_profile(self): self.assertTrue(profile.findtext("Profile")) self.assertEqual(profile.findtext("Icon"), self.root.findtext("Icon")) + def test_deployment_icon_is_256_pixel_png(self): + import struct + import zlib + data = (ROOT / "assets/icon.png").read_bytes() + self.assertEqual(data[:8], b"\x89PNG\r\n\x1a\n") + offset = 8 + chunks = [] + while offset < len(data): + size = struct.unpack(">I", data[offset:offset + 4])[0] + kind = data[offset + 4:offset + 8] + payload = data[offset + 8:offset + 8 + size] + crc = struct.unpack(">I", data[offset + 8 + size:offset + 12 + size])[0] + self.assertEqual(crc, zlib.crc32(kind + payload)) + self.assertIn(kind, (b"IHDR", b"bKGD", b"IDAT", b"IEND")) + chunks.append(kind) + if kind == b"IHDR": + self.assertEqual(struct.unpack(">II", payload[:8]), (256, 256)) + offset += 12 + size + self.assertEqual(offset, len(data)) + self.assertEqual(chunks[0], b"IHDR") + self.assertIn(b"IDAT", chunks) + self.assertEqual(chunks[-1], b"IEND") + for tag, root in variants(self.root): + with self.subTest(variant=tag): + self.assertTrue(root.findtext("Icon").endswith("/assets/icon.png")) + def test_icon_is_self_contained_svg(self): icon = ET.parse(ROOT / "assets/icon.svg").getroot() self.assertEqual(icon.tag, "{http://www.w3.org/2000/svg}svg") @@ -171,7 +197,7 @@ def test_selected_publication_destinations(self): self.assertEqual(self.root.findtext("Support"), base + "/issues") self.assertEqual(self.root.findtext("TemplateURL"), raw + "templates/audio-cpp.xml") self.assertEqual(self.root.findtext("ReadMe"), raw + "README.md") - self.assertEqual(self.root.findtext("Icon"), raw + "assets/icon.svg") + self.assertEqual(self.root.findtext("Icon"), raw + "assets/icon.png") profile = ET.parse(ROOT / "ca_profile.xml").getroot() self.assertEqual(profile.findtext("WebPage"), base) for path in (ROOT / "templates/audio-cpp.xml", ROOT / "ca_profile.xml"):