This is a Go implementation of the AO3 API, converted from the original Python version. I made this so quick and I'm currently on vacation so if anyone sees this repo please run tests for me. ;-;
To use this package in your Go project:
# Initialize your Go module if you haven't already
go mod init ao3api
# Add the AO3 API as a dependency
go get github.com/hyperiya/ao3api-gopackage main
import (
"fmt"
"log"
"github.com/hyperiya/ao3api-go/pkg/ao3"
)
func main() {
// Load a work by ID
work := ao3.NewWork(14392692, nil, true, true)
fmt.Printf("Title: %s\n", work.Title)
fmt.Printf("Author: %s\n", work.Authors[0].Username)
fmt.Printf("Chapters: %d\n", work.Nchapters)
fmt.Printf("Words: %d\n", work.Words)
// Get text from the first chapter
if len(work.Chapters) > 0 {
text, err := work.Chapters[0].GetText()
if err != nil {
log.Fatalf("Error getting chapter text: %v", err)
}
fmt.Printf("First 100 characters: %s...\n", text[:100])
}
}package main
import (
"fmt"
"log"
"github.com/hyperiya/ao3api/pkg/ao3"
)
func main() {
// Create a word count constraint
lowerBound := 5000
upperBound := 15000
// Create a search with functional options
search := ao3.NewSearch(
ao3.WithAnyField("Harry Potter"),
ao3.WithWordCount(&ao3.Constraint{
LowerBound: lowerBound,
UpperBound: &upperBound,
}),
ao3.WithSortColumn(ao3.SortKudos),
ao3.WithSortDirection(ao3.SortDirectionDescending),
)
// Execute the search
if err := search.Update(); err != nil {
log.Fatalf("Error searching: %v", err)
}
fmt.Printf("Found %d results\n", search.TotalResults)
// Print the first 5 results
for i, work := range search.Results {
if i >= 5 {
break
}
fmt.Printf("%d. %s by %s\n", i+1, work.Title, work.Authors[0].Username)
}
}package main
import (
"fmt"
"log"
"github.com/hyperiya/ao3api/pkg/ao3"
)
func main() {
// Create a guest session
guestSession := ao3.NewGuestSession()
// Or create an authenticated session
session, err := ao3.NewSession("username", "password")
if err != nil {
log.Fatalf("Error creating session: %v", err)
}
// Use the session to load a work
work := ao3.NewWork(14392692, session, true, true)
// Leave kudos on the work
success, err := work.LeaveKudos()
if err != nil {
log.Printf("Error leaving kudos: %v", err)
} else if success {
fmt.Println("Successfully left kudos!")
} else {
fmt.Println("You've already left kudos on this work")
}
// Get user's bookmarks
bookmarks, err := session.GetBookmarks(true)
if err != nil {
log.Fatalf("Error getting bookmarks: %v", err)
}
fmt.Printf("You have %d bookmarks\n", len(bookmarks))
}package main
import (
"fmt"
"sync"
"time"
"github.com/hyperiya/ao3api/pkg/ao3"
)
func main() {
// Load a series
series := ao3.NewSeries(1295090, nil, true)
// Load all works in the series concurrently
works := make([]*ao3.Work, 0)
var wg sync.WaitGroup
var mutex sync.Mutex
start := time.Now()
for _, work := range series.WorkList {
wg.Add(1)
go func(w *ao3.Work) {
defer wg.Done()
w.Reload(true)
mutex.Lock()
works = append(works, w)
mutex.Unlock()
}(work)
}
wg.Wait()
fmt.Printf("Loaded %d works in %.1f seconds\n", len(works), time.Since(start).Seconds())
}- Load works, chapters, users, and series
- Search for works with various filters
- Download works in different formats
- Leave kudos and comments
- Manage bookmarks and subscriptions
- Concurrent operations for better performance