From 06f4fed3ed5e6b81d8cc4b07db59f3ddf551d9c3 Mon Sep 17 00:00:00 2001 From: Rogee Date: Wed, 4 Sep 2024 13:08:22 +0800 Subject: [PATCH] feat: add upload logics --- internal/cmd_publish.go | 69 +++++++++++++++++++++++++++++++------ internal/db_channel_test.go | 14 +++++++- main.go | 2 ++ pkg/memos/memos.go | 46 +++++++++++++------------ 4 files changed, 97 insertions(+), 34 deletions(-) diff --git a/internal/cmd_publish.go b/internal/cmd_publish.go index 348f5a1..a10149c 100644 --- a/internal/cmd_publish.go +++ b/internal/cmd_publish.go @@ -2,6 +2,10 @@ package internal import ( "context" + "encoding/json" + "fmt" + "os" + "path/filepath" "exporter/config" "exporter/database/telegram_resource/public/model" @@ -23,13 +27,22 @@ func PublishCmd() *cobra.Command { return cmd } +type publishMsg struct { + model.ChannelMessages + model.Channels +} + func publishCmd(ctx context.Context) error { - var msg model.ChannelMessages + var msg publishMsg tbl := table.ChannelMessages - err := tbl.SELECT(tbl.AllColumns).WHERE(tbl.Published.IS_TRUE()).LIMIT(1).QueryContext(ctx, db, &msg) - if err != nil { - return err + tblC := table.Channels + stmt := tbl.SELECT(tbl.AllColumns, tblC.Title). + WHERE(tbl.Published.IS_FALSE()). + LIMIT(1). + FROM(tbl.LEFT_JOIN(tblC, tbl.ChannelID.EQ(tblC.UUID))) + if err := stmt.QueryContext(context.Background(), db, &msg); err != nil { + return errors.Wrap(err, "failed to get message") } // publish item @@ -37,7 +50,7 @@ func publishCmd(ctx context.Context) error { return errors.Wrap(err, "failed to publish") } - _, err = tbl.UPDATE().SET(tbl.Published.SET(Bool(true))).WHERE(tbl.ID.EQ(Int(msg.ID))).ExecContext(ctx, db) + _, err := tbl.UPDATE().SET(tbl.Published.SET(Bool(true))).WHERE(tbl.ID.EQ(Int64(msg.ChannelMessages.ID))).ExecContext(ctx, db) if err != nil { return err } @@ -45,14 +58,48 @@ func publishCmd(ctx context.Context) error { return nil } -func publish(ctx context.Context, msg model.ChannelMessages) error { +func publish(ctx context.Context, msg publishMsg) error { + memos.InitClient(config.C.PublishHost, config.C.PublishToken) + data := memos.PostData{ - Host: config.C.PublishHost, - Token: config.C.PublishToken, - Content: *msg.Content, - ChannelID: msg.ChannelID, - ChannelTitle: "", + Content: *msg.ChannelMessages.Content, + ChannelID: msg.ChannelMessages.ChannelID, + ChannelTitle: msg.Channels.Title, Resources: []memos.Resource{}, } + + var medias []ChannelMessageMedia + if err := json.Unmarshal([]byte(msg.ChannelMessages.Media), &medias); err != nil { + return errors.Wrap(err, "failed to unmarshal media") + } + + for _, media := range medias { + res := memos.Resource{} + + var file string + if media.Photo != nil { + res.Type = "image/jpg" + res.Name = *media.Photo + file = fmt.Sprintf("%d/%s", data.ChannelID, *media.Photo) + } else if media.Document != nil { + res.Type = media.Document.MimeType + res.Name = media.Document.Filename + file = fmt.Sprintf("%d/%d%s", data.ChannelID, media.AssetID, media.Document.Ext) + } + filepath := filepath.Join(config.C.Output, file) + b, err := os.ReadFile(filepath) + if err != nil { + return err + } + res.Content = b + + resource, err := memos.Upload(res) + if err != nil { + return err + } + + data.Resources = append(data.Resources, resource) + } + return memos.Post(data) } diff --git a/internal/db_channel_test.go b/internal/db_channel_test.go index b93bed1..d84c62f 100644 --- a/internal/db_channel_test.go +++ b/internal/db_channel_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "exporter/database/telegram_resource/public/model" "exporter/database/telegram_resource/public/table" "github.com/samber/lo" @@ -56,12 +57,23 @@ func Test_Join(t *testing.T) { if err := InitDB(dsn); err != nil { t.Error(err) } + // db.Exec(`truncate channel_messages`) + var msg struct { + model.ChannelMessages + model.Channels + } tblC := table.Channels tbl := table.ChannelMessages stmt := tbl.SELECT(tbl.AllColumns, tblC.Title). - WHERE(tbl.Published.IS_TRUE()). + WHERE(tbl.Published.IS_FALSE()). LIMIT(1). FROM(tbl.LEFT_JOIN(tblC, tbl.ChannelID.EQ(tblC.UUID))) t.Log(stmt.DebugSql()) + + if err := stmt.QueryContext(context.Background(), db, &msg); err != nil { + t.Error(err) + } + + t.Logf("%+v", msg) } diff --git a/main.go b/main.go index 4360c62..3ac2803 100644 --- a/main.go +++ b/main.go @@ -42,6 +42,8 @@ func main() { rootCmd.AddCommand( internal.LoginCmd(), internal.ExportCmd(), + internal.PublishCmd(), + internal.WatchCmd(), ) // rootCmd.SilenceErrors = true diff --git a/pkg/memos/memos.go b/pkg/memos/memos.go index e0ab3f9..f785016 100644 --- a/pkg/memos/memos.go +++ b/pkg/memos/memos.go @@ -22,35 +22,22 @@ type Memo struct { Uid string `json:"uid,omitempty"` // resp } +// Host string +// Token string type PostData struct { - Host string - Token string Content string ChannelID int64 ChannelTitle string Resources []Resource } +var client *req.Client + +func InitClient(host, token string) { + client = req.C().EnableInsecureSkipVerify().SetBaseURL(host).SetCommonBearerAuthToken(token) +} + func Post(pd PostData) error { - client := req.C().EnableInsecureSkipVerify().SetBaseURL(pd.Host).SetCommonBearerAuthToken(pd.Token) - - resources := []Resource{} - - for _, res := range pd.Resources { - var result Resource - - resp, err := client.R().SetSuccessResult(&result).SetBodyJsonMarshal(res).Post("/api/v1/resources") - if err != nil { - return errors.Wrap(err, "post resource failed") - } - - if !resp.IsSuccessState() { - return errors.New("post memo failed, body: " + resp.String()) - } - - resources = append(resources, result) - } - var createMemoResp Memo resp, err := client.R(). @@ -73,7 +60,7 @@ func Post(pd PostData) error { } resp, err = client.R(). - SetBodyJsonMarshal(Resources{Resources: resources}). + SetBodyJsonMarshal(Resources{Resources: pd.Resources}). Patch(fmt.Sprintf("/api/v1/%s/resources", createMemoResp.Name)) if err != nil { return errors.Wrap(err, "patch resources failed") @@ -85,3 +72,18 @@ func Post(pd PostData) error { return nil } + +func Upload(res Resource) (Resource, error) { + var result Resource + + resp, err := client.R().SetSuccessResult(&result).SetBodyJsonMarshal(res).Post("/api/v1/resources") + if err != nil { + return Resource{}, errors.Wrap(err, "post resource failed") + } + + if !resp.IsSuccessState() { + return Resource{}, errors.New("post memo failed, body: " + resp.String()) + } + + return res, nil +}