implement_new_e621_sdk_#17 (#18)
As mentioned in #17, I implemented the new SDK. I removed the scheduler and executor code since they were no longer needed. Reviewed-on: anthrove/e621-to-graph#18 Reviewed-by: Lennard Brinkhaus <lennard.brinkhaus@noreply.localhost> Reviewed-by: daskadse <daskadse@noreply.localhost> Co-authored-by: SoXX <soxx@fenpa.ws> Co-committed-by: SoXX <soxx@fenpa.ws>
This commit is contained in:
parent
b6d0f4d63f
commit
60b3502ee3
@ -14,7 +14,7 @@ jobs:
|
|||||||
uses: https://github.com/actions/setup-go@v3
|
uses: https://github.com/actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
# The Go version to download (if necessary) and use. Supports semver spec and ranges.
|
# The Go version to download (if necessary) and use. Supports semver spec and ranges.
|
||||||
go-version: 1.20 # optional
|
go-version: 1.21.3 # optional
|
||||||
# Path to the go.mod file.
|
# Path to the go.mod file.
|
||||||
go-version-file: ./go.mod # optional
|
go-version-file: ./go.mod # optional
|
||||||
# Set this option to true if you want the action to always check for the latest available version that satisfies the version spec
|
# Set this option to true if you want the action to always check for the latest available version that satisfies the version spec
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
FROM golang:alpine as builder
|
FROM golang:alpine as builder
|
||||||
|
|
||||||
WORKDIR /go/src/git.dragse.it/fenpaws/e621-to-neo4j
|
WORKDIR /go/src/git.dragse.it/fenpaws/e621-to-graph
|
||||||
|
|
||||||
RUN apk add -U --no-cache ca-certificates && update-ca-certificates
|
RUN apk add -U --no-cache ca-certificates && update-ca-certificates
|
||||||
|
|
||||||
@ -8,8 +8,8 @@ COPY go.mod go.sum ./
|
|||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
|
||||||
COPY . ./
|
COPY . ./
|
||||||
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags "-w -s" -o /app
|
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags "-w -s" -o /app ./cmd/scraper/
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/api"
|
"git.dragse.it/anthrove/e621-to-graph/internal/api"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/config"
|
"git.dragse.it/anthrove/e621-to-graph/internal/config"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/database/neo4j"
|
"git.dragse.it/anthrove/e621-to-graph/internal/database/neo4j"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/e621"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -42,9 +42,9 @@ func main() {
|
|||||||
}).Info("main: database connection successful")
|
}).Info("main: database connection successful")
|
||||||
|
|
||||||
// Initialize the e621API
|
// Initialize the e621API
|
||||||
e621Client := e621.NewClient(appConfig.E621APIKey, appConfig.E621Username)
|
client := e621.NewClient(appConfig.E621Username, appConfig.E621APIKey)
|
||||||
// Register the ScapeUserFavourites with the "/user" route
|
// Register the ScapeUserFavourites with the "/user" route
|
||||||
http.HandleFunc("/user", api.ScapeUserFavourites(ctx, graphConnection, e621Client))
|
http.HandleFunc("/user", api.ScapeUserFavourites(ctx, graphConnection, &client))
|
||||||
|
|
||||||
// Start the HTTP server
|
// Start the HTTP server
|
||||||
err = http.ListenAndServe(":8080", nil)
|
err = http.ListenAndServe(":8080", nil)
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
build: .
|
image: anthrove/e621-to-graph:latest
|
||||||
|
build:
|
||||||
|
context: ../.
|
||||||
|
dockerfile: build/package/Dockerfile
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
env_file: .env
|
env_file: .env
|
||||||
|
11
go.mod
11
go.mod
@ -1,12 +1,17 @@
|
|||||||
module git.dragse.it/anthrove/e621-to-graph
|
module git.dragse.it/anthrove/e621-to-graph
|
||||||
|
|
||||||
go 1.20
|
go 1.21.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
git.dragse.it/anthrove/e621-sdk-go v1.3.0
|
||||||
github.com/caarlos0/env v3.5.0+incompatible
|
github.com/caarlos0/env v3.5.0+incompatible
|
||||||
github.com/neo4j/neo4j-go-driver/v5 v5.8.1
|
github.com/neo4j/neo4j-go-driver/v5 v5.8.1
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
golang.org/x/time v0.3.0
|
|
||||||
)
|
)
|
||||||
|
|
||||||
require golang.org/x/sys v0.9.0 // indirect
|
require (
|
||||||
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
|
golang.org/x/sys v0.9.0 // indirect
|
||||||
|
golang.org/x/time v0.3.0 // indirect
|
||||||
|
)
|
||||||
|
6
go.sum
6
go.sum
@ -1,8 +1,14 @@
|
|||||||
|
git.dragse.it/anthrove/e621-sdk-go v1.3.0 h1:sbjrOps4WxXf42kyNb8ZVxC6dCiFrCkqv4C8BgKkIGA=
|
||||||
|
git.dragse.it/anthrove/e621-sdk-go v1.3.0/go.mod h1:urFl0jjx2UK8Vz1tMI253CvWK8fZqd/a9+xdE8ZBwq4=
|
||||||
github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yixi/rBrKyJs=
|
github.com/caarlos0/env v3.5.0+incompatible h1:Yy0UN8o9Wtr/jGHZDpCBLpNrzcFLLM2yixi/rBrKyJs=
|
||||||
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
|
github.com/caarlos0/env v3.5.0+incompatible/go.mod h1:tdCsowwCzMLdkqRYDlHpZCp2UooDD3MspDBjZ2AD02Y=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
|
||||||
|
github.com/jarcoal/httpmock v1.3.1/go.mod h1:3yb8rc4BI7TCBhFY8ng0gjuLKJNquuDNiPaZjnENuYg=
|
||||||
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/neo4j/neo4j-go-driver/v5 v5.8.1 h1:IysKg6KJIUgyItmnHRRrt2N8srbd6znMslRW3qQErTQ=
|
github.com/neo4j/neo4j-go-driver/v5 v5.8.1 h1:IysKg6KJIUgyItmnHRRrt2N8srbd6znMslRW3qQErTQ=
|
||||||
github.com/neo4j/neo4j-go-driver/v5 v5.8.1/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=
|
github.com/neo4j/neo4j-go-driver/v5 v5.8.1/go.mod h1:Vff8OwT7QpLm7L2yYr85XNWe9Rbqlbeb9asNXJTHO4k=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
@ -3,7 +3,7 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/e621"
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/service"
|
"git.dragse.it/anthrove/e621-to-graph/internal/service"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// ScapeUserFavourites is the handler for the user API
|
// ScapeUserFavourites is the handler for the user API
|
||||||
func ScapeUserFavourites(ctx context.Context, graphConnection logic.GraphConnection, e621Client *e621.Client) func(response http.ResponseWriter, request *http.Request) {
|
func ScapeUserFavourites(ctx context.Context, graphConnection logic.GraphConnection, client *e621.Client) func(response http.ResponseWriter, request *http.Request) {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||||
@ -27,7 +27,7 @@ func ScapeUserFavourites(ctx context.Context, graphConnection logic.GraphConnect
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Perform further processing with the username
|
// Perform further processing with the username
|
||||||
go service.ScrapeUser(ctx, graphConnection, *e621Client, username)
|
go service.ScrapeUser(ctx, graphConnection, client, username)
|
||||||
|
|
||||||
// Send a response
|
// Send a response
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
@ -2,7 +2,7 @@ package neo4j
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
||||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j/config"
|
"github.com/neo4j/neo4j-go-driver/v5/neo4j/config"
|
||||||
@ -20,19 +20,19 @@ func NewNeo4JConnection(neo4jDebug bool) logic.GraphConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) CheckUserToPostLink(ctx context.Context, e621PostID int64, e621UserID int64) (bool, error) {
|
func (c *neo4jConnection) CheckUserToPostLink(ctx context.Context, e621PostID model.PostID, e621UserID model.UserID) (bool, error) {
|
||||||
return RelationshipCheckUserToPost(ctx, c.driver, e621PostID, e621UserID)
|
return CheckUserToPostLink(ctx, c.driver, e621PostID, e621UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) EstablishPostToTagLink(ctx context.Context, e621PostID int64, e621Tag string) error {
|
func (c *neo4jConnection) EstablishPostToTagLink(ctx context.Context, e621PostID model.PostID, e621Tag string) error {
|
||||||
return EstablishPostTagLink(ctx, c.driver, e621PostID, e621Tag)
|
return EstablishPostTagLink(ctx, c.driver, e621PostID, e621Tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) EstablishPostToSourceLink(ctx context.Context, e621PostID int64, sourceURL string) error {
|
func (c *neo4jConnection) EstablishPostToSourceLink(ctx context.Context, e621PostID model.PostID, sourceURL string) error {
|
||||||
return EstablishPostToSourceLink(ctx, c.driver, e621PostID, sourceURL)
|
return EstablishPostToSourceLink(ctx, c.driver, e621PostID, sourceURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) EstablishUserToPostLink(ctx context.Context, e621PostID int64, e621UserID int64) error {
|
func (c *neo4jConnection) EstablishUserToPostLink(ctx context.Context, e621PostID model.PostID, e621UserID model.UserID) error {
|
||||||
return EstablishUserToPostLink(ctx, c.driver, e621PostID, e621UserID)
|
return EstablishUserToPostLink(ctx, c.driver, e621PostID, e621UserID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,15 +40,15 @@ func (c *neo4jConnection) UploadTag(ctx context.Context, name string, tagType st
|
|||||||
return CreateTagNode(ctx, c.driver, name, tagType)
|
return CreateTagNode(ctx, c.driver, name, tagType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) UploadPost(ctx context.Context, e621ID int64) error {
|
func (c *neo4jConnection) UploadPost(ctx context.Context, postID model.PostID) error {
|
||||||
return CreatePostNode(ctx, c.driver, e621ID)
|
return CreatePostNode(ctx, c.driver, postID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) UploadSource(ctx context.Context, SourceURL string) error {
|
func (c *neo4jConnection) UploadSource(ctx context.Context, SourceURL string) error {
|
||||||
return CreateSourceNode(ctx, c.driver, SourceURL)
|
return CreateSourceNode(ctx, c.driver, SourceURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *neo4jConnection) UploadUser(ctx context.Context, user model.E621User) error {
|
func (c *neo4jConnection) UploadUser(ctx context.Context, user model.User) error {
|
||||||
return CreateUserNode(ctx, c.driver, user)
|
return CreateUserNode(ctx, c.driver, user)
|
||||||
}
|
}
|
||||||
func (c *neo4jConnection) Connect(ctx context.Context, endpoint string, username string, password string) error {
|
func (c *neo4jConnection) Connect(ctx context.Context, endpoint string, username string, password string) error {
|
||||||
|
@ -2,16 +2,17 @@ package neo4j
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model"
|
||||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreatePostNode(ctx context.Context, driver neo4j.DriverWithContext, e621ID int64) error {
|
func CreatePostNode(ctx context.Context, driver neo4j.DriverWithContext, postID model.PostID) error {
|
||||||
query := `
|
query := `
|
||||||
MERGE (u:e621Post {e621PostID: $e621ID})
|
MERGE (u:e621Post {e621PostID: $postID})
|
||||||
RETURN u
|
RETURN u
|
||||||
`
|
`
|
||||||
params := map[string]any{
|
params := map[string]any{
|
||||||
"e621ID": e621ID,
|
"postID": postID,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer)
|
_, err := neo4j.ExecuteQuery(ctx, driver, query, params, neo4j.EagerResultTransformer)
|
||||||
|
@ -2,11 +2,12 @@ package neo4j
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model"
|
||||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func EstablishPostTagLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID int64, e621Tag string) error {
|
func EstablishPostTagLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID model.PostID, e621Tag string) error {
|
||||||
query := `
|
query := `
|
||||||
MATCH (p:e621Post {e621PostID: $e621PostID})
|
MATCH (p:e621Post {e621PostID: $e621PostID})
|
||||||
MATCH (t:e621Tag {e621Tag: $e621Tag})
|
MATCH (t:e621Tag {e621Tag: $e621Tag})
|
||||||
@ -29,7 +30,7 @@ func EstablishPostTagLink(ctx context.Context, driver neo4j.DriverWithContext, e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func EstablishPostToSourceLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID int64, sourceURL string) error {
|
func EstablishPostToSourceLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID model.PostID, sourceURL string) error {
|
||||||
query := `
|
query := `
|
||||||
MATCH (p:e621Post {e621PostID: $e621PostID})
|
MATCH (p:e621Post {e621PostID: $e621PostID})
|
||||||
MATCH (s:Source {URL: $sourceURL})
|
MATCH (s:Source {URL: $sourceURL})
|
||||||
@ -52,7 +53,7 @@ func EstablishPostToSourceLink(ctx context.Context, driver neo4j.DriverWithConte
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID int64, e621UserID int64) error {
|
func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID model.PostID, e621UserID model.UserID) error {
|
||||||
query := `
|
query := `
|
||||||
MATCH (p:e621Post {e621PostID: $e621PostID})
|
MATCH (p:e621Post {e621PostID: $e621PostID})
|
||||||
MATCH (u:e621User {e621ID: $e621ID})
|
MATCH (u:e621User {e621ID: $e621ID})
|
||||||
@ -74,8 +75,8 @@ func EstablishUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckUserToPostRelationship gives back a bool if the connection between the post and the user exists
|
// CheckUserToPostLink gives back a bool if the connection between the post and the user exists
|
||||||
func RelationshipCheckUserToPost(ctx context.Context, driver neo4j.DriverWithContext, e621PostID int64, e621UserID int64) (bool, error) {
|
func CheckUserToPostLink(ctx context.Context, driver neo4j.DriverWithContext, e621PostID model.PostID, e621UserID model.UserID) (bool, error) {
|
||||||
query := `
|
query := `
|
||||||
MATCH (user:e621User {e621ID: $e621ID})-[favorite:IS_FAVORITE]->(post:e621Post {e621PostID: $e621PostID})
|
MATCH (user:e621User {e621ID: $e621ID})-[favorite:IS_FAVORITE]->(post:e621Post {e621PostID: $e621PostID})
|
||||||
RETURN COUNT(favorite) > 0 AS isFavorite
|
RETURN COUNT(favorite) > 0 AS isFavorite
|
||||||
|
@ -2,11 +2,11 @@ package neo4j
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model"
|
||||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CreateUserNode(ctx context.Context, driver neo4j.DriverWithContext, user model.E621User) error {
|
func CreateUserNode(ctx context.Context, driver neo4j.DriverWithContext, user model.User) error {
|
||||||
query := `
|
query := `
|
||||||
MERGE (u:e621User {e621ID: $id, e621Username: $name})
|
MERGE (u:e621User {e621ID: $id, e621Username: $name})
|
||||||
RETURN u
|
RETURN u
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package e621
|
|
||||||
|
|
||||||
import (
|
|
||||||
e621 "git.dragse.it/anthrove/e621-to-graph/internal/e621/scheduler"
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Client represents the e621 API client.
|
|
||||||
type Client struct {
|
|
||||||
apiKey string
|
|
||||||
username string
|
|
||||||
scheduler *e621.Scheduler
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient creates a new e621 API client.
|
|
||||||
func NewClient(apiKey string, username string) *Client {
|
|
||||||
scheduler := e621.NewScheduler()
|
|
||||||
scheduler.SetLimiter(rate.NewLimiter(1, 2))
|
|
||||||
return &Client{
|
|
||||||
apiKey: apiKey,
|
|
||||||
username: username,
|
|
||||||
scheduler: scheduler,
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package e621
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/e621/scheduler"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetFavorites retrieves all favorites from the e621 API.
|
|
||||||
func (c *Client) GetFavorites(_ context.Context, user model.E621User, page int64) func() (model.PostResponseWrapper, error) {
|
|
||||||
URIPath := fmt.Sprintf("favorites.json?user_id=%d&limit=%d&page=%d", user.ID, 320, page)
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"user": user.Name,
|
|
||||||
"id": user.ID,
|
|
||||||
"page": page,
|
|
||||||
"uri": URIPath,
|
|
||||||
}).Trace("e621: adding task to get favorites")
|
|
||||||
e621Task := NewE621ApiTask[model.PostResponseWrapper](URIPath)
|
|
||||||
return scheduler.Schedule[model.PostResponseWrapper](c.scheduler, e621Task, c.username, c.apiKey)
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package scheduler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/util/queue"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
BASEURL = "https://e621.net"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetAPIRequest(schedulerTask queue.SchedulerTask) {
|
|
||||||
var err error
|
|
||||||
log.Debug("executing scheduler task")
|
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/%s", BASEURL, schedulerTask.UriPath())
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
schedulerTask.SendError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
req.Header.Set("User-Agent", "FavGetter (by Selloo)")
|
|
||||||
req.Header.Add("Accept", "application/json")
|
|
||||||
req.SetBasicAuth(schedulerTask.BasicAuth())
|
|
||||||
|
|
||||||
client := http.Client{}
|
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
schedulerTask.SendStatusCode(resp.StatusCode)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
schedulerTask.SendStatusCode(resp.StatusCode)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
schedulerTask.SendResponse(resp)
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
package scheduler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/util/queue"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"golang.org/x/time/rate"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Scheduler struct {
|
|
||||||
queue queue.Queue
|
|
||||||
limiter *rate.Limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewScheduler() *Scheduler {
|
|
||||||
scheduler := &Scheduler{
|
|
||||||
queue: queue.NewQueue(),
|
|
||||||
limiter: nil,
|
|
||||||
}
|
|
||||||
go scheduler.StartExecutionHandler()
|
|
||||||
return scheduler
|
|
||||||
}
|
|
||||||
|
|
||||||
func Schedule[T e621.DataType](s *Scheduler, t e621.Task[T], username string, apiKey string) func() (T, error) {
|
|
||||||
channel := make(chan e621.DataResponse[T])
|
|
||||||
schedulerTask := NewSchedulerTaskImpl[T](t, channel, username, apiKey)
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"type": reflect.TypeOf(*new(T)),
|
|
||||||
}).Debug("scheduler: pushing task to queue")
|
|
||||||
|
|
||||||
err := s.queue.Push(schedulerTask)
|
|
||||||
if err != nil {
|
|
||||||
return func() (T, error) {
|
|
||||||
var nil T
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"type": reflect.TypeOf(*new(T)),
|
|
||||||
}).Trace("scheduler: pushed task to queue")
|
|
||||||
|
|
||||||
return func() (T, error) {
|
|
||||||
log.Trace("scheduler: getting data from channel")
|
|
||||||
data := <-channel
|
|
||||||
return data.Data, data.Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Scheduler) SetLimiter(limiter *rate.Limiter) {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"burst": limiter.Burst(),
|
|
||||||
"limit": limiter.Limit(),
|
|
||||||
"tokens": limiter.Tokens(),
|
|
||||||
}).Debug("scheduler: setting limiter")
|
|
||||||
s.limiter = limiter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Scheduler) StartExecutionHandler() {
|
|
||||||
for {
|
|
||||||
if s.limiter != nil {
|
|
||||||
s.limiter.Wait(context.Background())
|
|
||||||
}
|
|
||||||
s.queue.WaitForElement()
|
|
||||||
log.Trace("scheduler: element found")
|
|
||||||
task, err := s.queue.Pop()
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
GetAPIRequest(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package scheduler
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/util/queue"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type schedulerTaskImpl[T e621.DataType] struct {
|
|
||||||
task e621.Task[T]
|
|
||||||
channel chan e621.DataResponse[T]
|
|
||||||
username string
|
|
||||||
apiKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s schedulerTaskImpl[T]) BasicAuth() (string, string) {
|
|
||||||
return s.username, s.apiKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSchedulerTaskImpl[T e621.DataType](task e621.Task[T], channel chan e621.DataResponse[T], username string, apiKey string) queue.SchedulerTask {
|
|
||||||
return &schedulerTaskImpl[T]{
|
|
||||||
task: task,
|
|
||||||
channel: channel,
|
|
||||||
username: username,
|
|
||||||
apiKey: apiKey,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s schedulerTaskImpl[T]) SendError(err error) {
|
|
||||||
s.channel <- s.task.HandleError(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s schedulerTaskImpl[T]) UriPath() string {
|
|
||||||
return s.task.UriPath()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s schedulerTaskImpl[T]) SendStatusCode(statusCode int) {
|
|
||||||
s.channel <- s.task.HandleStatusCode(statusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s schedulerTaskImpl[T]) SendResponse(response *http.Response) {
|
|
||||||
s.channel <- s.task.HandleResponse(response)
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
package e621
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621"
|
|
||||||
pgkError "git.dragse.it/anthrove/e621-to-graph/pkg/error"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"net/http"
|
|
||||||
"reflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
type e621APITask[T e621.DataType] struct {
|
|
||||||
uri string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewE621ApiTask[T e621.DataType](uri string) e621.Task[T] {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"uri": uri,
|
|
||||||
"type": reflect.TypeOf(*new(T)),
|
|
||||||
}).Debug("e621: task created")
|
|
||||||
return &e621APITask[T]{
|
|
||||||
uri: uri,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e e621APITask[T]) UriPath() string {
|
|
||||||
return e.uri
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e e621APITask[T]) HandleStatusCode(statusCode int) e621.DataResponse[T] {
|
|
||||||
var err error
|
|
||||||
switch statusCode {
|
|
||||||
case 421:
|
|
||||||
err = pgkError.RateLimitReachedError{}
|
|
||||||
case 424:
|
|
||||||
err = pgkError.InvalidParametersError{}
|
|
||||||
case 520:
|
|
||||||
err = pgkError.OriginConnectionTimeOutError{}
|
|
||||||
case 522:
|
|
||||||
err = pgkError.OriginConnectionTimeOutError{}
|
|
||||||
case 524:
|
|
||||||
err = pgkError.OriginConnectionTimeOutError{}
|
|
||||||
case 525:
|
|
||||||
err = pgkError.SSLHandshakeFailedError{}
|
|
||||||
default:
|
|
||||||
err = pgkError.StatusCodesToError(statusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"status_code": statusCode,
|
|
||||||
}).Debug("e621: handel status code")
|
|
||||||
return e621.DataResponse[T]{Error: err}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e e621APITask[T]) HandleResponse(responseData *http.Response) e621.DataResponse[T] {
|
|
||||||
var data T
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"type": reflect.TypeOf(*new(T)),
|
|
||||||
}).Debug("e621: decoding json response")
|
|
||||||
err := json.NewDecoder(responseData.Body).Decode(&data)
|
|
||||||
defer responseData.Body.Close()
|
|
||||||
if err != nil {
|
|
||||||
return e621.DataResponse[T]{Error: err}
|
|
||||||
}
|
|
||||||
return e621.DataResponse[T]{Data: data}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e e621APITask[T]) HandleError(error error) e621.DataResponse[T] {
|
|
||||||
return e621.DataResponse[T]{Error: error}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package e621
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/e621/scheduler"
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetUserInfo retrieves the users information from e621 API.
|
|
||||||
func (c *Client) GetUserInfo(username string) func() (model.E621User, error) {
|
|
||||||
URIPath := fmt.Sprintf("users/%s.json", username)
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"username": username,
|
|
||||||
"uri": URIPath,
|
|
||||||
}).Debug("e621: getting user info")
|
|
||||||
e621Task := NewE621ApiTask[model.E621User](URIPath)
|
|
||||||
return scheduler.Schedule[model.E621User](c.scheduler, e621Task, c.username, c.apiKey)
|
|
||||||
}
|
|
@ -2,21 +2,18 @@ package service
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/internal/e621"
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
"git.dragse.it/anthrove/e621-to-graph/pkg/logic"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/util"
|
"git.dragse.it/anthrove/e621-to-graph/pkg/util"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ScrapeUser(ctx context.Context, graphConnection logic.GraphConnection, e621Client e621.Client, username string) error {
|
func ScrapeUser(ctx context.Context, graphConnection logic.GraphConnection, client *e621.Client, username string) error {
|
||||||
var err error
|
var err error
|
||||||
var page int64 = 1
|
|
||||||
var allFavorites []model.Post
|
|
||||||
|
|
||||||
AwaitE621User := e621Client.GetUserInfo(username)
|
e621User, err := client.GetUserByName(username).Execute()
|
||||||
e621User, err := AwaitE621User()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info(err)
|
log.Info(err)
|
||||||
return err
|
return err
|
||||||
@ -47,29 +44,11 @@ func ScrapeUser(ctx context.Context, graphConnection logic.GraphConnection, e621
|
|||||||
}).Info("service: start processing favorites")
|
}).Info("service: start processing favorites")
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
for {
|
e621FavoritesBuilder := client.GetFavoritesBuilder().SetUserID(e621User.ID)
|
||||||
AwaitE621Favorites := e621Client.GetFavorites(ctx, e621User, page)
|
e621Favorites, err := client.GetAllFavoritesForUser(e621FavoritesBuilder)
|
||||||
|
|
||||||
favoritesPage, err := AwaitE621Favorites()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the fetched posts to the result slice
|
|
||||||
allFavorites = append(allFavorites, favoritesPage.Posts...)
|
|
||||||
|
|
||||||
// If no more posts are returned, return the accumulated favorites
|
|
||||||
if len(favoritesPage.Posts) == 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the last post ID for the next page request
|
|
||||||
page += 1
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uploads all Tags, Posts as Nodes to Neo4j
|
// Uploads all Tags, Posts as Nodes to Neo4j
|
||||||
for i, post := range allFavorites {
|
for i, post := range e621Favorites {
|
||||||
if exists, err := graphConnection.CheckUserToPostLink(ctx, post.ID, e621User.ID); err == nil && exists {
|
if exists, err := graphConnection.CheckUserToPostLink(ctx, post.ID, e621User.ID); err == nil && exists {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"e621_username": e621User.Name,
|
"e621_username": e621User.Name,
|
||||||
@ -90,7 +69,7 @@ func ScrapeUser(ctx context.Context, graphConnection logic.GraphConnection, e621
|
|||||||
"e621_username": e621User.Name,
|
"e621_username": e621User.Name,
|
||||||
"e621_user_id": e621User.ID,
|
"e621_user_id": e621User.ID,
|
||||||
"post_number": i,
|
"post_number": i,
|
||||||
"post_amount": len(allFavorites),
|
"post_amount": len(e621Favorites),
|
||||||
"post_id": post.ID,
|
"post_id": post.ID,
|
||||||
"upload_time": time.Since(start),
|
"upload_time": time.Since(start),
|
||||||
}).Debug("service: uploading post")
|
}).Debug("service: uploading post")
|
||||||
@ -135,7 +114,7 @@ func ScrapeUser(ctx context.Context, graphConnection logic.GraphConnection, e621
|
|||||||
"e621_username": e621User.Name,
|
"e621_username": e621User.Name,
|
||||||
"e621_user_id": e621User.ID,
|
"e621_user_id": e621User.ID,
|
||||||
"post_number": i,
|
"post_number": i,
|
||||||
"post_amount": len(allFavorites),
|
"post_amount": len(e621Favorites),
|
||||||
"post_id": post.ID,
|
"post_id": post.ID,
|
||||||
"upload_time": time.Since(start),
|
"upload_time": time.Since(start),
|
||||||
}).Debug("service: making relationship")
|
}).Debug("service: making relationship")
|
||||||
@ -143,7 +122,7 @@ func ScrapeUser(ctx context.Context, graphConnection logic.GraphConnection, e621
|
|||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"e621_username": e621User.Name,
|
"e621_username": e621User.Name,
|
||||||
"e621_user_id": e621User.ID,
|
"e621_user_id": e621User.ID,
|
||||||
"post_amount": len(allFavorites),
|
"post_amount": len(e621Favorites),
|
||||||
"scrape_time": time.Since(start),
|
"scrape_time": time.Since(start),
|
||||||
}).Info("service: finished processing favorites")
|
}).Info("service: finished processing favorites")
|
||||||
|
|
||||||
@ -217,7 +196,7 @@ func uploadNodes(ctx context.Context, graphConnection logic.GraphConnection, pos
|
|||||||
}
|
}
|
||||||
|
|
||||||
// uploadPostToUserRelationship creates a relationship between the user and the post
|
// uploadPostToUserRelationship creates a relationship between the user and the post
|
||||||
func uploadPostToUserRelationship(ctx context.Context, graphConnection logic.GraphConnection, post model.Post, e621User model.E621User) error {
|
func uploadPostToUserRelationship(ctx context.Context, graphConnection logic.GraphConnection, post model.Post, e621User model.User) error {
|
||||||
err := graphConnection.EstablishUserToPostLink(ctx, post.ID, e621User.ID)
|
err := graphConnection.EstablishUserToPostLink(ctx, post.ID, e621User.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1,102 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "encoding/json"
|
|
||||||
|
|
||||||
func UnmarshalE621Post(data []byte) (PostResponseWrapper, error) {
|
|
||||||
var r PostResponseWrapper
|
|
||||||
err := json.Unmarshal(data, &r)
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *PostResponseWrapper) Marshal() ([]byte, error) {
|
|
||||||
return json.Marshal(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostResponseWrapper struct {
|
|
||||||
Posts []Post `json:"posts"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Post struct {
|
|
||||||
ID int64 `json:"id"`
|
|
||||||
CreatedAt string `json:"created_at"`
|
|
||||||
UpdatedAt string `json:"updated_at"`
|
|
||||||
File File `json:"file"`
|
|
||||||
Preview Preview `json:"preview"`
|
|
||||||
Sample Sample `json:"sample"`
|
|
||||||
Score Score `json:"score"`
|
|
||||||
Tags PostTags `json:"tags"`
|
|
||||||
LockedTags []interface{} `json:"locked_tags"`
|
|
||||||
ChangeSeq int64 `json:"change_seq"`
|
|
||||||
Flags Flags `json:"flags"`
|
|
||||||
Rating string `json:"rating"`
|
|
||||||
FavCount int64 `json:"fav_count"`
|
|
||||||
Sources []string `json:"sources"`
|
|
||||||
Pools []interface{} `json:"pools"`
|
|
||||||
Relationships Relationships `json:"relationships"`
|
|
||||||
ApproverID *int64 `json:"approver_id"`
|
|
||||||
UploaderID int64 `json:"uploader_id"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
CommentCount int64 `json:"comment_count"`
|
|
||||||
IsFavorited bool `json:"is_favorited"`
|
|
||||||
HasNotes bool `json:"has_notes"`
|
|
||||||
Duration interface{} `json:"duration"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type File struct {
|
|
||||||
Width int64 `json:"width"`
|
|
||||||
Height int64 `json:"height"`
|
|
||||||
EXT string `json:"ext"`
|
|
||||||
Size int64 `json:"size"`
|
|
||||||
Md5 string `json:"md5"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Flags struct {
|
|
||||||
Pending bool `json:"pending"`
|
|
||||||
Flagged bool `json:"flagged"`
|
|
||||||
NoteLocked bool `json:"note_locked"`
|
|
||||||
StatusLocked bool `json:"status_locked"`
|
|
||||||
RatingLocked bool `json:"rating_locked"`
|
|
||||||
Deleted bool `json:"deleted"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Preview struct {
|
|
||||||
Width int64 `json:"width"`
|
|
||||||
Height int64 `json:"height"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Relationships struct {
|
|
||||||
ParentID interface{} `json:"parent_id"`
|
|
||||||
HasChildren bool `json:"has_children"`
|
|
||||||
HasActiveChildren bool `json:"has_active_children"`
|
|
||||||
Children []interface{} `json:"children"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Sample struct {
|
|
||||||
Has bool `json:"has"`
|
|
||||||
Height int64 `json:"height"`
|
|
||||||
Width int64 `json:"width"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Alternates Alternates `json:"alternates"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Alternates struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
type Score struct {
|
|
||||||
Up int64 `json:"up"`
|
|
||||||
Down int64 `json:"down"`
|
|
||||||
Total int64 `json:"total"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type PostTags struct {
|
|
||||||
General []string `json:"general"`
|
|
||||||
Species []string `json:"species"`
|
|
||||||
Character []string `json:"character"`
|
|
||||||
Copyright []string `json:"copyright"`
|
|
||||||
Artist []string `json:"artist"`
|
|
||||||
Invalid []interface{} `json:"invalid"`
|
|
||||||
Lore []interface{} `json:"lore"`
|
|
||||||
Meta []string `json:"meta"`
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "encoding/json"
|
|
||||||
|
|
||||||
func UnmarshalE621User(data []byte) (E621User, error) {
|
|
||||||
var r E621User
|
|
||||||
err := json.Unmarshal(data, &r)
|
|
||||||
return r, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *E621User) Marshal() ([]byte, error) {
|
|
||||||
return json.Marshal(r)
|
|
||||||
}
|
|
||||||
|
|
||||||
type E621User struct {
|
|
||||||
WikiPageVersionCount int64 `json:"wiki_page_version_count"`
|
|
||||||
ArtistVersionCount int64 `json:"artist_version_count"`
|
|
||||||
PoolVersionCount int64 `json:"pool_version_count"`
|
|
||||||
ForumPostCount int64 `json:"forum_post_count"`
|
|
||||||
CommentCount int64 `json:"comment_count"`
|
|
||||||
FlagCount int64 `json:"flag_count"`
|
|
||||||
FavoriteCount int64 `json:"favorite_count"`
|
|
||||||
PositiveFeedbackCount int64 `json:"positive_feedback_count"`
|
|
||||||
NeutralFeedbackCount int64 `json:"neutral_feedback_count"`
|
|
||||||
NegativeFeedbackCount int64 `json:"negative_feedback_count"`
|
|
||||||
UploadLimit int64 `json:"upload_limit"`
|
|
||||||
ID int64 `json:"id"`
|
|
||||||
CreatedAt string `json:"created_at"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Level int64 `json:"level"`
|
|
||||||
BaseUploadLimit int64 `json:"base_upload_limit"`
|
|
||||||
PostUploadCount int64 `json:"post_upload_count"`
|
|
||||||
PostUpdateCount int64 `json:"post_update_count"`
|
|
||||||
NoteUpdateCount int64 `json:"note_update_count"`
|
|
||||||
IsBanned bool `json:"is_banned"`
|
|
||||||
CanApprovePosts bool `json:"can_approve_posts"`
|
|
||||||
CanUploadFree bool `json:"can_upload_free"`
|
|
||||||
LevelString string `json:"level_string"`
|
|
||||||
AvatarID int64 `json:"avatar_id"`
|
|
||||||
ShowAvatars bool `json:"show_avatars"`
|
|
||||||
BlacklistAvatars bool `json:"blacklist_avatars"`
|
|
||||||
BlacklistUsers bool `json:"blacklist_users"`
|
|
||||||
DescriptionCollapsedInitially bool `json:"description_collapsed_initially"`
|
|
||||||
HideComments bool `json:"hide_comments"`
|
|
||||||
ShowHiddenComments bool `json:"show_hidden_comments"`
|
|
||||||
ShowPostStatistics bool `json:"show_post_statistics"`
|
|
||||||
HasMail bool `json:"has_mail"`
|
|
||||||
ReceiveEmailNotifications bool `json:"receive_email_notifications"`
|
|
||||||
EnableKeyboardNavigation bool `json:"enable_keyboard_navigation"`
|
|
||||||
EnablePrivacyMode bool `json:"enable_privacy_mode"`
|
|
||||||
StyleUsernames bool `json:"style_usernames"`
|
|
||||||
EnableAutoComplete bool `json:"enable_auto_complete"`
|
|
||||||
HasSavedSearches bool `json:"has_saved_searches"`
|
|
||||||
DisableCroppedThumbnails bool `json:"disable_cropped_thumbnails"`
|
|
||||||
DisableMobileGestures bool `json:"disable_mobile_gestures"`
|
|
||||||
EnableSafeMode bool `json:"enable_safe_mode"`
|
|
||||||
DisableResponsiveMode bool `json:"disable_responsive_mode"`
|
|
||||||
DisablePostTooltips bool `json:"disable_post_tooltips"`
|
|
||||||
NoFlagging bool `json:"no_flagging"`
|
|
||||||
NoFeedback bool `json:"no_feedback"`
|
|
||||||
DisableUserDmails bool `json:"disable_user_dmails"`
|
|
||||||
EnableCompactUploader bool `json:"enable_compact_uploader"`
|
|
||||||
ReplacementsBeta bool `json:"replacements_beta"`
|
|
||||||
IsBdStaff bool `json:"is_bd_staff"`
|
|
||||||
UpdatedAt string `json:"updated_at"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
LastLoggedInAt string `json:"last_logged_in_at"`
|
|
||||||
LastForumReadAt string `json:"last_forum_read_at"`
|
|
||||||
RecentTags string `json:"recent_tags"`
|
|
||||||
CommentThreshold int64 `json:"comment_threshold"`
|
|
||||||
DefaultImageSize string `json:"default_image_size"`
|
|
||||||
FavoriteTags string `json:"favorite_tags"`
|
|
||||||
BlacklistedTags string `json:"blacklisted_tags"`
|
|
||||||
TimeZone string `json:"time_zone"`
|
|
||||||
PerPage int64 `json:"per_page"`
|
|
||||||
CustomStyle string `json:"custom_style"`
|
|
||||||
APIRegenMultiplier int64 `json:"api_regen_multiplier"`
|
|
||||||
APIBurstLimit int64 `json:"api_burst_limit"`
|
|
||||||
RemainingAPILimit int64 `json:"remaining_api_limit"`
|
|
||||||
StatementTimeout int64 `json:"statement_timeout"`
|
|
||||||
FavoriteLimit int64 `json:"favorite_limit"`
|
|
||||||
TagQueryLimit int64 `json:"tag_query_limit"`
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package e621
|
|
||||||
|
|
||||||
import (
|
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type DataResponse[T DataType] struct {
|
|
||||||
Data T
|
|
||||||
Error error
|
|
||||||
}
|
|
||||||
|
|
||||||
type DataType interface {
|
|
||||||
model.E621User | model.PostResponseWrapper
|
|
||||||
}
|
|
||||||
|
|
||||||
type Task[T DataType] interface {
|
|
||||||
UriPath() string
|
|
||||||
HandleError(error error) DataResponse[T]
|
|
||||||
HandleStatusCode(statusCode int) DataResponse[T]
|
|
||||||
HandleResponse(responseData *http.Response) DataResponse[T]
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
package error
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
func StatusCodesToError(statusCode int) error {
|
|
||||||
var err error
|
|
||||||
switch statusCode {
|
|
||||||
case 403:
|
|
||||||
err = AccessDeniedError{}
|
|
||||||
case 404:
|
|
||||||
err = NotFoundError{}
|
|
||||||
case 412:
|
|
||||||
err = PreconditionFailedError{}
|
|
||||||
case 421:
|
|
||||||
err = RateLimitReachedError{}
|
|
||||||
case 424:
|
|
||||||
err = InvalidParametersError{}
|
|
||||||
case 500:
|
|
||||||
err = InternalServerError{}
|
|
||||||
case 502:
|
|
||||||
err = BadGatewayError{}
|
|
||||||
case 503:
|
|
||||||
err = ServiceUnavailableError{}
|
|
||||||
default:
|
|
||||||
err = fmt.Errorf("unhandels status code: %d", statusCode)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type AccessDeniedError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ AccessDeniedError) Error() string {
|
|
||||||
return "access denied"
|
|
||||||
}
|
|
||||||
|
|
||||||
type NotFoundError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ NotFoundError) Error() string {
|
|
||||||
return "not found"
|
|
||||||
}
|
|
||||||
|
|
||||||
type PreconditionFailedError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ PreconditionFailedError) Error() string {
|
|
||||||
return "precondition failed"
|
|
||||||
}
|
|
||||||
|
|
||||||
type RateLimitReachedError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ RateLimitReachedError) Error() string {
|
|
||||||
return "rate limit reached"
|
|
||||||
}
|
|
||||||
|
|
||||||
type InvalidParametersError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ InvalidParametersError) Error() string {
|
|
||||||
return "invalide parameters"
|
|
||||||
}
|
|
||||||
|
|
||||||
type InternalServerError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ InternalServerError) Error() string {
|
|
||||||
return "internal server error"
|
|
||||||
}
|
|
||||||
|
|
||||||
type BadGatewayError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ BadGatewayError) Error() string {
|
|
||||||
return "bad gateway"
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceUnavailableError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ ServiceUnavailableError) Error() string {
|
|
||||||
return "service unavailable"
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnknownError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ UnknownError) Error() string {
|
|
||||||
return "unknown error"
|
|
||||||
}
|
|
||||||
|
|
||||||
type OriginConnectionTimeOutError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ OriginConnectionTimeOutError) Error() string {
|
|
||||||
return "origin connection time-out"
|
|
||||||
}
|
|
||||||
|
|
||||||
type SSLHandshakeFailedError struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (_ SSLHandshakeFailedError) Error() string {
|
|
||||||
return "ssl handshake failed"
|
|
||||||
}
|
|
@ -2,17 +2,17 @@ package logic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"git.dragse.it/anthrove/e621-to-graph/pkg/e621/model"
|
"git.dragse.it/anthrove/e621-sdk-go/pkg/e621/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GraphConnection interface {
|
type GraphConnection interface {
|
||||||
Connect(ctx context.Context, endpoint string, username string, password string) error
|
Connect(ctx context.Context, endpoint string, username string, password string) error
|
||||||
UploadUser(ctx context.Context, user model.E621User) error
|
UploadUser(ctx context.Context, user model.User) error
|
||||||
UploadSource(ctx context.Context, SourceURL string) error
|
UploadSource(ctx context.Context, SourceURL string) error
|
||||||
UploadPost(ctx context.Context, e621ID int64) error
|
UploadPost(ctx context.Context, e621ID model.PostID) error
|
||||||
UploadTag(ctx context.Context, name string, tagType string) error
|
UploadTag(ctx context.Context, name string, tagType string) error
|
||||||
EstablishPostToTagLink(ctx context.Context, e621PostID int64, e621Tag string) error
|
EstablishPostToTagLink(ctx context.Context, e621PostID model.PostID, e621Tag string) error
|
||||||
EstablishPostToSourceLink(ctx context.Context, e621PostID int64, sourceURL string) error
|
EstablishPostToSourceLink(ctx context.Context, e621PostID model.PostID, sourceURL string) error
|
||||||
EstablishUserToPostLink(ctx context.Context, e621PostID int64, e621UserID int64) error
|
EstablishUserToPostLink(ctx context.Context, e621PostID model.PostID, e621UserID model.UserID) error
|
||||||
CheckUserToPostLink(ctx context.Context, e621PostID int64, e621UserID int64) (bool, error)
|
CheckUserToPostLink(ctx context.Context, e621PostID model.PostID, e621UserID model.UserID) (bool, error)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user