aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* Bump docker/metadata-action from 5 to 6 (#8)v1.3.6dependabot[bot]2026-07-151-1/+1
| | | | | | | | | | | | | | | | Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5 to 6. - [Release notes](https://github.com/docker/metadata-action/releases) - [Commits](https://github.com/docker/metadata-action/compare/v5...v6) --- updated-dependencies: - dependency-name: docker/metadata-action dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Bump docker/login-action from 3 to 4 (#7)dependabot[bot]2026-07-151-1/+1
| | | | | | | | | | | | | | | | Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Bump actions/checkout from 4 to 7 (#6)dependabot[bot]2026-07-151-1/+1
| | | | | | | | | | | | | | | | | Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 7. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Bump docker/setup-buildx-action from 3 to 4 (#5)dependabot[bot]2026-07-151-1/+1
| | | | | | | | | | | | | | | | Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3 to 4. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Bump docker/build-push-action from 6 to 7 (#4)dependabot[bot]2026-07-151-1/+1
| | | | | | | | | | | | | | | | Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6 to 7. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6...v7) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* fix: use commas in the viewport meta contentv1.3.5Christian Cleberg2026-07-151-1/+1
| | | | | | The viewport directives were separated with a semicolon, which browsers reject: "';' is not a valid key-value pair separator". Drop the duplicated trailing user-scalable directive that the semicolon introduced.
* fix: serve media again by unsetting download-proxy and scoping Host per requestChristian Cleberg2026-07-157-52/+77
| | | | | | | | | | | | | | | | | | | | | | | | | | Two independent faults made every image fail while pages still rendered. config.example.json shipped download-proxy=http://127.0.0.1:8080. Only media fetches go through that proxy — pages reach DeviantArt via devianter on the default transport — so when nothing listens there, images 502 and the rest of the page looks fine. In a scratch container 127.0.0.1 is the container itself, so the default could never work under Docker. Unset it and document that it must stay empty unless an operator really runs a proxy. Host was a package global reassigned by every request, so a concurrent request could overwrite it mid-render and emit URLs on another origin's host and port. The instance's own default-src 'self' CSP then blocked those images. Thread the request's host through skunkyart instead, and take it as an explicit argument in URLBuilder, ParseMedia, ParseDescription, BuildUserPlate and ConvertDeviantArtURLToSkunkyArt. Feeds keep their absolute URLs. Also start RefreshInstances after ExecuteConfig rather than before it: the goroutine read CFG while json.Unmarshal was writing it (a race the detector flags), and its fetch escaped both the throttle and the configured User-Agent. Verified: 300 concurrent requests with distinct Host headers now round-trip their own host (was 1 leak per 300), go test -race is clean, and cache+proxy both enabled serves 200 image/jpeg cold and from cache.
* ci: publish multi-arch image to GHCR on release tagsv1.3.4Christian Cleberg2026-07-155-2/+103
| | | | | | | | | | | Build and push linux/amd64 + linux/arm64 images to ghcr.io/zerolabsco/skunky-art on every v* tag, with a signed provenance attestation. The Dockerfile cross-compiles from $BUILDPLATFORM, so the arm64 image builds without QEMU emulation. Default both compose examples to the published image and keep `build: .` commented out for building from a checkout, and extend dependabot to the github-actions and docker ecosystems.
* docs: correct advertised proxifying flag and instance list linkChristian Cleberg2026-07-152-3/+3
| | | | | | | | | | The published entry for zerolabs.sh claimed proxifying was off while the instance runs with proxy enabled, so /about advertised the opposite of what the instance does. The instance list is fetched from main at runtime, so this corrects the live about page without a rebuild. Also point the instances.json link at skunky-art/main, which is what the app actually fetches, rather than the old SkunkyArt/dev path.
* build: bump builder image to Go 1.25Christian Cleberg2026-07-151-1/+1
| | | | | | | | | go.mod requires go 1.25.0, but the Dockerfile still pinned the builder to 1.18, which cannot parse a three-part version string and failed with "invalid go version '1.25.0': must match format 1.23". Track the 1.25 tag rather than a patch release so the builder does not drift out of date again.
* fix: attribute fork in copyright and replace upstream matrix linkChristian Cleberg2026-07-152-3/+3
| | | | | | | | | The copyright on /about and in the CLI help credited only lost+skunk and linked to their matrix account. Credit this fork alongside the original, as the X11 license requires retaining the upstream notice, and point the attribution at the upstream repo rather than the stale matrix link. Replace the upstream matrix room link with this fork's issue tracker.
* fix: document exported API, fix naming, and harden Downloadv1.3.3Christian Cleberg2026-07-1510-119/+259
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The remaining golangci-lint findings. These land together because the Url -> URL rename spans util.go, parsers.go and wrapper.go, and splitting it would leave an intermediate commit that does not compile. Download() carried the most serious bug here: try() only prints an error, it does not return, so a failed request fell through to resp.Body.Close() on a nil resp and panicked. Every failure path now returns the zero Downloaded, and callers check Status. ReturnHTTPError guards against the resulting status 0, which would otherwise panic WriteHeader. Requests carry a context with a timeout (noctx), and a download-proxy now routes through ProxiedTransport so it keeps the DA throttle and timeouts. Also: - doc comments on all 48 exported symbols (revive's exported rule, with checkPrivateReceivers, since most of app is exported methods on the unexported skunkyart type), plus package docs in new doc.go files so both the embed and non-embed builds are covered. - ST1003 naming: UrlBuilder -> URLBuilder, id_search -> idSearch, cache_config -> cacheConfig, TXT_RAW -> TxtRaw, mediaUrl -> mediaURL. - explicit json tags on structs that are unmarshaled (musttag); the hyphenated keys already had tags, the rest relied on case-insensitive fallback. Behaviour is unchanged. - modernization: range-over-int, WaitGroup.Go, stale +build lines, interface{} -> any, strings.Builder over string concatenation in a loop.
* fix: harden HTTP transport, server timeouts and panic pathsChristian Cleberg2026-07-155-55/+153
| | | | | | | | | | | | | | | | | | | | | | | | | | Correctness and security findings surfaced by golangci-lint, plus two latent panics found alongside them. - router: http.ListenAndServe has no timeouts at all (gosec G114), so a slow client could hold a connection and its handler open indefinitely. Replace it with an explicit http.Server carrying read/write/idle timeouts. - httpclient: InstallDAThrottle asserted http.DefaultTransport was a *http.Transport and would panic outright if anything had already wrapped it -- which is precisely what that function does. Check the assertion and fall back to a fresh transport. Expose ProxiedTransport so a configured download-proxy can inherit the same throttle and timeouts instead of silently bypassing them. - cache: the Sys() assertion to *syscall.Stat_t is only valid on unix and would panic elsewhere; skip rotation instead. Indexing Headers["Content-Type"][0] panics when the header is absent; use Headers.Get. Cache files are written 0600 rather than 0700, as they are never executed. - cli, api: check error returns, and exit rather than nil-dereference a file handle that failed to open. SHA-1 and math/rand keep //nolint:gosec with reasons: they are cache-key hashes and random-artwork picks, not security primitives.
* fix(cache): correct max-size megabyte conversionChristian Cleberg2026-07-151-1/+3
| | | | | | | | | | max-size is documented in SETUP.md as megabytes, but the conversion was `*= 1024 ^ 2`. In Go `^` is XOR, not exponentiation, so this multiplied by 1026 rather than 1048576 -- a configured max-size of 200 produced a ~205 KB cap instead of 200 MB, wiping the cache almost immediately. This changes runtime behaviour: the cache will now grow to the size the config actually asks for.
* build: add golangci-lint configurationChristian Cleberg2026-07-151-0/+48
| | | | | | | | | | | | | Enables the standard linters plus revive's exported rule, a set of correctness/security linters (bodyclose, noctx, gosec, forcetypeassert, canonicalheader, musttag, predeclared, exhaustive), modernization linters, and staticcheck's full check set including the doc-comment and naming checks that are off by default. The idiom-fighting linters stay off: varnamelen objects to short names that are idiomatic Go, exhaustruct demands every field be initialized, gochecknoglobals flags CFG/Host which are deliberate, and tagliatelle would rename JSON config keys and break existing instances' configs.
* fix: remove russian language throughoutChristian Cleberg2026-07-1510-94/+10
|
* Bump golang.org/x/net from 0.27.0 to 0.57.0 (#3)dependabot[bot]2026-07-152-4/+4
| | | | | | | | | | | | | | | Bumps [golang.org/x/net](https://github.com/golang/net) from 0.27.0 to 0.57.0. - [Commits](https://github.com/golang/net/compare/v0.27.0...v0.57.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.57.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* fix: point source links and instance fetch at this forkChristian Cleberg2026-07-146-7/+7
| | | | | | | | | | | | | | | Upstream references still pointed at git.macaw.me, which is unmaintained and whose instances.json is a dead link. Repoint them at this repo: - RefreshInstances now fetches instances.json from raw.githubusercontent - source/version links in index.htm, about.htm, and CLI help use the GitHub releases tag URL - SETUP.md/SETUP-RU.md language switch links were Gitea-absolute paths that 404 on GitHub; make them relative - --add-instance message says 'main' branch, matching this repo The fork attribution in README.md is left as-is: it credits upstream rather than pointing at the source.
* Merge dev: devianter v0.3.1 migration, DA throttle, fixesChristian Cleberg2026-07-1415-22/+380
|\ | | | | | | | | | | Migrate to github.com/zerolabsco/devianter v0.3.1 and adapt to its reordered return values, throttle outbound DeviantArt requests, harden the random-art retry loop, and fix the darwin build.
| * docs: add optional VPN egress compose exampleChristian Cleberg2026-07-143-0/+126
| | | | | | | | | | | | | | | | | | | | | | CloudFront/WAF blocks some egress IPs on the /_puppy path, making every DA-backed page fail while Go tries to unmarshal an HTML 403 page. Routing outbound through a non-blocked exit fixes it with no code change, since devianter's client honors HTTPS_PROXY. Adds a compose stack with an optional gluetun sidecar behind the "vpn" profile (off by default, so the stock direct setup is unchanged) and a matching .env.example. Ignore .env so real credentials stay out of git.
| * feat: throttle and time out outbound DeviantArt requestsChristian Cleberg2026-07-143-0/+209
| | | | | | | | | | | | | | | | | | | | | | | | DeviantArt fronts its API with CloudFront + WAF, which bans egress IPs that hit it too hard. devianter issues requests with a bare http.Client, so unbounded concurrent handlers each pulled ~150-200 KB of JSON, which both risked a ban and could exhaust the process under a bot flood. Wrap the default transport to bound rate and concurrency for deviantart.com and add timeouts. Other hosts (wixmp image CDN) pass straight through, so media stays fast, and ProxyFromEnvironment is preserved so HTTPS_PROXY egress still works.
| * fix(api): harden random-art retry loopChristian Cleberg2026-07-141-7/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three bugs in Random(): - The retry loop was unbounded. Only the NSFW path incremented attempt, so a run of DeviantArt errors span forever, hammering the API and risking an egress-IP ban. - string(rand.Intn(999)) converts a rune, not a number: string(65) is "A", not "65". Searches were querying garbage. Use strconv.Itoa. - rand.Intn panics on 0, so an empty result set crashed the handler. Skip empty results. The exhausted-retries error now fires when the loop ends rather than falling through to index an empty slice.
| * deps: migrate to github.com/zerolabsco/devianter v0.3.1Christian Cleberg2026-07-148-14/+14
| | | | | | | | | | | | | | | | | | | | Repoint the import path from git.macaw.me/skunky/devianter, replacing a placeholder v0.0.0 require that had no go.sum entry and did not resolve. v0.3.1 reorders the last two return values of PerformSearch, Group.Get and Group.Gallery from (..., error, Error) to (..., Error, error); adapt the call sites. The two types differ, so the compiler enforces this.
| * build: fix build on darwinChristian Cleberg2026-07-142-2/+17
| | | | | | | | | | | | macOS names the stat ctime field Ctimespec rather than Ctim, so stat.go failed to compile on a Mac. Split the darwin case into its own file and exclude darwin from the generic variant. Deploys are unaffected.
* | Set package ecosystem to 'gomod' in dependabot configChristian Cleberg2026-07-141-0/+11
|/
* documentation & metadata cleanup (#1)Christian Cleberg2026-07-145-130/+98
| | | | | | | * hard wrap LICENSE for readability * translate TODO.md from Russian to English * clean up TODO.md into a proper GFM todo list * fix: remove dead service links and add working links * update README to reflect new repository and structure
* Add da.opnxng.com + lost-skunk.cc is now in Finlandlost+skunk2025-04-0739-4/+16
|
* Add sa.dc09.rulost+skunk2025-03-191-1/+2
|
* Add sa.dc09.rulost+skunk2025-03-191-0/+11
|
* ыlost+skunk2025-02-231-1/+1
|
* Переключатель кеша в озу, небольшие ↵lost+skunk2025-02-227-49/+90
| | | | улучшения ксс, фикс нсфв, фикс максимального размера кеша
* clovius.club >> orehus.clublost+skunk2025-02-112-5/+5
|
* без второго коммита ну никак..lost+skunk2025-01-041-0/+1
|
* New domain and acknowledgement to vlnstlost+skunk2025-01-044-6/+7
|
* Merge pull request 'Docker' (#6) from vlnst/SkunkyArt:Docker into masterlost+skunk2024-11-264-0/+42
|\ | | | | | | Reviewed-on: https://git.macaw.me/skunky/SkunkyArt/pulls/6
| * Add Dockervlnst2024-11-264-0/+42
|/
* забыл нажать ^s...lost+skunk2024-11-151-4/+4
|
* офрцвагргшlost+skunk2024-11-151-2/+0
|
* ыlost+skunk2024-11-156-10/+16
|
* v1.3.2v1.3.2lost+skunk2024-09-2319-124/+230
|
* отображение ошибокlost+skunk2024-09-0411-35/+74
|
* фикс небольшого обосрамсаlost+skunk2024-09-031-1/+2
|
* Два API-эндпоинтаlost+skunk2024-09-0310-47/+114
|
* instance list updatelost+skunk2024-09-0212-43/+91
|
* user favouriteslost+skunk2024-08-149-123/+149
|
* [информативная подпись к коммиту]lost+skunk2024-08-131-1/+1
|
* да бляlost+skunk2024-08-131-1/+1
|
* небольшой обосрамс с примерными ссылкамиlost+skunk2024-08-131-1/+1
|
* темплейты в бинарнике и улучшенная ↵lost+skunk2024-08-1329-303/+555
| | | | система кеша
* instances.test.json -> instances.jsonv1.3.1lost+skunk2024-08-011-1/+1
|