diff --git a/cmd/client/client.go b/cmd/client/client.go index 53552adb..5213a1b4 100644 --- a/cmd/client/client.go +++ b/cmd/client/client.go @@ -3,12 +3,9 @@ package client import ( "context" "crypto/tls" - "errors" "fmt" - "io" "net/http" "net/url" - "os" "github.com/movsb/taoblog/protocols" "google.golang.org/grpc" @@ -16,15 +13,6 @@ import ( "google.golang.org/grpc/metadata" ) -var ( - // ErrStatusCode ... - ErrStatusCode = errors.New("http.statusCode != 200") -) - -const ( - contentTypeBinary = "application/octet-stream" -) - // Client ... // TODO: close client connection. type Client struct { @@ -102,27 +90,3 @@ func NewClient(config HostConfig) *Client { func (c *Client) token() context.Context { return metadata.NewOutgoingContext(context.TODO(), metadata.Pairs("token", c.config.Token)) } - -func (c *Client) post(path string, body io.Reader, ty string) *http.Response { - req, err := http.NewRequest("POST", c.config.API+path, body) - if err != nil { - panic(err) - } - req.Header.Set("Authorization", c.config.Token) - req.Header.Set("Content-Type", ty) - resp, err := c.client.Do(req) - if err != nil { - panic(err) - } - return resp -} - -func (c *Client) mustPost(path string, body io.Reader, ty string) *http.Response { - resp := c.post(path, body, ty) - if resp.StatusCode != 200 { - io.Copy(os.Stderr, resp.Body) - resp.Body.Close() - panic(resp.Status) - } - return resp -} diff --git a/cmd/client/post.go b/cmd/client/post.go index fe5bd5a8..650510bc 100644 --- a/cmd/client/post.go +++ b/cmd/client/post.go @@ -2,10 +2,10 @@ package client import ( "errors" - "fmt" "log" "os" "path/filepath" + "sort" "strings" "github.com/movsb/taoblog/protocols" @@ -225,6 +225,7 @@ func (c *Client) DeletePost(id int64) error { // UploadPostFiles 上传文章附件。 // TODO 目前为了简单起见,使用的是 HTTP POST 方式上传; // TODO 应该像 Backup 那样改成带进度的 protocol buffer 方式上传。 +// files 路径列表,相对于工作目录,相对路径。 func (c *Client) UploadPostFiles(files []string) { config := c.readPostConfig() if config.ID <= 0 { @@ -233,17 +234,177 @@ func (c *Client) UploadPostFiles(files []string) { if len(files) <= 0 { return } + + client, err := c.management.FileSystem(c.token()) + if err != nil { + panic(err) + } + defer client.CloseSend() + + if err := client.Send(&protocols.FileSystemRequest{ + Init: &protocols.FileSystemRequest_InitRequest{ + For: &protocols.FileSystemRequest_InitRequest_Post_{ + Post: &protocols.FileSystemRequest_InitRequest_Post{ + Id: config.ID, + }, + }, + }, + }); err != nil { + panic(err) + } + rsp, err := client.Recv() + if err != nil { + panic(err) + } + if rsp.GetInit() == nil { + panic("expect init") + } + + // log.Println("获取远程文件列表...") + if err := client.Send(&protocols.FileSystemRequest{ + Request: &protocols.FileSystemRequest_ListFiles{ + ListFiles: &protocols.FileSystemRequest_ListFilesRequest{}, + }, + }); err != nil { + panic(err) + } + rsp, err = client.Recv() + if err != nil { + panic(err) + } + remoteList := rsp.GetListFiles() + if remoteList == nil { + panic("list is nil") + } + remoteFiles := remoteList.GetFiles() + + // log.Println("获取本地文件列表...") + var localFiles []*protocols.FileSpec for _, file := range files { - fmt.Println(" +", file) - var err error - fp, err := os.Open(file) + stat, err := os.Stat(file) if err != nil { log.Fatalln(err) } - defer fp.Close() - path := fmt.Sprintf("/posts/%d/files/%s", config.ID, file) - resp := c.mustPost(path, fp, contentTypeBinary) - _ = resp + f := protocols.FileSpec{ + Path: file, + Mode: uint32(stat.Mode()), + Size: uint32(stat.Size()), + Time: uint32(stat.ModTime().Unix()), + } + localFiles = append(localFiles, &f) + } + + sort.Slice(remoteFiles, func(i, j int) bool { + return strings.Compare(remoteFiles[i].Path, remoteFiles[j].Path) < 0 + }) + sort.Slice(localFiles, func(i, j int) bool { + return strings.Compare(localFiles[i].Path, localFiles[j].Path) < 0 + }) + + rl, rr := localFiles, remoteFiles + i, j := len(rl)-1, len(rr)-1 + + for { + if i == -1 && j == -1 { + // log.Println("没有更多需要比较的文件。") + break + } + + deleteRemote := func(r *protocols.FileSpec) { + // delete remote + if err := client.Send(&protocols.FileSystemRequest{ + Request: &protocols.FileSystemRequest_DeleteFile{ + DeleteFile: &protocols.FileSystemRequest_DeleteFileRequest{ + Path: r.Path, + }, + }, + }); err != nil { + panic(err) + } + rsp, err := client.Recv() + if err != nil { + panic(err) + } + if rsp.GetDeleteFile() == nil { + panic("expect get delete") + } + log.Println("删除远程:", r.Path) + } + + if i == -1 { + deleteRemote(rr[j]) + j-- + continue + } + copyToRemote := func(l *protocols.FileSpec, data []byte) { + // log.Println("准备复制到远程:", l.Path) + if err := client.Send(&protocols.FileSystemRequest{ + Request: &protocols.FileSystemRequest_WriteFile{ + WriteFile: &protocols.FileSystemRequest_WriteFileRequest{ + Spec: l, + Data: data, + }, + }, + }); err != nil { + panic(err) + } + rsp, err := client.Recv() + if err != nil { + panic(err) + } + if rsp.GetWriteFile() == nil { + panic("expect write file") + } + log.Println("复制到远程:", l.Path) + } + if j == -1 { + data, err := os.ReadFile(localFiles[i].Path) + if err != nil { + // TODO 不正确的判断方式 + if !strings.Contains(err.Error(), "is a dir") { + panic(err) + } + i-- + continue + } + l := localFiles[i] + copyToRemote(l, data) + i-- + continue + } + switch n := strings.Compare(rl[i].Path, rr[j].Path); { + case n < 0: + data, err := os.ReadFile(rl[i].Path) + if err != nil { + panic(err) + } + copyToRemote(rl[i], data) + case n > 0: + deleteRemote(rr[j]) + case n == 0: + lm, rm := os.FileMode(rl[i].Mode), os.FileMode(rr[j].Mode) + if lm.IsDir() != rm.IsDir() { + panic(("file != dir")) + } + shouldSync := false + if rl[i].Size != rr[j].Size { + shouldSync = true + } + if rl[i].Time != rr[j].Time { + shouldSync = true + } + if shouldSync { + if rm.IsRegular() { + data, err := os.ReadFile(rl[i].Path) + if err != nil { + panic(err) + } + copyToRemote(rl[i], data) + } + } + i-- + j-- + } } } diff --git a/gateway/file.go b/gateway/file.go deleted file mode 100644 index d58432eb..00000000 --- a/gateway/file.go +++ /dev/null @@ -1,59 +0,0 @@ -package gateway - -import ( - "encoding/json" - "io" - "net/http" - "path/filepath" - - "github.com/movsb/taoblog/modules/utils" -) - -// ListFiles ... -func (g *Gateway) ListFiles(w http.ResponseWriter, req *http.Request, params map[string]string) { - postID := utils.MustToInt64(params["post_id"]) - list, err := g.service.Store().List(postID) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - e := json.NewEncoder(w) - e.SetIndent(``, ` `) - e.Encode(list) -} - -// GetFile ... -func (g *Gateway) GetFile(w http.ResponseWriter, req *http.Request, params map[string]string) { - postID := utils.MustToInt64(params["post_id"]) - file := params["file"] - fp, err := g.service.Store().Open(postID, filepath.Clean(file)) - if err != nil { - // TODO(movsb): format code - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer fp.Close() - stat, err := fp.Stat() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - http.ServeContent(w, req, stat.Name(), stat.ModTime(), fp) -} - -// CreateFile ... -func (g *Gateway) CreateFile(w http.ResponseWriter, req *http.Request, params map[string]string) { - postID := utils.MustToInt64(params["post_id"]) - file := params["file"] - fp, err := g.service.Store().Create(postID, filepath.Clean(file)) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer fp.Close() - if _, err := io.Copy(fp, req.Body); err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - w.WriteHeader(200) -} diff --git a/gateway/main.go b/gateway/main.go index 032b37bf..ac6a3a84 100644 --- a/gateway/main.go +++ b/gateway/main.go @@ -84,11 +84,6 @@ func (g *Gateway) runHTTPService(ctx context.Context, mux *http.ServeMux, mux2 * handle(`GET`, `/v3/avatar/{id}`, g.GetAvatar) - handle(`GET`, `/v3/posts/{post_id}/files`, g.ListFiles) - handle(`GET`, `/v3/posts/{post_id}/files/{file=**}`, g.GetFile) - handle(`POST`, `/v3/posts/{post_id}/files/{file=**}`, g.CreateFile) - // handle(`DELETE`, `/v3/posts/{post_id}/files/{file=**}`, g.DeleteFile) - handle(`GET`, `/v3/redirect-to-grafana`, redirectToGrafana) return nil diff --git a/protocols/post.pb.go b/protocols/post.pb.go index edc500cd..5d9085bd 100644 --- a/protocols/post.pb.go +++ b/protocols/post.pb.go @@ -628,6 +628,698 @@ func (x *SetRedirectRequest) GetStatusCode() int32 { return 0 } +type FileSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Mode uint32 `protobuf:"varint,2,opt,name=mode,proto3" json:"mode,omitempty"` + Size uint32 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` + Time uint32 `protobuf:"varint,4,opt,name=time,proto3" json:"time,omitempty"` +} + +func (x *FileSpec) Reset() { + *x = FileSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSpec) ProtoMessage() {} + +func (x *FileSpec) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSpec.ProtoReflect.Descriptor instead. +func (*FileSpec) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{9} +} + +func (x *FileSpec) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *FileSpec) GetMode() uint32 { + if x != nil { + return x.Mode + } + return 0 +} + +func (x *FileSpec) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *FileSpec) GetTime() uint32 { + if x != nil { + return x.Time + } + return 0 +} + +type FileSystemRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Init *FileSystemRequest_InitRequest `protobuf:"bytes,1,opt,name=init,proto3" json:"init,omitempty"` + // Types that are assignable to Request: + // + // *FileSystemRequest_ListFiles + // *FileSystemRequest_WriteFile + // *FileSystemRequest_DeleteFile + Request isFileSystemRequest_Request `protobuf_oneof:"Request"` +} + +func (x *FileSystemRequest) Reset() { + *x = FileSystemRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemRequest) ProtoMessage() {} + +func (x *FileSystemRequest) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemRequest.ProtoReflect.Descriptor instead. +func (*FileSystemRequest) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{10} +} + +func (x *FileSystemRequest) GetInit() *FileSystemRequest_InitRequest { + if x != nil { + return x.Init + } + return nil +} + +func (m *FileSystemRequest) GetRequest() isFileSystemRequest_Request { + if m != nil { + return m.Request + } + return nil +} + +func (x *FileSystemRequest) GetListFiles() *FileSystemRequest_ListFilesRequest { + if x, ok := x.GetRequest().(*FileSystemRequest_ListFiles); ok { + return x.ListFiles + } + return nil +} + +func (x *FileSystemRequest) GetWriteFile() *FileSystemRequest_WriteFileRequest { + if x, ok := x.GetRequest().(*FileSystemRequest_WriteFile); ok { + return x.WriteFile + } + return nil +} + +func (x *FileSystemRequest) GetDeleteFile() *FileSystemRequest_DeleteFileRequest { + if x, ok := x.GetRequest().(*FileSystemRequest_DeleteFile); ok { + return x.DeleteFile + } + return nil +} + +type isFileSystemRequest_Request interface { + isFileSystemRequest_Request() +} + +type FileSystemRequest_ListFiles struct { + ListFiles *FileSystemRequest_ListFilesRequest `protobuf:"bytes,10,opt,name=list_files,json=listFiles,proto3,oneof"` +} + +type FileSystemRequest_WriteFile struct { + WriteFile *FileSystemRequest_WriteFileRequest `protobuf:"bytes,11,opt,name=write_file,json=writeFile,proto3,oneof"` +} + +type FileSystemRequest_DeleteFile struct { + DeleteFile *FileSystemRequest_DeleteFileRequest `protobuf:"bytes,12,opt,name=delete_file,json=deleteFile,proto3,oneof"` +} + +func (*FileSystemRequest_ListFiles) isFileSystemRequest_Request() {} + +func (*FileSystemRequest_WriteFile) isFileSystemRequest_Request() {} + +func (*FileSystemRequest_DeleteFile) isFileSystemRequest_Request() {} + +type FileSystemResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Init *FileSystemResponse_InitResponse `protobuf:"bytes,1,opt,name=init,proto3" json:"init,omitempty"` + // Types that are assignable to Response: + // + // *FileSystemResponse_ListFiles + // *FileSystemResponse_WriteFile + // *FileSystemResponse_DeleteFile + Response isFileSystemResponse_Response `protobuf_oneof:"Response"` +} + +func (x *FileSystemResponse) Reset() { + *x = FileSystemResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemResponse) ProtoMessage() {} + +func (x *FileSystemResponse) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemResponse.ProtoReflect.Descriptor instead. +func (*FileSystemResponse) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{11} +} + +func (x *FileSystemResponse) GetInit() *FileSystemResponse_InitResponse { + if x != nil { + return x.Init + } + return nil +} + +func (m *FileSystemResponse) GetResponse() isFileSystemResponse_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *FileSystemResponse) GetListFiles() *FileSystemResponse_ListFilesResponse { + if x, ok := x.GetResponse().(*FileSystemResponse_ListFiles); ok { + return x.ListFiles + } + return nil +} + +func (x *FileSystemResponse) GetWriteFile() *FileSystemResponse_WriteFileResponse { + if x, ok := x.GetResponse().(*FileSystemResponse_WriteFile); ok { + return x.WriteFile + } + return nil +} + +func (x *FileSystemResponse) GetDeleteFile() *FileSystemResponse_DeleteFileResponse { + if x, ok := x.GetResponse().(*FileSystemResponse_DeleteFile); ok { + return x.DeleteFile + } + return nil +} + +type isFileSystemResponse_Response interface { + isFileSystemResponse_Response() +} + +type FileSystemResponse_ListFiles struct { + ListFiles *FileSystemResponse_ListFilesResponse `protobuf:"bytes,10,opt,name=list_files,json=listFiles,proto3,oneof"` +} + +type FileSystemResponse_WriteFile struct { + WriteFile *FileSystemResponse_WriteFileResponse `protobuf:"bytes,11,opt,name=write_file,json=writeFile,proto3,oneof"` +} + +type FileSystemResponse_DeleteFile struct { + DeleteFile *FileSystemResponse_DeleteFileResponse `protobuf:"bytes,12,opt,name=delete_file,json=deleteFile,proto3,oneof"` +} + +func (*FileSystemResponse_ListFiles) isFileSystemResponse_Response() {} + +func (*FileSystemResponse_WriteFile) isFileSystemResponse_Response() {} + +func (*FileSystemResponse_DeleteFile) isFileSystemResponse_Response() {} + +type FileSystemRequest_InitRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to For: + // + // *FileSystemRequest_InitRequest_Post_ + For isFileSystemRequest_InitRequest_For `protobuf_oneof:"For"` +} + +func (x *FileSystemRequest_InitRequest) Reset() { + *x = FileSystemRequest_InitRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemRequest_InitRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemRequest_InitRequest) ProtoMessage() {} + +func (x *FileSystemRequest_InitRequest) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemRequest_InitRequest.ProtoReflect.Descriptor instead. +func (*FileSystemRequest_InitRequest) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{10, 0} +} + +func (m *FileSystemRequest_InitRequest) GetFor() isFileSystemRequest_InitRequest_For { + if m != nil { + return m.For + } + return nil +} + +func (x *FileSystemRequest_InitRequest) GetPost() *FileSystemRequest_InitRequest_Post { + if x, ok := x.GetFor().(*FileSystemRequest_InitRequest_Post_); ok { + return x.Post + } + return nil +} + +type isFileSystemRequest_InitRequest_For interface { + isFileSystemRequest_InitRequest_For() +} + +type FileSystemRequest_InitRequest_Post_ struct { + Post *FileSystemRequest_InitRequest_Post `protobuf:"bytes,1,opt,name=post,proto3,oneof"` +} + +func (*FileSystemRequest_InitRequest_Post_) isFileSystemRequest_InitRequest_For() {} + +type FileSystemRequest_ListFilesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FileSystemRequest_ListFilesRequest) Reset() { + *x = FileSystemRequest_ListFilesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemRequest_ListFilesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemRequest_ListFilesRequest) ProtoMessage() {} + +func (x *FileSystemRequest_ListFilesRequest) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemRequest_ListFilesRequest.ProtoReflect.Descriptor instead. +func (*FileSystemRequest_ListFilesRequest) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{10, 1} +} + +type FileSystemRequest_WriteFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Spec *FileSpec `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *FileSystemRequest_WriteFileRequest) Reset() { + *x = FileSystemRequest_WriteFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemRequest_WriteFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemRequest_WriteFileRequest) ProtoMessage() {} + +func (x *FileSystemRequest_WriteFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemRequest_WriteFileRequest.ProtoReflect.Descriptor instead. +func (*FileSystemRequest_WriteFileRequest) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{10, 2} +} + +func (x *FileSystemRequest_WriteFileRequest) GetSpec() *FileSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *FileSystemRequest_WriteFileRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type FileSystemRequest_DeleteFileRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` +} + +func (x *FileSystemRequest_DeleteFileRequest) Reset() { + *x = FileSystemRequest_DeleteFileRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemRequest_DeleteFileRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemRequest_DeleteFileRequest) ProtoMessage() {} + +func (x *FileSystemRequest_DeleteFileRequest) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemRequest_DeleteFileRequest.ProtoReflect.Descriptor instead. +func (*FileSystemRequest_DeleteFileRequest) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{10, 3} +} + +func (x *FileSystemRequest_DeleteFileRequest) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +type FileSystemRequest_InitRequest_Post struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *FileSystemRequest_InitRequest_Post) Reset() { + *x = FileSystemRequest_InitRequest_Post{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemRequest_InitRequest_Post) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemRequest_InitRequest_Post) ProtoMessage() {} + +func (x *FileSystemRequest_InitRequest_Post) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemRequest_InitRequest_Post.ProtoReflect.Descriptor instead. +func (*FileSystemRequest_InitRequest_Post) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{10, 0, 0} +} + +func (x *FileSystemRequest_InitRequest_Post) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type FileSystemResponse_InitResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FileSystemResponse_InitResponse) Reset() { + *x = FileSystemResponse_InitResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemResponse_InitResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemResponse_InitResponse) ProtoMessage() {} + +func (x *FileSystemResponse_InitResponse) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemResponse_InitResponse.ProtoReflect.Descriptor instead. +func (*FileSystemResponse_InitResponse) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{11, 0} +} + +type FileSystemResponse_ListFilesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Files []*FileSpec `protobuf:"bytes,1,rep,name=files,proto3" json:"files,omitempty"` +} + +func (x *FileSystemResponse_ListFilesResponse) Reset() { + *x = FileSystemResponse_ListFilesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemResponse_ListFilesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemResponse_ListFilesResponse) ProtoMessage() {} + +func (x *FileSystemResponse_ListFilesResponse) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemResponse_ListFilesResponse.ProtoReflect.Descriptor instead. +func (*FileSystemResponse_ListFilesResponse) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{11, 1} +} + +func (x *FileSystemResponse_ListFilesResponse) GetFiles() []*FileSpec { + if x != nil { + return x.Files + } + return nil +} + +type FileSystemResponse_WriteFileResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FileSystemResponse_WriteFileResponse) Reset() { + *x = FileSystemResponse_WriteFileResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemResponse_WriteFileResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemResponse_WriteFileResponse) ProtoMessage() {} + +func (x *FileSystemResponse_WriteFileResponse) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemResponse_WriteFileResponse.ProtoReflect.Descriptor instead. +func (*FileSystemResponse_WriteFileResponse) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{11, 2} +} + +type FileSystemResponse_DeleteFileResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FileSystemResponse_DeleteFileResponse) Reset() { + *x = FileSystemResponse_DeleteFileResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_protocols_post_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FileSystemResponse_DeleteFileResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FileSystemResponse_DeleteFileResponse) ProtoMessage() {} + +func (x *FileSystemResponse_DeleteFileResponse) ProtoReflect() protoreflect.Message { + mi := &file_protocols_post_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FileSystemResponse_DeleteFileResponse.ProtoReflect.Descriptor instead. +func (*FileSystemResponse_DeleteFileResponse) Descriptor() ([]byte, []int) { + return file_protocols_post_proto_rawDescGZIP(), []int{11, 3} +} + var File_protocols_post_proto protoreflect.FileDescriptor var file_protocols_post_proto_rawDesc = []byte{ @@ -707,10 +1399,82 @@ var file_protocols_post_proto_rawDesc = []byte{ 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x42, 0x24, 0x5a, 0x22, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x76, 0x73, 0x62, 0x2f, 0x74, 0x61, 0x6f, 0x62, 0x6c, - 0x6f, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x5a, 0x0a, 0x08, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x70, + 0x65, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x22, 0xd0, 0x04, 0x0a, 0x11, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x04, 0x69, 0x6e, 0x69, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x4e, 0x0a, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69, 0x73, + 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, + 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x09, 0x77, 0x72, 0x69, + 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x51, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x71, 0x0a, 0x0b, 0x49, 0x6e, 0x69, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x43, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x48, 0x00, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x1a, 0x16, 0x0a, + 0x04, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x02, 0x69, 0x64, 0x42, 0x05, 0x0a, 0x03, 0x46, 0x6f, 0x72, 0x1a, 0x12, 0x0a, 0x10, + 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x4f, 0x0a, 0x10, 0x57, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x1a, 0x27, 0x0a, 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x42, 0x09, 0x0a, 0x07, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xd4, 0x03, 0x0a, 0x12, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x04, + 0x69, 0x6e, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x04, 0x69, 0x6e, 0x69, 0x74, 0x12, 0x50, 0x0a, 0x0a, + 0x6c, 0x69, 0x73, 0x74, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x48, 0x00, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x50, + 0x0a, 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, + 0x12, 0x53, 0x0a, 0x0b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x46, 0x69, 0x6c, 0x65, 0x1a, 0x0e, 0x0a, 0x0c, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x3e, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x70, 0x65, 0x63, 0x52, 0x05, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x1a, 0x13, 0x0a, 0x11, 0x57, 0x72, 0x69, 0x74, 0x65, 0x46, 0x69, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x14, 0x0a, 0x12, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x0a, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x24, 0x5a, 0x22, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x76, 0x73, 0x62, + 0x2f, 0x74, 0x61, 0x6f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -725,29 +1489,52 @@ func file_protocols_post_proto_rawDescGZIP() []byte { return file_protocols_post_proto_rawDescData } -var file_protocols_post_proto_msgTypes = make([]protoimpl.MessageInfo, 10) +var file_protocols_post_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_protocols_post_proto_goTypes = []interface{}{ - (*Post)(nil), // 0: protocols.Post - (*GetPostRequest)(nil), // 1: protocols.GetPostRequest - (*UpdatePostRequest)(nil), // 2: protocols.UpdatePostRequest - (*DeletePostRequest)(nil), // 3: protocols.DeletePostRequest - (*GetPostCommentsCountRequest)(nil), // 4: protocols.GetPostCommentsCountRequest - (*GetPostCommentsCountResponse)(nil), // 5: protocols.GetPostCommentsCountResponse - (*SetPostStatusRequest)(nil), // 6: protocols.SetPostStatusRequest - (*SetPostStatusResponse)(nil), // 7: protocols.SetPostStatusResponse - (*SetRedirectRequest)(nil), // 8: protocols.SetRedirectRequest - nil, // 9: protocols.Post.MetasEntry - (*fieldmaskpb.FieldMask)(nil), // 10: google.protobuf.FieldMask + (*Post)(nil), // 0: protocols.Post + (*GetPostRequest)(nil), // 1: protocols.GetPostRequest + (*UpdatePostRequest)(nil), // 2: protocols.UpdatePostRequest + (*DeletePostRequest)(nil), // 3: protocols.DeletePostRequest + (*GetPostCommentsCountRequest)(nil), // 4: protocols.GetPostCommentsCountRequest + (*GetPostCommentsCountResponse)(nil), // 5: protocols.GetPostCommentsCountResponse + (*SetPostStatusRequest)(nil), // 6: protocols.SetPostStatusRequest + (*SetPostStatusResponse)(nil), // 7: protocols.SetPostStatusResponse + (*SetRedirectRequest)(nil), // 8: protocols.SetRedirectRequest + (*FileSpec)(nil), // 9: protocols.FileSpec + (*FileSystemRequest)(nil), // 10: protocols.FileSystemRequest + (*FileSystemResponse)(nil), // 11: protocols.FileSystemResponse + nil, // 12: protocols.Post.MetasEntry + (*FileSystemRequest_InitRequest)(nil), // 13: protocols.FileSystemRequest.InitRequest + (*FileSystemRequest_ListFilesRequest)(nil), // 14: protocols.FileSystemRequest.ListFilesRequest + (*FileSystemRequest_WriteFileRequest)(nil), // 15: protocols.FileSystemRequest.WriteFileRequest + (*FileSystemRequest_DeleteFileRequest)(nil), // 16: protocols.FileSystemRequest.DeleteFileRequest + (*FileSystemRequest_InitRequest_Post)(nil), // 17: protocols.FileSystemRequest.InitRequest.Post + (*FileSystemResponse_InitResponse)(nil), // 18: protocols.FileSystemResponse.InitResponse + (*FileSystemResponse_ListFilesResponse)(nil), // 19: protocols.FileSystemResponse.ListFilesResponse + (*FileSystemResponse_WriteFileResponse)(nil), // 20: protocols.FileSystemResponse.WriteFileResponse + (*FileSystemResponse_DeleteFileResponse)(nil), // 21: protocols.FileSystemResponse.DeleteFileResponse + (*fieldmaskpb.FieldMask)(nil), // 22: google.protobuf.FieldMask } var file_protocols_post_proto_depIdxs = []int32{ - 9, // 0: protocols.Post.metas:type_name -> protocols.Post.MetasEntry + 12, // 0: protocols.Post.metas:type_name -> protocols.Post.MetasEntry 0, // 1: protocols.UpdatePostRequest.post:type_name -> protocols.Post - 10, // 2: protocols.UpdatePostRequest.update_mask:type_name -> google.protobuf.FieldMask - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 22, // 2: protocols.UpdatePostRequest.update_mask:type_name -> google.protobuf.FieldMask + 13, // 3: protocols.FileSystemRequest.init:type_name -> protocols.FileSystemRequest.InitRequest + 14, // 4: protocols.FileSystemRequest.list_files:type_name -> protocols.FileSystemRequest.ListFilesRequest + 15, // 5: protocols.FileSystemRequest.write_file:type_name -> protocols.FileSystemRequest.WriteFileRequest + 16, // 6: protocols.FileSystemRequest.delete_file:type_name -> protocols.FileSystemRequest.DeleteFileRequest + 18, // 7: protocols.FileSystemResponse.init:type_name -> protocols.FileSystemResponse.InitResponse + 19, // 8: protocols.FileSystemResponse.list_files:type_name -> protocols.FileSystemResponse.ListFilesResponse + 20, // 9: protocols.FileSystemResponse.write_file:type_name -> protocols.FileSystemResponse.WriteFileResponse + 21, // 10: protocols.FileSystemResponse.delete_file:type_name -> protocols.FileSystemResponse.DeleteFileResponse + 17, // 11: protocols.FileSystemRequest.InitRequest.post:type_name -> protocols.FileSystemRequest.InitRequest.Post + 9, // 12: protocols.FileSystemRequest.WriteFileRequest.spec:type_name -> protocols.FileSpec + 9, // 13: protocols.FileSystemResponse.ListFilesResponse.files:type_name -> protocols.FileSpec + 14, // [14:14] is the sub-list for method output_type + 14, // [14:14] is the sub-list for method input_type + 14, // [14:14] is the sub-list for extension type_name + 14, // [14:14] is the sub-list for extension extendee + 0, // [0:14] is the sub-list for field type_name } func init() { file_protocols_post_proto_init() } @@ -864,6 +1651,163 @@ func file_protocols_post_proto_init() { return nil } } + file_protocols_post_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemRequest_InitRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemRequest_ListFilesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemRequest_WriteFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemRequest_DeleteFileRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemRequest_InitRequest_Post); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemResponse_InitResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemResponse_ListFilesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemResponse_WriteFileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_protocols_post_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FileSystemResponse_DeleteFileResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_protocols_post_proto_msgTypes[10].OneofWrappers = []interface{}{ + (*FileSystemRequest_ListFiles)(nil), + (*FileSystemRequest_WriteFile)(nil), + (*FileSystemRequest_DeleteFile)(nil), + } + file_protocols_post_proto_msgTypes[11].OneofWrappers = []interface{}{ + (*FileSystemResponse_ListFiles)(nil), + (*FileSystemResponse_WriteFile)(nil), + (*FileSystemResponse_DeleteFile)(nil), + } + file_protocols_post_proto_msgTypes[13].OneofWrappers = []interface{}{ + (*FileSystemRequest_InitRequest_Post_)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -871,7 +1815,7 @@ func file_protocols_post_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_protocols_post_proto_rawDesc, NumEnums: 0, - NumMessages: 10, + NumMessages: 22, NumExtensions: 0, NumServices: 0, }, diff --git a/protocols/post.proto b/protocols/post.proto index 05988f77..476a6a98 100644 --- a/protocols/post.proto +++ b/protocols/post.proto @@ -65,3 +65,55 @@ message SetRedirectRequest { string target_path = 2; int32 status_code = 3; } + +message FileSpec { + string path = 1; + uint32 mode = 2; + uint32 size = 3; + uint32 time = 4; +} + +message FileSystemRequest { + message InitRequest { + message Post { + int64 id = 1; + } + oneof For { + Post post = 1; + } + } + + InitRequest init = 1; + + message ListFilesRequest {} + message WriteFileRequest { + FileSpec spec = 1; + bytes data = 2; + } + message DeleteFileRequest { + string path = 1; + } + oneof Request { + ListFilesRequest list_files = 10; + WriteFileRequest write_file = 11; + DeleteFileRequest delete_file = 12; + } +} + +message FileSystemResponse { + message InitResponse{} + + InitResponse init = 1; + + message ListFilesResponse { + repeated FileSpec files = 1; + } + message WriteFileResponse { } + message DeleteFileResponse { } + + oneof Response { + ListFilesResponse list_files = 10; + WriteFileResponse write_file = 11; + DeleteFileResponse delete_file = 12; + } +} diff --git a/protocols/service.pb.go b/protocols/service.pb.go index 326cac73..54660d7e 100644 --- a/protocols/service.pb.go +++ b/protocols/service.pb.go @@ -129,7 +129,7 @@ var file_protocols_service_proto_rawDesc = []byte{ 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x32, - 0xcb, 0x02, 0x0a, 0x0a, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x76, + 0xb0, 0x03, 0x0a, 0x0a, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x76, 0x0a, 0x06, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x12, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x42, @@ -149,142 +149,148 @@ var file_protocols_service_proto_rawDesc = []byte{ 0x69, 0x72, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x17, 0x92, 0x41, 0x14, 0x1a, 0x12, 0xe8, 0xae, 0xbe, 0xe7, 0xbd, - 0xae, 0xe9, 0x87, 0x8d, 0xe5, 0xae, 0x9a, 0xe5, 0x90, 0x91, 0xe3, 0x80, 0x82, 0x32, 0x84, 0x01, - 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x7a, 0x0a, 0x0b, 0x53, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x92, 0x41, 0x11, 0x1a, 0x0f, 0xe6, 0x96, 0x87, - 0xe7, 0xab, 0xa0, 0xe6, 0x90, 0x9c, 0xe7, 0xb4, 0xa2, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x70, - 0x6f, 0x73, 0x74, 0x73, 0x32, 0xaf, 0x0f, 0x0a, 0x07, 0x54, 0x61, 0x6f, 0x42, 0x6c, 0x6f, 0x67, - 0x12, 0x5f, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x69, 0x6e, - 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x92, 0x41, 0x13, 0x1a, 0x11, - 0x50, 0x69, 0x6e, 0x67, 0x20, 0xe6, 0x9c, 0x8d, 0xe5, 0x8a, 0xa1, 0xe5, 0x99, 0xa8, 0xe3, 0x80, - 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x69, 0x6e, - 0x67, 0x12, 0x5b, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x12, - 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x6f, 0x73, 0x74, - 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x6f, 0x73, - 0x74, 0x22, 0x2b, 0x92, 0x41, 0x14, 0x1a, 0x12, 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe6, 0x96, - 0xb0, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0e, - 0x3a, 0x01, 0x2a, 0x22, 0x09, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x69, - 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, - 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x22, 0x32, 0x92, 0x41, 0x17, 0x1a, 0x15, 0xe8, 0x8e, 0xb7, 0xe5, - 0x8f, 0x96, 0xe6, 0x9f, 0x90, 0xe7, 0xaf, 0x87, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, - 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, - 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x12, 0x71, 0x0a, 0x0a, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x73, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x22, 0x34, 0x92, 0x41, 0x11, 0x1a, 0x0f, 0xe6, 0x9b, 0xb4, - 0xe6, 0x96, 0xb0, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x32, 0x15, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, - 0x2f, 0x7b, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x12, 0x9e, 0x01, 0x0a, - 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, - 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x5a, 0x92, 0x41, 0x41, 0x1a, 0x3f, 0xe5, 0x88, 0xa0, 0xe9, 0x99, 0xa4, 0xe6, 0x96, - 0x87, 0xe7, 0xab, 0xa0, 0xe5, 0x8f, 0x8a, 0xe5, 0x85, 0xb6, 0xe6, 0x89, 0x80, 0xe6, 0x9c, 0x89, - 0xe7, 0x9b, 0xb8, 0xe5, 0x85, 0xb3, 0xe8, 0xb5, 0x84, 0xe6, 0xba, 0x90, 0xef, 0xbc, 0x88, 0xe8, - 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x81, 0xe6, 0xa0, 0x87, 0xe7, 0xad, 0xbe, 0xe7, 0xad, - 0x89, 0xef, 0xbc, 0x89, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x2a, 0x0e, 0x2f, - 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x93, 0x01, - 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x74, 0x50, - 0x6f, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x74, - 0x50, 0x6f, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x3f, 0x92, 0x41, 0x17, 0x1a, 0x15, 0xe6, 0x98, 0xaf, 0xe5, 0x90, 0xa6, 0xe5, - 0x85, 0xac, 0xe5, 0xbc, 0x80, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, 0x82, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, - 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x7c, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, - 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x43, 0x92, 0x41, - 0x17, 0x1a, 0x15, 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe4, 0xb8, 0x80, 0xe6, 0x9d, 0xa1, 0xe8, - 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x23, 0x3a, 0x01, - 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x6f, - 0x73, 0x74, 0x5f, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x12, 0x7e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, - 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, + 0xae, 0xe9, 0x87, 0x8d, 0xe5, 0xae, 0x9a, 0xe5, 0x90, 0x91, 0xe3, 0x80, 0x82, 0x12, 0x63, 0x0a, + 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x1c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x14, 0x92, 0x41, 0x11, 0x1a, 0x0f, 0xe6, + 0x96, 0x87, 0xe4, 0xbb, 0xb6, 0xe7, 0xae, 0xa1, 0xe7, 0x90, 0x86, 0xe3, 0x80, 0x82, 0x28, 0x01, + 0x30, 0x01, 0x32, 0x84, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x7a, 0x0a, + 0x0b, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x6f, 0x73, 0x74, 0x73, 0x12, 0x1d, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, + 0x6f, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x6f, + 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x92, 0x41, 0x11, + 0x1a, 0x0f, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe6, 0x90, 0x9c, 0xe7, 0xb4, 0xa2, 0xe3, 0x80, + 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x32, 0xaf, 0x0f, 0x0a, 0x07, 0x54, 0x61, + 0x6f, 0x42, 0x6c, 0x6f, 0x67, 0x12, 0x5f, 0x0a, 0x04, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x2e, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, + 0x92, 0x41, 0x13, 0x1a, 0x11, 0x50, 0x69, 0x6e, 0x67, 0x20, 0xe6, 0x9c, 0x8d, 0xe5, 0x8a, 0xa1, + 0xe5, 0x99, 0xa8, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0a, 0x12, 0x08, 0x2f, 0x76, + 0x33, 0x2f, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x5b, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x50, 0x6f, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, + 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x22, 0x2b, 0x92, 0x41, 0x14, 0x1a, 0x12, 0xe5, 0x88, 0x9b, + 0xe5, 0xbb, 0xba, 0xe6, 0x96, 0xb0, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, 0x82, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x0e, 0x3a, 0x01, 0x2a, 0x22, 0x09, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, + 0x73, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x19, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, + 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x22, 0x32, 0x92, 0x41, 0x17, 0x1a, + 0x15, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xe6, 0x9f, 0x90, 0xe7, 0xaf, 0x87, 0xe6, 0x96, 0x87, + 0xe7, 0xab, 0xa0, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, + 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x12, 0x71, + 0x0a, 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x12, 0x1c, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, + 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x22, 0x34, 0x92, 0x41, 0x11, + 0x1a, 0x0f, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, + 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x32, 0x15, 0x2f, 0x76, 0x33, 0x2f, + 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x6f, 0x73, 0x74, 0x2e, 0x69, 0x64, 0x3d, 0x2a, + 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, + 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x50, 0x6f, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x5a, 0x92, 0x41, 0x41, 0x1a, 0x3f, 0xe5, 0x88, 0xa0, + 0xe9, 0x99, 0xa4, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe5, 0x8f, 0x8a, 0xe5, 0x85, 0xb6, 0xe6, + 0x89, 0x80, 0xe6, 0x9c, 0x89, 0xe7, 0x9b, 0xb8, 0xe5, 0x85, 0xb3, 0xe8, 0xb5, 0x84, 0xe6, 0xba, + 0x90, 0xef, 0xbc, 0x88, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x81, 0xe6, 0xa0, 0x87, + 0xe7, 0xad, 0xbe, 0xe7, 0xad, 0x89, 0xef, 0xbc, 0x89, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x10, 0x2a, 0x0e, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x69, + 0x64, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, + 0x2e, 0x53, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x2e, 0x53, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3f, 0x92, 0x41, 0x17, 0x1a, 0x15, 0xe6, 0x98, + 0xaf, 0xe5, 0x90, 0xa6, 0xe5, 0x85, 0xac, 0xe5, 0xbc, 0x80, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, + 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x76, + 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x3a, 0x73, + 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x7c, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, - 0x74, 0x22, 0x3e, 0x92, 0x41, 0x20, 0x1a, 0x1e, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xe6, 0x8c, - 0x87, 0xe5, 0xae, 0x9a, 0xe7, 0xbc, 0x96, 0xe5, 0x8f, 0xb7, 0xe7, 0x9a, 0x84, 0xe8, 0xaf, 0x84, - 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x76, - 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, - 0x7d, 0x12, 0x8f, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x49, 0x92, 0x41, 0x20, 0x1a, 0x1e, 0xe6, - 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe6, 0x8c, 0x87, 0xe5, 0xae, 0x9a, 0xe7, 0xbc, 0x96, 0xe5, 0x8f, - 0xb7, 0xe7, 0x9a, 0x84, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, - 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x64, - 0x3d, 0x2a, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, - 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, - 0x6c, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x92, 0x41, 0x17, 0x1a, 0x15, 0xe5, - 0x88, 0xa0, 0xe9, 0x99, 0xa4, 0xe6, 0x9f, 0x90, 0xe6, 0x9d, 0xa1, 0xe8, 0xaf, 0x84, 0xe8, 0xae, - 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x76, 0x33, 0x2f, - 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x12, - 0xa6, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x55, 0x92, 0x41, 0x2c, 0x1a, 0x2a, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xef, 0xbc, - 0x88, 0xe6, 0x9f, 0x90, 0xe7, 0xaf, 0x87, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe7, 0x9a, 0x84, - 0xef, 0xbc, 0x89, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe5, 0x88, 0x97, 0xe8, 0xa1, 0xa8, 0xe3, - 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, + 0x74, 0x22, 0x43, 0x92, 0x41, 0x17, 0x1a, 0x15, 0xe5, 0x88, 0x9b, 0xe5, 0xbb, 0xba, 0xe4, 0xb8, + 0x80, 0xe6, 0x9d, 0xa1, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x23, 0x3a, 0x01, 0x2a, 0x22, 0x1e, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, + 0x73, 0x2f, 0x7b, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x2f, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x7e, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x3e, 0x92, 0x41, 0x20, 0x1a, 0x1e, 0xe8, 0x8e, 0xb7, + 0xe5, 0x8f, 0x96, 0xe6, 0x8c, 0x87, 0xe5, 0xae, 0x9a, 0xe7, 0xbc, 0x96, 0xe5, 0x8f, 0xb7, 0xe7, + 0x9a, 0x84, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x15, 0x12, 0x13, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x12, 0x8f, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x49, 0x92, + 0x41, 0x20, 0x1a, 0x1e, 0xe6, 0x9b, 0xb4, 0xe6, 0x96, 0xb0, 0xe6, 0x8c, 0x87, 0xe5, 0xae, 0x9a, + 0xe7, 0xbc, 0x96, 0xe5, 0x8f, 0xb7, 0xe7, 0x9a, 0x84, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, + 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x32, 0x1b, 0x2f, 0x76, 0x33, + 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x0d, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x92, + 0x41, 0x17, 0x1a, 0x15, 0xe5, 0x88, 0xa0, 0xe9, 0x99, 0xa4, 0xe6, 0x9f, 0x90, 0xe6, 0x9d, 0xa1, + 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, + 0x13, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, + 0x64, 0x3d, 0x2a, 0x7d, 0x12, 0xa6, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x55, 0x92, 0x41, 0x2c, 0x1a, 0x2a, 0xe8, 0x8e, 0xb7, + 0xe5, 0x8f, 0x96, 0xef, 0xbc, 0x88, 0xe6, 0x9f, 0x90, 0xe7, 0xaf, 0x87, 0xe6, 0x96, 0x87, 0xe7, + 0xab, 0xa0, 0xe7, 0x9a, 0x84, 0xef, 0xbc, 0x89, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe5, 0x88, + 0x97, 0xe8, 0xa1, 0xa8, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x12, 0x1e, 0x2f, + 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x69, + 0x64, 0x3d, 0x2a, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0xc9, 0x01, + 0x0a, 0x10, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x74, + 0x49, 0x44, 0x12, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, + 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x44, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, + 0x74, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6c, 0x92, 0x41, 0x41, + 0x1a, 0x3f, 0xe8, 0xbd, 0xac, 0xe7, 0xa7, 0xbb, 0xe6, 0x9f, 0x90, 0xe9, 0xa1, 0xb6, 0xe7, 0xba, + 0xa7, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xef, 0xbc, 0x88, 0xe8, 0xbf, 0x9e, 0xe5, 0x90, 0x8c, + 0xe5, 0xad, 0x90, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xef, 0xbc, 0x89, 0xe5, 0x88, 0xb0, 0xe5, + 0x8f, 0xa6, 0xe4, 0xb8, 0x80, 0xe7, 0xaf, 0x87, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, + 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x33, 0x2f, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x3a, + 0x73, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x44, 0x12, 0xb2, 0x01, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x47, + 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x49, 0x92, 0x41, 0x1a, 0x1a, 0x18, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, + 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe6, 0x95, 0xb0, 0xe3, + 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x2f, - 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0xc9, 0x01, 0x0a, 0x10, 0x53, 0x65, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x44, 0x12, 0x22, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6d, - 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x53, 0x65, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x49, 0x44, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x6c, 0x92, 0x41, 0x41, 0x1a, 0x3f, 0xe8, 0xbd, 0xac, - 0xe7, 0xa7, 0xbb, 0xe6, 0x9f, 0x90, 0xe9, 0xa1, 0xb6, 0xe7, 0xba, 0xa7, 0xe8, 0xaf, 0x84, 0xe8, - 0xae, 0xba, 0xef, 0xbc, 0x88, 0xe8, 0xbf, 0x9e, 0xe5, 0x90, 0x8c, 0xe5, 0xad, 0x90, 0xe8, 0xaf, - 0x84, 0xe8, 0xae, 0xba, 0xef, 0xbc, 0x89, 0xe5, 0x88, 0xb0, 0xe5, 0x8f, 0xa6, 0xe4, 0xb8, 0x80, - 0xe7, 0xaf, 0x87, 0xe6, 0x96, 0x87, 0xe7, 0xab, 0xa0, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x22, 0x3a, 0x01, 0x2a, 0x22, 0x1d, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x3a, 0x73, 0x65, 0x74, 0x50, 0x6f, - 0x73, 0x74, 0x49, 0x44, 0x12, 0xb2, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, - 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, - 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, - 0x73, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x6f, 0x73, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x49, - 0x92, 0x41, 0x1a, 0x1a, 0x18, 0xe8, 0x8e, 0xb7, 0xe5, 0x8f, 0x96, 0xe6, 0x96, 0x87, 0xe7, 0xab, - 0xa0, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe6, 0x95, 0xb0, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x2f, 0x7b, - 0x70, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x3d, 0x2a, 0x7d, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, - 0x6e, 0x74, 0x73, 0x3a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x8a, 0x01, 0x0a, 0x0e, 0x50, 0x72, - 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x20, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, - 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x72, 0x65, 0x76, 0x69, - 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x33, 0x92, 0x41, 0x11, 0x1a, 0x0f, 0xe8, 0xaf, 0x84, 0xe8, 0xae, 0xba, 0xe9, 0xa2, - 0x84, 0xe8, 0xa7, 0x88, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x3a, 0x01, 0x2a, - 0x22, 0x14, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x70, - 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x42, 0x24, 0x5a, 0x22, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x76, 0x73, 0x62, 0x2f, 0x74, 0x61, 0x6f, 0x62, 0x6c, - 0x6f, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x8a, + 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, 0x50, 0x72, + 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x2e, + 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x92, 0x41, 0x11, 0x1a, 0x0f, 0xe8, 0xaf, 0x84, + 0xe8, 0xae, 0xba, 0xe9, 0xa2, 0x84, 0xe8, 0xa7, 0x88, 0xe3, 0x80, 0x82, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x19, 0x3a, 0x01, 0x2a, 0x22, 0x14, 0x2f, 0x76, 0x33, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x3a, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x42, 0x24, 0x5a, 0x22, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x6f, 0x76, 0x73, 0x62, 0x2f, + 0x74, 0x61, 0x6f, 0x62, 0x6c, 0x6f, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -306,70 +312,74 @@ var file_protocols_service_proto_goTypes = []interface{}{ (*BackupRequest)(nil), // 2: protocols.BackupRequest (*BackupFilesRequest)(nil), // 3: protocols.BackupFilesRequest (*SetRedirectRequest)(nil), // 4: protocols.SetRedirectRequest - (*SearchPostsRequest)(nil), // 5: protocols.SearchPostsRequest - (*Post)(nil), // 6: protocols.Post - (*GetPostRequest)(nil), // 7: protocols.GetPostRequest - (*UpdatePostRequest)(nil), // 8: protocols.UpdatePostRequest - (*DeletePostRequest)(nil), // 9: protocols.DeletePostRequest - (*SetPostStatusRequest)(nil), // 10: protocols.SetPostStatusRequest - (*Comment)(nil), // 11: protocols.Comment - (*GetCommentRequest)(nil), // 12: protocols.GetCommentRequest - (*UpdateCommentRequest)(nil), // 13: protocols.UpdateCommentRequest - (*DeleteCommentRequest)(nil), // 14: protocols.DeleteCommentRequest - (*ListCommentsRequest)(nil), // 15: protocols.ListCommentsRequest - (*SetCommentPostIDRequest)(nil), // 16: protocols.SetCommentPostIDRequest - (*GetPostCommentsCountRequest)(nil), // 17: protocols.GetPostCommentsCountRequest - (*PreviewCommentRequest)(nil), // 18: protocols.PreviewCommentRequest - (*BackupResponse)(nil), // 19: protocols.BackupResponse - (*BackupFilesResponse)(nil), // 20: protocols.BackupFilesResponse - (*emptypb.Empty)(nil), // 21: google.protobuf.Empty - (*SearchPostsResponse)(nil), // 22: protocols.SearchPostsResponse - (*SetPostStatusResponse)(nil), // 23: protocols.SetPostStatusResponse - (*DeleteCommentResponse)(nil), // 24: protocols.DeleteCommentResponse - (*ListCommentsResponse)(nil), // 25: protocols.ListCommentsResponse - (*SetCommentPostIDResponse)(nil), // 26: protocols.SetCommentPostIDResponse - (*GetPostCommentsCountResponse)(nil), // 27: protocols.GetPostCommentsCountResponse - (*PreviewCommentResponse)(nil), // 28: protocols.PreviewCommentResponse + (*FileSystemRequest)(nil), // 5: protocols.FileSystemRequest + (*SearchPostsRequest)(nil), // 6: protocols.SearchPostsRequest + (*Post)(nil), // 7: protocols.Post + (*GetPostRequest)(nil), // 8: protocols.GetPostRequest + (*UpdatePostRequest)(nil), // 9: protocols.UpdatePostRequest + (*DeletePostRequest)(nil), // 10: protocols.DeletePostRequest + (*SetPostStatusRequest)(nil), // 11: protocols.SetPostStatusRequest + (*Comment)(nil), // 12: protocols.Comment + (*GetCommentRequest)(nil), // 13: protocols.GetCommentRequest + (*UpdateCommentRequest)(nil), // 14: protocols.UpdateCommentRequest + (*DeleteCommentRequest)(nil), // 15: protocols.DeleteCommentRequest + (*ListCommentsRequest)(nil), // 16: protocols.ListCommentsRequest + (*SetCommentPostIDRequest)(nil), // 17: protocols.SetCommentPostIDRequest + (*GetPostCommentsCountRequest)(nil), // 18: protocols.GetPostCommentsCountRequest + (*PreviewCommentRequest)(nil), // 19: protocols.PreviewCommentRequest + (*BackupResponse)(nil), // 20: protocols.BackupResponse + (*BackupFilesResponse)(nil), // 21: protocols.BackupFilesResponse + (*emptypb.Empty)(nil), // 22: google.protobuf.Empty + (*FileSystemResponse)(nil), // 23: protocols.FileSystemResponse + (*SearchPostsResponse)(nil), // 24: protocols.SearchPostsResponse + (*SetPostStatusResponse)(nil), // 25: protocols.SetPostStatusResponse + (*DeleteCommentResponse)(nil), // 26: protocols.DeleteCommentResponse + (*ListCommentsResponse)(nil), // 27: protocols.ListCommentsResponse + (*SetCommentPostIDResponse)(nil), // 28: protocols.SetCommentPostIDResponse + (*GetPostCommentsCountResponse)(nil), // 29: protocols.GetPostCommentsCountResponse + (*PreviewCommentResponse)(nil), // 30: protocols.PreviewCommentResponse } var file_protocols_service_proto_depIdxs = []int32{ 2, // 0: protocols.Management.Backup:input_type -> protocols.BackupRequest 3, // 1: protocols.Management.BackupFiles:input_type -> protocols.BackupFilesRequest 4, // 2: protocols.Management.SetRedirect:input_type -> protocols.SetRedirectRequest - 5, // 3: protocols.Search.SearchPosts:input_type -> protocols.SearchPostsRequest - 0, // 4: protocols.TaoBlog.Ping:input_type -> protocols.PingRequest - 6, // 5: protocols.TaoBlog.CreatePost:input_type -> protocols.Post - 7, // 6: protocols.TaoBlog.GetPost:input_type -> protocols.GetPostRequest - 8, // 7: protocols.TaoBlog.UpdatePost:input_type -> protocols.UpdatePostRequest - 9, // 8: protocols.TaoBlog.DeletePost:input_type -> protocols.DeletePostRequest - 10, // 9: protocols.TaoBlog.SetPostStatus:input_type -> protocols.SetPostStatusRequest - 11, // 10: protocols.TaoBlog.CreateComment:input_type -> protocols.Comment - 12, // 11: protocols.TaoBlog.GetComment:input_type -> protocols.GetCommentRequest - 13, // 12: protocols.TaoBlog.UpdateComment:input_type -> protocols.UpdateCommentRequest - 14, // 13: protocols.TaoBlog.DeleteComment:input_type -> protocols.DeleteCommentRequest - 15, // 14: protocols.TaoBlog.ListComments:input_type -> protocols.ListCommentsRequest - 16, // 15: protocols.TaoBlog.SetCommentPostID:input_type -> protocols.SetCommentPostIDRequest - 17, // 16: protocols.TaoBlog.GetPostCommentsCount:input_type -> protocols.GetPostCommentsCountRequest - 18, // 17: protocols.TaoBlog.PreviewComment:input_type -> protocols.PreviewCommentRequest - 19, // 18: protocols.Management.Backup:output_type -> protocols.BackupResponse - 20, // 19: protocols.Management.BackupFiles:output_type -> protocols.BackupFilesResponse - 21, // 20: protocols.Management.SetRedirect:output_type -> google.protobuf.Empty - 22, // 21: protocols.Search.SearchPosts:output_type -> protocols.SearchPostsResponse - 1, // 22: protocols.TaoBlog.Ping:output_type -> protocols.PingResponse - 6, // 23: protocols.TaoBlog.CreatePost:output_type -> protocols.Post - 6, // 24: protocols.TaoBlog.GetPost:output_type -> protocols.Post - 6, // 25: protocols.TaoBlog.UpdatePost:output_type -> protocols.Post - 21, // 26: protocols.TaoBlog.DeletePost:output_type -> google.protobuf.Empty - 23, // 27: protocols.TaoBlog.SetPostStatus:output_type -> protocols.SetPostStatusResponse - 11, // 28: protocols.TaoBlog.CreateComment:output_type -> protocols.Comment - 11, // 29: protocols.TaoBlog.GetComment:output_type -> protocols.Comment - 11, // 30: protocols.TaoBlog.UpdateComment:output_type -> protocols.Comment - 24, // 31: protocols.TaoBlog.DeleteComment:output_type -> protocols.DeleteCommentResponse - 25, // 32: protocols.TaoBlog.ListComments:output_type -> protocols.ListCommentsResponse - 26, // 33: protocols.TaoBlog.SetCommentPostID:output_type -> protocols.SetCommentPostIDResponse - 27, // 34: protocols.TaoBlog.GetPostCommentsCount:output_type -> protocols.GetPostCommentsCountResponse - 28, // 35: protocols.TaoBlog.PreviewComment:output_type -> protocols.PreviewCommentResponse - 18, // [18:36] is the sub-list for method output_type - 0, // [0:18] is the sub-list for method input_type + 5, // 3: protocols.Management.FileSystem:input_type -> protocols.FileSystemRequest + 6, // 4: protocols.Search.SearchPosts:input_type -> protocols.SearchPostsRequest + 0, // 5: protocols.TaoBlog.Ping:input_type -> protocols.PingRequest + 7, // 6: protocols.TaoBlog.CreatePost:input_type -> protocols.Post + 8, // 7: protocols.TaoBlog.GetPost:input_type -> protocols.GetPostRequest + 9, // 8: protocols.TaoBlog.UpdatePost:input_type -> protocols.UpdatePostRequest + 10, // 9: protocols.TaoBlog.DeletePost:input_type -> protocols.DeletePostRequest + 11, // 10: protocols.TaoBlog.SetPostStatus:input_type -> protocols.SetPostStatusRequest + 12, // 11: protocols.TaoBlog.CreateComment:input_type -> protocols.Comment + 13, // 12: protocols.TaoBlog.GetComment:input_type -> protocols.GetCommentRequest + 14, // 13: protocols.TaoBlog.UpdateComment:input_type -> protocols.UpdateCommentRequest + 15, // 14: protocols.TaoBlog.DeleteComment:input_type -> protocols.DeleteCommentRequest + 16, // 15: protocols.TaoBlog.ListComments:input_type -> protocols.ListCommentsRequest + 17, // 16: protocols.TaoBlog.SetCommentPostID:input_type -> protocols.SetCommentPostIDRequest + 18, // 17: protocols.TaoBlog.GetPostCommentsCount:input_type -> protocols.GetPostCommentsCountRequest + 19, // 18: protocols.TaoBlog.PreviewComment:input_type -> protocols.PreviewCommentRequest + 20, // 19: protocols.Management.Backup:output_type -> protocols.BackupResponse + 21, // 20: protocols.Management.BackupFiles:output_type -> protocols.BackupFilesResponse + 22, // 21: protocols.Management.SetRedirect:output_type -> google.protobuf.Empty + 23, // 22: protocols.Management.FileSystem:output_type -> protocols.FileSystemResponse + 24, // 23: protocols.Search.SearchPosts:output_type -> protocols.SearchPostsResponse + 1, // 24: protocols.TaoBlog.Ping:output_type -> protocols.PingResponse + 7, // 25: protocols.TaoBlog.CreatePost:output_type -> protocols.Post + 7, // 26: protocols.TaoBlog.GetPost:output_type -> protocols.Post + 7, // 27: protocols.TaoBlog.UpdatePost:output_type -> protocols.Post + 22, // 28: protocols.TaoBlog.DeletePost:output_type -> google.protobuf.Empty + 25, // 29: protocols.TaoBlog.SetPostStatus:output_type -> protocols.SetPostStatusResponse + 12, // 30: protocols.TaoBlog.CreateComment:output_type -> protocols.Comment + 12, // 31: protocols.TaoBlog.GetComment:output_type -> protocols.Comment + 12, // 32: protocols.TaoBlog.UpdateComment:output_type -> protocols.Comment + 26, // 33: protocols.TaoBlog.DeleteComment:output_type -> protocols.DeleteCommentResponse + 27, // 34: protocols.TaoBlog.ListComments:output_type -> protocols.ListCommentsResponse + 28, // 35: protocols.TaoBlog.SetCommentPostID:output_type -> protocols.SetCommentPostIDResponse + 29, // 36: protocols.TaoBlog.GetPostCommentsCount:output_type -> protocols.GetPostCommentsCountResponse + 30, // 37: protocols.TaoBlog.PreviewComment:output_type -> protocols.PreviewCommentResponse + 19, // [19:38] is the sub-list for method output_type + 0, // [0:19] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/protocols/service.proto b/protocols/service.proto index c1b70f53..e38d47f9 100644 --- a/protocols/service.proto +++ b/protocols/service.proto @@ -33,6 +33,14 @@ service Management { description: "设置重定向。"; }; }; + + // 文件系统管理:期允许管理的对象:文章附近、评论附件、备份文件、根目录等。 + + rpc FileSystem(stream FileSystemRequest) returns (stream FileSystemResponse) { + option (grpc.gateway.protoc_gen_swagger.options.openapiv2_operation) = { + description: "文件管理。"; + }; + } } service Search { diff --git a/protocols/service_grpc.pb.go b/protocols/service_grpc.pb.go index 42b6a1e5..73d20ca0 100644 --- a/protocols/service_grpc.pb.go +++ b/protocols/service_grpc.pb.go @@ -26,6 +26,7 @@ type ManagementClient interface { Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (Management_BackupClient, error) BackupFiles(ctx context.Context, opts ...grpc.CallOption) (Management_BackupFilesClient, error) SetRedirect(ctx context.Context, in *SetRedirectRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + FileSystem(ctx context.Context, opts ...grpc.CallOption) (Management_FileSystemClient, error) } type managementClient struct { @@ -108,6 +109,37 @@ func (c *managementClient) SetRedirect(ctx context.Context, in *SetRedirectReque return out, nil } +func (c *managementClient) FileSystem(ctx context.Context, opts ...grpc.CallOption) (Management_FileSystemClient, error) { + stream, err := c.cc.NewStream(ctx, &Management_ServiceDesc.Streams[2], "/protocols.Management/FileSystem", opts...) + if err != nil { + return nil, err + } + x := &managementFileSystemClient{stream} + return x, nil +} + +type Management_FileSystemClient interface { + Send(*FileSystemRequest) error + Recv() (*FileSystemResponse, error) + grpc.ClientStream +} + +type managementFileSystemClient struct { + grpc.ClientStream +} + +func (x *managementFileSystemClient) Send(m *FileSystemRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *managementFileSystemClient) Recv() (*FileSystemResponse, error) { + m := new(FileSystemResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // ManagementServer is the server API for Management service. // All implementations must embed UnimplementedManagementServer // for forward compatibility @@ -115,6 +147,7 @@ type ManagementServer interface { Backup(*BackupRequest, Management_BackupServer) error BackupFiles(Management_BackupFilesServer) error SetRedirect(context.Context, *SetRedirectRequest) (*emptypb.Empty, error) + FileSystem(Management_FileSystemServer) error mustEmbedUnimplementedManagementServer() } @@ -131,6 +164,9 @@ func (UnimplementedManagementServer) BackupFiles(Management_BackupFilesServer) e func (UnimplementedManagementServer) SetRedirect(context.Context, *SetRedirectRequest) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method SetRedirect not implemented") } +func (UnimplementedManagementServer) FileSystem(Management_FileSystemServer) error { + return status.Errorf(codes.Unimplemented, "method FileSystem not implemented") +} func (UnimplementedManagementServer) mustEmbedUnimplementedManagementServer() {} // UnsafeManagementServer may be embedded to opt out of forward compatibility for this service. @@ -209,6 +245,32 @@ func _Management_SetRedirect_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } +func _Management_FileSystem_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ManagementServer).FileSystem(&managementFileSystemServer{stream}) +} + +type Management_FileSystemServer interface { + Send(*FileSystemResponse) error + Recv() (*FileSystemRequest, error) + grpc.ServerStream +} + +type managementFileSystemServer struct { + grpc.ServerStream +} + +func (x *managementFileSystemServer) Send(m *FileSystemResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *managementFileSystemServer) Recv() (*FileSystemRequest, error) { + m := new(FileSystemRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + // Management_ServiceDesc is the grpc.ServiceDesc for Management service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -233,6 +295,12 @@ var Management_ServiceDesc = grpc.ServiceDesc{ ServerStreams: true, ClientStreams: true, }, + { + StreamName: "FileSystem", + Handler: _Management_FileSystem_Handler, + ServerStreams: true, + ClientStreams: true, + }, }, Metadata: "protocols/service.proto", } diff --git a/service/filesystem.go b/service/filesystem.go new file mode 100644 index 00000000..ae74c87c --- /dev/null +++ b/service/filesystem.go @@ -0,0 +1,198 @@ +package service + +import ( + "bytes" + "errors" + "fmt" + "io" + fspkg "io/fs" + "log" + "os" + "time" + + "github.com/movsb/taoblog/protocols" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (s *Service) FileSystem(srv protocols.Management_FileSystemServer) error { + if !s.auth.AuthGRPC(srv.Context()).IsAdmin() { + return status.Error(codes.Unauthenticated, "bad credentials") + } + + initialized := false + + var fs _FileSystem + + for { + req, err := srv.Recv() + if err != nil { + if errors.Is(err, io.EOF) { + return nil + } + if st, ok := status.FromError(err); ok && st.Code() == codes.Canceled { + return nil + } + log.Println(`接收消息失败:`, err) + return err + } + + initReq := req.GetInit() + if !initialized && initReq == nil { + log.Println(`没收到初始化消息。`) + return status.Error(codes.FailedPrecondition, "not init") + } else if initialized && initReq != nil { + log.Println(`重复初始化。`) + return status.Error(codes.Aborted, "re-init") + } else if initReq != nil { + initialized = true + if init := initReq.GetPost(); init != nil { + fs, err = s.fileSystemForPost(init.Id) + } + if err != nil { + return status.Error(codes.Internal, err.Error()) + } + if fs == nil { + return status.Error(codes.InvalidArgument, "unknown file system to operate") + } + if err := srv.Send(&protocols.FileSystemResponse{ + Init: &protocols.FileSystemResponse_InitResponse{}, + }); err != nil { + return err + } + continue + } + + if fs == nil { + return status.Error(codes.Internal, "not init") + } + + if list := req.GetListFiles(); list != nil { + files, err := fs.ListFiles() + if err != nil { + return err + } + if err = srv.Send(&protocols.FileSystemResponse{ + Response: &protocols.FileSystemResponse_ListFiles{ + ListFiles: &protocols.FileSystemResponse_ListFilesResponse{ + Files: files, + }, + }, + }); err != nil { + return err + } + } else if write := req.GetWriteFile(); write != nil { + if err := fs.WriteFile(write.Spec, bytes.NewReader(write.Data)); err != nil { + return err + } + if err = srv.Send(&protocols.FileSystemResponse{ + Response: &protocols.FileSystemResponse_WriteFile{ + WriteFile: &protocols.FileSystemResponse_WriteFileResponse{}, + }, + }); err != nil { + return err + } + } else if delete := req.GetDeleteFile(); delete != nil { + if err := fs.DeleteFile(delete.Path); err != nil { + return err + } + if err = srv.Send(&protocols.FileSystemResponse{ + Response: &protocols.FileSystemResponse_DeleteFile{ + DeleteFile: &protocols.FileSystemResponse_DeleteFileResponse{}, + }, + }); err != nil { + return err + } + } + } +} + +type _FileSystem interface { + ListFiles() ([]*protocols.FileSpec, error) + DeleteFile(path string) error + WriteFile(spec *protocols.FileSpec, r io.Reader) error +} + +type _FileSystemForPost struct { + s *Service + id int64 +} + +func (fs *_FileSystemForPost) ListFiles() ([]*protocols.FileSpec, error) { + filePaths, err := fs.s.Store().List(fs.id) + if err != nil { + return nil, err + } + + files := []*protocols.FileSpec{} + for _, path := range filePaths { + spec, err := func() (*protocols.FileSpec, error) { + fp, err := fs.s.Store().Open(fs.id, path) + if err != nil { + return nil, err + } + defer fp.Close() + stat, err := fp.Stat() + if err != nil { + return nil, err + } + return &protocols.FileSpec{ + Path: path, + Mode: uint32(stat.Mode()), + Size: uint32(stat.Size()), + Time: uint32(stat.ModTime().Unix()), + }, nil + }() + if err != nil { + return nil, err + } + files = append(files, spec) + } + + return files, nil +} + +func (fs *_FileSystemForPost) DeleteFile(path string) error { + return fs.s.Store().Remove(fs.id, path) +} + +func (fs *_FileSystemForPost) WriteFile(spec *protocols.FileSpec, r io.Reader) error { + tmp, err := os.CreateTemp("", `taoblog-*`) + if err != nil { + return err + } + + if n, err := io.Copy(tmp, r); err != nil || n != int64(spec.Size) { + return fmt.Errorf(`write error: %d %v`, n, err) + } + + if err := tmp.Chmod(fspkg.FileMode(spec.Mode)); err != nil { + return err + } + + if err := tmp.Close(); err != nil { + return err + } + + t := time.Unix(int64(spec.Time), 0) + + if err := os.Chtimes(tmp.Name(), t, t); err != nil { + return err + } + + path, _ := fs.s.Store().PathOf(fs.id, spec.Path) + if err := os.Rename(tmp.Name(), path); err != nil { + return err + } + + return nil +} + +func (s *Service) fileSystemForPost(id int64) (*_FileSystemForPost, error) { + _ = s.MustGetPost(id) + + return &_FileSystemForPost{ + s: s, + id: id, + }, nil +} diff --git a/service/modules/storage/local/local.go b/service/modules/storage/local/local.go index 0c48a20f..8a5041e4 100644 --- a/service/modules/storage/local/local.go +++ b/service/modules/storage/local/local.go @@ -31,7 +31,7 @@ func (l *Local) path(id int64, path string, createDir bool) (string, error) { return "", err } } - path = filepath.Join(dir, path) + path = filepath.Join(dir, filepath.Clean(path)) return path, nil }