package handlers import ( "context" "encoding/json" "fmt" oapi "nyanimedb/api" sqlc "nyanimedb/sql" "strconv" "github.com/jackc/pgx/v5" log "github.com/sirupsen/logrus" ) func Word2Sqlc(s *string) *string { if s == nil || *s == "" { return nil } return s } type SqlcStatus struct { ongoing string finished string planned string } func TitleStatus2Sqlc(s *[]oapi.TitleStatus) (*SqlcStatus, error) { var sqlc_status SqlcStatus if s == nil { return &sqlc_status, nil } for _, t := range *s { switch t { case oapi.TitleStatusFinished: sqlc_status.finished = "finished" case oapi.TitleStatusOngoing: sqlc_status.ongoing = "ongoing" case oapi.TitleStatusPlanned: sqlc_status.planned = "planned" default: return nil, fmt.Errorf("unexpected tittle status: %s", t) } } return &sqlc_status, nil } func TitleStatus2oapi(s *sqlc.TitleStatusT) (*oapi.TitleStatus, error) { if s == nil { return nil, nil } var t oapi.TitleStatus switch *s { case sqlc.TitleStatusTFinished: t = oapi.TitleStatusFinished case sqlc.TitleStatusTOngoing: t = oapi.TitleStatusOngoing case sqlc.TitleStatusTPlanned: t = oapi.TitleStatusPlanned default: return nil, fmt.Errorf("unexpected tittle status: %s", *s) } return &t, nil } func ReleaseSeason2sqlc(s *oapi.ReleaseSeason) (*sqlc.ReleaseSeasonT, error) { if s == nil { return nil, nil } var t sqlc.ReleaseSeasonT switch *s { case oapi.Winter: t = sqlc.ReleaseSeasonTWinter case oapi.Spring: t = sqlc.ReleaseSeasonTSpring case oapi.Summer: t = sqlc.ReleaseSeasonTSummer case oapi.Fall: t = sqlc.ReleaseSeasonTFall default: return nil, fmt.Errorf("unexpected release season: %s", *s) } return &t, nil } func (s Server) GetTagsByTitleId(ctx context.Context, id int64) (oapi.Tags, error) { sqlc_title_tags, err := s.db.GetTitleTags(ctx, id) if err != nil { if err == pgx.ErrNoRows { return nil, nil } return nil, fmt.Errorf("query GetTitleTags: %v", err) } oapi_tag_names := make(oapi.Tags, 1) for _, title_tag := range sqlc_title_tags { oapi_tag_name := make(map[string]string, 1) err = json.Unmarshal(title_tag, &oapi_tag_name) if err != nil { return nil, fmt.Errorf("unmarshalling title_tag: %v", err) } oapi_tag_names = append(oapi_tag_names, oapi_tag_name) } return oapi_tag_names, nil } func (s Server) GetImage(ctx context.Context, id int64) (*oapi.Image, error) { var oapi_image oapi.Image sqlc_image, err := s.db.GetImageByID(ctx, id) if err != nil { if err == pgx.ErrNoRows { return nil, nil //todo: error reference in db } return &oapi_image, fmt.Errorf("query GetImageByID: %v", err) } //can cast and dont use brain cause all this fields required in image table oapi_image.Id = &sqlc_image.ID oapi_image.ImagePath = &sqlc_image.ImagePath storageTypeStr := string(sqlc_image.StorageType) oapi_image.StorageType = &storageTypeStr return &oapi_image, nil } func (s Server) GetStudio(ctx context.Context, id int64) (*oapi.Studio, error) { var oapi_studio oapi.Studio sqlc_studio, err := s.db.GetStudioByID(ctx, id) if err != nil { if err == pgx.ErrNoRows { return nil, nil } return &oapi_studio, fmt.Errorf("query GetStudioByID: %v", err) } oapi_studio.Id = sqlc_studio.ID oapi_studio.Name = sqlc_studio.StudioName oapi_studio.Description = sqlc_studio.StudioDesc if sqlc_studio.IllustID == nil { return &oapi_studio, nil } oapi_illust, err := s.GetImage(ctx, *sqlc_studio.IllustID) if err != nil { return &oapi_studio, fmt.Errorf("GetImage: %v", err) } if oapi_illust != nil { oapi_studio.Poster = oapi_illust } return &oapi_studio, nil } func (s Server) GetTitlesTitleId(ctx context.Context, request oapi.GetTitlesTitleIdRequestObject) (oapi.GetTitlesTitleIdResponseObject, error) { var oapi_title oapi.Title sqlc_title, err := s.db.GetTitleByID(ctx, request.TitleId) if err != nil { if err == pgx.ErrNoRows { return oapi.GetTitlesTitleId204Response{}, nil } log.Errorf("%v", err) return oapi.GetTitlesTitleId500Response{}, nil } _sqlc_title := sqlc.SearchTitlesRow{ ID: sqlc_title.ID, StudioID: sqlc_title.StudioID, PosterID: sqlc_title.PosterID, TitleStatus: sqlc_title.TitleStatus, Rating: sqlc_title.Rating, RatingCount: sqlc_title.RatingCount, ReleaseYear: sqlc_title.ReleaseYear, ReleaseSeason: sqlc_title.ReleaseSeason, Season: sqlc_title.Season, EpisodesAired: sqlc_title.EpisodesAired, EpisodesAll: sqlc_title.EpisodesAll, EpisodesLen: sqlc_title.EpisodesLen, TitleStorageType: sqlc_title.TitleStorageType, TitleImagePath: sqlc_title.TitleImagePath, TagNames: sqlc_title.TitleNames, StudioName: sqlc_title.StudioName, StudioIllustID: sqlc_title.StudioIllustID, StudioDesc: sqlc_title.StudioDesc, StudioStorageType: sqlc_title.StudioStorageType, StudioImagePath: sqlc_title.StudioImagePath, } oapi_title, err = s.mapTitle(ctx, _sqlc_title) if err != nil { log.Errorf("%v", err) return oapi.GetTitlesTitleId500Response{}, nil } return oapi.GetTitlesTitleId200JSONResponse(oapi_title), nil } func (s Server) GetTitles(ctx context.Context, request oapi.GetTitlesRequestObject) (oapi.GetTitlesResponseObject, error) { opai_titles := make([]oapi.Title, 0) word := Word2Sqlc(request.Params.Word) status, err := TitleStatus2Sqlc(request.Params.Status) if err != nil { log.Errorf("%v", err) return oapi.GetTitles400Response{}, err } season, err := ReleaseSeason2sqlc(request.Params.ReleaseSeason) if err != nil { log.Errorf("%v", err) return oapi.GetTitles400Response{}, err } params := sqlc.SearchTitlesParams{ Word: word, Ongoing: status.ongoing, Finished: status.finished, Planned: status.planned, Rating: request.Params.Rating, ReleaseYear: request.Params.ReleaseYear, ReleaseSeason: season, Forward: true, SortBy: "id", Limit: request.Params.Limit, } if request.Params.SortForward != nil { params.Forward = *request.Params.SortForward } if request.Params.Sort != nil { params.SortBy = string(*request.Params.Sort) if request.Params.Cursor != nil { err := ParseCursorInto(string(*request.Params.Sort), string(*request.Params.Cursor), ¶ms) if err != nil { log.Errorf("%v", err) return oapi.GetTitles400Response{}, nil } } } // param = nil means it will not be used titles, err := s.db.SearchTitles(ctx, params) if err != nil { log.Errorf("%v", err) return oapi.GetTitles500Response{}, nil } if len(titles) == 0 { return oapi.GetTitles204Response{}, nil } var new_cursor oapi.CursorObj for _, title := range titles { t, err := s.mapTitle(ctx, title) if err != nil { log.Errorf("%v", err) return oapi.GetTitles500Response{}, nil } opai_titles = append(opai_titles, t) new_cursor.Id = t.Id if request.Params.Sort != nil { switch string(*request.Params.Sort) { case "year": tmp := fmt.Sprint("%d", *t.ReleaseYear) new_cursor.Param = &tmp case "rating": tmp := strconv.FormatFloat(*t.Rating, 'f', -1, 64) new_cursor.Param = &tmp } } } return oapi.GetTitles200JSONResponse{Cursor: new_cursor, Data: opai_titles}, nil }