log: http better log handling
This commit is contained in:
parent
66fc1a964b
commit
2f66122be1
|
@ -7,6 +7,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tigorlazuardi/redmage/pkg/caller"
|
||||||
"github.com/tigorlazuardi/redmage/pkg/errs"
|
"github.com/tigorlazuardi/redmage/pkg/errs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,6 +23,8 @@ func (reddit *Reddit) CheckSubreddit(ctx context.Context, params CheckSubredditP
|
||||||
ctx, span := tracer.Start(ctx, "*Reddit.CheckSubreddit")
|
ctx, span := tracer.Start(ctx, "*Reddit.CheckSubreddit")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
|
|
||||||
|
ctx = caller.WithContext(ctx, caller.New(2))
|
||||||
|
|
||||||
url := fmt.Sprintf("https://reddit.com/%s/%s.json?limit=1", params.SubredditType, params.Subreddit)
|
url := fmt.Sprintf("https://reddit.com/%s/%s.json?limit=1", params.SubredditType, params.Subreddit)
|
||||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody)
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, http.NoBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/tigorlazuardi/redmage/config"
|
"github.com/tigorlazuardi/redmage/config"
|
||||||
|
"github.com/tigorlazuardi/redmage/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client interface {
|
type Client interface {
|
||||||
|
@ -25,6 +26,22 @@ func (ro roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)
|
||||||
func createRoundTripper(cfg *config.Config) roundTripperFunc {
|
func createRoundTripper(cfg *config.Config) roundTripperFunc {
|
||||||
return func(r *http.Request) (*http.Response, error) {
|
return func(r *http.Request) (*http.Response, error) {
|
||||||
r.Header.Set("User-Agent", cfg.String("download.useragent"))
|
r.Header.Set("User-Agent", cfg.String("download.useragent"))
|
||||||
return http.DefaultTransport.RoundTrip(r)
|
resp, err := http.DefaultTransport.RoundTrip(r)
|
||||||
|
if err != nil {
|
||||||
|
log.New(r.Context()).
|
||||||
|
Err(err).
|
||||||
|
Errorf("reddit: %s %s", r.Method, r.URL)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
log.New(r.Context()).
|
||||||
|
Errorf("reddit: %s %s %d", r.Method, r.URL, resp.StatusCode)
|
||||||
|
return resp, err
|
||||||
|
}
|
||||||
|
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||||
|
log.New(r.Context()).
|
||||||
|
Infof("reddit: %s %s %d", r.Method, r.URL, resp.StatusCode)
|
||||||
|
}
|
||||||
|
return resp, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package caller
|
package caller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -70,3 +71,14 @@ func From(pc uintptr) Caller {
|
||||||
c.Frame, _ = runtime.CallersFrames([]uintptr{pc}).Next()
|
c.Frame, _ = runtime.CallersFrames([]uintptr{pc}).Next()
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type contextKey struct{}
|
||||||
|
|
||||||
|
func WithContext(ctx context.Context, caller Caller) context.Context {
|
||||||
|
return context.WithValue(ctx, contextKey{}, caller)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FromContext(ctx context.Context) (Caller, bool) {
|
||||||
|
call, ok := ctx.Value(contextKey{}).(Caller)
|
||||||
|
return call, ok
|
||||||
|
}
|
||||||
|
|
|
@ -273,6 +273,9 @@ func (entry *Entry) getCaller() caller.Caller {
|
||||||
if entry.caller.PC != 0 {
|
if entry.caller.PC != 0 {
|
||||||
return entry.caller
|
return entry.caller
|
||||||
}
|
}
|
||||||
|
if call, ok := caller.FromContext(entry.ctx); ok {
|
||||||
|
return call
|
||||||
|
}
|
||||||
return caller.New(4)
|
return caller.New(4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ POST http://localhost:8080/api/v1/subreddits HTTP/1.1
|
||||||
Host: localhost:8080
|
Host: localhost:8080
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "CultureImpact",
|
"name": "AnimeLandscapes",
|
||||||
"enable_schedule": 1,
|
"enable_schedule": 1,
|
||||||
"schedule": "@daily",
|
"schedule": "@daily",
|
||||||
"countback": 300
|
"countback": 300
|
||||||
|
|
|
@ -3,5 +3,5 @@ Host: localhost:8080
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"subreddit": "CultureImpact"
|
"subreddit": "AnimeLandscapes"
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,11 +24,11 @@ templ home(_ *views.Context, data Data) {
|
||||||
<div class="prose">
|
<div class="prose">
|
||||||
<section class="mb-4 mx-auto">
|
<section class="mb-4 mx-auto">
|
||||||
<h1>Recently Added</h1>
|
<h1>Recently Added</h1>
|
||||||
for _, deviceMapValue := range data.RecentlyAddedImages {
|
for _, recently := range data.RecentlyAddedImages {
|
||||||
<h2>{ deviceMapValue.device.Name }</h2>
|
<h2>{ recently.Device.Name }</h2>
|
||||||
for _, subreddit := range deviceMapValue.subreddits {
|
for _, subreddit := range recently.Subreddits {
|
||||||
<h4>{ subreddit.subreddit.Name }</h4>
|
<h4>{ subreddit.Subreddit.Name }</h4>
|
||||||
@RecentlyAddedImageList(subreddit.images, 0)
|
@RecentlyAddedImageList(subreddit.Images, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package homeview
|
package homeview
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/tigorlazuardi/redmage/api"
|
"github.com/tigorlazuardi/redmage/api"
|
||||||
"github.com/tigorlazuardi/redmage/models"
|
"github.com/tigorlazuardi/redmage/models"
|
||||||
)
|
)
|
||||||
|
@ -11,38 +14,74 @@ type Data struct {
|
||||||
Error error
|
Error error
|
||||||
}
|
}
|
||||||
|
|
||||||
type RecentlyAddedImages = map[int32]deviceMapValue
|
type RecentlyAddedImages = []RecentlyAddedImage
|
||||||
|
|
||||||
type deviceMapValue struct {
|
|
||||||
device *models.Device
|
|
||||||
subreddits map[int32]subredditMapValue
|
|
||||||
}
|
|
||||||
|
|
||||||
type subredditMapValue struct {
|
type subredditMapValue struct {
|
||||||
subreddit *models.Subreddit
|
subreddit *models.Subreddit
|
||||||
images []*models.Image
|
images []*models.Image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RecentlyAddedImage struct {
|
||||||
|
Device *models.Device
|
||||||
|
Subreddits []Subreddit
|
||||||
|
}
|
||||||
|
|
||||||
|
type Subreddit struct {
|
||||||
|
Subreddit *models.Subreddit
|
||||||
|
Images models.ImageSlice
|
||||||
|
}
|
||||||
|
|
||||||
func NewRecentlyAddedImages(images models.ImageSlice) RecentlyAddedImages {
|
func NewRecentlyAddedImages(images models.ImageSlice) RecentlyAddedImages {
|
||||||
r := make(RecentlyAddedImages)
|
r := make(RecentlyAddedImages, 0, len(images))
|
||||||
for _, image := range images {
|
for _, image := range images {
|
||||||
if image.R.Device == nil || image.R.Subreddit == nil {
|
if image.R.Device == nil || image.R.Subreddit == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, ok := r[image.R.Device.ID]; !ok {
|
var deviceFound bool
|
||||||
r[image.R.Device.ID] = deviceMapValue{
|
for i, ra := range r {
|
||||||
device: image.R.Device,
|
if ra.Device.ID == image.R.Device.ID {
|
||||||
subreddits: make(map[int32]subredditMapValue),
|
deviceFound = true
|
||||||
|
var subredditFound bool
|
||||||
|
for j, subreddit := range r[i].Subreddits {
|
||||||
|
if subreddit.Subreddit.ID == image.R.Subreddit.ID {
|
||||||
|
subredditFound = true
|
||||||
|
r[i].Subreddits[j].Images = append(r[i].Subreddits[j].Images, image)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !subredditFound {
|
||||||
|
r[i].Subreddits = append(r[i].Subreddits, Subreddit{
|
||||||
|
Subreddit: image.R.Subreddit,
|
||||||
|
Images: models.ImageSlice{image},
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, ok := r[image.R.Device.ID].subreddits[image.R.Subreddit.ID]; !ok {
|
if !deviceFound {
|
||||||
r[image.R.Device.ID].subreddits[image.R.Subreddit.ID] = subredditMapValue{}
|
r = append(r, RecentlyAddedImage{
|
||||||
}
|
Device: image.R.Device,
|
||||||
images := append(r[image.R.Device.ID].subreddits[image.R.Subreddit.ID].images, image)
|
Subreddits: []Subreddit{
|
||||||
r[image.R.Device.ID].subreddits[image.R.Subreddit.ID] = subredditMapValue{
|
{
|
||||||
subreddit: image.R.Subreddit,
|
Subreddit: image.R.Subreddit,
|
||||||
images: images,
|
Images: models.ImageSlice{image},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, r := range r {
|
||||||
|
slices.SortFunc(r.Subreddits, func(left, right Subreddit) int {
|
||||||
|
leftName := strings.ToLower(left.Subreddit.Name)
|
||||||
|
rightName := strings.ToLower(right.Subreddit.Name)
|
||||||
|
return strings.Compare(leftName, rightName)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.SortFunc(r, func(left, right RecentlyAddedImage) int {
|
||||||
|
leftName := strings.ToLower(left.Device.Name)
|
||||||
|
rightName := strings.ToLower(right.Device.Name)
|
||||||
|
return strings.Compare(leftName, rightName)
|
||||||
|
})
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue