diff --git a/api/main.proto b/api/main.proto index d9f5926..cc9d02f 100644 --- a/api/main.proto +++ b/api/main.proto @@ -12,8 +12,38 @@ service pinnedMessage { get: "/ping" }; } + + rpc GetDays(GetDaysReq) returns (GetDaysRsp) { + option (google.api.http) = { + get: "/schedule" + }; + } } message PingReq {} message PingRsp {} + +message GetDaysReq {} + +message GetDaysRsp { + repeated Day days = 1; +} + +message Day { + string date = 1; + repeated Performance performances = 2; +} + +message Performance { + string time_collection = 1; + string time_start = 2; + string place = 3; + string name = 4; + repeated Number numbers = 5; + string costumes = 6; +} + +message Number { + string name = 1; +} diff --git a/cmd/pinned_message/__debug_bin3555703031 b/cmd/pinned_message/__debug_bin3555703031 new file mode 100755 index 0000000..0477784 Binary files /dev/null and b/cmd/pinned_message/__debug_bin3555703031 differ diff --git a/cmd/pinned_message/main.go b/cmd/pinned_message/main.go index 01b3952..e46d3b0 100644 --- a/cmd/pinned_message/main.go +++ b/cmd/pinned_message/main.go @@ -9,6 +9,7 @@ import ( "pinned_message/internal/config" "pinned_message/internal/modules/data_parser" "pinned_message/internal/modules/date_parser" + "pinned_message/internal/services" "pinned_message/internal/services/schedule_parser" "pinned_message/internal/services/schedule_storage" proto "pinned_message/proto" @@ -29,17 +30,25 @@ func main() { s := grpc.NewServer() ctx := context.Background() + scheduleStorage := schedule_storage.NewScheduleStorage(config.GetScheduleFilepath()) scheduleParser := schedule_parser.NewScheduleParser( data_parser.NewGoogleTableScheduleParser(), date_parser.NewDateParser(), - *schedule_storage.NewScheduleStorage(config.GetScheduleFilepath()), + scheduleStorage, ) go func() { scheduleParser.Run(ctx) }() // Attach the Greeter service to the server - proto.RegisterPinnedMessageServer(s, app.NewServer()) + proto.RegisterPinnedMessageServer( + s, + app.NewServer( + services.NewServices( + scheduleStorage, + ), + ), + ) // Serve gRPC server log.Println("Serving gRPC on 0.0.0.0:8080") go func() { diff --git a/internal/app/server.go b/internal/app/server.go index 9f3a4ee..166a4eb 100644 --- a/internal/app/server.go +++ b/internal/app/server.go @@ -2,17 +2,27 @@ package app import ( "context" + "pinned_message/internal/services" proto "pinned_message/proto" ) type Server struct { proto.UnimplementedPinnedMessageServer + services *services.Services } -func NewServer() *Server { - return &Server{} +func NewServer( + services *services.Services, +) *Server { + return &Server{ + services: services, + } } func (s *Server) Ping(_ context.Context, _ *proto.PingReq) (*proto.PingRsp, error) { return &proto.PingRsp{}, nil } + +func (s *Server) GetDays(ctx context.Context, req *proto.GetDaysReq) (*proto.GetDaysRsp, error) { + return s.services.GetDays(ctx, req) +} diff --git a/internal/services/schedule_parser/service.go b/internal/services/schedule_parser/service.go index 35dc80f..87e328e 100644 --- a/internal/services/schedule_parser/service.go +++ b/internal/services/schedule_parser/service.go @@ -25,13 +25,13 @@ type performance struct { type ScheduleParser struct { dataParser data_parser.IDataParser dateParser date_parser.IDateParser - scheduleStorage schedule_storage.ScheduleStorage + scheduleStorage *schedule_storage.ScheduleStorage } func NewScheduleParser( dataParser data_parser.IDataParser, dateParser date_parser.IDateParser, - scheduleStorage schedule_storage.ScheduleStorage, + scheduleStorage *schedule_storage.ScheduleStorage, ) *ScheduleParser { return &ScheduleParser{ dataParser: dataParser, diff --git a/internal/services/schedule_storage/service.go b/internal/services/schedule_storage/service.go index 93f6052..35da310 100644 --- a/internal/services/schedule_storage/service.go +++ b/internal/services/schedule_storage/service.go @@ -2,6 +2,7 @@ package schedule_storage import ( "encoding/json" + "fmt" "log" "os" "pinned_message/internal/models" @@ -30,3 +31,16 @@ func (s *ScheduleStorage) SaveSchedule(days []*models.Day) error { log.Printf("save story to: %s", s.filepath) return nil } + +func (s *ScheduleStorage) GetSchedule() ([]*models.Day, error) { + data, err := os.ReadFile(s.filepath) + if err != nil { + return nil, fmt.Errorf("story file %s not found", s.filepath) + } + log.Printf("load story from: %s", s.filepath) + days := []*models.Day{} + if err := json.Unmarshal(data, &days); err != nil { + return nil, err + } + return days, nil +} diff --git a/internal/services/services.go b/internal/services/services.go new file mode 100644 index 0000000..3ea25e8 --- /dev/null +++ b/internal/services/services.go @@ -0,0 +1,66 @@ +package services + +import ( + "context" + "pinned_message/internal/services/schedule_storage" + "pinned_message/proto" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +type Services struct { + scheduleStorage *schedule_storage.ScheduleStorage +} + +func NewServices( + scheduleStorage *schedule_storage.ScheduleStorage, +) *Services { + return &Services{ + scheduleStorage: scheduleStorage, + } +} + +func (s *Services) GetDays(context.Context, *proto.GetDaysReq) (*proto.GetDaysRsp, error) { + days, err := s.scheduleStorage.GetSchedule() + if err != nil { + return nil, status.Errorf(codes.Internal, err.Error()) + } + + res := &proto.GetDaysRsp{} + for _, day := range days { + + resPerformances := make([]*proto.Performance, 0, len(day.Performances)) + for _, performance := range day.Performances { + resNumbers := make([]*proto.Number, 0, len(performance.Numbers)) + for _, number := range performance.Numbers { + resNumbers = append( + resNumbers, + &proto.Number{ + Name: number.Name, + }, + ) + } + resPerformances = append( + resPerformances, + &proto.Performance{ + TimeCollection: performance.TimeCollection, + TimeStart: performance.TimeStart, + Place: performance.Place, + Name: performance.Name, + Numbers: resNumbers, + Costumes: performance.Costumes, + }, + ) + } + res.Days = append( + res.Days, + &proto.Day{ + Date: day.Date.String(), + Performances: resPerformances, + }, + ) + } + + return res, nil +} diff --git a/proto/main.pb.go b/proto/main.pb.go index 813278b..37fb916 100644 --- a/proto/main.pb.go +++ b/proto/main.pb.go @@ -94,6 +94,266 @@ func (*PingRsp) Descriptor() ([]byte, []int) { return file_main_proto_rawDescGZIP(), []int{1} } +type GetDaysReq struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetDaysReq) Reset() { + *x = GetDaysReq{} + mi := &file_main_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetDaysReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDaysReq) ProtoMessage() {} + +func (x *GetDaysReq) ProtoReflect() protoreflect.Message { + mi := &file_main_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDaysReq.ProtoReflect.Descriptor instead. +func (*GetDaysReq) Descriptor() ([]byte, []int) { + return file_main_proto_rawDescGZIP(), []int{2} +} + +type GetDaysRsp struct { + state protoimpl.MessageState `protogen:"open.v1"` + Days []*Day `protobuf:"bytes,1,rep,name=days,proto3" json:"days,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetDaysRsp) Reset() { + *x = GetDaysRsp{} + mi := &file_main_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetDaysRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDaysRsp) ProtoMessage() {} + +func (x *GetDaysRsp) ProtoReflect() protoreflect.Message { + mi := &file_main_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDaysRsp.ProtoReflect.Descriptor instead. +func (*GetDaysRsp) Descriptor() ([]byte, []int) { + return file_main_proto_rawDescGZIP(), []int{3} +} + +func (x *GetDaysRsp) GetDays() []*Day { + if x != nil { + return x.Days + } + return nil +} + +type Day struct { + state protoimpl.MessageState `protogen:"open.v1"` + Date string `protobuf:"bytes,1,opt,name=date,proto3" json:"date,omitempty"` + Performances []*Performance `protobuf:"bytes,2,rep,name=performances,proto3" json:"performances,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Day) Reset() { + *x = Day{} + mi := &file_main_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Day) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Day) ProtoMessage() {} + +func (x *Day) ProtoReflect() protoreflect.Message { + mi := &file_main_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Day.ProtoReflect.Descriptor instead. +func (*Day) Descriptor() ([]byte, []int) { + return file_main_proto_rawDescGZIP(), []int{4} +} + +func (x *Day) GetDate() string { + if x != nil { + return x.Date + } + return "" +} + +func (x *Day) GetPerformances() []*Performance { + if x != nil { + return x.Performances + } + return nil +} + +type Performance struct { + state protoimpl.MessageState `protogen:"open.v1"` + TimeCollection string `protobuf:"bytes,1,opt,name=time_collection,json=timeCollection,proto3" json:"time_collection,omitempty"` + TimeStart string `protobuf:"bytes,2,opt,name=time_start,json=timeStart,proto3" json:"time_start,omitempty"` + Place string `protobuf:"bytes,3,opt,name=place,proto3" json:"place,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Numbers []*Number `protobuf:"bytes,5,rep,name=numbers,proto3" json:"numbers,omitempty"` + Costumes string `protobuf:"bytes,6,opt,name=costumes,proto3" json:"costumes,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Performance) Reset() { + *x = Performance{} + mi := &file_main_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Performance) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Performance) ProtoMessage() {} + +func (x *Performance) ProtoReflect() protoreflect.Message { + mi := &file_main_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Performance.ProtoReflect.Descriptor instead. +func (*Performance) Descriptor() ([]byte, []int) { + return file_main_proto_rawDescGZIP(), []int{5} +} + +func (x *Performance) GetTimeCollection() string { + if x != nil { + return x.TimeCollection + } + return "" +} + +func (x *Performance) GetTimeStart() string { + if x != nil { + return x.TimeStart + } + return "" +} + +func (x *Performance) GetPlace() string { + if x != nil { + return x.Place + } + return "" +} + +func (x *Performance) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Performance) GetNumbers() []*Number { + if x != nil { + return x.Numbers + } + return nil +} + +func (x *Performance) GetCostumes() string { + if x != nil { + return x.Costumes + } + return "" +} + +type Number struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Number) Reset() { + *x = Number{} + mi := &file_main_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Number) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Number) ProtoMessage() {} + +func (x *Number) ProtoReflect() protoreflect.Message { + mi := &file_main_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Number.ProtoReflect.Descriptor instead. +func (*Number) Descriptor() ([]byte, []int) { + return file_main_proto_rawDescGZIP(), []int{6} +} + +func (x *Number) GetName() string { + if x != nil { + return x.Name + } + return "" +} + var File_main_proto protoreflect.FileDescriptor const file_main_proto_rawDesc = "" + @@ -101,9 +361,28 @@ const file_main_proto_rawDesc = "" + "\n" + "main.proto\x12\x14crabs.pinned_message\x1a\x1cgoogle/api/annotations.proto\"\t\n" + "\aPingReq\"\t\n" + - "\aPingRsp2d\n" + + "\aPingRsp\"\f\n" + + "\n" + + "GetDaysReq\";\n" + + "\n" + + "GetDaysRsp\x12-\n" + + "\x04days\x18\x01 \x03(\v2\x19.crabs.pinned_message.DayR\x04days\"`\n" + + "\x03Day\x12\x12\n" + + "\x04date\x18\x01 \x01(\tR\x04date\x12E\n" + + "\fperformances\x18\x02 \x03(\v2!.crabs.pinned_message.PerformanceR\fperformances\"\xd3\x01\n" + + "\vPerformance\x12'\n" + + "\x0ftime_collection\x18\x01 \x01(\tR\x0etimeCollection\x12\x1d\n" + + "\n" + + "time_start\x18\x02 \x01(\tR\ttimeStart\x12\x14\n" + + "\x05place\x18\x03 \x01(\tR\x05place\x12\x12\n" + + "\x04name\x18\x04 \x01(\tR\x04name\x126\n" + + "\anumbers\x18\x05 \x03(\v2\x1c.crabs.pinned_message.NumberR\anumbers\x12\x1a\n" + + "\bcostumes\x18\x06 \x01(\tR\bcostumes\"\x1c\n" + + "\x06Number\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name2\xc6\x01\n" + "\rpinnedMessage\x12S\n" + - "\x04Ping\x12\x1d.crabs.pinned_message.PingReq\x1a\x1d.crabs.pinned_message.PingRsp\"\r\x82\xd3\xe4\x93\x02\a\x12\x05/pingB\vZ\tpkg/protob\x06proto3" + "\x04Ping\x12\x1d.crabs.pinned_message.PingReq\x1a\x1d.crabs.pinned_message.PingRsp\"\r\x82\xd3\xe4\x93\x02\a\x12\x05/ping\x12`\n" + + "\aGetDays\x12 .crabs.pinned_message.GetDaysReq\x1a .crabs.pinned_message.GetDaysRsp\"\x11\x82\xd3\xe4\x93\x02\v\x12\t/scheduleB\vZ\tpkg/protob\x06proto3" var ( file_main_proto_rawDescOnce sync.Once @@ -117,19 +396,29 @@ func file_main_proto_rawDescGZIP() []byte { return file_main_proto_rawDescData } -var file_main_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_main_proto_msgTypes = make([]protoimpl.MessageInfo, 7) var file_main_proto_goTypes = []any{ - (*PingReq)(nil), // 0: crabs.pinned_message.PingReq - (*PingRsp)(nil), // 1: crabs.pinned_message.PingRsp + (*PingReq)(nil), // 0: crabs.pinned_message.PingReq + (*PingRsp)(nil), // 1: crabs.pinned_message.PingRsp + (*GetDaysReq)(nil), // 2: crabs.pinned_message.GetDaysReq + (*GetDaysRsp)(nil), // 3: crabs.pinned_message.GetDaysRsp + (*Day)(nil), // 4: crabs.pinned_message.Day + (*Performance)(nil), // 5: crabs.pinned_message.Performance + (*Number)(nil), // 6: crabs.pinned_message.Number } var file_main_proto_depIdxs = []int32{ - 0, // 0: crabs.pinned_message.pinnedMessage.Ping:input_type -> crabs.pinned_message.PingReq - 1, // 1: crabs.pinned_message.pinnedMessage.Ping:output_type -> crabs.pinned_message.PingRsp - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] 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 + 4, // 0: crabs.pinned_message.GetDaysRsp.days:type_name -> crabs.pinned_message.Day + 5, // 1: crabs.pinned_message.Day.performances:type_name -> crabs.pinned_message.Performance + 6, // 2: crabs.pinned_message.Performance.numbers:type_name -> crabs.pinned_message.Number + 0, // 3: crabs.pinned_message.pinnedMessage.Ping:input_type -> crabs.pinned_message.PingReq + 2, // 4: crabs.pinned_message.pinnedMessage.GetDays:input_type -> crabs.pinned_message.GetDaysReq + 1, // 5: crabs.pinned_message.pinnedMessage.Ping:output_type -> crabs.pinned_message.PingRsp + 3, // 6: crabs.pinned_message.pinnedMessage.GetDays:output_type -> crabs.pinned_message.GetDaysRsp + 5, // [5:7] is the sub-list for method output_type + 3, // [3:5] 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 } func init() { file_main_proto_init() } @@ -143,7 +432,7 @@ func file_main_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_main_proto_rawDesc), len(file_main_proto_rawDesc)), NumEnums: 0, - NumMessages: 2, + NumMessages: 7, NumExtensions: 0, NumServices: 1, }, diff --git a/proto/main.pb.gw.go b/proto/main.pb.gw.go index 69c4c79..e488dec 100644 --- a/proto/main.pb.gw.go +++ b/proto/main.pb.gw.go @@ -56,6 +56,27 @@ func local_request_PinnedMessage_Ping_0(ctx context.Context, marshaler runtime.M return msg, metadata, err } +func request_PinnedMessage_GetDays_0(ctx context.Context, marshaler runtime.Marshaler, client PinnedMessageClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GetDaysReq + metadata runtime.ServerMetadata + ) + if req.Body != nil { + _, _ = io.Copy(io.Discard, req.Body) + } + msg, err := client.GetDays(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err +} + +func local_request_PinnedMessage_GetDays_0(ctx context.Context, marshaler runtime.Marshaler, server PinnedMessageServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var ( + protoReq GetDaysReq + metadata runtime.ServerMetadata + ) + msg, err := server.GetDays(ctx, &protoReq) + return msg, metadata, err +} + // RegisterPinnedMessageHandlerServer registers the http handlers for service PinnedMessage to "mux". // UnaryRPC :call PinnedMessageServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -82,6 +103,26 @@ func RegisterPinnedMessageHandlerServer(ctx context.Context, mux *runtime.ServeM } forward_PinnedMessage_Ping_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodGet, pattern_PinnedMessage_GetDays_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/crabs.pinned_message.PinnedMessage/GetDays", runtime.WithHTTPPathPattern("/schedule")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_PinnedMessage_GetDays_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_PinnedMessage_GetDays_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } @@ -139,13 +180,32 @@ func RegisterPinnedMessageHandlerClient(ctx context.Context, mux *runtime.ServeM } forward_PinnedMessage_Ping_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) + mux.Handle(http.MethodGet, pattern_PinnedMessage_GetDays_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + annotatedContext, err := runtime.AnnotateContext(ctx, mux, req, "/crabs.pinned_message.PinnedMessage/GetDays", runtime.WithHTTPPathPattern("/schedule")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_PinnedMessage_GetDays_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + forward_PinnedMessage_GetDays_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + }) return nil } var ( - pattern_PinnedMessage_Ping_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"ping"}, "")) + pattern_PinnedMessage_Ping_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"ping"}, "")) + pattern_PinnedMessage_GetDays_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"schedule"}, "")) ) var ( - forward_PinnedMessage_Ping_0 = runtime.ForwardResponseMessage + forward_PinnedMessage_Ping_0 = runtime.ForwardResponseMessage + forward_PinnedMessage_GetDays_0 = runtime.ForwardResponseMessage ) diff --git a/proto/main.swagger.json b/proto/main.swagger.json index 79c5742..7a803db 100644 --- a/proto/main.swagger.json +++ b/proto/main.swagger.json @@ -32,9 +32,90 @@ "pinnedMessage" ] } + }, + "/schedule": { + "get": { + "operationId": "pinnedMessage_GetDays", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/pinned_messageGetDaysRsp" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/runtimeError" + } + } + }, + "tags": [ + "pinnedMessage" + ] + } } }, "definitions": { + "pinned_messageDay": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "performances": { + "type": "array", + "items": { + "$ref": "#/definitions/pinned_messagePerformance" + } + } + } + }, + "pinned_messageGetDaysRsp": { + "type": "object", + "properties": { + "days": { + "type": "array", + "items": { + "$ref": "#/definitions/pinned_messageDay" + } + } + } + }, + "pinned_messageNumber": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "pinned_messagePerformance": { + "type": "object", + "properties": { + "time_collection": { + "type": "string" + }, + "time_start": { + "type": "string" + }, + "place": { + "type": "string" + }, + "name": { + "type": "string" + }, + "numbers": { + "type": "array", + "items": { + "$ref": "#/definitions/pinned_messageNumber" + } + }, + "costumes": { + "type": "string" + } + } + }, "pinned_messagePingRsp": { "type": "object" }, diff --git a/proto/main_grpc.pb.go b/proto/main_grpc.pb.go index f3403d6..3cae8cd 100644 --- a/proto/main_grpc.pb.go +++ b/proto/main_grpc.pb.go @@ -19,7 +19,8 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - PinnedMessage_Ping_FullMethodName = "/crabs.pinned_message.pinnedMessage/Ping" + PinnedMessage_Ping_FullMethodName = "/crabs.pinned_message.pinnedMessage/Ping" + PinnedMessage_GetDays_FullMethodName = "/crabs.pinned_message.pinnedMessage/GetDays" ) // PinnedMessageClient is the client API for PinnedMessage service. @@ -27,6 +28,7 @@ const ( // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type PinnedMessageClient interface { Ping(ctx context.Context, in *PingReq, opts ...grpc.CallOption) (*PingRsp, error) + GetDays(ctx context.Context, in *GetDaysReq, opts ...grpc.CallOption) (*GetDaysRsp, error) } type pinnedMessageClient struct { @@ -47,11 +49,22 @@ func (c *pinnedMessageClient) Ping(ctx context.Context, in *PingReq, opts ...grp return out, nil } +func (c *pinnedMessageClient) GetDays(ctx context.Context, in *GetDaysReq, opts ...grpc.CallOption) (*GetDaysRsp, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(GetDaysRsp) + err := c.cc.Invoke(ctx, PinnedMessage_GetDays_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + // PinnedMessageServer is the server API for PinnedMessage service. // All implementations must embed UnimplementedPinnedMessageServer // for forward compatibility. type PinnedMessageServer interface { Ping(context.Context, *PingReq) (*PingRsp, error) + GetDays(context.Context, *GetDaysReq) (*GetDaysRsp, error) mustEmbedUnimplementedPinnedMessageServer() } @@ -65,6 +78,9 @@ type UnimplementedPinnedMessageServer struct{} func (UnimplementedPinnedMessageServer) Ping(context.Context, *PingReq) (*PingRsp, error) { return nil, status.Errorf(codes.Unimplemented, "method Ping not implemented") } +func (UnimplementedPinnedMessageServer) GetDays(context.Context, *GetDaysReq) (*GetDaysRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDays not implemented") +} func (UnimplementedPinnedMessageServer) mustEmbedUnimplementedPinnedMessageServer() {} func (UnimplementedPinnedMessageServer) testEmbeddedByValue() {} @@ -104,6 +120,24 @@ func _PinnedMessage_Ping_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _PinnedMessage_GetDays_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetDaysReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(PinnedMessageServer).GetDays(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: PinnedMessage_GetDays_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(PinnedMessageServer).GetDays(ctx, req.(*GetDaysReq)) + } + return interceptor(ctx, in, info, handler) +} + // PinnedMessage_ServiceDesc is the grpc.ServiceDesc for PinnedMessage service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -115,6 +149,10 @@ var PinnedMessage_ServiceDesc = grpc.ServiceDesc{ MethodName: "Ping", Handler: _PinnedMessage_Ping_Handler, }, + { + MethodName: "GetDays", + Handler: _PinnedMessage_GetDays_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "main.proto", diff --git a/test.json b/test.json new file mode 100644 index 0000000..79b9271 --- /dev/null +++ b/test.json @@ -0,0 +1,245 @@ +{ + "days": [ + { + "date": "2026-03-24 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "-", + "timeStart": "18:00 - 20:00", + "place": "танцкласс", + "name": "репетиция", + "numbers": [{ "name": "все" }], + "costumes": "-" + } + ] + }, + { + "date": "2026-03-26 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "-", + "timeStart": "18:00 - 20:00", + "place": "танцкласс", + "name": "репетиция", + "numbers": [{ "name": "все" }], + "costumes": "-" + } + ] + }, + { + "date": "2026-03-27 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "13:00", + "timeStart": "15:00 - 17:00", + "place": "КДМ (Юрина 204в)", + "name": "Закрытие регионального этапа Всероссийского проекта-фестиваля «Российская школьная весна» Алтайского края и Открытие Краевого фестиваля студенческого творчества \"Студенческая весна на Алтае. Феста - 2026\"", + "numbers": [{ "name": "Гавря" }], + "costumes": "" + } + ] + }, + { + "date": "2026-03-28 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "17:30 - 21:00", + "place": "актовый зал С", + "name": "репетиция КП", + "numbers": [{ "name": "Еще люблю" }], + "costumes": "реп форма" + } + ] + }, + { + "date": "2026-03-29 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "12.15", + "timeStart": "13:00-14:00", + "place": "концертный зал Д", + "name": "День открытых дверей АлтГУ", + "numbers": [{ "name": "Русская душа" }], + "costumes": "" + } + ] + }, + { + "date": "2026-03-30 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "11:30-15:00", + "place": "аграрка на красноармейском", + "name": "ФЕСТА. Оригинальный жанр", + "numbers": [{ "name": "Песня цыганки" }], + "costumes": "" + } + ] + }, + { + "date": "2026-03-31 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "17:30 - 21:00", + "place": "актовый зал С", + "name": "репетиция КП", + "numbers": [{ "name": "Еще люблю" }], + "costumes": "реп форма" + } + ] + }, + { + "date": "2026-04-01 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "17:30 - 21:00", + "place": "актовый зал С", + "name": "репетиция КП", + "numbers": [{ "name": "Еще люблю" }], + "costumes": "костюм свой" + } + ] + }, + { + "date": "2026-04-02 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "17:30 - 21:00", + "place": "актовый зал С", + "name": "репетиция КП", + "numbers": [{ "name": "Еще люблю" }], + "costumes": "костюм свой" + } + ] + }, + { + "date": "2026-04-03 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "10:00-11:00", + "place": "актовый зал С", + "name": "ФЕСТА. КП", + "numbers": [{ "name": "Еще люблю" }], + "costumes": "костюм свой" + }, + { + "timeCollection": "", + "timeStart": "15:00-16:00", + "place": "актовый зал С", + "name": "репетиция танцевального направления", + "numbers": [ + { "name": "Русская душа" }, + { "name": " Гавря" }, + { "name": " Полька" } + ], + "costumes": "" + } + ] + }, + { + "date": "2026-04-04 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "", + "place": "актовый зал С", + "name": "ФЕСТА. Танцевальное направление", + "numbers": [ + { "name": "Русская душа" }, + { "name": " Гавря" }, + { "name": " Полька" } + ], + "costumes": "" + } + ] + }, + { + "date": "2026-04-05 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "", + "place": "актовый зал С", + "name": "ФЕСТА. Танцевальное направление", + "numbers": [ + { "name": "Русская душа" }, + { "name": " Гавря" }, + { "name": " Полька" } + ], + "costumes": "" + } + ] + }, + { + "date": "2026-04-06 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "", + "place": "концертный зал Д", + "name": "ЕММО. открытие", + "numbers": [{ "name": "Китайский" }, { "name": " Полька" }], + "costumes": "" + } + ] + }, + { + "date": "2026-04-08 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "", + "place": "концертный зал Д", + "name": "ЕММО. закрытие", + "numbers": [{ "name": "Гавря" }, { "name": " Русская душа" }], + "costumes": "" + } + ] + }, + { + "date": "2026-04-17 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "Вечер", + "place": "актовый зал С", + "name": "Мисс ИББ", + "numbers": [{ "name": "Китайский" }], + "costumes": "" + } + ] + }, + { + "date": "2026-04-24 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "", + "place": "актовый зал С", + "name": "Отчетник", + "numbers": [{ "name": "мы сдохнем" }], + "costumes": "" + } + ] + }, + { + "date": "2026-05-01 00:00:00 +0700 +07", + "performances": [ + { + "timeCollection": "", + "timeStart": "", + "place": "отъезд от гаража С", + "name": "Маральник", + "numbers": [{ "name": "" }], + "costumes": "" + } + ] + } + ] +}