Compare commits

..

3 Commits

Author SHA1 Message Date
ike
e5a9fa5109 adjust the connector word percentage 2025-08-28 23:12:04 +00:00
ike
c09b66ea65 default to jagged little pill words 2025-08-28 22:59:52 +00:00
ike
2d60d26245 add readme; make links more frequent 2025-08-27 20:42:57 +00:00
7 changed files with 124 additions and 263 deletions

BIN
.DS_Store vendored

Binary file not shown.

25
README.md Normal file
View File

@ -0,0 +1,25 @@
![jaggedpill](jaggedpill.jpg)
# Jagged Pill
Jagged Pill is a webserver that responds to any request with a generated
HTML page containing random text and links. The generator is tuned to be very
nonsensical, but ends up creating some weirdly strange and poetic prose...
keep following links to find more!
I use this as an AI scraper labyrinth (or poison pill), with the following NGINX config:
```
# No AI Bots
if ($http_user_agent ~* '(AIBot|AnotherBot|YetAnotherBot)') {
rewrite ^(.*)$ /clank/$1;
}
location /clank/ {
rewrite ^/clank/(.*)$ $1 break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://localhost:4791;
}
```

12
go.mod
View File

@ -2,14 +2,4 @@ module jaggedpill
go 1.22.1 go 1.22.1
require ( require github.com/mroth/weightedrand/v2 v2.1.0
github.com/mroth/weightedrand/v2 v2.1.0
github.com/schollz/progressbar/v3 v3.18.0
)
require (
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/rivo/uniseg v0.4.7 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/term v0.28.0 // indirect
)

22
go.sum
View File

@ -1,24 +1,2 @@
github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM=
github.com/chengxilo/virtualterm v1.0.4/go.mod h1:DyxxBZz/x1iqJjFxTFcr6/x+jSpqN0iwWCOK1q10rlY=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU= github.com/mroth/weightedrand/v2 v2.1.0 h1:o1ascnB1CIVzsqlfArQQjeMy1U0NcIbBO5rfd5E/OeU=
github.com/mroth/weightedrand/v2 v2.1.0/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU= github.com/mroth/weightedrand/v2 v2.1.0/go.mod h1:f2faGsfOGOwc1p94wzHKKZyTpcJUW7OJ/9U4yfiNAOU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

BIN
jaggedpill.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

110
main.go
View File

@ -3,13 +3,11 @@ package main
import ( import (
"fmt" "fmt"
"github.com/mroth/weightedrand/v2" "github.com/mroth/weightedrand/v2"
"github.com/schollz/progressbar/v3"
"io" "io"
"math/rand" "math/rand"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"slices"
"strings" "strings"
"text/template" "text/template"
"time" "time"
@ -69,7 +67,6 @@ func main() {
var fileFolder = "html_pages" var fileFolder = "html_pages"
var wordTree PocketGraph = isShePervertedLikeMe() var wordTree PocketGraph = isShePervertedLikeMe()
var distances DelusionGraph = weAllHadDelusions(wordTree)
// youOughtaKnow returns an HTTP handler that processes requests. // youOughtaKnow returns an HTTP handler that processes requests.
func youOughtaKnow() http.Handler { func youOughtaKnow() http.Handler {
@ -345,7 +342,7 @@ func iDontWannaBeTheFiller() string {
paragraph := strings.Join(sentences, " ") paragraph := strings.Join(sentences, " ")
// Should paragraph contain link? // Should paragraph contain link?
if rand.Float64() < 0.5 { if rand.Float64() < 0.7 {
// Pick two or three words out of the paragraph // Pick two or three words out of the paragraph
words := strings.Fields(paragraph) words := strings.Fields(paragraph)
if len(words) < 2 { if len(words) < 2 {
@ -384,7 +381,7 @@ func thanksForYourPatience() (string, error) {
return fmt.Sprintf("Error calculating size of file folder %s: %v\n", fileFolder, err), err return fmt.Sprintf("Error calculating size of file folder %s: %v\n", fileFolder, err), err
} }
if size > 10*1024*1024 { // If the size of the folder is greater than 10 MB if size > 10*1024*1024 { // If the size of the folder is greater than 100 MB
// If the file is older than the average file age, delete it // If the file is older than the average file age, delete it
err = filepath.Walk(fileFolder, func(_ string, info os.FileInfo, err error) error { err = filepath.Walk(fileFolder, func(_ string, info os.FileInfo, err error) error {
if err != nil { if err != nil {
@ -427,11 +424,7 @@ func isShePervertedLikeMe() PocketGraph {
} }
// read words.txt into a list // read words.txt into a list
longmanBytes, err := os.ReadFile("word_lists/longman9000.txt") wordsBytes, err := os.ReadFile("word_lists/jaggedpill.txt")
jaggedLittlePillBytes, err := os.ReadFile("word_lists/jaggedlittlepill.txt")
wordsBytes := append(longmanBytes, jaggedLittlePillBytes...)
if err != nil { if err != nil {
fmt.Println("Error reading words.txt:", err) fmt.Println("Error reading words.txt:", err)
} }
@ -440,7 +433,7 @@ func isShePervertedLikeMe() PocketGraph {
tree := make(PocketGraph) tree := make(PocketGraph)
for _, word := range ConnectionWords { for _, word := range ConnectionWords {
var percentageOfWords float64 = 0.02 var percentageOfWords float64 = 0.005
var numberOfConnections = float64(len(words)) * percentageOfWords var numberOfConnections = float64(len(words)) * percentageOfWords
for j := 0; j < int(numberOfConnections); j++ { for j := 0; j < int(numberOfConnections); j++ {
randomWord := words[rand.Intn(len(words))] randomWord := words[rand.Intn(len(words))]
@ -465,7 +458,7 @@ func isShePervertedLikeMe() PocketGraph {
// connect word to connector words? // connect word to connector words?
shouldConnect := rand.Intn(2) == 0 shouldConnect := rand.Intn(2) == 0
if shouldConnect { if shouldConnect {
numConnectionWords := rand.Intn(2) + 1 numConnectionWords := rand.Intn(len(ConnectionWords)) + 1 // Random number of connection words between 1 and 3
for j := 0; j < numConnectionWords; j++ { for j := 0; j < numConnectionWords; j++ {
connectionWord := ConnectionWords[rand.Intn(len(ConnectionWords))] connectionWord := ConnectionWords[rand.Intn(len(ConnectionWords))]
tree[word] = append(tree[word], connectionWord) tree[word] = append(tree[word], connectionWord)
@ -475,50 +468,6 @@ func isShePervertedLikeMe() PocketGraph {
return tree return tree
} }
type DelusionGraph map[string]map[string]int
func weAllHadDelusions(m PocketGraph) DelusionGraph {
distances := make(DelusionGraph)
bar := progressbar.Default(int64(len(m)*len(m)), "Calculating distances...")
// Initialize distances for each word
for word := range m {
distances[word] = make(map[string]int)
for otherWord := range m {
if word == otherWord {
distances[word][otherWord] = 0 // Distance to itself is 0
} else if slices.Contains(m[word], otherWord) {
distances[word][otherWord] = 1 // Direct connection
}
bar.Add(1)
}
}
for word, linkedWords := range m {
for _, linkedWord := range linkedWords {
if _, exists := distances[word][linkedWord]; !exists {
distances[word][linkedWord] = 1 // Direct connection
}
for otherWord, distance := range distances[linkedWord] {
if otherWord == word {
continue // Skip self-distance
}
if _, exists := distances[word][otherWord]; !exists {
distances[word][otherWord] = distance + 1 // Update distance
} else {
// If the distance is shorter, update it
if distance+1 < distances[word][otherWord] {
distances[word][otherWord] = distance + 1
}
}
}
}
}
return distances
}
// forgiveMeLove generates N random words from the tree // forgiveMeLove generates N random words from the tree
func (m PocketGraph) forgiveMeLove(n int) Words { func (m PocketGraph) forgiveMeLove(n int) Words {
if n <= 0 { if n <= 0 {
@ -528,49 +477,18 @@ func (m PocketGraph) forgiveMeLove(n int) Words {
// Create a slice to hold the random words // Create a slice to hold the random words
randomWords := make(Words, 0, n) randomWords := make(Words, 0, n)
// Pick 30% of N words out of the tree at random // Generate N random words from the tree
numWords := int(float64(n) * 0.3) word := m[iWentToYourHouse(m)] // Start with a random word from the tree
for i := 0; i < numWords; i++ { for i := 0; i < n-1; i++ {
randomWord := iWentToYourHouse(m) if len(word) == 0 {
if randomWord == "" {
continue // Skip if the word is empty
}
randomWords = append(randomWords, randomWord)
}
// Connect the randomWords together using words that are linked to them, refering to distance
for i := 0; i < len(randomWords) && len(randomWords) <= n; i++ {
if len(randomWords) >= n {
break break
} }
if len(randomWords[i]) == 0 { random := rand.Intn(len(word))
continue // Skip empty words nextWord := word[random] // Randomly select a word from the current word's linked words
} randomWords = append(randomWords, nextWord)
// Get the linked words for the random word word = m[nextWord] // Update the word to the next linked word
wordDistances := distances[randomWords[i]]
if len(wordDistances) == 0 {
continue // Skip if there are no linked words
}
// do any of the random words link to each other?
for j := 0; j < len(randomWords); j++ {
if i == j || len(randomWords[j]) == 0 {
continue // Skip self or empty words
}
// Check if the random word links to the other random word
if distance, exists := wordDistances[randomWords[j]]; exists && distance > 0 {
// If they are linked, connect them by adding the other random word to the slice
if !slices.Contains(randomWords, randomWords[j]) {
randomWords = append(randomWords, randomWords[j])
}
}
for linkedWord, dist := range distances[randomWords[j]] {
if dist > 0 && !slices.Contains(randomWords, linkedWord) {
randomWords = append(randomWords, linkedWord)
}
}
}
} }
return randomWords return randomWords
} }

View File

@ -1,22 +1,24 @@
a
able able
about about
abvious
adored adored
advice advice
afraid afraid
afternoon
again again
ah
air air
alarmed alarmed
alive alive
all All
alleluia Alleluia
along along
already already
alright alright
am am
ammunition ammunition
amount amount
an An
and and
angry angry
any any
@ -44,21 +46,17 @@ back
back-loaded back-loaded
backwards backwards
bandage bandage
bath
be be
bear bear
bearer bearer
beat beat
beautiful beautiful
bed
been been
before before
believe believe
bell
bend bend
benefits benefits
best best
better
big big
bills bills
biting biting
@ -81,8 +79,7 @@ broke
brothers brothers
bruises bruises
bug bug
burned But
but
by by
cab cab
calm calm
@ -93,14 +90,13 @@ carry
cars cars
case case
catch catch
catholic Catholic
cause Cause
caution caution
cds
censor censor
certainly certainly
chance chance
chardonnay Chardonnay
chew chew
chicken chicken
child child
@ -110,18 +106,16 @@ choir
choke choke
choose choose
cigarette cigarette
ck
clears clears
cling cling
close
clothes
coaster coaster
cologne
come come
comes comes
comfort comfort
coming coming
common common
compared Compared
concept concept
confessed confessed
conflicts conflicts
@ -142,7 +136,6 @@ cry
crying crying
damn damn
dance dance
danced
darkest darkest
day day
deadlines deadlines
@ -152,10 +145,8 @@ deeds
deeper deeper
deliverance deliverance
delusions delusions
den
deny deny
desk Did
did
didn't didn't
die die
died died
@ -166,33 +157,31 @@ direction
dissect dissect
distraction distraction
disturb disturb
do Do
doctor Doctor
does Does
doesn't doesn't
doing doing
don't don't
door door
down down
drawer drawer
drawers
dream dream
dreams dreams
drift drift
drunk drunk
dry dry
duplicity Duplicity
dust dust
easier easier
easy easy
egg egg
eloquently eloquently
else else
else's
empty empty
enough Enough
envious envious
estella Estella
eventually eventually
ever ever
every every
@ -201,21 +190,19 @@ everything's
ex ex
excellent excellent
excuse excuse
eyes
face face
fade
fair fair
fall fall
falling falling
farther farther
fascinated fascinated
fast fast
father Father
fault fault
feel feel
feelings feelings
feels feels
feet Feet
fell fell
felt felt
few few
@ -239,10 +226,8 @@ food
foot foot
for for
forget forget
forgive Forgiven
forgiven
forgot forgot
found
fountain fountain
fractured fractured
free free
@ -255,7 +240,6 @@ friends
frightened frightened
from from
frustrated frustrated
fuck
full full
fun fun
fundamental fundamental
@ -290,8 +274,7 @@ gunshot
had had
hailing hailing
half half
hall Hand
hand
handle handle
hands hands
happy happy
@ -301,22 +284,21 @@ has
hate hate
have have
haven't haven't
he He
head head
heading heading
heads
healthy healthy
hear hear
heart heart
heights heights
held held
hello Hello
help help
helping helping
her her
here Here
hey Hey
hidden Hidden
high high
him him
his his
@ -324,12 +306,9 @@ hold
holds holds
hole hole
holes holes
home
honest honest
hope
hopeful hopeful
hours hours
house
how how
humble humble
humbled humbled
@ -338,37 +317,33 @@ hunt
hunter hunter
hurry hurry
hurt hurt
i I
i'd I'd
i'll I'll
i'm I'm
i've I've
idol idol
if if
impatient impatient
in in
incense
information information
inhaling inhaling
innocent innocent
inquisition inquisition
inside inside
insist insist
insistence insistance
intellectual intellectual
intercourse intercourse
into Ironic
ironic
is is
isn't isn't
it it
it's It's
its
jagged jagged
jam jam
jane Jane
joke joke
joni
jump jump
jumping jumping
just just
@ -382,8 +357,7 @@ kindred
kissed kissed
knife knife
knock knock
know Know
laid
land land
last last
late late
@ -393,9 +367,8 @@ learn
learned learned
least least
left left
lend Lend
let's let's
letter
life life
light light
like like
@ -421,7 +394,8 @@ maker
malt malt
man man
many many
mary Mary
mate
matter matter
matters matters
may may
@ -432,20 +406,19 @@ mean
measure measure
meet meet
meeting meeting
melt Melt
merely merely
mess mess
met met
middle middle
midnight midnight
might Mind
mind
minds minds
mine mine
minute minute
minutes minutes
mispronounced mispronounced
miss Miss
moment moment
money money
months months
@ -453,11 +426,10 @@ more
mother mother
motto motto
mouth mouth
mr Mr
much much
must must
my My
nails
naked naked
name name
nature nature
@ -471,13 +443,12 @@ ninety-eight
no no
not not
nothing nothing
noticed
now now
obvious obvious
occasion occasion
of of
off off
oh Oh
okay okay
old old
older older
@ -486,13 +457,13 @@ one
one's one's
only only
open open
opened Or
or
other other
oughta Oughta
our our
out out
over outta
Over
overwhelmed overwhelmed
own own
packed packed
@ -506,8 +477,7 @@ patience
peace peace
peaceful peaceful
pedestal pedestal
perfect Perfect
permission
perverted perverted
petrified petrified
piano piano
@ -517,11 +487,11 @@ pill
pity pity
place place
plane plane
play-it-safe Play
played played
playing playing
please Please
pocket Pocket
point point
poor poor
pray pray
@ -533,18 +503,16 @@ problem
proud proud
prouder prouder
puppet puppet
push Push
put
question question
quickly quickly
quiet quiet
quite quite
rain rain
raising Raising
ran
rational rational
rays rays
really Really
reasons reasons
receive receive
recommend recommend
@ -558,24 +526,20 @@ resistance
responsible responsible
restless restless
ride ride
right Right
ringing
robe
roller roller
room room
rose rose
row row
ruler ruler
sad sad
Safe
said said
salt
sane sane
sang sang
sat
saviors saviors
say say
scan scan
scratch
scream scream
screw screw
see see
@ -592,9 +556,7 @@ shells
shit shit
short short
should should
shouldn't
show show
shower
sick sick
sign sign
silence silence
@ -603,10 +565,8 @@ single
sinners sinners
sir sir
sit sit
six Skeptic
skeptic Slap
slap
smell
smile smile
smoke smoke
smoking smoking
@ -619,14 +579,12 @@ solely
solitary solitary
some some
someday someday
someone Someone
something something
sometimes Sometimes
son Son
soon
sorry sorry
soul soul
soulmate
sound sound
speak speak
speed speed
@ -635,9 +593,7 @@ spit
spite spite
splintered splintered
spoons spoons
stairs
stated stated
stay
sticking sticking
still still
stomach stomach
@ -648,10 +604,10 @@ stupid
substitute substitute
suffer suffer
suitcase suitcase
sunday Sunday
sure sure
surprised surprised
swallow Swallow
swallowed swallowed
sweater sweater
sweeper sweeper
@ -667,29 +623,29 @@ tell
ten ten
than than
thank thank
thanks Thanks
that that
that's That's
the the
theatre theatre
then then
there there
there's There's
they they
thick thick
thing Thing
things things
think think
thinking thinkin'
this this
thought thought
thousand thousand
three-year-old three-year-old
thrill thrill
through through
throw Throw
ticket ticket
til Til
time time
times times
tired tired
@ -706,7 +662,7 @@ trampled
treat treat
trembling trembling
trucks trucks
try Try
trying trying
turned turned
two two
@ -723,17 +679,15 @@ value
version version
very very
vicarious vicarious
visiting Visiting
voice voice
void void
wait Wait
waited waited
wake Wake
walk walk
walked
walking walking
wanna Want
want
wanted wanted
warm warm
was was
@ -742,7 +696,7 @@ wavelength
way way
ways ways
we we
we'll We'll
wear wear
wedding wedding
week week
@ -750,9 +704,8 @@ weight
well well
went went
what what
what's What's
when when
where
while while
whiskey whiskey
who who
@ -768,28 +721,25 @@ wine
wise wise
wish wish
with with
without
womb womb
won won
wonder wonder
woo
word word
working working
worry Worry
would would
would've would've
wouldn't wouldn't
wound wound
wounded wounded
writing
wrong wrong
yeah yeah
yet yet
you you
you'd You'd
you'll you'll
you're you're
you've You've
young young
your your
yours yours