diff options
| author | Christian Cleberg <[email protected]> | 2026-07-15 17:26:22 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-07-15 17:26:22 -0500 |
| commit | b80180e77eebad8476aa66c8a5433764da672c62 (patch) | |
| tree | 3078b122345c45a4bd8a5477ae21ad63fa56f13d /doc.go | |
| parent | b70d3dd588c8f9d6c9ed0ff111af06b76fa1f6ba (diff) | |
| download | devianter-b80180e77eebad8476aa66c8a5433764da672c62.tar.gz devianter-b80180e77eebad8476aa66c8a5433764da672c62.tar.bz2 devianter-b80180e77eebad8476aa66c8a5433764da672c62.zip | |
docs: document the exported API, and fix five bugs found writing it (#2)v0.3.2
* docs: translate Russian comments and document exported API
The package carried 35 Russian comments and no doc comments on its
exported identifiers, so pkg.go.dev rendered a bare list of signatures.
Translate the Russian to English and give every exported identifier a
doc comment in godoc form. Add doc.go with a package overview covering
the guest-session requirement, the Error-as-struct convention, and
CloudFront blocking.
The comments record what the signatures cannot: that UpdateCSRF must run
first and that its token expires, that Error is a struct and so is never
nil, that Thread is one comment rather than a thread, and that
GetComments' page parameter costs one request per page.
Comments only; the struct field realignment is gofmt's, from doc comments
splitting alignment groups.
Refs #1
* add CODEOWNERS
* fix: stop the library killing its caller, and flatten text correctly
Writing doc comments for the exported API surfaced behavior too alarming
to document and leave alone. A library should never terminate the process
that imports it.
Crashes:
- GetComments panicked on a comment with an empty body: the shape check
read m[0] and m[len(m)-1] with no length check.
- Group.Favourites and Group.Gallery indexed their variadic folderid
without checking len, so omitting it — which the signature invites —
panicked. Omitting it now means 0.
- AEmedia and PerformSearch called log.Fatalln on a bad argument rune,
terminating the caller. Both now return an error, which their
signatures already allowed for.
Draft.js flattening, in the same code both callers share:
- The block loop assigned rather than accumulated, so every block but the
last was dropped and a multi-paragraph body came back as its closing
line alone. Blocks are block-level elements, so join them with newlines.
- GetDeviation guarded on txt[1] == '{', the second character of a body
that opens with {"blocks". It never fired, so descriptions were handed
back as raw Draft.js JSON. It now shares flattenComment with
GetComments rather than keeping its own copy.
Both flattening fixes change output for existing callers.
Refs #1
Diffstat (limited to 'doc.go')
| -rw-r--r-- | doc.go | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -0,0 +1,45 @@ +// Package devianter is a client for DeviantArt's internal "_puppy" API, the +// JSON backend that deviantart.com's own web frontend calls. +// +// This is not the official, documented DeviantArt API. There is no application +// registration and no OAuth: the package authenticates the way a logged-out +// browser does, by fetching a guest session cookie and a CSRF token from the +// homepage. Everything reachable here is what an anonymous visitor can see. +// Because the endpoints are internal, DeviantArt can change or remove them +// without notice. +// +// # Usage +// +// Call [UpdateCSRF] once before anything else to establish the guest session. +// Every other call depends on the cookie and token it stores, and will fail +// until it has run: +// +// if err := devianter.UpdateCSRF(); err != nil { +// log.Fatal(err) +// } +// +// post, apiErr := devianter.GetDeviation("123456789", "someuser") +// if apiErr.Reason != "" { +// log.Fatal(apiErr.Error) +// } +// fmt.Println(post.Deviation.Title, post.IMG) +// +// The session does not refresh itself. A long-running program should call +// [UpdateCSRF] again when calls start failing, since tokens expire. +// +// # Errors +// +// Most functions return an [Error] value rather than a Go error. It is a struct, +// not an interface, so it is never nil; a call succeeded if Error.Reason is +// empty. Functions that can also fail on their arguments before any request is +// made (such as [PerformSearch] and [Group.Gallery]) return an ordinary error +// alongside it for that case. +// +// # Rate limiting and blocking +// +// DeviantArt sits behind CloudFront, which blocks IP addresses that request too +// aggressively. A blocked request surfaces as an [Error] whose Error field +// mentions CloudFront/WAF. This package does no rate limiting, retrying, or +// backoff of its own; a caller making bulk requests is expected to pace itself. +// Set [UserAgent] to identify your client and [Timeout] to bound each request. +package devianter |
