refactor: http routes
This commit is contained in:
parent
5c6f7eebfb
commit
b57b1f3959
|
@ -0,0 +1,104 @@
|
||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
|
||||||
|
"github.com/dstotijn/go-notion"
|
||||||
|
"github.com/emersion/go-ical"
|
||||||
|
notionClient "github.com/fmartingr/notion2ical/internal/notion"
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type routes struct {
|
||||||
|
logger *zap.Logger
|
||||||
|
router *fiber.App
|
||||||
|
notion *notionClient.NotionClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *routes) Setup() *routes {
|
||||||
|
r.router.
|
||||||
|
Get("/liveness", r.livenessHandler).
|
||||||
|
Get("/calendar/:databaseID/", r.calendarHandler)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *routes) Router() *fiber.App {
|
||||||
|
return r.router
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *routes) livenessHandler(c *fiber.Ctx) error {
|
||||||
|
return c.SendStatus(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
type calendarOptions struct {
|
||||||
|
AllDayEvents bool `query:"all_day_events"`
|
||||||
|
DateFieldProperty string `query:"date_field_property"`
|
||||||
|
NameProperty string `query:"name_property"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *routes) calendarHandler(c *fiber.Ctx) error {
|
||||||
|
var options calendarOptions
|
||||||
|
if err := c.QueryParser(&options); err != nil {
|
||||||
|
r.logger.Error("error parsing query", zap.String("query", c.Context().QueryArgs().String()))
|
||||||
|
}
|
||||||
|
|
||||||
|
dbID := c.Params("databaseID")
|
||||||
|
|
||||||
|
query := notion.DatabaseQuery{
|
||||||
|
Filter: ¬ion.DatabaseQueryFilter{
|
||||||
|
Property: options.DateFieldProperty,
|
||||||
|
Date: ¬ion.DateDatabaseQueryFilter{
|
||||||
|
IsNotEmpty: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := r.notion.Client.QueryDatabase(c.Context(), dbID, &query)
|
||||||
|
if err != nil {
|
||||||
|
r.logger.Error("can't query notion database", zap.Error(err))
|
||||||
|
return c.SendStatus(500)
|
||||||
|
}
|
||||||
|
|
||||||
|
cal := ical.NewCalendar()
|
||||||
|
cal.Props.SetText(ical.PropVersion, "2.0")
|
||||||
|
cal.Props.SetText(ical.PropProductID, "-//notion2ical.fmartingr.dev//NONSGML PDA Calendar Version 1.0//EN")
|
||||||
|
|
||||||
|
for _, r := range result.Results {
|
||||||
|
event := ical.NewEvent()
|
||||||
|
event.Props.SetText(ical.PropUID, r.ID)
|
||||||
|
dateProperty := r.Properties.(notion.DatabasePageProperties)[options.DateFieldProperty].Date
|
||||||
|
dateStart := dateProperty.Start.Time
|
||||||
|
dateEnd := dateStart
|
||||||
|
if dateProperty.End != nil {
|
||||||
|
dateEnd = dateProperty.End.Time
|
||||||
|
}
|
||||||
|
if options.AllDayEvents {
|
||||||
|
event.Props.SetDate(ical.PropDateTimeStamp, dateStart)
|
||||||
|
event.Props.SetDate(ical.PropDateTimeStart, dateEnd)
|
||||||
|
} else {
|
||||||
|
event.Props.SetDateTime(ical.PropDateTimeStamp, dateStart)
|
||||||
|
event.Props.SetDateTime(ical.PropDateTimeStart, dateEnd)
|
||||||
|
}
|
||||||
|
event.Props.SetText(ical.PropSummary, r.Properties.(notion.DatabasePageProperties)[options.NameProperty].Title[0].Text.Content)
|
||||||
|
|
||||||
|
cal.Children = append(cal.Children, event.Component)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := ical.NewEncoder(&buf).Encode(cal); err != nil {
|
||||||
|
r.logger.Fatal("error encoding calendar", zap.Error(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Send(buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRoutes(logger *zap.Logger, notion *notionClient.NotionClient) *routes {
|
||||||
|
routes := routes{
|
||||||
|
logger: logger,
|
||||||
|
notion: notion,
|
||||||
|
router: fiber.New(),
|
||||||
|
}
|
||||||
|
routes.Setup()
|
||||||
|
return &routes
|
||||||
|
}
|
|
@ -1,20 +1,16 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dstotijn/go-notion"
|
|
||||||
"github.com/emersion/go-ical"
|
|
||||||
notionClient "github.com/fmartingr/notion2ical/internal/notion"
|
notionClient "github.com/fmartingr/notion2ical/internal/notion"
|
||||||
"github.com/fmartingr/notion2ical/internal/server/http/middleware"
|
"github.com/fmartingr/notion2ical/internal/server/http/middleware"
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/gofiber/fiber/v2/middleware/cache"
|
"github.com/gofiber/fiber/v2/middleware/cache"
|
||||||
"github.com/gofiber/fiber/v2/middleware/recover"
|
"github.com/gofiber/fiber/v2/middleware/recover"
|
||||||
"github.com/gofiber/fiber/v2/middleware/requestid"
|
"github.com/gofiber/fiber/v2/middleware/requestid"
|
||||||
"github.com/gofiber/fiber/v2/middleware/timeout"
|
|
||||||
"github.com/gofiber/fiber/v2/utils"
|
"github.com/gofiber/fiber/v2/utils"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -23,7 +19,7 @@ type HttpServer struct {
|
||||||
http *fiber.App
|
http *fiber.App
|
||||||
addr string
|
addr string
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
notion *notionClient.NotionClient
|
routes *routes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HttpServer) Setup() {
|
func (s *HttpServer) Setup() {
|
||||||
|
@ -48,8 +44,7 @@ func (s *HttpServer) Setup() {
|
||||||
})).
|
})).
|
||||||
Use(recover.New()).
|
Use(recover.New()).
|
||||||
Static("/", "./public").
|
Static("/", "./public").
|
||||||
Get("/calendar/:databaseID", timeout.New(s.calendarHandler, time.Second*30)).
|
Mount("/", s.routes.Router()).
|
||||||
Get("/liveness", s.livenessHandler).
|
|
||||||
Use(s.notFound)
|
Use(s.notFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,77 +62,11 @@ func (s *HttpServer) notFound(c *fiber.Ctx) error {
|
||||||
return c.SendStatus(404)
|
return c.SendStatus(404)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *HttpServer) livenessHandler(c *fiber.Ctx) error {
|
|
||||||
return c.SendStatus(200)
|
|
||||||
}
|
|
||||||
|
|
||||||
type calendarOptions struct {
|
|
||||||
AllDayEvents bool `query:"all_day_events"`
|
|
||||||
DateFieldProperty string `query:"date_field_property"`
|
|
||||||
NameProperty string `query:"name_property"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *HttpServer) calendarHandler(c *fiber.Ctx) error {
|
|
||||||
var options calendarOptions
|
|
||||||
if err := c.QueryParser(&options); err != nil {
|
|
||||||
s.logger.Error("error parsing query", zap.String("query", c.Context().QueryArgs().String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
dbID := c.Params("databaseID")
|
|
||||||
|
|
||||||
query := notion.DatabaseQuery{
|
|
||||||
Filter: ¬ion.DatabaseQueryFilter{
|
|
||||||
Property: options.DateFieldProperty,
|
|
||||||
Date: ¬ion.DateDatabaseQueryFilter{
|
|
||||||
IsNotEmpty: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
result, err := s.notion.Client.QueryDatabase(c.Context(), dbID, &query)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Error("can't query notion database", zap.Error(err))
|
|
||||||
return c.SendStatus(500)
|
|
||||||
}
|
|
||||||
|
|
||||||
cal := ical.NewCalendar()
|
|
||||||
cal.Props.SetText(ical.PropVersion, "2.0")
|
|
||||||
cal.Props.SetText(ical.PropProductID, "-//notion2ical.fmartingr.dev//NONSGML PDA Calendar Version 1.0//EN")
|
|
||||||
|
|
||||||
for _, r := range result.Results {
|
|
||||||
event := ical.NewEvent()
|
|
||||||
event.Props.SetText(ical.PropUID, r.ID)
|
|
||||||
dateProperty := r.Properties.(notion.DatabasePageProperties)[options.DateFieldProperty].Date
|
|
||||||
dateStart := dateProperty.Start.Time
|
|
||||||
dateEnd := dateStart
|
|
||||||
if dateProperty.End != nil {
|
|
||||||
dateEnd = dateProperty.End.Time
|
|
||||||
}
|
|
||||||
if options.AllDayEvents {
|
|
||||||
event.Props.SetDate(ical.PropDateTimeStamp, dateStart)
|
|
||||||
event.Props.SetDate(ical.PropDateTimeStart, dateEnd)
|
|
||||||
} else {
|
|
||||||
event.Props.SetDateTime(ical.PropDateTimeStamp, dateStart)
|
|
||||||
event.Props.SetDateTime(ical.PropDateTimeStart, dateEnd)
|
|
||||||
}
|
|
||||||
event.Props.SetText(ical.PropSummary, r.Properties.(notion.DatabasePageProperties)[options.NameProperty].Title[0].Text.Content)
|
|
||||||
|
|
||||||
cal.Children = append(cal.Children, event.Component)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if err := ical.NewEncoder(&buf).Encode(cal); err != nil {
|
|
||||||
s.logger.Fatal("error encoding calendar", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.Send(buf.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHttpServer(logger *zap.Logger, port int, notionClient *notionClient.NotionClient) *HttpServer {
|
func NewHttpServer(logger *zap.Logger, port int, notionClient *notionClient.NotionClient) *HttpServer {
|
||||||
server := HttpServer{
|
server := HttpServer{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
addr: fmt.Sprintf(":%d", port),
|
addr: fmt.Sprintf(":%d", port),
|
||||||
notion: notionClient,
|
routes: newRoutes(logger, notionClient),
|
||||||
http: fiber.New(fiber.Config{
|
http: fiber.New(fiber.Config{
|
||||||
ErrorHandler: func(c *fiber.Ctx, err error) error {
|
ErrorHandler: func(c *fiber.Ctx, err error) error {
|
||||||
logger.Error(
|
logger.Error(
|
||||||
|
|
Loading…
Reference in New Issue