summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-08-07 18:09:39 -0500
committerChristian Cleberg <[email protected]>2026-08-07 18:11:47 -0500
commitddb8aa297962379fa7731032140221ba35f84b50 (patch)
tree8a0d85912ddd41d34f6d4832b0e3c1dcaecbccd0
parentad54fbcda1ba7f654dc27c06bf22f2628f6c7cf4 (diff)
downloadskunky-art-ddb8aa297962379fa7731032140221ba35f84b50.tar.gz
skunky-art-ddb8aa297962379fa7731032140221ba35f84b50.tar.bz2
skunky-art-ddb8aa297962379fa7731032140221ba35f84b50.zip
feat: add hide-ai option to omit AI-generated deviationsv1.3.8
Adds a hide-ai config flag that drops deviations flagged data.AI from every listing (search, daily, galleries, favourites) in the shared DeviationList loop, analogous to how nsfw gates mature content. The flag is already parsed and shown as a marker, so this is a filter over existing data. Off by default. Closes #15
-rwxr-xr-xSETUP.txt2
-rwxr-xr-xapp/config.go1
-rwxr-xr-xapp/parsers.go3
-rw-r--r--app/parsers_test.go58
-rwxr-xr-xconfig.example.json3
5 files changed, 66 insertions, 1 deletions
diff --git a/SETUP.txt b/SETUP.txt
index 987041a..cbc61fa 100755
--- a/SETUP.txt
+++ b/SETUP.txt
@@ -35,6 +35,8 @@ Time units:
DeviantArt's CDN. Required by `cache`; when off, clients fetch images from
wixmp directly.
* `nsfw` — Show mature content.
+* `hide-ai` — Omit AI-generated deviations (those flagged `[🤖]`) from all
+ listings: search, daily deviations, galleries and favourites.
# Setting up reverse proxy
Pretty much business as usual, except for the [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) header setting.
diff --git a/app/config.go b/app/config.go
index 2faa69d..b790f71 100755
--- a/app/config.go
+++ b/app/config.go
@@ -34,6 +34,7 @@ type config struct {
Cache cacheConfig `json:"cache"`
Proxy bool `json:"proxy"`
Nsfw bool `json:"nsfw"`
+ HideAI bool `json:"hide-ai"`
UserAgent string `json:"user-agent"`
DownloadProxy string `json:"download-proxy"`
StaticPath string `json:"static-path"`
diff --git a/app/parsers.go b/app/parsers.go
index 68fdbe4..2027503 100755
--- a/app/parsers.go
+++ b/app/parsers.go
@@ -92,6 +92,9 @@ func (s skunkyart) DeviationList(devs []devianter.Deviation, allowAtom bool, con
for i, l := 0, len(devs); i < l; i++ {
data := &devs[i]
+ if data.AI && CFG.HideAI {
+ continue
+ }
if preview, fullview := ParseMedia(s.Host, data.Media, 320), ParseMedia(s.Host, data.Media); !data.NSFW || CFG.Nsfw {
if allowAtom && s.Atom {
s.Writer.Header().Add("Content-Type", "application/atom+xml")
diff --git a/app/parsers_test.go b/app/parsers_test.go
new file mode 100644
index 0000000..3d42bb4
--- /dev/null
+++ b/app/parsers_test.go
@@ -0,0 +1,58 @@
+package app
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/krazywarez/devianter"
+)
+
+// aiListDevs returns one human-made and one AI-flagged deviation, each with a
+// distinct title so the rendered output can be searched for either one.
+func aiListDevs() []devianter.Deviation {
+ human := devianter.Deviation{Title: "HumanArt"}
+ human.Author.Username = "alice"
+
+ robot := devianter.Deviation{Title: "RobotArt", AI: true}
+ robot.Author.Username = "bob"
+
+ return []devianter.Deviation{human, robot}
+}
+
+// TestDeviationListHidesAIWhenConfigured is the regression test for the hide-ai
+// option: with it on, deviations flagged data.AI must not appear in a listing at
+// all, while human-made ones are untouched.
+func TestDeviationListHidesAIWhenConfigured(t *testing.T) {
+ nsfw, hide := CFG.Nsfw, CFG.HideAI
+ CFG.Nsfw, CFG.HideAI = true, true
+ defer func() { CFG.Nsfw, CFG.HideAI = nsfw, hide }()
+
+ out := skunkyart{Host: "http://localhost"}.DeviationList(aiListDevs(), false)
+
+ if !strings.Contains(out, "HumanArt") {
+ t.Error("human deviation was dropped, want it kept")
+ }
+ if strings.Contains(out, "RobotArt") {
+ t.Error("AI deviation rendered while hide-ai is on, want it omitted")
+ }
+ if strings.Contains(out, "🤖") {
+ t.Error("AI marker present while hide-ai is on")
+ }
+}
+
+// TestDeviationListShowsAIByDefault pins down that the filter is opt-in: with
+// hide-ai off the AI deviation is still listed and still carries its marker.
+func TestDeviationListShowsAIByDefault(t *testing.T) {
+ nsfw, hide := CFG.Nsfw, CFG.HideAI
+ CFG.Nsfw, CFG.HideAI = true, false
+ defer func() { CFG.Nsfw, CFG.HideAI = nsfw, hide }()
+
+ out := skunkyart{Host: "http://localhost"}.DeviationList(aiListDevs(), false)
+
+ if !strings.Contains(out, "RobotArt") {
+ t.Error("AI deviation dropped while hide-ai is off, want it kept")
+ }
+ if !strings.Contains(out, "🤖") {
+ t.Error("AI marker missing while hide-ai is off")
+ }
+}
diff --git a/config.example.json b/config.example.json
index f3186f1..c90886e 100755
--- a/config.example.json
+++ b/config.example.json
@@ -13,5 +13,6 @@
"download-proxy": "",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
"proxy": true,
- "nsfw": false
+ "nsfw": false,
+ "hide-ai": false
}