Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
775b7933
Commit
775b7933
authored
May 02, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update object in s3
parent
26545c85
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
80 additions
and
71 deletions
+80
-71
s3.go
plugin/storage/s3/s3.go
+18
-6
webhook.go
plugin/webhook/webhook.go
+10
-33
memo_service.go
server/router/api/v1/memo_service.go
+12
-26
resource_service.go
server/router/api/v1/resource_service.go
+1
-1
resource.go
store/resource.go
+39
-5
No files found.
plugin/storage/s3/s3.go
View file @
775b7933
...
@@ -45,10 +45,10 @@ func NewClient(ctx context.Context, s3Config *storepb.WorkspaceStorageSetting_S3
...
@@ -45,10 +45,10 @@ func NewClient(ctx context.Context, s3Config *storepb.WorkspaceStorageSetting_S3
}
}
// UploadObject uploads an object to S3.
// UploadObject uploads an object to S3.
func
(
c
lient
*
Client
)
UploadObject
(
ctx
context
.
Context
,
key
string
,
fileType
string
,
content
io
.
Reader
)
(
string
,
error
)
{
func
(
c
*
Client
)
UploadObject
(
ctx
context
.
Context
,
key
string
,
fileType
string
,
content
io
.
Reader
)
(
string
,
error
)
{
uploader
:=
manager
.
NewUploader
(
c
lient
.
Client
)
uploader
:=
manager
.
NewUploader
(
c
.
Client
)
putInput
:=
s3
.
PutObjectInput
{
putInput
:=
s3
.
PutObjectInput
{
Bucket
:
c
lient
.
Bucket
,
Bucket
:
c
.
Bucket
,
Key
:
aws
.
String
(
key
),
Key
:
aws
.
String
(
key
),
ContentType
:
aws
.
String
(
fileType
),
ContentType
:
aws
.
String
(
fileType
),
Body
:
content
,
Body
:
content
,
...
@@ -66,10 +66,10 @@ func (client *Client) UploadObject(ctx context.Context, key string, fileType str
...
@@ -66,10 +66,10 @@ func (client *Client) UploadObject(ctx context.Context, key string, fileType str
}
}
// PresignGetObject presigns an object in S3.
// PresignGetObject presigns an object in S3.
func
(
c
lient
*
Client
)
PresignGetObject
(
ctx
context
.
Context
,
bucke
t
,
key
string
)
(
string
,
error
)
{
func
(
c
*
Client
)
PresignGetObject
(
ctx
context
.
Contex
t
,
key
string
)
(
string
,
error
)
{
presignClient
:=
s3
.
NewPresignClient
(
c
lient
.
Client
)
presignClient
:=
s3
.
NewPresignClient
(
c
.
Client
)
presignResult
,
err
:=
presignClient
.
PresignGetObject
(
context
.
TODO
(),
&
s3
.
GetObjectInput
{
presignResult
,
err
:=
presignClient
.
PresignGetObject
(
context
.
TODO
(),
&
s3
.
GetObjectInput
{
Bucket
:
aws
.
String
(
b
ucket
),
Bucket
:
aws
.
String
(
*
c
.
B
ucket
),
Key
:
aws
.
String
(
key
),
Key
:
aws
.
String
(
key
),
},
func
(
opts
*
s3
.
PresignOptions
)
{
},
func
(
opts
*
s3
.
PresignOptions
)
{
opts
.
Expires
=
time
.
Duration
(
presignLifetimeSecs
*
int64
(
time
.
Second
))
opts
.
Expires
=
time
.
Duration
(
presignLifetimeSecs
*
int64
(
time
.
Second
))
...
@@ -79,3 +79,15 @@ func (client *Client) PresignGetObject(ctx context.Context, bucket, key string)
...
@@ -79,3 +79,15 @@ func (client *Client) PresignGetObject(ctx context.Context, bucket, key string)
}
}
return
presignResult
.
URL
,
nil
return
presignResult
.
URL
,
nil
}
}
// DeleteObject deletes an object in S3.
func
(
c
*
Client
)
DeleteObject
(
ctx
context
.
Context
,
key
string
)
error
{
_
,
err
:=
c
.
Client
.
DeleteObject
(
ctx
,
&
s3
.
DeleteObjectInput
{
Bucket
:
c
.
Bucket
,
Key
:
aws
.
String
(
key
),
})
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to delete object"
)
}
return
nil
}
plugin/webhook/webhook.go
View file @
775b7933
...
@@ -8,6 +8,8 @@ import (
...
@@ -8,6 +8,8 @@ import (
"time"
"time"
"github.com/pkg/errors"
"github.com/pkg/errors"
v1pb
"github.com/usememos/memos/proto/gen/api/v1"
)
)
var
(
var
(
...
@@ -22,44 +24,19 @@ type Memo struct {
...
@@ -22,44 +24,19 @@ type Memo struct {
UpdatedTs
int64
`json:"updatedTs"`
UpdatedTs
int64
`json:"updatedTs"`
// Domain specific fields
// Domain specific fields
Content
string
`json:"content"`
Content
string
`json:"content"`
Visibility
string
`json:"visibility"`
Visibility
string
`json:"visibility"`
Pinned
bool
`json:"pinned"`
Pinned
bool
`json:"pinned"`
ResourceList
[]
*
Resource
`json:"resourceList"`
RelationList
[]
*
MemoRelation
`json:"relationList"`
}
type
Resource
struct
{
ID
int32
`json:"id"`
UID
string
`json:"uid"`
// Standard fields
CreatorID
int32
`json:"creatorId"`
CreatedTs
int64
`json:"createdTs"`
UpdatedTs
int64
`json:"updatedTs"`
// Domain specific fields
Filename
string
`json:"filename"`
InternalPath
string
`json:"internalPath"`
ExternalLink
string
`json:"externalLink"`
Type
string
`json:"type"`
Size
int64
`json:"size"`
}
type
MemoRelation
struct
{
MemoID
int32
`json:"memoId"`
RelatedMemoID
int32
`json:"relatedMemoId"`
Type
string
`json:"type"`
}
}
// WebhookPayload is the payload of webhook request.
// WebhookPayload is the payload of webhook request.
// nolint
// nolint
type
WebhookPayload
struct
{
type
WebhookPayload
struct
{
URL
string
`json:"url"`
URL
string
`json:"url"`
ActivityType
string
`json:"activityType"`
ActivityType
string
`json:"activityType"`
CreatorID
int32
`json:"creatorId"`
CreatorID
int32
`json:"creatorId"`
CreatedTs
int64
`json:"createdTs"`
CreatedTs
int64
`json:"createdTs"`
Memo
*
Memo
`json:"memo"`
Memo
*
v1pb
.
Memo
`json:"memo"`
}
}
// WebhookResponse is the response of webhook request.
// WebhookResponse is the response of webhook request.
...
...
server/router/api/v1/memo_service.go
View file @
775b7933
...
@@ -314,6 +314,17 @@ func (s *APIV1Service) DeleteMemo(ctx context.Context, request *v1pb.DeleteMemoR
...
@@ -314,6 +314,17 @@ func (s *APIV1Service) DeleteMemo(ctx context.Context, request *v1pb.DeleteMemoR
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to delete memo"
)
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to delete memo"
)
}
}
// Delete related resources.
resources
,
err
:=
s
.
Store
.
ListResources
(
ctx
,
&
store
.
FindResource
{
MemoID
:
&
id
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to list resources"
)
}
for
_
,
resource
:=
range
resources
{
if
err
:=
s
.
Store
.
DeleteResource
(
ctx
,
&
store
.
DeleteResource
{
ID
:
resource
.
ID
});
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to delete resource"
)
}
}
return
&
emptypb
.
Empty
{},
nil
return
&
emptypb
.
Empty
{},
nil
}
}
...
@@ -841,34 +852,9 @@ func convertMemoToWebhookPayload(memo *v1pb.Memo) (*webhook.WebhookPayload, erro
...
@@ -841,34 +852,9 @@ func convertMemoToWebhookPayload(memo *v1pb.Memo) (*webhook.WebhookPayload, erro
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"invalid memo creator"
)
return
nil
,
errors
.
Wrap
(
err
,
"invalid memo creator"
)
}
}
id
,
err
:=
ExtractMemoIDFromName
(
memo
.
Name
)
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"invalid memo name"
)
}
return
&
webhook
.
WebhookPayload
{
return
&
webhook
.
WebhookPayload
{
CreatorID
:
creatorID
,
CreatorID
:
creatorID
,
CreatedTs
:
time
.
Now
()
.
Unix
(),
CreatedTs
:
time
.
Now
()
.
Unix
(),
Memo
:
&
webhook
.
Memo
{
Memo
:
memo
,
ID
:
id
,
CreatorID
:
creatorID
,
CreatedTs
:
memo
.
CreateTime
.
Seconds
,
UpdatedTs
:
memo
.
UpdateTime
.
Seconds
,
Content
:
memo
.
Content
,
Visibility
:
memo
.
Visibility
.
String
(),
Pinned
:
memo
.
Pinned
,
ResourceList
:
func
()
[]
*
webhook
.
Resource
{
resources
:=
[]
*
webhook
.
Resource
{}
for
_
,
resource
:=
range
memo
.
Resources
{
resources
=
append
(
resources
,
&
webhook
.
Resource
{
UID
:
resource
.
Uid
,
Filename
:
resource
.
Filename
,
ExternalLink
:
resource
.
ExternalLink
,
Type
:
resource
.
Type
,
Size
:
resource
.
Size
,
})
}
return
resources
}(),
},
},
nil
},
nil
}
}
server/router/api/v1/resource_service.go
View file @
775b7933
...
@@ -365,7 +365,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
...
@@ -365,7 +365,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc
if
err
!=
nil
{
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Failed to upload via s3 client"
)
return
errors
.
Wrap
(
err
,
"Failed to upload via s3 client"
)
}
}
presignURL
,
err
:=
s3Client
.
PresignGetObject
(
ctx
,
s3Config
.
Bucket
,
key
)
presignURL
,
err
:=
s3Client
.
PresignGetObject
(
ctx
,
key
)
if
err
!=
nil
{
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Failed to presign via s3 client"
)
return
errors
.
Wrap
(
err
,
"Failed to presign via s3 client"
)
}
}
...
...
store/resource.go
View file @
775b7933
...
@@ -2,12 +2,14 @@ package store
...
@@ -2,12 +2,14 @@ package store
import
(
import
(
"context"
"context"
"log/slog"
"os"
"os"
"path/filepath"
"path/filepath"
"github.com/pkg/errors"
"github.com/pkg/errors"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/internal/util"
"github.com/usememos/memos/plugin/storage/s3"
storepb
"github.com/usememos/memos/proto/gen/store"
storepb
"github.com/usememos/memos/proto/gen/store"
)
)
...
@@ -100,13 +102,45 @@ func (s *Store) DeleteResource(ctx context.Context, delete *DeleteResource) erro
...
@@ -100,13 +102,45 @@ func (s *Store) DeleteResource(ctx context.Context, delete *DeleteResource) erro
return
errors
.
Wrap
(
nil
,
"resource not found"
)
return
errors
.
Wrap
(
nil
,
"resource not found"
)
}
}
// Delete the local file.
if
resource
.
StorageType
==
storepb
.
ResourceStorageType_LOCAL
{
if
resource
.
StorageType
==
storepb
.
ResourceStorageType_LOCAL
{
p
:=
filepath
.
FromSlash
(
resource
.
Reference
)
if
err
:=
func
()
error
{
if
!
filepath
.
IsAbs
(
p
)
{
p
:=
filepath
.
FromSlash
(
resource
.
Reference
)
p
=
filepath
.
Join
(
s
.
Profile
.
Data
,
p
)
if
!
filepath
.
IsAbs
(
p
)
{
p
=
filepath
.
Join
(
s
.
Profile
.
Data
,
p
)
}
err
:=
os
.
Remove
(
p
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to delete local file"
)
}
return
nil
}();
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to delete local file"
)
}
}
else
if
resource
.
StorageType
==
storepb
.
ResourceStorageType_S3
{
if
err
:=
func
()
error
{
s3ObjectPayload
:=
resource
.
Payload
.
GetS3Object
()
if
s3ObjectPayload
==
nil
{
return
errors
.
Errorf
(
"No s3 object found"
)
}
workspaceStorageSetting
,
err
:=
s
.
GetWorkspaceStorageSetting
(
ctx
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"failed to get workspace storage setting"
)
}
s3Config
:=
workspaceStorageSetting
.
S3Config
if
s3Config
==
nil
{
return
errors
.
Errorf
(
"No actived external storage found"
)
}
s3Client
,
err
:=
s3
.
NewClient
(
ctx
,
s3Config
)
if
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Failed to create s3 client"
)
}
if
err
:=
s3Client
.
DeleteObject
(
ctx
,
s3ObjectPayload
.
Key
);
err
!=
nil
{
return
errors
.
Wrap
(
err
,
"Failed to delete s3 object"
)
}
return
nil
}();
err
!=
nil
{
slog
.
Warn
(
"Failed to delete s3 object"
,
err
)
}
}
_
=
os
.
Remove
(
p
)
}
}
return
s
.
driver
.
DeleteResource
(
ctx
,
delete
)
return
s
.
driver
.
DeleteResource
(
ctx
,
delete
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment