The code and data behind xeiaso.net
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix events API

Signed-off-by: Xe Iaso <me@xeiaso.net>

Xe Iaso 547402be 6c74ae14

+64 -555
+7
cmd/xesite/main.go
··· 17 17 "xeiaso.net/v4/internal" 18 18 "xeiaso.net/v4/internal/lume" 19 19 "xeiaso.net/v4/pb" 20 + "xeiaso.net/v4/pb/external/mi" 20 21 ) 21 22 22 23 var ( ··· 87 88 88 89 fsrv := pb.NewFeedServer(&FeedServer{fs}, twirp.WithServerPathPrefix("/api")) 89 90 mux.Handle(fsrv.PathPrefix(), fsrv) 91 + 92 + es := mi.NewEventsServer( 93 + mi.NewEventsProtobufClient(*miURL, http.DefaultClient), 94 + twirp.WithServerPathPrefix("/api"), 95 + ) 96 + mux.Handle(es.PathPrefix(), es) 90 97 91 98 mux.HandleFunc("/blog.atom", func(w http.ResponseWriter, r *http.Request) { 92 99 http.Redirect(w, r, "/blog.rss", http.StatusMovedPermanently)
+1 -1
internal/adminpb/internal.pb.go
··· 1 1 // Code generated by protoc-gen-go. DO NOT EDIT. 2 2 // versions: 3 - // protoc-gen-go v1.32.0 3 + // protoc-gen-go v1.34.1 4 4 // protoc v5.26.1 5 5 // source: internal.proto 6 6
+7
pb/external/mi.proto
··· 4 4 package within.website.x.mi; 5 5 option go_package = "xeiaso.net/v4/pb/external/mi"; 6 6 7 + import "google/protobuf/empty.proto"; 7 8 import "google/protobuf/timestamp.proto"; 8 9 9 10 // Event is a single event that Xe will be attending. ··· 28 29 message EventFeed { 29 30 // The events in the feed 30 31 repeated Event events = 1; 32 + } 33 + 34 + // Events lets users fetch the current feed of events that Xe will be attending. 35 + service Events { 36 + // Get fetches the current feed of upcoming events. 37 + rpc Get(google.protobuf.Empty) returns (EventFeed); 31 38 }
+16 -9
pb/external/mi/mi.pb.go
··· 2 2 3 3 // Code generated by protoc-gen-go. DO NOT EDIT. 4 4 // versions: 5 - // protoc-gen-go v1.32.0 5 + // protoc-gen-go v1.34.1 6 6 // protoc v5.26.1 7 7 // source: mi.proto 8 8 ··· 11 11 import ( 12 12 protoreflect "google.golang.org/protobuf/reflect/protoreflect" 13 13 protoimpl "google.golang.org/protobuf/runtime/protoimpl" 14 - _ "google.golang.org/protobuf/types/known/emptypb" 14 + emptypb "google.golang.org/protobuf/types/known/emptypb" 15 15 timestamppb "google.golang.org/protobuf/types/known/timestamppb" 16 16 reflect "reflect" 17 17 sync "sync" ··· 203 203 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x06, 0x65, 0x76, 204 204 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x77, 0x69, 0x74, 205 205 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69, 206 - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x1e, 207 - 0x5a, 0x1c, 0x78, 0x65, 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x34, 0x2f, 208 - 0x70, 0x62, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x69, 0x62, 0x06, 209 - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 206 + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x32, 0x47, 207 + 0x0a, 0x06, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 208 + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 209 + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1e, 0x2e, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 210 + 0x2e, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69, 0x2e, 0x45, 0x76, 211 + 0x65, 0x6e, 0x74, 0x46, 0x65, 0x65, 0x64, 0x42, 0x1e, 0x5a, 0x1c, 0x78, 0x65, 0x69, 0x61, 0x73, 212 + 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x62, 0x2f, 0x65, 0x78, 0x74, 0x65, 213 + 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 210 214 } 211 215 212 216 var ( ··· 226 230 (*Event)(nil), // 0: within.website.x.mi.Event 227 231 (*EventFeed)(nil), // 1: within.website.x.mi.EventFeed 228 232 (*timestamppb.Timestamp)(nil), // 2: google.protobuf.Timestamp 233 + (*emptypb.Empty)(nil), // 3: google.protobuf.Empty 229 234 } 230 235 var file_mi_proto_depIdxs = []int32{ 231 236 2, // 0: within.website.x.mi.Event.start_date:type_name -> google.protobuf.Timestamp 232 237 2, // 1: within.website.x.mi.Event.end_date:type_name -> google.protobuf.Timestamp 233 238 0, // 2: within.website.x.mi.EventFeed.events:type_name -> within.website.x.mi.Event 234 - 3, // [3:3] is the sub-list for method output_type 235 - 3, // [3:3] is the sub-list for method input_type 239 + 3, // 3: within.website.x.mi.Events.Get:input_type -> google.protobuf.Empty 240 + 1, // 4: within.website.x.mi.Events.Get:output_type -> within.website.x.mi.EventFeed 241 + 4, // [4:5] is the sub-list for method output_type 242 + 3, // [3:4] is the sub-list for method input_type 236 243 3, // [3:3] is the sub-list for extension type_name 237 244 3, // [3:3] is the sub-list for extension extendee 238 245 0, // [0:3] is the sub-list for field type_name ··· 277 284 NumEnums: 0, 278 285 NumMessages: 2, 279 286 NumExtensions: 0, 280 - NumServices: 0, 287 + NumServices: 1, 281 288 }, 282 289 GoTypes: file_mi_proto_goTypes, 283 290 DependencyIndexes: file_mi_proto_depIdxs,
+1 -1
pb/external/mimi/announce/mimi-announce.pb.go
··· 1 1 // Code generated by protoc-gen-go. DO NOT EDIT. 2 2 // versions: 3 - // protoc-gen-go v1.32.0 3 + // protoc-gen-go v1.34.1 4 4 // protoc v5.26.1 5 5 // source: mimi-announce.proto 6 6
+1 -1
pb/external/protofeed/protofeed.pb.go
··· 1 1 // Code generated by protoc-gen-go. DO NOT EDIT. 2 2 // versions: 3 - // protoc-gen-go v1.32.0 3 + // protoc-gen-go v1.34.1 4 4 // protoc v5.26.1 5 5 // source: protofeed.proto 6 6
+1 -1
pb/openapi.json
··· 270 270 }, 271 271 "openapi": "3.0.0", 272 272 "paths": { 273 - "/api/xeiaso.net.Events/Get": { 273 + "/api/within.website.x.mi.Events/Get": { 274 274 "post": { 275 275 "description": "\nGet fetches the current feed of upcoming events.", 276 276 "requestBody": {
+10 -17
pb/xesite.pb.go
··· 1 1 // Code generated by protoc-gen-go. DO NOT EDIT. 2 2 // versions: 3 - // protoc-gen-go v1.32.0 3 + // protoc-gen-go v1.34.1 4 4 // protoc v5.26.1 5 5 // source: xesite.proto 6 6 ··· 13 13 timestamppb "google.golang.org/protobuf/types/known/timestamppb" 14 14 reflect "reflect" 15 15 sync "sync" 16 - mi "xeiaso.net/v4/pb/external/mi" 16 + _ "xeiaso.net/v4/pb/external/mi" 17 17 protofeed "xeiaso.net/v4/pb/external/protofeed" 18 18 ) 19 19 ··· 140 140 0x66, 0x6f, 0x32, 0x36, 0x0a, 0x04, 0x46, 0x65, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x47, 0x65, 141 141 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 142 142 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 143 - 0x6f, 0x66, 0x65, 0x65, 0x64, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x32, 0x47, 0x0a, 0x06, 0x45, 0x76, 144 - 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 145 - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 146 - 0x70, 0x74, 0x79, 0x1a, 0x1e, 0x2e, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x2e, 0x77, 0x65, 0x62, 147 - 0x73, 0x69, 0x74, 0x65, 0x2e, 0x78, 0x2e, 0x6d, 0x69, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 148 - 0x65, 0x65, 0x64, 0x42, 0x12, 0x5a, 0x10, 0x78, 0x65, 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 149 - 0x74, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 143 + 0x6f, 0x66, 0x65, 0x65, 0x64, 0x2e, 0x46, 0x65, 0x65, 0x64, 0x42, 0x12, 0x5a, 0x10, 0x78, 0x65, 144 + 0x69, 0x61, 0x73, 0x6f, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x76, 0x34, 0x2f, 0x70, 0x62, 0x62, 0x06, 145 + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 150 146 } 151 147 152 148 var ( ··· 167 163 (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp 168 164 (*emptypb.Empty)(nil), // 2: google.protobuf.Empty 169 165 (*protofeed.Feed)(nil), // 3: protofeed.Feed 170 - (*mi.EventFeed)(nil), // 4: within.website.x.mi.EventFeed 171 166 } 172 167 var file_xesite_proto_depIdxs = []int32{ 173 168 1, // 0: xeiaso.net.BuildInfo.build_time:type_name -> google.protobuf.Timestamp 174 169 2, // 1: xeiaso.net.Meta.Metadata:input_type -> google.protobuf.Empty 175 170 2, // 2: xeiaso.net.Feed.Get:input_type -> google.protobuf.Empty 176 - 2, // 3: xeiaso.net.Events.Get:input_type -> google.protobuf.Empty 177 - 0, // 4: xeiaso.net.Meta.Metadata:output_type -> xeiaso.net.BuildInfo 178 - 3, // 5: xeiaso.net.Feed.Get:output_type -> protofeed.Feed 179 - 4, // 6: xeiaso.net.Events.Get:output_type -> within.website.x.mi.EventFeed 180 - 4, // [4:7] is the sub-list for method output_type 181 - 1, // [1:4] is the sub-list for method input_type 171 + 0, // 3: xeiaso.net.Meta.Metadata:output_type -> xeiaso.net.BuildInfo 172 + 3, // 4: xeiaso.net.Feed.Get:output_type -> protofeed.Feed 173 + 3, // [3:5] is the sub-list for method output_type 174 + 1, // [1:3] is the sub-list for method input_type 182 175 1, // [1:1] is the sub-list for extension type_name 183 176 1, // [1:1] is the sub-list for extension extendee 184 177 0, // [0:1] is the sub-list for field type_name ··· 211 204 NumEnums: 0, 212 205 NumMessages: 1, 213 206 NumExtensions: 0, 214 - NumServices: 3, 207 + NumServices: 2, 215 208 }, 216 209 GoTypes: file_xesite_proto_goTypes, 217 210 DependencyIndexes: file_xesite_proto_depIdxs,
-6
pb/xesite.proto
··· 33 33 service Feed { 34 34 // Get fetches the current feed of posts. 35 35 rpc Get(google.protobuf.Empty) returns (protofeed.Feed); 36 - } 37 - 38 - // Events lets users fetch the current feed of events that Xe will be attending. 39 - service Events { 40 - // Get fetches the current feed of upcoming events. 41 - rpc Get(google.protobuf.Empty) returns (within.website.x.mi.EventFeed); 42 36 }
+20 -519
pb/xesite.twirp.go
··· 18 18 19 19 import google_protobuf "google.golang.org/protobuf/types/known/emptypb" 20 20 import protofeed "xeiaso.net/v4/pb/external/protofeed" 21 - import within_website_x_mi "xeiaso.net/v4/pb/external/mi" 22 21 23 22 import bytes "bytes" 24 23 import errors "errors" ··· 1024 1023 return baseServicePath(s.pathPrefix, "xeiaso.net", "Feed") 1025 1024 } 1026 1025 1027 - // ================ 1028 - // Events Interface 1029 - // ================ 1030 - 1031 - // Events lets users fetch the current feed of events that Xe will be attending. 1032 - type Events interface { 1033 - // Get fetches the current feed of upcoming events. 1034 - Get(context.Context, *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) 1035 - } 1036 - 1037 - // ====================== 1038 - // Events Protobuf Client 1039 - // ====================== 1040 - 1041 - type eventsProtobufClient struct { 1042 - client HTTPClient 1043 - urls [1]string 1044 - interceptor twirp.Interceptor 1045 - opts twirp.ClientOptions 1046 - } 1047 - 1048 - // NewEventsProtobufClient creates a Protobuf client that implements the Events interface. 1049 - // It communicates using Protobuf and can be configured with a custom HTTPClient. 1050 - func NewEventsProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Events { 1051 - if c, ok := client.(*http.Client); ok { 1052 - client = withoutRedirects(c) 1053 - } 1054 - 1055 - clientOpts := twirp.ClientOptions{} 1056 - for _, o := range opts { 1057 - o(&clientOpts) 1058 - } 1059 - 1060 - // Using ReadOpt allows backwards and forwards compatibility with new options in the future 1061 - literalURLs := false 1062 - _ = clientOpts.ReadOpt("literalURLs", &literalURLs) 1063 - var pathPrefix string 1064 - if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { 1065 - pathPrefix = "/twirp" // default prefix 1066 - } 1067 - 1068 - // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method> 1069 - serviceURL := sanitizeBaseURL(baseURL) 1070 - serviceURL += baseServicePath(pathPrefix, "xeiaso.net", "Events") 1071 - urls := [1]string{ 1072 - serviceURL + "Get", 1073 - } 1074 - 1075 - return &eventsProtobufClient{ 1076 - client: client, 1077 - urls: urls, 1078 - interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), 1079 - opts: clientOpts, 1080 - } 1081 - } 1082 - 1083 - func (c *eventsProtobufClient) Get(ctx context.Context, in *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1084 - ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net") 1085 - ctx = ctxsetters.WithServiceName(ctx, "Events") 1086 - ctx = ctxsetters.WithMethodName(ctx, "Get") 1087 - caller := c.callGet 1088 - if c.interceptor != nil { 1089 - caller = func(ctx context.Context, req *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1090 - resp, err := c.interceptor( 1091 - func(ctx context.Context, req interface{}) (interface{}, error) { 1092 - typedReq, ok := req.(*google_protobuf.Empty) 1093 - if !ok { 1094 - return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor") 1095 - } 1096 - return c.callGet(ctx, typedReq) 1097 - }, 1098 - )(ctx, req) 1099 - if resp != nil { 1100 - typedResp, ok := resp.(*within_website_x_mi.EventFeed) 1101 - if !ok { 1102 - return nil, twirp.InternalError("failed type assertion resp.(*within_website_x_mi.EventFeed) when calling interceptor") 1103 - } 1104 - return typedResp, err 1105 - } 1106 - return nil, err 1107 - } 1108 - } 1109 - return caller(ctx, in) 1110 - } 1111 - 1112 - func (c *eventsProtobufClient) callGet(ctx context.Context, in *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1113 - out := new(within_website_x_mi.EventFeed) 1114 - ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) 1115 - if err != nil { 1116 - twerr, ok := err.(twirp.Error) 1117 - if !ok { 1118 - twerr = twirp.InternalErrorWith(err) 1119 - } 1120 - callClientError(ctx, c.opts.Hooks, twerr) 1121 - return nil, err 1122 - } 1123 - 1124 - callClientResponseReceived(ctx, c.opts.Hooks) 1125 - 1126 - return out, nil 1127 - } 1128 - 1129 - // ================== 1130 - // Events JSON Client 1131 - // ================== 1132 - 1133 - type eventsJSONClient struct { 1134 - client HTTPClient 1135 - urls [1]string 1136 - interceptor twirp.Interceptor 1137 - opts twirp.ClientOptions 1138 - } 1139 - 1140 - // NewEventsJSONClient creates a JSON client that implements the Events interface. 1141 - // It communicates using JSON and can be configured with a custom HTTPClient. 1142 - func NewEventsJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) Events { 1143 - if c, ok := client.(*http.Client); ok { 1144 - client = withoutRedirects(c) 1145 - } 1146 - 1147 - clientOpts := twirp.ClientOptions{} 1148 - for _, o := range opts { 1149 - o(&clientOpts) 1150 - } 1151 - 1152 - // Using ReadOpt allows backwards and forwards compatibility with new options in the future 1153 - literalURLs := false 1154 - _ = clientOpts.ReadOpt("literalURLs", &literalURLs) 1155 - var pathPrefix string 1156 - if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { 1157 - pathPrefix = "/twirp" // default prefix 1158 - } 1159 - 1160 - // Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method> 1161 - serviceURL := sanitizeBaseURL(baseURL) 1162 - serviceURL += baseServicePath(pathPrefix, "xeiaso.net", "Events") 1163 - urls := [1]string{ 1164 - serviceURL + "Get", 1165 - } 1166 - 1167 - return &eventsJSONClient{ 1168 - client: client, 1169 - urls: urls, 1170 - interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), 1171 - opts: clientOpts, 1172 - } 1173 - } 1174 - 1175 - func (c *eventsJSONClient) Get(ctx context.Context, in *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1176 - ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net") 1177 - ctx = ctxsetters.WithServiceName(ctx, "Events") 1178 - ctx = ctxsetters.WithMethodName(ctx, "Get") 1179 - caller := c.callGet 1180 - if c.interceptor != nil { 1181 - caller = func(ctx context.Context, req *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1182 - resp, err := c.interceptor( 1183 - func(ctx context.Context, req interface{}) (interface{}, error) { 1184 - typedReq, ok := req.(*google_protobuf.Empty) 1185 - if !ok { 1186 - return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor") 1187 - } 1188 - return c.callGet(ctx, typedReq) 1189 - }, 1190 - )(ctx, req) 1191 - if resp != nil { 1192 - typedResp, ok := resp.(*within_website_x_mi.EventFeed) 1193 - if !ok { 1194 - return nil, twirp.InternalError("failed type assertion resp.(*within_website_x_mi.EventFeed) when calling interceptor") 1195 - } 1196 - return typedResp, err 1197 - } 1198 - return nil, err 1199 - } 1200 - } 1201 - return caller(ctx, in) 1202 - } 1203 - 1204 - func (c *eventsJSONClient) callGet(ctx context.Context, in *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1205 - out := new(within_website_x_mi.EventFeed) 1206 - ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) 1207 - if err != nil { 1208 - twerr, ok := err.(twirp.Error) 1209 - if !ok { 1210 - twerr = twirp.InternalErrorWith(err) 1211 - } 1212 - callClientError(ctx, c.opts.Hooks, twerr) 1213 - return nil, err 1214 - } 1215 - 1216 - callClientResponseReceived(ctx, c.opts.Hooks) 1217 - 1218 - return out, nil 1219 - } 1220 - 1221 - // ===================== 1222 - // Events Server Handler 1223 - // ===================== 1224 - 1225 - type eventsServer struct { 1226 - Events 1227 - interceptor twirp.Interceptor 1228 - hooks *twirp.ServerHooks 1229 - pathPrefix string // prefix for routing 1230 - jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response 1231 - jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names 1232 - } 1233 - 1234 - // NewEventsServer builds a TwirpServer that can be used as an http.Handler to handle 1235 - // HTTP requests that are routed to the right method in the provided svc implementation. 1236 - // The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks). 1237 - func NewEventsServer(svc Events, opts ...interface{}) TwirpServer { 1238 - serverOpts := newServerOpts(opts) 1239 - 1240 - // Using ReadOpt allows backwards and forwards compatibility with new options in the future 1241 - jsonSkipDefaults := false 1242 - _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults) 1243 - jsonCamelCase := false 1244 - _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase) 1245 - var pathPrefix string 1246 - if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { 1247 - pathPrefix = "/twirp" // default prefix 1248 - } 1249 - 1250 - return &eventsServer{ 1251 - Events: svc, 1252 - hooks: serverOpts.Hooks, 1253 - interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...), 1254 - pathPrefix: pathPrefix, 1255 - jsonSkipDefaults: jsonSkipDefaults, 1256 - jsonCamelCase: jsonCamelCase, 1257 - } 1258 - } 1259 - 1260 - // writeError writes an HTTP response with a valid Twirp error format, and triggers hooks. 1261 - // If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err) 1262 - func (s *eventsServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) { 1263 - writeError(ctx, resp, err, s.hooks) 1264 - } 1265 - 1266 - // handleRequestBodyError is used to handle error when the twirp server cannot read request 1267 - func (s *eventsServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) { 1268 - if context.Canceled == ctx.Err() { 1269 - s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled")) 1270 - return 1271 - } 1272 - if context.DeadlineExceeded == ctx.Err() { 1273 - s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded")) 1274 - return 1275 - } 1276 - s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err)) 1277 - } 1278 - 1279 - // EventsPathPrefix is a convenience constant that may identify URL paths. 1280 - // Should be used with caution, it only matches routes generated by Twirp Go clients, 1281 - // with the default "/twirp" prefix and default CamelCase service and method names. 1282 - // More info: https://twitchtv.github.io/twirp/docs/routing.html 1283 - const EventsPathPrefix = "/twirp/xeiaso.net.Events/" 1284 - 1285 - func (s *eventsServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 1286 - ctx := req.Context() 1287 - ctx = ctxsetters.WithPackageName(ctx, "xeiaso.net") 1288 - ctx = ctxsetters.WithServiceName(ctx, "Events") 1289 - ctx = ctxsetters.WithResponseWriter(ctx, resp) 1290 - 1291 - var err error 1292 - ctx, err = callRequestReceived(ctx, s.hooks) 1293 - if err != nil { 1294 - s.writeError(ctx, resp, err) 1295 - return 1296 - } 1297 - 1298 - if req.Method != "POST" { 1299 - msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method) 1300 - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 1301 - return 1302 - } 1303 - 1304 - // Verify path format: [<prefix>]/<package>.<Service>/<Method> 1305 - prefix, pkgService, method := parseTwirpPath(req.URL.Path) 1306 - if pkgService != "xeiaso.net.Events" { 1307 - msg := fmt.Sprintf("no handler for path %q", req.URL.Path) 1308 - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 1309 - return 1310 - } 1311 - if prefix != s.pathPrefix { 1312 - msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path) 1313 - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 1314 - return 1315 - } 1316 - 1317 - switch method { 1318 - case "Get": 1319 - s.serveGet(ctx, resp, req) 1320 - return 1321 - default: 1322 - msg := fmt.Sprintf("no handler for path %q", req.URL.Path) 1323 - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) 1324 - return 1325 - } 1326 - } 1327 - 1328 - func (s *eventsServer) serveGet(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1329 - header := req.Header.Get("Content-Type") 1330 - i := strings.Index(header, ";") 1331 - if i == -1 { 1332 - i = len(header) 1333 - } 1334 - switch strings.TrimSpace(strings.ToLower(header[:i])) { 1335 - case "application/json": 1336 - s.serveGetJSON(ctx, resp, req) 1337 - case "application/protobuf": 1338 - s.serveGetProtobuf(ctx, resp, req) 1339 - default: 1340 - msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) 1341 - twerr := badRouteError(msg, req.Method, req.URL.Path) 1342 - s.writeError(ctx, resp, twerr) 1343 - } 1344 - } 1345 - 1346 - func (s *eventsServer) serveGetJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1347 - var err error 1348 - ctx = ctxsetters.WithMethodName(ctx, "Get") 1349 - ctx, err = callRequestRouted(ctx, s.hooks) 1350 - if err != nil { 1351 - s.writeError(ctx, resp, err) 1352 - return 1353 - } 1354 - 1355 - d := json.NewDecoder(req.Body) 1356 - rawReqBody := json.RawMessage{} 1357 - if err := d.Decode(&rawReqBody); err != nil { 1358 - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1359 - return 1360 - } 1361 - reqContent := new(google_protobuf.Empty) 1362 - unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} 1363 - if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { 1364 - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) 1365 - return 1366 - } 1367 - 1368 - handler := s.Events.Get 1369 - if s.interceptor != nil { 1370 - handler = func(ctx context.Context, req *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1371 - resp, err := s.interceptor( 1372 - func(ctx context.Context, req interface{}) (interface{}, error) { 1373 - typedReq, ok := req.(*google_protobuf.Empty) 1374 - if !ok { 1375 - return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor") 1376 - } 1377 - return s.Events.Get(ctx, typedReq) 1378 - }, 1379 - )(ctx, req) 1380 - if resp != nil { 1381 - typedResp, ok := resp.(*within_website_x_mi.EventFeed) 1382 - if !ok { 1383 - return nil, twirp.InternalError("failed type assertion resp.(*within_website_x_mi.EventFeed) when calling interceptor") 1384 - } 1385 - return typedResp, err 1386 - } 1387 - return nil, err 1388 - } 1389 - } 1390 - 1391 - // Call service method 1392 - var respContent *within_website_x_mi.EventFeed 1393 - func() { 1394 - defer ensurePanicResponses(ctx, resp, s.hooks) 1395 - respContent, err = handler(ctx, reqContent) 1396 - }() 1397 - 1398 - if err != nil { 1399 - s.writeError(ctx, resp, err) 1400 - return 1401 - } 1402 - if respContent == nil { 1403 - s.writeError(ctx, resp, twirp.InternalError("received a nil *within_website_x_mi.EventFeed and nil error while calling Get. nil responses are not supported")) 1404 - return 1405 - } 1406 - 1407 - ctx = callResponsePrepared(ctx, s.hooks) 1408 - 1409 - marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} 1410 - respBytes, err := marshaler.Marshal(respContent) 1411 - if err != nil { 1412 - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) 1413 - return 1414 - } 1415 - 1416 - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1417 - resp.Header().Set("Content-Type", "application/json") 1418 - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1419 - resp.WriteHeader(http.StatusOK) 1420 - 1421 - if n, err := resp.Write(respBytes); err != nil { 1422 - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1423 - twerr := twirp.NewError(twirp.Unknown, msg) 1424 - ctx = callError(ctx, s.hooks, twerr) 1425 - } 1426 - callResponseSent(ctx, s.hooks) 1427 - } 1428 - 1429 - func (s *eventsServer) serveGetProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { 1430 - var err error 1431 - ctx = ctxsetters.WithMethodName(ctx, "Get") 1432 - ctx, err = callRequestRouted(ctx, s.hooks) 1433 - if err != nil { 1434 - s.writeError(ctx, resp, err) 1435 - return 1436 - } 1437 - 1438 - buf, err := io.ReadAll(req.Body) 1439 - if err != nil { 1440 - s.handleRequestBodyError(ctx, resp, "failed to read request body", err) 1441 - return 1442 - } 1443 - reqContent := new(google_protobuf.Empty) 1444 - if err = proto.Unmarshal(buf, reqContent); err != nil { 1445 - s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) 1446 - return 1447 - } 1448 - 1449 - handler := s.Events.Get 1450 - if s.interceptor != nil { 1451 - handler = func(ctx context.Context, req *google_protobuf.Empty) (*within_website_x_mi.EventFeed, error) { 1452 - resp, err := s.interceptor( 1453 - func(ctx context.Context, req interface{}) (interface{}, error) { 1454 - typedReq, ok := req.(*google_protobuf.Empty) 1455 - if !ok { 1456 - return nil, twirp.InternalError("failed type assertion req.(*google_protobuf.Empty) when calling interceptor") 1457 - } 1458 - return s.Events.Get(ctx, typedReq) 1459 - }, 1460 - )(ctx, req) 1461 - if resp != nil { 1462 - typedResp, ok := resp.(*within_website_x_mi.EventFeed) 1463 - if !ok { 1464 - return nil, twirp.InternalError("failed type assertion resp.(*within_website_x_mi.EventFeed) when calling interceptor") 1465 - } 1466 - return typedResp, err 1467 - } 1468 - return nil, err 1469 - } 1470 - } 1471 - 1472 - // Call service method 1473 - var respContent *within_website_x_mi.EventFeed 1474 - func() { 1475 - defer ensurePanicResponses(ctx, resp, s.hooks) 1476 - respContent, err = handler(ctx, reqContent) 1477 - }() 1478 - 1479 - if err != nil { 1480 - s.writeError(ctx, resp, err) 1481 - return 1482 - } 1483 - if respContent == nil { 1484 - s.writeError(ctx, resp, twirp.InternalError("received a nil *within_website_x_mi.EventFeed and nil error while calling Get. nil responses are not supported")) 1485 - return 1486 - } 1487 - 1488 - ctx = callResponsePrepared(ctx, s.hooks) 1489 - 1490 - respBytes, err := proto.Marshal(respContent) 1491 - if err != nil { 1492 - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) 1493 - return 1494 - } 1495 - 1496 - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) 1497 - resp.Header().Set("Content-Type", "application/protobuf") 1498 - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) 1499 - resp.WriteHeader(http.StatusOK) 1500 - if n, err := resp.Write(respBytes); err != nil { 1501 - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) 1502 - twerr := twirp.NewError(twirp.Unknown, msg) 1503 - ctx = callError(ctx, s.hooks, twerr) 1504 - } 1505 - callResponseSent(ctx, s.hooks) 1506 - } 1507 - 1508 - func (s *eventsServer) ServiceDescriptor() ([]byte, int) { 1509 - return twirpFileDescriptor0, 2 1510 - } 1511 - 1512 - func (s *eventsServer) ProtocGenTwirpVersion() string { 1513 - return "v8.1.3" 1514 - } 1515 - 1516 - // PathPrefix returns the base service path, in the form: "/<prefix>/<package>.<Service>/" 1517 - // that is everything in a Twirp route except for the <Method>. This can be used for routing, 1518 - // for example to identify the requests that are targeted to this service in a mux. 1519 - func (s *eventsServer) PathPrefix() string { 1520 - return baseServicePath(s.pathPrefix, "xeiaso.net", "Events") 1521 - } 1522 - 1523 1026 // ===== 1524 1027 // Utils 1525 1028 // ===== ··· 2086 1589 } 2087 1590 2088 1591 var twirpFileDescriptor0 = []byte{ 2089 - // 329 bytes of a gzipped FileDescriptorProto 2090 - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x91, 0x4f, 0x4b, 0xc3, 0x40, 2091 - 0x10, 0xc5, 0x89, 0xad, 0xc5, 0x4c, 0xeb, 0xbf, 0x05, 0x4b, 0x88, 0xa8, 0x55, 0x10, 0x7a, 0xda, 2092 - 0x40, 0x14, 0xa1, 0x07, 0x0f, 0x16, 0x6a, 0xf1, 0xe0, 0xa5, 0x88, 0x07, 0x2f, 0x25, 0x31, 0xd3, 2093 - 0xb8, 0xd0, 0xdd, 0x0d, 0xcd, 0xb4, 0x8d, 0x9f, 0xd0, 0xaf, 0x25, 0xbb, 0x49, 0x1b, 0x50, 0xf4, 2094 - 0xb4, 0xcc, 0x9b, 0xdf, 0xcc, 0xbe, 0x7d, 0x0b, 0x9d, 0x02, 0x73, 0x41, 0xc8, 0xb3, 0x85, 0x26, 2095 - 0xcd, 0xa0, 0x40, 0x11, 0xe5, 0x9a, 0x2b, 0x24, 0xff, 0x34, 0xd5, 0x3a, 0x9d, 0x63, 0x60, 0x3b, 2096 - 0xf1, 0x72, 0x16, 0xa0, 0xcc, 0xe8, 0xb3, 0x04, 0xfd, 0x8b, 0x9f, 0x4d, 0x12, 0x12, 0x73, 0x8a, 2097 - 0x64, 0x56, 0x01, 0xc7, 0x58, 0x10, 0x2e, 0x54, 0x34, 0x0f, 0xa4, 0xa8, 0x24, 0x6f, 0x2b, 0xd9, 2098 - 0x7a, 0x86, 0x98, 0x94, 0x9d, 0xab, 0x2f, 0x07, 0xdc, 0xe1, 0x52, 0xcc, 0x93, 0x27, 0x35, 0xd3, 2099 - 0xac, 0x0b, 0xad, 0x77, 0x2d, 0xa5, 0x20, 0xcf, 0xe9, 0x39, 0x7d, 0x77, 0x52, 0x55, 0x6c, 0x00, 2100 - 0x10, 0x1b, 0x68, 0x6a, 0xee, 0xf2, 0x76, 0x7a, 0x4e, 0xbf, 0x1d, 0xfa, 0xbc, 0x34, 0xc2, 0x37, 2101 - 0x46, 0xf8, 0xcb, 0xc6, 0xc8, 0xc4, 0xb5, 0xb4, 0xa9, 0xd9, 0x19, 0x40, 0xaa, 0xa7, 0x2b, 0x5c, 2102 - 0xe4, 0x42, 0x2b, 0xaf, 0x61, 0xd7, 0xba, 0xa9, 0x7e, 0x2d, 0x05, 0x76, 0x09, 0x9d, 0x04, 0x55, 2103 - 0x0d, 0x34, 0x2d, 0xd0, 0x36, 0xda, 0x06, 0xb9, 0x86, 0x83, 0x32, 0xa9, 0x2d, 0xb4, 0x6b, 0xa1, 2104 - 0xfd, 0x52, 0xad, 0xb0, 0xf0, 0x01, 0x9a, 0xcf, 0x48, 0x11, 0x1b, 0xc0, 0x9e, 0x39, 0x93, 0x88, 2105 - 0x22, 0xd6, 0xfd, 0xe5, 0x71, 0x64, 0x92, 0xf4, 0x4f, 0x78, 0x9d, 0x36, 0xdf, 0x3e, 0x3f, 0xbc, 2106 - 0x83, 0xe6, 0x23, 0x62, 0xc2, 0x38, 0x34, 0xc6, 0x48, 0x7f, 0x4e, 0x1f, 0xf2, 0x3a, 0x45, 0xc3, 2107 - 0x87, 0x63, 0x68, 0x8d, 0x56, 0xa8, 0x28, 0x67, 0xf7, 0xff, 0x4f, 0x9e, 0xf3, 0xb5, 0xa0, 0x0f, 2108 - 0xa1, 0xf8, 0x1a, 0x63, 0xfb, 0xf7, 0x05, 0x97, 0x82, 0xdb, 0x59, 0xb3, 0x68, 0xc8, 0xde, 0x8e, 2109 - 0x6a, 0x63, 0xc1, 0xea, 0x36, 0xc8, 0xe2, 0xb8, 0x65, 0x77, 0xdc, 0x7c, 0x07, 0x00, 0x00, 0xff, 2110 - 0xff, 0xba, 0x70, 0xbe, 0x6e, 0x2f, 0x02, 0x00, 0x00, 1592 + // 296 bytes of a gzipped FileDescriptorProto 1593 + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x5f, 0x4b, 0xc3, 0x30, 1594 + 0x14, 0xc5, 0xa9, 0xab, 0xc3, 0xde, 0xcd, 0x7f, 0x01, 0x47, 0xa9, 0x88, 0x53, 0x10, 0xf6, 0x94, 1595 + 0x42, 0x15, 0x61, 0x8f, 0x0e, 0x54, 0x7c, 0xf0, 0x65, 0x88, 0x0f, 0xbe, 0x8c, 0xd4, 0xde, 0x96, 1596 + 0x40, 0xd3, 0x94, 0x36, 0x1b, 0xf5, 0x13, 0xfa, 0xb5, 0x24, 0x49, 0xff, 0x80, 0xe2, 0x53, 0xb8, 1597 + 0xe7, 0xfc, 0x72, 0x73, 0x72, 0x60, 0xda, 0x60, 0xcd, 0x15, 0xd2, 0xb2, 0x92, 0x4a, 0x12, 0x68, 1598 + 0x90, 0xb3, 0x5a, 0xd2, 0x02, 0x55, 0x70, 0x9e, 0x49, 0x99, 0xe5, 0x18, 0x1a, 0x27, 0xde, 0xa6, 1599 + 0x21, 0x8a, 0x52, 0x7d, 0x59, 0x30, 0xb8, 0xfc, 0x6d, 0x2a, 0x2e, 0xb0, 0x56, 0x4c, 0x94, 0x2d, 1600 + 0x70, 0x8a, 0x8d, 0xc2, 0xaa, 0x60, 0x79, 0x28, 0x78, 0x2b, 0xf9, 0xbd, 0x64, 0xe6, 0x14, 0x31, 1601 + 0xb1, 0xce, 0xf5, 0xb7, 0x03, 0xde, 0x6a, 0xcb, 0xf3, 0xe4, 0xa5, 0x48, 0x25, 0x99, 0xc1, 0xf8, 1602 + 0x53, 0x0a, 0xc1, 0x95, 0xef, 0xcc, 0x9d, 0x85, 0xb7, 0x6e, 0x27, 0xb2, 0x04, 0x88, 0x35, 0xb4, 1603 + 0xd1, 0x6f, 0xf9, 0x7b, 0x73, 0x67, 0x31, 0x89, 0x02, 0x6a, 0x83, 0xd0, 0x2e, 0x08, 0x7d, 0xeb, 1604 + 0x82, 0xac, 0x3d, 0x43, 0xeb, 0x99, 0x5c, 0x00, 0x64, 0x72, 0xb3, 0xc3, 0xaa, 0xe6, 0xb2, 0xf0, 1605 + 0x47, 0x66, 0xad, 0x97, 0xc9, 0x77, 0x2b, 0x90, 0x2b, 0x98, 0x26, 0x58, 0x0c, 0x80, 0x6b, 0x80, 1606 + 0x89, 0xd6, 0x3a, 0xe4, 0x06, 0x8e, 0x6c, 0x53, 0x3d, 0xb4, 0x6f, 0xa0, 0x43, 0xab, 0xb6, 0x58, 1607 + 0xf4, 0x00, 0xee, 0x2b, 0x2a, 0x46, 0x96, 0x70, 0xa0, 0xcf, 0x84, 0x29, 0x46, 0x66, 0x7f, 0x32, 1608 + 0x3e, 0xea, 0x26, 0x83, 0x33, 0x3a, 0xb4, 0x4d, 0xfb, 0xef, 0x47, 0xf7, 0xe0, 0x3e, 0x21, 0x26, 1609 + 0x84, 0xc2, 0xe8, 0x19, 0xd5, 0xbf, 0xb7, 0x8f, 0xe9, 0xd0, 0xa2, 0xe6, 0x57, 0xe4, 0xe3, 0x64, 1610 + 0xd8, 0x17, 0xee, 0xee, 0xc2, 0x32, 0x8e, 0xc7, 0x86, 0xb9, 0xfd, 0x09, 0x00, 0x00, 0xff, 0xff, 1611 + 0x23, 0x62, 0xd8, 0x88, 0xe6, 0x01, 0x00, 0x00, 2111 1612 }