Bluemage/go/api/subreddits_resolve.go

77 lines
2 KiB
Go

package api
import (
"context"
"connectrpc.com/connect"
"github.com/tigorlazuardi/bluemage/go/gen/reddit"
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
"github.com/tigorlazuardi/bluemage/go/pkg/log"
"github.com/tigorlazuardi/bluemage/go/pkg/telemetry"
)
type SubredditResolveNameRequest struct {
Name string
Type string
}
func (api *API) SubredditResolveName(ctx context.Context, request SubredditResolveNameRequest) (resolved string, err error) {
ctx, span := tracer.Start(ctx, "SubredditResolveName")
defer func() { telemetry.EndWithStatus(span, err) }()
ctx, httplog := log.ContextWithRoundTripCollector(ctx)
typ := reddit.GetListingTypeR
if request.Type == "user" {
typ = reddit.GetListingTypeUser
}
resp, err := api.Reddit.GetListing(ctx, reddit.GetListingParams{
Type: typ,
Name: request.Name,
})
if err != nil {
err = errs.Wrapw(err, "failed to get listing from reddit", "round_trip", httplog)
return resolved, err
}
switch resp := resp.(type) {
case *reddit.GetListingForbidden:
err = errs.
Failw(
"subreddit is private",
"round_trip", httplog,
).
Code(connect.CodePermissionDenied)
return resolved, err
case *reddit.GetListingTooManyRequests:
err = errs.
Failw(
"too many requests error response from reddit",
"round_trip", httplog,
).
Code(connect.CodeResourceExhausted)
return resolved, err
case *reddit.ListingResponse:
if !isValidSubreddit(resp) {
err = errs.
Failf("subreddit '%s' of type '%s' seems to be empty or not valid", request.Name, request.Type).
Details("round_trip", httplog).
Code(connect.CodeNotFound)
return resolved, err
}
data := resp.Data.Children[0].Data
if request.Type == "user" {
return data.Author, nil
}
return data.Subreddit, nil
default:
err = errs.
Failw("unexpected response from reddit", "round_trip", httplog)
return resolved, err
}
}
func isValidSubreddit(list *reddit.ListingResponse) bool {
return list.Data.After.Null && len(list.Data.Children) == 0
}