From c3044325cb4610b55250089e9cc0727dd35ceb8b Mon Sep 17 00:00:00 2001 From: Frank Elsinga Date: Mon, 30 Oct 2023 21:47:29 +0100 Subject: [PATCH 01/43] bug:Unflexible TUFilm Parser (#268) * first (intal) draft * fixed the testcases * added a cronjob * changed the cronjob accordingly * reformated the test-html * formatting * fixed the movie title * made sure that even legacy feeds are saved * fixed linting issues * refactored the canals to be cleaner * documented `OMDB_API_KEY` * rebase --- README.md | 1 + server/api/tumdev/campus_backend.pb.go | 670 +++++++++--------- server/api/tumdev/campus_backend.proto | 27 +- server/api/tumdev/campus_backend.swagger.json | 46 +- server/backend/cron/movie_parsers/omdb.go | 60 ++ .../cron/movie_parsers/test_data/babylon.html | 349 +++++++++ .../movie_parsers/test_data/oppenheimer.html | 351 +++++++++ .../test_data/supprise_film.html | 273 +++++++ server/backend/cron/movie_parsers/tufilm.go | 241 +++++++ .../backend/cron/movie_parsers/tufilm_test.go | 95 +++ server/backend/cron/movies.go | 223 ++---- server/backend/cron/movies_test.go | 69 -- server/backend/migration/20231023000000.go | 51 ++ server/backend/migration/migration.go | 1 + server/backend/movie.go | 29 +- server/backend/movie_test.go | 78 +- server/model/kino.go | 13 +- 17 files changed, 1939 insertions(+), 638 deletions(-) create mode 100644 server/backend/cron/movie_parsers/omdb.go create mode 100644 server/backend/cron/movie_parsers/test_data/babylon.html create mode 100644 server/backend/cron/movie_parsers/test_data/oppenheimer.html create mode 100644 server/backend/cron/movie_parsers/test_data/supprise_film.html create mode 100644 server/backend/cron/movie_parsers/tufilm.go create mode 100644 server/backend/cron/movie_parsers/tufilm_test.go delete mode 100644 server/backend/cron/movies_test.go create mode 100644 server/backend/migration/20231023000000.go diff --git a/README.md b/README.md index a1c4d7db..285d9510 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ The following environment variables need to be set for the server to work proper * [REQUIRED] `DB_ROOT_PASSWORD`: The password of the root user. * [OPTIONAL] `DB_PORT`: The port of the database server. Defaults to `3306`. * [OPTIONAL] `SENTRY_DSN`: The Sentry [Data Source Name](https://sentry-docs-git-patch-1.sentry.dev/product/sentry-basics/dsn-explainer/) for reporting issues and crashes. +* [OPTIONAL] `OMDB_API_KEY`: The key to get more information for tu-film movies from [omdbapi](https://omdbapi.com/). See [omdbapi](https://omdbapi.com/apikey.aspx) for a key. * **[iOS Push Notification Service [OPTIONAL]](#ios-push-notifications-service)**: * [REQUIRED] `APNS_KEY_ID`: The key ID of the APNs key => APNs Key needs to be downloaded from the Apple Developer Portal the name of the file also contains the key ID. * [REQUIRED] `APNS_TEAM_ID`: The team ID of the iOS app can be found in AppStoreConnect. diff --git a/server/api/tumdev/campus_backend.pb.go b/server/api/tumdev/campus_backend.pb.go index adc7e75e..a78d39a9 100644 --- a/server/api/tumdev/campus_backend.pb.go +++ b/server/api/tumdev/campus_backend.pb.go @@ -3245,22 +3245,36 @@ type Movie struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MovieId int64 `protobuf:"varint,3,opt,name=movie_id,json=movieId,proto3" json:"movie_id,omitempty"` - Date *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=date,proto3" json:"date,omitempty"` + // the id of the movie + MovieId int64 `protobuf:"varint,3,opt,name=movie_id,json=movieId,proto3" json:"movie_id,omitempty"` + // the date of the movie + Date *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=date,proto3" json:"date,omitempty"` + // when the movie was created in OUR database Created *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"` - Title string `protobuf:"bytes,6,opt,name=title,proto3" json:"title,omitempty"` - // release year of the movie + // title of the movie if available, empty otherwise + Title string `protobuf:"bytes,6,opt,name=title,proto3" json:"title,omitempty"` + // Where the movie is shown + Location string `protobuf:"bytes,18,opt,name=location,proto3" json:"location,omitempty"` + // release year of the movie if available, empty otherwise ReleaseYear string `protobuf:"bytes,7,opt,name=release_year,json=releaseYear,proto3" json:"release_year,omitempty"` - Runtime string `protobuf:"bytes,8,opt,name=runtime,proto3" json:"runtime,omitempty"` - Genre string `protobuf:"bytes,9,opt,name=genre,proto3" json:"genre,omitempty"` - Director string `protobuf:"bytes,10,opt,name=director,proto3" json:"director,omitempty"` - Actors string `protobuf:"bytes,11,opt,name=actors,proto3" json:"actors,omitempty"` - // imdb rating - ImdbRating string `protobuf:"bytes,12,opt,name=imdb_rating,json=imdbRating,proto3" json:"imdb_rating,omitempty"` + // runtime of the movie if available, empty otherwise + Runtime string `protobuf:"bytes,8,opt,name=runtime,proto3" json:"runtime,omitempty"` + // genre of the movie if available, empty otherwise + Genre string `protobuf:"bytes,9,opt,name=genre,proto3" json:"genre,omitempty"` + // director of the movie as by omdb(/tu-film), empty otherwise + Director string `protobuf:"bytes,10,opt,name=director,proto3" json:"director,omitempty"` + // actors of the movie as by omdb(/tu-film), empty otherwise + Actors string `protobuf:"bytes,11,opt,name=actors,proto3" json:"actors,omitempty"` + // imdb rating for the movie if available, empty otherwise + ImdbRating string `protobuf:"bytes,12,opt,name=imdb_rating,json=imdbRating,proto3" json:"imdb_rating,omitempty"` + // short description of the movie including limited html tags (only , ) Description string `protobuf:"bytes,13,opt,name=description,proto3" json:"description,omitempty"` - CoverId int64 `protobuf:"varint,14,opt,name=cover_id,json=coverId,proto3" json:"cover_id,omitempty"` + // Where to find a trailer for this movie + TrailerUrl string `protobuf:"bytes,15,opt,name=trailer_url,json=trailerUrl,proto3" json:"trailer_url,omitempty"` // Where to find additional information about this movie - Link string `protobuf:"bytes,16,opt,name=link,proto3" json:"link,omitempty"` + AdditionalInformationUrl string `protobuf:"bytes,16,opt,name=additional_information_url,json=additionalInformationUrl,proto3" json:"additional_information_url,omitempty"` + // the id of the cover image + CoverId int64 `protobuf:"varint,14,opt,name=cover_id,json=coverId,proto3" json:"cover_id,omitempty"` // Where to find a cover image for this movie CoverUrl string `protobuf:"bytes,17,opt,name=cover_url,json=coverUrl,proto3" json:"cover_url,omitempty"` } @@ -3325,6 +3339,13 @@ func (x *Movie) GetTitle() string { return "" } +func (x *Movie) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + func (x *Movie) GetReleaseYear() string { if x != nil { return x.ReleaseYear @@ -3374,20 +3395,27 @@ func (x *Movie) GetDescription() string { return "" } -func (x *Movie) GetCoverId() int64 { +func (x *Movie) GetTrailerUrl() string { if x != nil { - return x.CoverId + return x.TrailerUrl } - return 0 + return "" } -func (x *Movie) GetLink() string { +func (x *Movie) GetAdditionalInformationUrl() string { if x != nil { - return x.Link + return x.AdditionalInformationUrl } return "" } +func (x *Movie) GetCoverId() int64 { + if x != nil { + return x.CoverId + } + return 0 +} + func (x *Movie) GetCoverUrl() string { if x != nil { return x.CoverUrl @@ -4688,7 +4716,7 @@ var file_tumdev_campus_backend_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x22, 0x0a, 0x06, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x52, 0x06, 0x6d, - 0x6f, 0x76, 0x69, 0x65, 0x73, 0x22, 0xc6, 0x03, 0x0a, 0x05, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x12, + 0x6f, 0x76, 0x69, 0x65, 0x73, 0x22, 0xa7, 0x04, 0x0a, 0x05, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, @@ -4698,312 +4726,318 @@ var file_tumdev_campus_backend_proto_rawDesc = []byte{ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x07, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, - 0x65, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x59, 0x65, 0x61, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x75, 0x6e, - 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x65, 0x6e, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x67, 0x65, 0x6e, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, - 0x0b, 0x69, 0x6d, 0x64, 0x62, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6d, 0x64, 0x62, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x20, - 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x19, 0x0a, 0x08, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x07, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, - 0x69, 0x6e, 0x6b, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, - 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x11, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x4a, 0x04, 0x08, 0x01, - 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x0f, 0x10, 0x10, 0x22, 0xcc, - 0x02, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, - 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x69, - 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, - 0x74, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, - 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, - 0x6e, 0x74, 0x22, 0x29, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, - 0x0b, 0x0a, 0x07, 0x54, 0x55, 0x4d, 0x5f, 0x44, 0x45, 0x56, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, - 0x54, 0x55, 0x4d, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x43, 0x54, 0x10, 0x01, 0x22, 0x46, 0x0a, - 0x0a, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, - 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, 0x6c, - 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, - 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, - 0x69, 0x74, 0x75, 0x64, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, - 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x32, 0x0a, 0x18, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x22, 0x47, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, - 0x63, 0x6b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x19, - 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x07, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x72, 0x22, 0x29, 0x0a, 0x10, 0x47, 0x65, 0x74, - 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, - 0x06, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, - 0x72, 0x7a, 0x49, 0x64, 0x22, 0x58, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, - 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x72, 0x7a, 0x49, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x64, 0x22, 0x2f, - 0x0a, 0x16, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x72, 0x7a, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x72, 0x7a, 0x49, 0x64, 0x22, - 0xb3, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x63, 0x6d, 0x5f, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x63, 0x6d, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x5f, - 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, - 0x65, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0x41, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xa9, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x74, 0x75, 0x72, 0x65, 0x22, 0x48, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, - 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x35, - 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3b, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, - 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, - 0x49, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, - 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x02, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2a, 0x2f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x49, 0x4f, 0x53, 0x10, 0x00, 0x12, 0x0b, 0x0a, - 0x07, 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x49, - 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x10, 0x02, 0x32, 0xe6, 0x16, 0x0a, 0x06, 0x43, 0x61, 0x6d, 0x70, - 0x75, 0x73, 0x12, 0x64, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, 0x6c, - 0x65, 0x72, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, - 0x65, 0x77, 0x73, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, - 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x16, 0x62, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x0c, 0x2f, 0x6e, 0x65, 0x77, - 0x73, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x62, 0x07, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x12, 0x0d, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x12, - 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x0d, 0x62, 0x04, 0x6e, 0x65, 0x77, 0x73, 0x12, 0x05, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x12, 0x72, - 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, - 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, - 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, - 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x67, - 0x65, 0x74, 0x12, 0x63, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, - 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, - 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, - 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, - 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x65, 0x74, 0x12, 0x75, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, - 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, - 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x63, 0x61, 0x6e, 0x74, - 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x69, - 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, - 0x6e, 0x67, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, - 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, - 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, - 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x8c, 0x01, 0x0a, 0x15, 0x4c, 0x69, + 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x79, 0x65, + 0x61, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, + 0x65, 0x59, 0x65, 0x61, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x67, 0x65, 0x6e, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x67, 0x65, 0x6e, 0x72, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6d, 0x64, + 0x62, 0x5f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x69, 0x6d, 0x64, 0x62, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, + 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x0f, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x3c, 0x0a, + 0x1a, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x18, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, + 0x75, 0x72, 0x6c, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x76, 0x65, 0x72, + 0x55, 0x72, 0x6c, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x22, + 0xcc, 0x02, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x63, + 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, + 0x6e, 0x74, 0x52, 0x09, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, + 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x70, 0x70, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x70, 0x70, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, + 0x65, 0x6e, 0x74, 0x22, 0x29, 0x0a, 0x09, 0x52, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, + 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x55, 0x4d, 0x5f, 0x44, 0x45, 0x56, 0x10, 0x00, 0x12, 0x0f, 0x0a, + 0x0b, 0x54, 0x55, 0x4d, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x43, 0x54, 0x10, 0x01, 0x22, 0x46, + 0x0a, 0x0a, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x12, 0x1a, 0x0a, 0x08, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x08, + 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x6e, 0x67, + 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, + 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x32, 0x0a, + 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x22, 0x47, 0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, + 0x61, 0x63, 0x6b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x19, 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x6e, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x07, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x72, 0x22, 0x29, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, + 0x0a, 0x06, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x6c, 0x72, 0x7a, 0x49, 0x64, 0x22, 0x58, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x72, 0x7a, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x72, 0x7a, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x49, 0x64, 0x22, + 0x2f, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6c, 0x72, 0x7a, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x72, 0x7a, 0x49, 0x64, + 0x22, 0xb3, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x63, 0x6d, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x63, + 0x6d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x74, 0x75, 0x64, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x6d, 0x70, 0x6c, 0x6f, 0x79, 0x65, 0x65, + 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x6d, 0x70, 0x6c, 0x6f, + 0x79, 0x65, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0x41, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0xa9, 0x01, 0x0a, 0x14, 0x47, 0x65, + 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x48, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, + 0x35, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x3b, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, + 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, + 0x6e, 0x49, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, + 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x02, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2a, 0x2f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x49, 0x4f, 0x53, 0x10, 0x00, 0x12, 0x0b, + 0x0a, 0x07, 0x41, 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, + 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x10, 0x02, 0x32, 0xe6, 0x16, 0x0a, 0x06, 0x43, 0x61, 0x6d, + 0x70, 0x75, 0x73, 0x12, 0x64, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, + 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4e, 0x65, 0x77, 0x73, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, + 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x16, 0x62, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x0c, 0x2f, 0x6e, 0x65, + 0x77, 0x73, 0x2f, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x0f, 0x4c, 0x69, 0x73, + 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x62, 0x07, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x0d, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, + 0x12, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x0d, 0x62, 0x04, 0x6e, 0x65, 0x77, 0x73, 0x12, 0x05, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x12, + 0x72, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, + 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, + 0x67, 0x65, 0x74, 0x12, 0x63, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, + 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, + 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x65, 0x74, 0x12, 0x75, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, + 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, + 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, + 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x63, 0x61, 0x6e, + 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, + 0x69, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, + 0x69, 0x6e, 0x67, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, + 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, + 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x8c, 0x01, 0x0a, 0x15, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, + 0x54, 0x61, 0x67, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, - 0x61, 0x67, 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, - 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, - 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x62, - 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x2f, 0x64, - 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, - 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x73, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, - 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x27, 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, - 0x18, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, - 0x6c, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x18, 0x4c, 0x69, + 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, + 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x2f, + 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, + 0x61, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67, 0x73, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, + 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x27, 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, + 0x12, 0x18, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, + 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x18, 0x4c, + 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x74, + 0x65, 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, - 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, - 0x6e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, - 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, - 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1d, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, - 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, - 0x54, 0x61, 0x67, 0x73, 0x12, 0x67, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, - 0x65, 0x65, 0x6e, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, - 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, - 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x62, 0x07, - 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x12, 0x14, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, - 0x6e, 0x2f, 0x61, 0x6c, 0x6c, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x12, 0x59, 0x0a, - 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, - 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x17, 0x62, 0x04, 0x64, 0x69, 0x73, 0x68, 0x12, 0x0f, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x61, - 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x7a, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x32, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1d, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, + 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, 0x74, 0x69, 0x6e, + 0x67, 0x54, 0x61, 0x67, 0x73, 0x12, 0x67, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, + 0x74, 0x65, 0x65, 0x6e, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, + 0x6e, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x62, + 0x07, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x12, 0x14, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, + 0x65, 0x6e, 0x2f, 0x61, 0x6c, 0x6c, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x12, 0x59, + 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x69, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x17, 0x62, 0x04, 0x64, 0x69, 0x73, 0x68, 0x12, 0x0f, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, + 0x61, 0x6c, 0x6c, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x7a, 0x0a, 0x15, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, - 0x6e, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, - 0x62, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x66, 0x72, 0x65, 0x65, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x63, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x72, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, + 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, + 0x2f, 0x62, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x66, 0x72, 0x65, 0x65, 0x2f, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x63, 0x74, 0x73, 0x12, 0x7b, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x72, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x24, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x62, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x66, 0x72, 0x65, - 0x65, 0x2f, 0x6d, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x6e, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, - 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, - 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x6e, - 0x67, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, - 0x7d, 0x12, 0x62, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, - 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, - 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, - 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x2f, 0x7b, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x55, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, - 0x69, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, - 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, 0x6f, 0x76, 0x69, - 0x65, 0x73, 0x2f, 0x7b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x67, 0x0a, 0x0e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x1a, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, - 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x0a, 0x61, 0x74, - 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x09, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x62, - 0x61, 0x63, 0x6b, 0x28, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, - 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, - 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, - 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, - 0x69, 0x64, 0x7d, 0x12, 0x73, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x28, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, - 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x72, 0x6d, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x24, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x1e, 0x12, 0x1c, 0x2f, 0x62, 0x61, 0x72, 0x72, 0x69, 0x65, 0x72, 0x66, 0x72, + 0x65, 0x65, 0x2f, 0x6d, 0x6f, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x6e, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, + 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, + 0x70, 0x65, 0x6e, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, + 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x69, + 0x6e, 0x67, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x2f, 0x7b, 0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, + 0x65, 0x7d, 0x12, 0x62, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, + 0x6f, 0x74, 0x65, 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, + 0x74, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, + 0x15, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x2f, 0x7b, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x7d, 0x12, 0x55, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, + 0x76, 0x69, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x6f, 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, 0x6f, 0x76, + 0x69, 0x65, 0x73, 0x2f, 0x7b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x67, 0x0a, + 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x12, + 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x0a, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x09, 0x2f, 0x66, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x28, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, + 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x2f, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, + 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x73, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, + 0x28, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2a, 0x12, 0x28, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x09, 0x47, - 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, - 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, - 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x7d, 0x12, - 0x7e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, - 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, + 0x66, 0x69, 0x72, 0x6d, 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, + 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x2a, 0x12, 0x28, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x09, + 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x13, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0x7e, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, + 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, - 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x2f, 0x7b, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, - 0x99, 0x01, 0x0a, 0x18, 0x49, 0x4f, 0x53, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x49, 0x4f, 0x53, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x4f, 0x53, 0x44, 0x65, 0x76, 0x69, - 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, 0x01, - 0x2a, 0x22, 0x28, 0x2f, 0x69, 0x6f, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0c, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x3a, 0x01, 0x2a, 0x22, 0x07, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, - 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x64, 0x65, - 0x76, 0x69, 0x63, 0x65, 0x2f, 0x7b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, - 0x42, 0x5e, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x2e, 0x74, 0x75, 0x6d, 0x2e, 0x63, 0x61, 0x6d, 0x70, - 0x75, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, 0x70, - 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x55, 0x4d, 0x2d, 0x44, 0x65, 0x76, 0x2f, 0x43, 0x61, 0x6d, - 0x70, 0x75, 0x73, 0x2d, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, 0xaa, - 0x02, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, + 0x1f, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x2f, 0x7b, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x7d, + 0x12, 0x99, 0x01, 0x0a, 0x18, 0x49, 0x4f, 0x53, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x49, 0x4f, 0x53, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x49, 0x4f, 0x53, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x3a, + 0x01, 0x2a, 0x22, 0x28, 0x2f, 0x69, 0x6f, 0x73, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x0c, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x3a, 0x01, 0x2a, 0x22, 0x07, 0x2f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x7b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x42, 0x5e, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x2e, 0x74, 0x75, 0x6d, 0x2e, 0x63, 0x61, 0x6d, + 0x70, 0x75, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, + 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x55, 0x4d, 0x2d, 0x44, 0x65, 0x76, 0x2f, 0x43, 0x61, + 0x6d, 0x70, 0x75, 0x73, 0x2d, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, + 0xaa, 0x02, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/server/api/tumdev/campus_backend.proto b/server/api/tumdev/campus_backend.proto index 56452d89..f245bb21 100644 --- a/server/api/tumdev/campus_backend.proto +++ b/server/api/tumdev/campus_backend.proto @@ -487,25 +487,38 @@ message ListMoviesReply { } message Movie { - reserved /*string cover_name = */ 1; - reserved /*string cover_path =*/ 2; + // the id of the movie int64 movie_id = 3; + // the date of the movie google.protobuf.Timestamp date = 4; + // when the movie was created in OUR database google.protobuf.Timestamp created = 5; + // title of the movie if available, empty otherwise string title = 6; - // release year of the movie + // Where the movie is shown + string location = 18; + // release year of the movie if available, empty otherwise string release_year = 7; + // runtime of the movie if available, empty otherwise string runtime = 8; + // genre of the movie if available, empty otherwise string genre = 9; + // director of the movie as by omdb(/tu-film), empty otherwise string director = 10; + // actors of the movie as by omdb(/tu-film), empty otherwise string actors = 11; - // imdb rating + // imdb rating for the movie if available, empty otherwise string imdb_rating = 12; + // short description of the movie including limited html tags (only , ) string description = 13; - int64 cover_id = 14; - reserved /*string trailer*/ 15; + // Where to find a trailer for this movie + string trailer_url = 15; // Where to find additional information about this movie - string link = 16; + string additional_information_url = 16; + + reserved /*cover_name,cover_path = */ 1, 2; + // the id of the cover image + int64 cover_id = 14; // Where to find a cover image for this movie string cover_url = 17; } diff --git a/server/api/tumdev/campus_backend.swagger.json b/server/api/tumdev/campus_backend.swagger.json index 146bc5b7..95bca358 100644 --- a/server/api/tumdev/campus_backend.swagger.json +++ b/server/api/tumdev/campus_backend.swagger.json @@ -1483,50 +1483,68 @@ "properties": { "movieId": { "type": "string", - "format": "int64" + "format": "int64", + "title": "the id of the movie" }, "date": { "type": "string", - "format": "date-time" + "format": "date-time", + "title": "the date of the movie" }, "created": { "type": "string", - "format": "date-time" + "format": "date-time", + "title": "when the movie was created in OUR database" }, "title": { - "type": "string" + "type": "string", + "title": "title of the movie if available, empty otherwise" + }, + "location": { + "type": "string", + "title": "Where the movie is shown" }, "releaseYear": { "type": "string", - "title": "release year of the movie" + "title": "release year of the movie if available, empty otherwise" }, "runtime": { - "type": "string" + "type": "string", + "title": "runtime of the movie if available, empty otherwise" }, "genre": { - "type": "string" + "type": "string", + "title": "genre of the movie if available, empty otherwise" }, "director": { - "type": "string" + "type": "string", + "title": "director of the movie as by omdb(/tu-film), empty otherwise" }, "actors": { - "type": "string" + "type": "string", + "title": "actors of the movie as by omdb(/tu-film), empty otherwise" }, "imdbRating": { "type": "string", - "title": "imdb rating" + "title": "imdb rating for the movie if available, empty otherwise" }, "description": { - "type": "string" + "type": "string", + "title": "short description of the movie including limited html tags (only \u003cb\u003e, \u003ci\u003e)" }, - "coverId": { + "trailerUrl": { "type": "string", - "format": "int64" + "title": "Where to find a trailer for this movie" }, - "link": { + "additionalInformationUrl": { "type": "string", "title": "Where to find additional information about this movie" }, + "coverId": { + "type": "string", + "format": "int64", + "title": "the id of the cover image" + }, "coverUrl": { "type": "string", "title": "Where to find a cover image for this movie" diff --git a/server/backend/cron/movie_parsers/omdb.go b/server/backend/cron/movie_parsers/omdb.go new file mode 100644 index 00000000..480d2d34 --- /dev/null +++ b/server/backend/cron/movie_parsers/omdb.go @@ -0,0 +1,60 @@ +package movie_parsers + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + + log "github.com/sirupsen/logrus" +) + +type OmdbResults struct { + ReleaseYear string `json:"Year"` + Runtime string + Genre string + Director string + Actors string + Plot string + ImdbRating string `json:"imdbRating"` +} + +func GetOmdbMovie(id string) (*OmdbResults, error) { + url := fmt.Sprintf("https://www.omdbapi.com/?r=json&v=1&i=%s&apikey=%s", id, os.Getenv("OMDB_API_KEY")) + resp, err := http.Get(url) + if err != nil { + log.WithField("url", url).WithError(err).Error("Error while getting response for request") + return nil, err + } + // check if the api key is valid + if resp.StatusCode == http.StatusUnauthorized { + return nil, errors.New("missing or invalid api key for omdb (environment variable OMDB_API_KEY)") + } + // other errors + if resp.StatusCode != http.StatusOK { + body, err := io.ReadAll(resp.Body) + if err != nil { + log.WithError(err).Warn("Unable to read http body") + return nil, err + } else { + log.WithField("status", resp.StatusCode).WithField("status", resp.Status).WithField("body", string(body)).Error("error while getting omdb movie") + return nil, errors.New("error while getting omdb movie") + } + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + log.WithField("url", url).WithError(err).Error("Error while closing body") + } + }(resp.Body) + // parse the response body + var res OmdbResults + err = json.NewDecoder(resp.Body).Decode(&res) + if err != nil { + log.WithField("url", url).WithError(err).Error("Error while unmarshalling omdbResults") + return nil, err + } + return &res, nil +} diff --git a/server/backend/cron/movie_parsers/test_data/babylon.html b/server/backend/cron/movie_parsers/test_data/babylon.html new file mode 100644 index 00000000..8b198df6 --- /dev/null +++ b/server/backend/cron/movie_parsers/test_data/babylon.html @@ -0,0 +1,349 @@ + + + + + + + der tu film - "Babylon" + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +
+
+ + +
+ +

6. April: Babylon (Garching, OV)

+
+ + + + + + + + +
+

Babylon (Digital)

+

USA (2022)

+
+
+ Zum Trailer
+ ab 16 + Dolby Digital + CinemaScope +
Regie: Damien Chazelle +
Schauspieler: Brad Pitt, Margot Robbie, Jean Smart +
189 Minuten +
+
+ Do you know where I can find some drugs? +
+
+

Its the 1920s, California, a chaotic world of parties and movie sets, crime and + exuberance. Newcomers Nellie LaRoy (Margot Robbie) and Manny Torres (Diego Calva) + will do everything to find their success. In front of the camera or behind it. When + movies + start getting lounder and + sets get quiet, they and movie stars of old like Jack Conrad (Brad Pitt) will have + to adapt or face extinction.

+

+ + Dont let that story stop you tough, these three hours are filled with dance and + drugs, music and montages, porn and poetry. You might not need that much of an + attention span and you might not want it. +

+

+ In the end, there is one thing Hollywood does best: Make movies about themselves. + Did they forget to mention that these movies were made for nazi germany? Is all this + crime and perversion really ok because the movies are just that good? Don't think + about it too much, you will still enjoy it.

+ +
+ +
+ + +
+
+ Chazelle’s film commemorates the era’s hubris as it indulges in a bit of its own. This + is how a world ends. Not with a whimper but a great deal of banging, baby. And vomiting. + And snorting. (Irish Times) +
+
+
+
+
+ +
+
+ +
+ +
+ +
+
+ + + + + + diff --git a/server/backend/cron/movie_parsers/test_data/oppenheimer.html b/server/backend/cron/movie_parsers/test_data/oppenheimer.html new file mode 100644 index 00000000..bbc4bdab --- /dev/null +++ b/server/backend/cron/movie_parsers/test_data/oppenheimer.html @@ -0,0 +1,351 @@ + + + + + + + der tu film - "Oppenheimer" + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +
+
+ + +
+ +

2. November: Oppenheimer (Garching, OV)

+
+ + + + + + + + +
+

Oppenheimer (Digital)

+

USA, UK (2023)

+
+
+ ab 12 + Dolby Digital + CinemaScope +
Regie: Christopher Nolan +
Schauspieler: Cillian Murphy, Emily Blunt, Matt Damon +
180 Minuten +
+
+ When the world changed forever +
+
+

In a hearing on his appeal against the revocation of + his security clearance, physicist Julius Robert + Oppenheimer looks back: on his beginnings, his private life and, above all, on the + time when he is assigned scientific leadership of the Manhattan + Project + during World War II. At Los Alamos National Laboratory in New Mexico, he and his + team are to develop + a nuclear weapon under the supervision of Lt. Leslie + Groves. Oppenheimer is proclaimed the "father of + the atomic bomb", but after his deadly invention is + used with serious consequences in Hiroshima and + Nagasaki, the just jubilant Oppenheimer is plunged + into serious doubts.

+ +

In the further course of the film Lewis Strauss is to + be confirmed as Secretary of Commerce in the + cabinet of President Dwight D. Eisenhower. + Soon it is also about his relations with Oppenheimer after the war, to whom he was + superior + as head of the Atomic Energy Authority. Thereby it concerns above all the reproaches + to + old connection to the communism which + Oppenheimer is accused of.

+ +
+ +
+ + +
+
+ An intellectual thriller that is a masterpiece of image and word, of complex ideas made + manifest, and all kept at a very human level to maintain constant immediacy. (Andrea + Chase, Killer Movie Reviews) +
+
+
+
+
+ +
+
+ +
+ +
+ +
+
+ + + + + + diff --git a/server/backend/cron/movie_parsers/test_data/supprise_film.html b/server/backend/cron/movie_parsers/test_data/supprise_film.html new file mode 100644 index 00000000..ea30b284 --- /dev/null +++ b/server/backend/cron/movie_parsers/test_data/supprise_film.html @@ -0,0 +1,273 @@ + + + + + + + der tu film - "Ãœberraschungsfilm" + + + + + + + + + + + + +
+ +
+ + + +
+
+ + + +
+
+ + +
+ +

25. Januar 2024: Ãœberraschungsfilm (Garching)

+
+ + + + + + + + +
+

Ãœberraschungsfilm (Digital)

+

+
+
+
+
+ Ãœberraschung! +
+
+

Seid gespannt und bereitet euch auf großes Kino vor – an diesem Termin spielen + wir einen Ãœberraschungsfilm für euch! Welcher Film das sein wird? Das wissen wir + selbst noch nicht. Fest steht, die Kinobranche schläft nie und wir wollen uns + nicht immer bereits ein halbes Jahr im Voraus festlegen, welche Filme bei uns + laufen.

+

+ Seid also gespannt, welche Perle wir für euch aus dem Zauberhut ziehen! Der Film + wird zwei Wochen davor über unsere üblichen Informationskanäle bekannt gegeben.

+

Habt ihr Meinungen dazu? Dann lasst es uns wissen und schreibt uns an + ueberraschungsfilm@tu-film.de

+
+
+
+
+
+ +
+
+ +
+ +
+ +
+
+ + + + + + diff --git a/server/backend/cron/movie_parsers/tufilm.go b/server/backend/cron/movie_parsers/tufilm.go new file mode 100644 index 00000000..0024fdc8 --- /dev/null +++ b/server/backend/cron/movie_parsers/tufilm.go @@ -0,0 +1,241 @@ +package movie_parsers + +import ( + "encoding/xml" + "errors" + "fmt" + "io" + "net/http" + "regexp" + "strings" + + "github.com/PuerkitoBio/goquery" + "github.com/guregu/null" + "github.com/microcosm-cc/bluemonday" + log "github.com/sirupsen/logrus" +) + +type TuFilmWebsiteInformation struct { + ImdbID null.String + TrailerUrl null.String + ImageUrl string + ShortenedDescription string + ReleaseYear null.String + Director null.String + Actors null.String + Runtime null.String +} + +// GetTuFilmWebsiteInformation scrapes the tu-film website for all usefully information +// url: url of the tu-film website, e.g. https://www.tu-film.de/programm/view/1204 +func GetTuFilmWebsiteInformation(url string) (*TuFilmWebsiteInformation, error) { + resp, err := http.Get(url) + if err != nil { + return nil, errors.New("error while getting response for request") + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + log.WithError(err).Error("Error while closing body") + } + }(resp.Body) + // parse the response body + doc, err := goquery.NewDocumentFromReader(resp.Body) + if err != nil { + log.WithError(err).Error("Error while parsing document") + return nil, err + } + + return parseWebsiteInformation(doc) +} + +func parseWebsiteInformation(doc *goquery.Document) (*TuFilmWebsiteInformation, error) { + Director, Actors, Runtime := parseDirectorActorsRuntime(doc) + return &TuFilmWebsiteInformation{ + ImdbID: parseImdbID(doc), + TrailerUrl: parseTrailerUrl(doc), + ImageUrl: parseImageUrl(doc), + ShortenedDescription: parseShortenedDescription(doc), + ReleaseYear: parseReleaseYear(doc), + Director: Director, + Actors: Actors, + Runtime: Runtime, + }, nil +} + +func parseDirectorActorsRuntime(doc *goquery.Document) (null.String, null.String, null.String) { + bm := bluemonday.StrictPolicy() + rawTable := doc.Find("td.film").Text() + rawTable = bm.Sanitize(rawTable) + rawTable = strings.TrimSpace(rawTable) + for strings.Contains(rawTable, " ") { + rawTable = strings.ReplaceAll(rawTable, " ", " ") + rawTable = strings.ReplaceAll(rawTable, "\n ", "\n") + } + re := regexp.MustCompile(`Regie: (?P.+)\nSchauspieler: (?P.+)\n(?P\d+) Minuten`) + matches := re.FindStringSubmatch(rawTable) + if len(matches) < re.NumSubexp() { + return null.String{}, null.String{}, null.String{} + } + director, actors, runtime := matches[re.SubexpIndex("director")], matches[re.SubexpIndex("actors")], matches[re.SubexpIndex("runtime")] + return null.StringFrom(director), null.StringFrom(actors), null.StringFrom(runtime + " min") +} + +func parseReleaseYear(doc *goquery.Document) null.String { + releasePlaceYear := doc.Find(".title h4").Text() + re := regexp.MustCompile(`(?P.+) \((?P\d{4})\)`) + match := re.FindStringSubmatch(releasePlaceYear) + index := re.SubexpIndex("release_year") + if len(match) < index+1 { + return null.String{} + } + return null.StringFrom(match[index]) +} + +func parseShortenedDescription(doc *goquery.Document) string { + bm := bluemonday.StrictPolicy() + result := "" + teaser := strings.TrimSpace(doc.Find("div.teaser").Text()) + if teaser != "" { + result += fmt.Sprintf("%s\n", bm.Sanitize(teaser)) + } + + doc.Find("div.description").Each(func(i int, s *goquery.Selection) { + // images which are randomly inserted in the text is great for the website, but not for us + s.Find("img").Each(func(i int, s *goquery.Selection) { + s.Remove() + }) + // paragraphs are used to separate the text + s.Find("p").Each(func(i int, s *goquery.Selection) { + content := strings.TrimSpace(s.Text()) + content = strings.ReplaceAll(content, "\n", "") + if content != "" { + result += "\n" + bm.Sanitize(content) + } + }) + }) + // cover the case where we have no teaser + result = strings.TrimSpace(result) + + comment := doc.Find("div.comment").Text() + comment = strings.TrimSpace(comment) + comment = strings.ReplaceAll(comment, "\n", "") + if comment != "" { + result += fmt.Sprintf("\n\n%s", bm.Sanitize(comment)) + } + // clean up the result + for strings.Contains(result, " ") { + result = strings.ReplaceAll(result, " ", " ") + } + if result == "" { + return "Surprise yourself" + } + return result +} + +func parseImageUrl(doc *goquery.Document) string { + href, exists := doc.Find("img.poster").First().Attr("src") + if !exists { + return "https://www.tu-film.de/img/film/poster/.sized.berraschungsfilm.jpg" + } + sanitisedHref := bluemonday.StrictPolicy().Sanitize(href) + return "https://www.tu-film.de" + sanitisedHref +} + +func parseTrailerUrl(doc *goquery.Document) null.String { + trailerLinks := doc.Find("a").FilterFunction(func(i int, s *goquery.Selection) bool { + return s.Text() == "Zum Trailer" + }) + if trailerLinks.Length() == 0 { + return null.String{} + } + if trailerLinks.Length() > 1 { + log.Warn("more than one trailer link found. using first one") + } + // extract the imdb id from the link + href, exists := trailerLinks.First().Attr("href") + if !exists { + log.Error("'Zum Trailer' does not have a link") + return null.String{} + } + href = strings.Replace(href, "http://", "https://", 1) + href = bluemonday.StrictPolicy().Sanitize(href) + return null.StringFrom(href) +} + +func parseImdbID(doc *goquery.Document) null.String { + imdbLinks := doc.Find("a").FilterFunction(func(i int, s *goquery.Selection) bool { + href, hrefExists := s.Attr("href") + return hrefExists && strings.Contains(href, "imdb.com/title/") + }) + if imdbLinks.Length() == 0 { + return null.String{} + } + if imdbLinks.Length() > 1 { + log.Warn("more than one imdb link found. using first one") + } + // extract the imdb id from the link + href, _ := imdbLinks.First().Attr("href") + re := regexp.MustCompile(`.*imdb.com/title/(?P[a-zA-Z0-9]+)/?`) + return null.StringFrom(re.FindStringSubmatch(href)[re.SubexpIndex("imdb_id")]) +} + +type MovieItems struct { + Title string `xml:"title"` + Link string `xml:"link"` + PubDate string `xml:"pubDate"` + Location string `xml:"location"` + Enclosure struct { + Url string `xml:"url,attr"` + Length string `xml:"length,attr"` + Type string `xml:"type,attr"` + } `xml:"enclosure"` +} + +type MovieChannel struct { + Items []MovieItems `xml:"item"` +} + +// GetFeeds gets all feeds from the tu-film website +func GetFeeds() ([]MovieChannel, error) { + var channels []MovieChannel + if newChannels, err := GetFeed("https://www.tu-film.de/programm/index/upcoming.rss"); err != nil { + return nil, err + } else { + channels = append(channels, newChannels...) + } + for i := 2001; i <= 2023; i++ { + for _, semester := range []string{"ws", "ss"} { + if newChannels, err := GetFeed(fmt.Sprintf("https://www.tu-film.de/programm/index/%s%d.rss", semester, i)); err != nil { + log.WithError(err).Warn("Error while getting old movie feed") + } else { + channels = append(channels, newChannels...) + } + } + } + return channels, nil +} + +func GetFeed(url string) ([]MovieChannel, error) { + resp, err := http.Get(url) + if err != nil { + log.WithError(err).Error("Error while getting response for request") + return nil, err + } + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + log.WithError(err).Error("Error while closing body") + } + }(resp.Body) + //Parse the data into a struct + var newMovies struct { + Channels []MovieChannel `xml:"channel"` + } + err = xml.NewDecoder(resp.Body).Decode(&newMovies) + if err != nil { + log.WithError(err).Error("Error while unmarshalling UpcomingFeed") + return nil, err + } + return newMovies.Channels, nil +} diff --git a/server/backend/cron/movie_parsers/tufilm_test.go b/server/backend/cron/movie_parsers/tufilm_test.go new file mode 100644 index 00000000..ee30dc81 --- /dev/null +++ b/server/backend/cron/movie_parsers/tufilm_test.go @@ -0,0 +1,95 @@ +package movie_parsers + +import ( + _ "embed" + "fmt" + "strings" + "testing" + + "github.com/guregu/null" + + "github.com/PuerkitoBio/goquery" + "github.com/stretchr/testify/require" +) + +//go:embed test_data/oppenheimer.html +var htmlOppenheimer string + +//go:embed test_data/supprise_film.html +var htmlSuppriseFilm string + +//go:embed test_data/babylon.html +var htmlBabylon string + +func TestOppenheimer(t *testing.T) { + doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlOppenheimer)) + require.NoError(t, err) + header := "When the world changed forever" + description := "In a hearing on his appeal against the revocation of his security clearance, physicist Julius Robert Oppenheimer looks back: on his beginnings, his private life and, above all, on the time when he is assigned scientific leadership of the Manhattan Project during World War II. At Los Alamos National Laboratory in New Mexico, he and his team are to develop a nuclear weapon under the supervision of Lt. Leslie Groves. Oppenheimer is proclaimed the "father of the atomic bomb", but after his deadly invention is used with serious consequences in Hiroshima and Nagasaki, the just jubilant Oppenheimer is plunged into serious doubts.\n" + + "In the further course of the film Lewis Strauss is to be confirmed as Secretary of Commerce in the cabinet of President Dwight D. Eisenhower. Soon it is also about his relations with Oppenheimer after the war, to whom he was superior as head of the Atomic Energy Authority. Thereby it concerns above all the reproaches to old connection to the communism which Oppenheimer is accused of." + comment := "An intellectual thriller that is a masterpiece of image and word, of complex ideas made manifest, and all kept at a very human level to maintain constant immediacy. (Andrea Chase, Killer Movie Reviews)" + expected := TuFilmWebsiteInformation{ + ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.Oppenheimer.jpg", + ShortenedDescription: fmt.Sprintf("%s\n\n%s\n\n%s", header, description, comment), + Director: null.StringFrom("Christopher Nolan"), + Actors: null.StringFrom("Cillian Murphy, Emily Blunt, Matt Damon"), + Runtime: null.StringFrom("180 min"), + ImdbID: null.StringFrom("tt15398776"), + ReleaseYear: null.StringFrom("2023"), + TrailerUrl: null.String{}, + } + info, err := parseWebsiteInformation(doc) + require.NoError(t, err) + require.Equal(t, &expected, info) +} + +func TestBabylon(t *testing.T) { + doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlBabylon)) + require.NoError(t, err) + header := "Do you know where I can find some drugs?" + description := "Its the 1920s, California, a chaotic world of parties and movie sets, crime and exuberance. Newcomers Nellie LaRoy (Margot Robbie) and Manny Torres (Diego Calva) will do everything to find their success. In front of the camera or behind it. When movies start getting lounder and sets get quiet, they and movie stars of old like Jack Conrad (Brad Pitt) will have to adapt or face extinction.\n" + + "Dont let that story stop you tough, these three hours are filled with dance and drugs, music and montages, porn and poetry. You might not need that much of an attention span and you might not want it.\n" + + "In the end, there is one thing Hollywood does best: Make movies about themselves. Did they forget to mention that these movies were made for nazi germany? Is all this crime and perversion really ok because the movies are just that good? Don't think about it too much, you will still enjoy it." + comment := "Chazelle’s film commemorates the era’s hubris as it indulges in a bit of its own. This is how a world ends. Not with a whimper but a great deal of banging, baby. And vomiting. And snorting. (Irish Times)" + expected := TuFilmWebsiteInformation{ + ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.Babylon.jpg", + ShortenedDescription: fmt.Sprintf("%s\n\n%s\n\n%s", header, description, comment), + Director: null.StringFrom("Damien Chazelle"), + Actors: null.StringFrom("Brad Pitt, Margot Robbie, Jean Smart"), + Runtime: null.StringFrom("189 min"), + ImdbID: null.StringFrom("tt10640346"), + ReleaseYear: null.StringFrom("2022"), + TrailerUrl: null.StringFrom("https://www.youtube.com/watch?v=5muQK7CuFtY"), + } + info, err := parseWebsiteInformation(doc) + require.NoError(t, err) + require.Equal(t, &expected, info) +} + +func TestSurpriseFilm(t *testing.T) { + doc, err := goquery.NewDocumentFromReader(strings.NewReader(htmlSuppriseFilm)) + require.NoError(t, err) + header := "Überraschung!" + description := "Seid gespannt und bereitet euch auf großes Kino vor – an diesem Termin spielen wir einen Überraschungsfilm für euch! Welcher Film das sein wird? Das wissen wir selbst noch nicht. Fest steht, die Kinobranche schläft nie und wir wollen uns nicht immer bereits ein halbes Jahr im Voraus festlegen, welche Filme bei uns laufen.\n" + + "Seid also gespannt, welche Perle wir für euch aus dem Zauberhut ziehen! Der Film wird zwei Wochen davor über unsere üblichen Informationskanäle bekannt gegeben.\n" + + "Habt ihr Meinungen dazu? Dann lasst es uns wissen und schreibt uns an ueberraschungsfilm@tu-film.de" + expected := TuFilmWebsiteInformation{ + ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.berraschungsfilm.jpg", + ShortenedDescription: fmt.Sprintf("%s\n\n%s", header, description), + } + info, err := parseWebsiteInformation(doc) + require.NoError(t, err) + require.Equal(t, &expected, info) +} + +func TestNoExtration(t *testing.T) { + doc, err := goquery.NewDocumentFromReader(strings.NewReader("")) + require.NoError(t, err) + expected := TuFilmWebsiteInformation{ + ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.berraschungsfilm.jpg", + ShortenedDescription: "Surprise yourself", + } + info, err := parseWebsiteInformation(doc) + require.NoError(t, err) + require.Equal(t, &expected, info) +} diff --git a/server/backend/cron/movies.go b/server/backend/cron/movies.go index 1d2a85e4..3de7a1cf 100644 --- a/server/backend/cron/movies.go +++ b/server/backend/cron/movies.go @@ -1,59 +1,37 @@ package cron import ( - "encoding/json" - "encoding/xml" - "errors" - "fmt" - "io" - "net/http" - "os" "regexp" - "strings" + "slices" "time" + "github.com/TUM-Dev/Campus-Backend/server/backend/cron/movie_parsers" + "github.com/guregu/null" - "github.com/PuerkitoBio/goquery" "github.com/TUM-Dev/Campus-Backend/server/model" log "github.com/sirupsen/logrus" ) -type MovieItems struct { - Title string `xml:"title"` - Link string `xml:"link"` - PubDate string `xml:"pubDate"` - Location string `xml:"location"` - Enclosure struct { - Url string `xml:"url,attr"` - Length string `xml:"length,attr"` - Type string `xml:"type,attr"` - } `xml:"enclosure"` -} - -type MovieChannel struct { - Items []MovieItems `xml:"item"` -} - const ( MovieImageDirectory = "movie/" ) func (c *CronService) movieCron() error { log.Trace("parsing upcoming feed") - channels, err := parseUpcomingFeed() + var allMovieLinks []string + if err := c.db.Model(&model.Kino{}).Distinct().Pluck("Link", &allMovieLinks).Error; err != nil { + return err + } + + channels, err := movie_parsers.GetFeeds() if err != nil { return err } for _, channel := range channels { for _, item := range channel.Items { logFields := log.Fields{"link": item.Link, "title": item.Title, "date": item.PubDate, "location": item.Location, "url": item.Enclosure.Url} - var exists bool - if err := c.db.Model(model.Kino{}).Select("count(*) > 0").Find(&exists, "link = ?", item.Link).Error; err != nil { - log.WithError(err).WithFields(logFields).Error("Cound lot check if movie already exists") - continue - } - if exists { + if slices.Contains(allMovieLinks, item.Link) { log.WithFields(logFields).Trace("Movie already exists") continue } @@ -64,166 +42,65 @@ func (c *CronService) movieCron() error { log.WithError(err).WithFields(logFields).Error("Couldn't check if movie already exists") continue } + re := regexp.MustCompile(`(?P[\d. ]+): (?P.+)$`) + matches := re.FindStringSubmatch(item.Title) + if len(matches) < re.NumSubexp() { + log.WithFields(logFields).Error("Couldn't parse movie title") + continue + } + item.Title = matches[re.SubexpIndex("title")] // populate extra data from omdb - imdbID, err := extractImdbIDFromTUFilmWebsite(item.Link) + movieInformation, err := movie_parsers.GetTuFilmWebsiteInformation(item.Link) if err != nil { log.WithFields(logFields).WithError(err).Error("error while finding imdb id") continue } - omdbMovie, err := getOmdbMovie(imdbID) - if err != nil { - log.WithFields(logFields).WithError(err).Error("error while getting omdb movie") - continue + movie := model.Kino{ + Date: date, + Title: item.Title, + Location: null.StringFrom(item.Location), + Year: movieInformation.ReleaseYear, + Runtime: movieInformation.Runtime, + Director: movieInformation.Director, + Actors: movieInformation.Actors, + Description: movieInformation.ShortenedDescription, + Trailer: movieInformation.TrailerUrl, + Link: item.Link, } - - // add a file to preview (downloaded in another cronjob) - file := model.File{ + previewFile := model.File{ Name: item.Title, Path: MovieImageDirectory, URL: null.StringFrom(item.Enclosure.Url), } - if err := c.db.Create(&file).Error; err != nil { - log.WithFields(logFields).WithError(err).Error("error while creating file") - continue + if movieInformation.ImdbID.ValueOrZero() != "" { + omdbMovie, err := movie_parsers.GetOmdbMovie(movieInformation.ImdbID.ValueOrZero()) + if err != nil { + log.WithFields(logFields).WithError(err).Error("error while getting omdb movie") + continue + } + // enrich the movie with data from omdb if present + movie.Year = null.StringFrom(omdbMovie.ReleaseYear) + movie.Runtime = null.StringFrom(omdbMovie.Runtime) + movie.Genre = null.StringFrom(omdbMovie.Genre) + movie.Director = null.StringFrom(omdbMovie.Director) + movie.Actors = null.StringFrom(omdbMovie.Actors) + movie.ImdbRating = null.StringFrom(omdbMovie.ImdbRating) + movie.Description = omdbMovie.Plot // tu-fim does truncate their plot } // save the result of the previous steps (🎉) - movie := model.Kino{ - Date: date, - Title: item.Title, - Year: omdbMovie.ReleaseYear, - Runtime: omdbMovie.Runtime, - Genre: omdbMovie.Genre, - Director: omdbMovie.Director, - Actors: omdbMovie.Actors, - ImdbRating: omdbMovie.ImdbRating, - Description: omdbMovie.Plot, // we get this from imdb as tu-fim does truncate their plot - FileID: file.File, - File: file, - Link: item.Link, + if err := c.db.Create(&previewFile).Error; err != nil { + log.WithFields(logFields).WithError(err).Error("error while creating file") + continue } + // assign the file_id to make sure the id is assigned + movie.File = previewFile + movie.FileID = previewFile.File if err := c.db.Create(&movie).Error; err != nil { log.WithFields(logFields).WithError(err).Error("error while creating movie") - continue - } else { - log.WithFields(logFields).Debug("created movie") } } } return nil } - -type omdbResults struct { - ReleaseYear string `json:"Year"` - Runtime string - Genre string - Director string - Actors string - Plot string - ImdbRating string `json:"imdbRating"` -} - -func getOmdbMovie(id string) (*omdbResults, error) { - url := fmt.Sprintf("https://www.omdbapi.com/?r=json&v=1&i=%s&apikey=%s", id, os.Getenv("OMDB_API_KEY")) - resp, err := http.Get(url) - if err != nil { - log.WithField("url", url).WithError(err).Error("Error while getting response for request") - return nil, err - } - // check if the api key is valid - if resp.StatusCode == http.StatusUnauthorized { - return nil, errors.New("missing or invalid api key for omdb (environment variable OMDB_API_KEY)") - } - // other errors - if resp.StatusCode != http.StatusOK { - body, err := io.ReadAll(resp.Body) - if err != nil { - log.WithError(err).Warn("Unable to read http body") - return nil, err - } else { - log.WithField("status", resp.StatusCode).WithField("status", resp.Status).WithField("body", string(body)).Error("error while getting omdb movie") - return nil, errors.New("error while getting omdb movie") - } - } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - log.WithField("url", url).WithError(err).Error("Error while closing body") - } - }(resp.Body) - // parse the response body - var res omdbResults - err = json.NewDecoder(resp.Body).Decode(&res) - if err != nil { - log.WithField("url", url).WithError(err).Error("Error while unmarshalling omdbResults") - return nil, err - } - return &res, nil -} - -// extractImdbIDFromTUFilmWebsite scrapes the imdb id and fullDescription from the tu-film website -// url: url of the tu-film website, e.g. https://www.tu-film.de/programm/view/1204 -func extractImdbIDFromTUFilmWebsite(url string) (string, error) { - resp, err := http.Get(url) - if err != nil { - return "", errors.New("error while getting response for request") - } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - log.WithError(err).Error("Error while closing body") - } - }(resp.Body) - // parse the response body - return parseImdbIDFromReader(resp.Body) -} - -func parseImdbIDFromReader(body io.Reader) (string, error) { - doc, err := goquery.NewDocumentFromReader(body) - if err != nil { - log.WithError(err).Error("Error while parsing document") - return "", err - } - - // extract the imdb link - imdbLinks := doc.Find("a").FilterFunction(func(i int, s *goquery.Selection) bool { - href, hrefExists := s.Attr("href") - return hrefExists && strings.Contains(href, "imdb.com/title/") - }) - if imdbLinks.Length() == 0 { - return "", errors.New("no imdb link found") - } - if imdbLinks.Length() > 1 { - log.Warn("more than one imdb link found. using first one") - } - // extract the imdb id from the link - href, _ := imdbLinks.First().Attr("href") - re := regexp.MustCompile(`https?://www.imdb.com/title/(?P<imdb_id>[^/]+)/?`) - return re.FindStringSubmatch(href)[re.SubexpIndex("imdb_id")], nil -} - -// parseUpcomingFeed downloads a file from a given url and returns the path to the file -func parseUpcomingFeed() ([]MovieChannel, error) { - resp, err := http.Get("https://www.tu-film.de/programm/index/upcoming.rss") - if err != nil { - log.WithError(err).Error("Error while getting response for request") - return nil, err - } - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - log.WithError(err).Error("Error while closing body") - } - }(resp.Body) - //Parse the data into a struct - var upcomingMovies struct { - Channels []MovieChannel `xml:"channel"` - } - err = xml.NewDecoder(resp.Body).Decode(&upcomingMovies) - if err != nil { - log.WithError(err).Error("Error while unmarshalling UpcomingFeed") - return nil, err - } - return upcomingMovies.Channels, nil -} diff --git a/server/backend/cron/movies_test.go b/server/backend/cron/movies_test.go deleted file mode 100644 index 3f95b1b3..00000000 --- a/server/backend/cron/movies_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package cron - -import ( - "strings" - "testing" -) - -func TestIMDBExtration(t *testing.T) { - reader := strings.NewReader(`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"> -<body class="white"> -<div class="container"> - <div id="main"> - <a name="top"></a> - <div id="content"> -<div class="widgets"> -<div class="widget right info programm"> - <h3>Vorstellung</h3> - <div>Do, 6. April 2023<br /> - um 20:00 Uhr<br /> - <a href="https://goo.gl/maps/WA54uV2bmsABudTi8">Hörsaal MW1801, Campus Garching</a></div> -<h1>6. April: Babylon<i> (Garching, OV)</i></h1> -<div class="widget" id="films"> -<table> -<tr class="top"> -<td colspan="2" class="title"> -<h3><a href="http://www.imdb.com/title/tt10640346/" target="_blank" title="In der IMDB nachschlagen">Babylon</a> (Digital)</h3> -<h4>USA (2022)</h4> -</td> -</tr> -<tr class="bottom"> -<td class="film"> -<img src="/img/film/poster/.sized.Babylon.jpg" class="poster" alt="" /><br /> -<a href="http://www.youtube.com/watch?v=5muQK7CuFtY">Zum Trailer</a><br /> -<img src="/img/film/fsk_16.png" class="icon" alt="ab 16" /> -<img src="/img/film/sf_dolbydigital.png" class="icon" alt="Dolby Digital" /> -<img src="/img/film/pf_cinemascope.png" class="icon" alt="CinemaScope" /> -<br /><i>Regie: </i>Damien Chazelle -<br /><i>Schauspieler: </i>Brad Pitt, Margot Robbie, Jean Smart -<br />189 Minuten -</td> -<td class="text"> -<div class="teaser">Do you know where I can find some drugs?</div> -<div class="description"> -<p>Its the 1920s, California, a chaotic world of parties and movie sets, crime and exuberance. Newcomers Nellie LaRoy (Margot Robbie) and Manny Torres (Diego Calva) will do everything to find their success. In front of the camera or behind it. When movies -<img src="/img/film/scenes/.thumb.Babylon-1.jpg" title="Szene aus Babylon" class="scene first" 0="0" alt="" /><img src="/img/film/scenes/.thumb.Babylon-2.jpg" title="Szene aus Babylon" class="scene" 0="0" alt="" /><img src="/img/film/scenes/.thumb.Babylon.jpg" title="Szene aus Babylon" class="scene" 0="0" alt="" /> start getting lounder and sets get quiet, they and movie stars of old like Jack Conrad (Brad Pitt) will have to adapt or face extinction.</p> -<p> - -Dont let that story stop you tough, these three hours are filled with dance and drugs, music and montages, porn and poetry. You might not need that much of an attention span and you might not want it. -</p><p> -In the end, there is one thing Hollywood does best: Make movies about themselves. Did they forget to mention that these movies were made for nazi germany? Is all this crime and perversion really ok because the movies are just that good? Don't think about it too much, you will still enjoy it.</p> -</div> -<div class="comment">Chazelle’s film commemorates the era’s hubris as it indulges in a bit of its own. This is how a world ends. Not with a whimper but a great deal of banging, baby. And vomiting. And snorting. (Irish Times)</div> -</td> -</tr> -</table></div> -</div> -</div> -</body> -</html> -`) - imdbID, err := parseImdbIDFromReader(reader) - if err != nil { - t.Error(err) - } - if imdbID != "tt10640346" { - t.Error("imdbID is not correct") - } -} diff --git a/server/backend/migration/20231023000000.go b/server/backend/migration/20231023000000.go new file mode 100644 index 00000000..89b5c1f9 --- /dev/null +++ b/server/backend/migration/20231023000000.go @@ -0,0 +1,51 @@ +package migration + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "github.com/guregu/null" + "gorm.io/gorm" +) + +type KinoWithNullableFields struct { + Year null.String `gorm:"column:year;type:varchar(4)"` + Runtime null.String `gorm:"column:runtime;type:varchar(40)"` + Genre null.String `gorm:"column:genre;type:varchar(100)"` + Director null.String `gorm:"column:director;type:text"` + Actors null.String `gorm:"column:actors;type:text"` + ImdbRating null.String `gorm:"column:rating;type:varchar(4)"` + Location null.String `gorm:"column:location;default:null"` +} + +type KinoWithoutNullableFields struct { + Year string `gorm:"column:year;type:varchar(4);not null;"` + Runtime string `gorm:"column:runtime;type:varchar(40);not null;"` + Genre string `gorm:"column:genre;type:varchar(100);not null;"` + Director string `gorm:"column:director;type:text;not null;"` + Actors string `gorm:"column:actors;type:text;not null;"` + ImdbRating string `gorm:"column:rating;type:varchar(4);not null;"` +} + +// TableName sets the insert table name for this struct type +func (n *KinoWithNullableFields) TableName() string { + return "kino" +} + +// migrate20231023000000 +// migrates the static data for the canteen rating system and adds the necessary cronjob entries +func migrate20231023000000() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "20231023000000", + Migrate: func(tx *gorm.DB) error { + return tx.Migrator().AutoMigrate(&KinoWithNullableFields{}) + }, + Rollback: func(tx *gorm.DB) error { + if err := tx.Exec("DROP FROM kino WHERE year IS NULL OR runtime IS NULL OR genre IS NULL OR director IS NULL OR actors IS NULL OR rating IS NULL").Error; err != nil { + return err + } + if err := tx.Migrator().DropColumn(&KinoWithNullableFields{}, "location"); err != nil { + return err + } + return tx.Migrator().AutoMigrate(&KinoWithoutNullableFields{}) + }, + } +} diff --git a/server/backend/migration/migration.go b/server/backend/migration/migration.go index 2c477d31..e21f84cb 100644 --- a/server/backend/migration/migration.go +++ b/server/backend/migration/migration.go @@ -79,6 +79,7 @@ func manualMigrate(db *gorm.DB) error { migrate20230904100000(), migrate20230826000000(), migrate20231003000000(), + migrate20231023000000(), } return gormigrate.New(db, gormigrateOptions, migrations).Migrate() } diff --git a/server/backend/movie.go b/server/backend/movie.go index 12981ccd..e692b0c6 100644 --- a/server/backend/movie.go +++ b/server/backend/movie.go @@ -24,20 +24,21 @@ func (s *CampusServer) ListMovies(ctx context.Context, req *pb.ListMoviesRequest var movieResponse []*pb.Movie for _, movie := range movies { movieResponse = append(movieResponse, &pb.Movie{ - MovieId: movie.Id, - Date: timestamppb.New(movie.Date), - Created: timestamppb.New(movie.Created), - Title: movie.Title, - ReleaseYear: movie.Year, - Runtime: movie.Runtime, - Genre: movie.Genre, - Director: movie.Director, - Actors: movie.Actors, - ImdbRating: movie.ImdbRating, - Description: movie.Description, - CoverUrl: movie.File.FullExternalUrl(), - CoverId: movie.File.File, - Link: movie.Link, + MovieId: movie.Id, + Date: timestamppb.New(movie.Date), + Created: timestamppb.New(movie.Created), + Title: movie.Title, + ReleaseYear: movie.Year.String, + Runtime: movie.Runtime.String, + Genre: movie.Genre.String, + Director: movie.Director.String, + Actors: movie.Actors.String, + ImdbRating: movie.ImdbRating.String, + Description: movie.Description, + CoverUrl: movie.File.FullExternalUrl(), + CoverId: movie.File.File, + AdditionalInformationUrl: movie.Link, + Location: movie.Location.String, }) } return &pb.ListMoviesReply{ diff --git a/server/backend/movie_test.go b/server/backend/movie_test.go index db06e585..5144a6cb 100644 --- a/server/backend/movie_test.go +++ b/server/backend/movie_test.go @@ -42,46 +42,50 @@ func (s *MovieSuite) SetupSuite() { var ( movie1 = pb.Movie{ - MovieId: 1, - Date: timestamppb.New(time.Now()), - Created: timestamppb.New(time.Now()), - Title: "Mission Impossible 4 - Ghost Protocol", - ReleaseYear: "2011", - Runtime: "133 min", - Genre: "Action, Adventure, Thriller", - Director: "Brad Bird", - Actors: "Tom Cruise, Jeremy Renner, Simon Pegg, Paula Patton", - ImdbRating: "7.4", - Description: "The IMF is shut down when it's implicated in the bombing of the Kremlin, causing Ethan Hunt and his new team to go rogue to clear their organization's name.", - CoverUrl: "https://api.tum.app/files/movie/mission_impossible_4.jpg", - CoverId: 1, - Link: "https://www.imdb.com/title/tt1229238/", + MovieId: 1, + Date: timestamppb.New(time.Now()), + Created: timestamppb.New(time.Now()), + Title: "Mission Impossible 4 - Ghost Protocol", + ReleaseYear: "2011", + Runtime: "133 min", + Genre: "Action, Adventure, Thriller", + Director: "Brad Bird", + Actors: "Tom Cruise, Jeremy Renner, Simon Pegg, Paula Patton", + ImdbRating: "7.4", + Description: "The IMF is shut down when it's implicated in the bombing of the Kremlin, causing Ethan Hunt and his new team to go rogue to clear their organization's name.", + CoverUrl: "https://api.tum.app/files/movie/mission_impossible_4.jpg", + CoverId: 1, + AdditionalInformationUrl: "https://www.imdb.com/title/tt1229238/", + Location: "Hörsaal 1200, Stammgelände", } movie2 = pb.Movie{ - MovieId: 2, - Date: timestamppb.New(time.Now()), - Created: timestamppb.New(time.Now()), - Title: "Mission Impossible 5 - Rogue Nation", - ReleaseYear: "2015", - Runtime: "131 min", - Genre: "Action, Adventure, Thriller", - Director: "Christopher McQuarrie", - Actors: "Tom Cruise, Jeremy Renner, Simon Pegg, Rebecca Ferguson", - ImdbRating: "7.4", - Description: "Ethan and his team take on their most impossible mission yet when they have to eradicate an international rogue organization as highly skilled as they are and committed to destroying the IMF.", - CoverUrl: "https://api.tum.app/files/movie/mission_impossible_5.jpg", - CoverId: 2, - Link: "https://www.imdb.com/title/tt2381249/", + MovieId: 2, + Date: timestamppb.New(time.Now()), + Created: timestamppb.New(time.Now()), + Title: "Mission Impossible 5 - Rogue Nation", + ReleaseYear: "2015", + Runtime: "131 min", + Genre: "Action, Adventure, Thriller", + Director: "Christopher McQuarrie", + Actors: "Tom Cruise, Jeremy Renner, Simon Pegg, Rebecca Ferguson", + ImdbRating: "7.4", + Description: "Ethan and his team take on their most impossible mission yet when they have to eradicate an international rogue organization as highly skilled as they are and committed to destroying the IMF.", + CoverUrl: "https://api.tum.app/files/movie/mission_impossible_5.jpg", + CoverId: 2, + AdditionalInformationUrl: "https://www.imdb.com/title/tt2381249/", + Location: "Hörsaal MW1801, Campus Garching", } ) +const ListMoviesQuery = "SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`kino`.`location`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ?" + func (s *MovieSuite) Test_ListMoviesAll() { server := CampusServer{db: s.DB} - s.mock.ExpectQuery("SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ?"). + s.mock.ExpectQuery(ListMoviesQuery). WithArgs(-1). - WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"}). - AddRow(movie2.MovieId, movie2.Date.AsTime(), movie2.Created.AsTime(), movie2.Title, movie2.ReleaseYear, movie2.Runtime, movie2.Genre, movie2.Director, movie2.Actors, movie2.ImdbRating, movie2.Description, nil, movie2.CoverId, movie2.Link, movie2.CoverId, "mission_impossible_5.jpg", "movie/", 1, "", 1). - AddRow(movie1.MovieId, movie1.Date.AsTime(), movie1.Created.AsTime(), movie1.Title, movie1.ReleaseYear, movie1.Runtime, movie1.Genre, movie1.Director, movie1.Actors, movie1.ImdbRating, movie1.Description, nil, movie1.CoverId, movie1.Link, movie1.CoverId, "mission_impossible_4.jpg", "movie/", 1, "", 1)) + WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "location", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"}). + AddRow(movie2.MovieId, movie2.Date.AsTime(), movie2.Created.AsTime(), movie2.Title, movie2.ReleaseYear, movie2.Runtime, movie2.Genre, movie2.Director, movie2.Actors, movie2.ImdbRating, movie2.Description, nil, movie2.CoverId, movie2.AdditionalInformationUrl, movie2.Location, movie2.CoverId, "mission_impossible_5.jpg", "movie/", 1, "", 1). + AddRow(movie1.MovieId, movie1.Date.AsTime(), movie1.Created.AsTime(), movie1.Title, movie1.ReleaseYear, movie1.Runtime, movie1.Genre, movie1.Director, movie1.Actors, movie1.ImdbRating, movie1.Description, nil, movie1.CoverId, movie1.AdditionalInformationUrl, movie1.Location, movie1.CoverId, "mission_impossible_4.jpg", "movie/", 1, "", 1)) response, err := server.ListMovies(context.Background(), &pb.ListMoviesRequest{LastId: -1}) require.NoError(s.T(), err) require.Equal(s.T(), &pb.ListMoviesReply{Movies: []*pb.Movie{&movie2, &movie1}}, response) @@ -89,10 +93,10 @@ func (s *MovieSuite) Test_ListMoviesAll() { func (s *MovieSuite) Test_ListMoviesOne() { server := CampusServer{db: s.DB} - s.mock.ExpectQuery("SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ?"). + s.mock.ExpectQuery(ListMoviesQuery). WithArgs(1). - WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"}). - AddRow(movie1.MovieId, movie1.Date.AsTime(), movie1.Created.AsTime(), movie1.Title, movie1.ReleaseYear, movie1.Runtime, movie1.Genre, movie1.Director, movie1.Actors, movie1.ImdbRating, movie1.Description, nil, movie1.CoverId, movie1.Link, movie1.CoverId, "mission_impossible_4.jpg", "movie/", 1, "", 1)) + WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "location", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"}). + AddRow(movie1.MovieId, movie1.Date.AsTime(), movie1.Created.AsTime(), movie1.Title, movie1.ReleaseYear, movie1.Runtime, movie1.Genre, movie1.Director, movie1.Actors, movie1.ImdbRating, movie1.Description, nil, movie1.CoverId, movie1.AdditionalInformationUrl, movie1.Location, movie1.CoverId, "mission_impossible_4.jpg", "movie/", 1, "", 1)) response, err := server.ListMovies(context.Background(), &pb.ListMoviesRequest{LastId: 1}) require.NoError(s.T(), err) require.Equal(s.T(), &pb.ListMoviesReply{Movies: []*pb.Movie{&movie1}}, response) @@ -100,9 +104,9 @@ func (s *MovieSuite) Test_ListMoviesOne() { func (s *MovieSuite) Test_ListMoviesNone() { server := CampusServer{db: s.DB} - s.mock.ExpectQuery("SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ?"). + s.mock.ExpectQuery(ListMoviesQuery). WithArgs(42). - WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"})) + WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "location", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"})) response, err := server.ListMovies(context.Background(), &pb.ListMoviesRequest{LastId: 42}) require.NoError(s.T(), err) require.Equal(s.T(), &pb.ListMoviesReply{Movies: []*pb.Movie(nil)}, response) diff --git a/server/model/kino.go b/server/model/kino.go index f8eec7a0..c1dc417d 100644 --- a/server/model/kino.go +++ b/server/model/kino.go @@ -12,17 +12,18 @@ type Kino struct { Date time.Time `gorm:"column:date;type:datetime;not null;"` Created time.Time `gorm:"column:created;type:timestamp;not null;default:CURRENT_TIMESTAMP"` Title string `gorm:"column:title;type:text;not null;"` - Year string `gorm:"column:year;type:varchar(4);not null;"` - Runtime string `gorm:"column:runtime;type:varchar(40);not null;"` - Genre string `gorm:"column:genre;type:varchar(100);not null;"` - Director string `gorm:"column:director;type:text;not null;"` - Actors string `gorm:"column:actors;type:text;not null;"` - ImdbRating string `gorm:"column:rating;type:varchar(4);not null;"` + Year null.String `gorm:"column:year;type:varchar(4)"` + Runtime null.String `gorm:"column:runtime;type:varchar(40)"` + Genre null.String `gorm:"column:genre;type:varchar(100)"` + Director null.String `gorm:"column:director;type:text"` + Actors null.String `gorm:"column:actors;type:text"` + ImdbRating null.String `gorm:"column:rating;type:varchar(4)"` Description string `gorm:"column:description;type:text;not null;"` Trailer null.String `gorm:"column:trailer"` FileID int64 `gorm:"column:cover"` File File `gorm:"foreignKey:FileID;references:file"` Link string `gorm:"column:link;type:varchar(190);not null;unique;"` + Location null.String `gorm:"column:location;default:null"` } // TableName sets the insert table name for this struct type From 4870d0261c2bf308176075003d084690c8e7149b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20K=C3=B6rber?= <56073945+jakobkoerber@users.noreply.github.com> Date: Mon, 30 Oct 2023 21:54:59 +0100 Subject: [PATCH 02/43] Fixes Workflow after Branch was renamed in Campus-Flutter (#281) --- .github/workflows/client_update.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client_update.yml b/.github/workflows/client_update.yml index 98e3bb33..c0ed831d 100644 --- a/.github/workflows/client_update.yml +++ b/.github/workflows/client_update.yml @@ -7,6 +7,8 @@ on: paths: - 'server/api/tumdev/campus_backend.proto' + workflow_dispatch: + jobs: deploy: runs-on: macos-latest @@ -36,7 +38,7 @@ jobs: echo "BRANCH_NAME=chore/update-protos-to-\$LATEST_TAG" >> $GITHUB_ENV - name: Clone Repository - run: git clone --depth=1 --branch=development https://runner:${{ secrets.CAMPUS_FLUTTER_TOKEN }}@github.com/${{ env.REPOSITORY }} ${{ env.FOLDER }} + run: git clone --depth=1 --branch=main https://runner:${{ secrets.CAMPUS_FLUTTER_TOKEN }}@github.com/${{ env.REPOSITORY }} ${{ env.FOLDER }} - name: Update Proto Files run: | @@ -74,7 +76,7 @@ jobs: --body "" \ --title "Chore: Update Protos to ${{ env.LATEST_TAG }}" \ --head "${{ env.BRANCH_NAME }}" \ - --base "development" + --base "main" - name: Error Message if: steps.commit.outcome != 'success' From b7f340200211376069eea6707a822d97777289e0 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 00:45:44 +0100 Subject: [PATCH 03/43] made sure all places use the same methodology to construct response arrays --- server/backend/cafeteria.go | 36 ++++++++++++++++-------------------- server/backend/news.go | 10 ++++------ server/backend/news_test.go | 10 ++-------- 3 files changed, 22 insertions(+), 34 deletions(-) diff --git a/server/backend/cafeteria.go b/server/backend/cafeteria.go index 947873ab..18e8a2a2 100644 --- a/server/backend/cafeteria.go +++ b/server/backend/cafeteria.go @@ -113,20 +113,17 @@ func queryLastCafeteriaRatingsWithLimit(input *pb.ListCanteenRatingsRequest, caf log.WithError(err).Error("while querying last cafeteria ratings.") return make([]*pb.SingleRatingReply, 0) } - ratingResults := make([]*pb.SingleRatingReply, len(ratings)) - - for i, v := range ratings { - - tagRatings := queryTagRatingsOverviewForRating(v.CafeteriaRating, CAFETERIA, tx) - ratingResults[i] = &pb.SingleRatingReply{ + var resp []*pb.SingleRatingReply + for _, v := range ratings { + resp = append(resp, &pb.SingleRatingReply{ Points: v.Points, Comment: v.Comment, Image: getImageToBytes(v.Image), Visited: timestamppb.New(v.Timestamp), - RatingTags: tagRatings, - } + RatingTags: queryTagRatingsOverviewForRating(v.CafeteriaRating, CAFETERIA, tx), + }) } - return ratingResults + return resp } else { return make([]*pb.SingleRatingReply, 0) } @@ -217,18 +214,17 @@ func queryLastDishRatingsWithLimit(input *pb.GetDishRatingsRequest, cafeteriaID log.WithError(err).Error("while querying last dish ratings from Database.") return make([]*pb.SingleRatingReply, 0) } - ratingResults := make([]*pb.SingleRatingReply, len(ratings)) - - for i, v := range ratings { - ratingResults[i] = &pb.SingleRatingReply{ + var resp []*pb.SingleRatingReply + for _, v := range ratings { + resp = append(resp, &pb.SingleRatingReply{ Points: v.Points, Comment: v.Comment, RatingTags: queryTagRatingsOverviewForRating(v.DishRating, DISH, tx), Image: getImageToBytes(v.Image), Visited: timestamppb.New(v.Timestamp), - } + }) } - return ratingResults + return resp } else { return make([]*pb.SingleRatingReply, 0) } @@ -305,18 +301,18 @@ func queryTags(cafeteriaID int32, dishID int32, ratingType ModelType, tx *gorm.D } //needed since the gRPC element does not specify column names - cannot be directly queried into the grpc message object. - elements := make([]*pb.RatingTagResult, len(results)) - for i, v := range results { - elements[i] = &pb.RatingTagResult{ + var resp []*pb.RatingTagResult + for _, v := range results { + resp = append(resp, &pb.RatingTagResult{ TagId: v.TagId, Avg: v.Average, Std: v.Std, Min: v.Min, Max: v.Max, - } + }) } - return elements + return resp } // queryTagRatingOverviewForRating diff --git a/server/backend/news.go b/server/backend/news.go index f8f29847..fb2ccf64 100644 --- a/server/backend/news.go +++ b/server/backend/news.go @@ -29,7 +29,6 @@ func (s *CampusServer) ListNewsSources(ctx context.Context, _ *pb.ListNewsSource var resp []*pb.NewsSource for _, source := range sources { - log.WithField("title", source.Title).Trace("sending news source") resp = append(resp, &pb.NewsSource{ Source: fmt.Sprintf("%d", source.Source), Title: source.Title, @@ -60,14 +59,13 @@ func (s *CampusServer) ListNews(ctx context.Context, req *pb.ListNewsRequest) (* return nil, status.Error(codes.Internal, "could not ListNews") } - resp := make([]*pb.News, len(newsEntries)) - for i, item := range newsEntries { - log.WithField("title", item.Title).Trace("sending news") + var resp []*pb.News + for _, item := range newsEntries { imgUrl := "" if item.File != nil { imgUrl = item.File.FullExternalUrl() } - resp[i] = &pb.News{ + resp = append(resp, &pb.News{ Id: item.News, Title: item.Title, Text: item.Description, @@ -78,7 +76,7 @@ func (s *CampusServer) ListNews(ctx context.Context, req *pb.ListNewsRequest) (* SourceIconUrl: item.NewsSource.File.FullExternalUrl(), Created: timestamppb.New(item.Created), Date: timestamppb.New(item.Date), - } + }) } return &pb.ListNewsReply{News: resp}, nil } diff --git a/server/backend/news_test.go b/server/backend/news_test.go index 62922c7c..3a892310 100644 --- a/server/backend/news_test.go +++ b/server/backend/news_test.go @@ -152,10 +152,7 @@ func (s *NewsSuite) Test_ListNewsNone_withFilters() { server := CampusServer{db: s.DB, deviceBuf: s.deviceBuf} response, err := server.ListNews(meta, &pb.ListNewsRequest{NewsSource: 1, LastNewsId: 2}) require.NoError(s.T(), err) - expectedResp := &pb.ListNewsReply{ - News: []*pb.News{}, - } - require.Equal(s.T(), expectedResp, response) + require.Equal(s.T(), &pb.ListNewsReply{News: nil}, response) } func (s *NewsSuite) Test_ListNewsNone() { s.mock.ExpectQuery(regexp.QuoteMeta(ExpectedListNewsQuery)). @@ -165,10 +162,7 @@ func (s *NewsSuite) Test_ListNewsNone() { server := CampusServer{db: s.DB, deviceBuf: s.deviceBuf} response, err := server.ListNews(meta, &pb.ListNewsRequest{}) require.NoError(s.T(), err) - expectedResp := &pb.ListNewsReply{ - News: []*pb.News{}, - } - require.Equal(s.T(), expectedResp, response) + require.Equal(s.T(), &pb.ListNewsReply{News: nil}, response) } func (s *NewsSuite) Test_ListNewsMultiple() { n1 := news1() From f0863303c84a951fab60056209840f9d8d497b92 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 00:46:29 +0100 Subject: [PATCH 04/43] added a order statement for the movie query --- server/backend/movie.go | 2 +- server/backend/movie_test.go | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/server/backend/movie.go b/server/backend/movie.go index e692b0c6..2e6f7df4 100644 --- a/server/backend/movie.go +++ b/server/backend/movie.go @@ -13,7 +13,7 @@ import ( func (s *CampusServer) ListMovies(ctx context.Context, req *pb.ListMoviesRequest) (*pb.ListMoviesReply, error) { var movies []model.Kino - tx := s.db.WithContext(ctx).Joins("File") + tx := s.db.WithContext(ctx).Joins("File").Order("date DESC") if req.OldestDateAt.GetSeconds() != 0 || req.OldestDateAt.GetNanos() != 0 { tx = tx.Where("date > ?", req.OldestDateAt.AsTime()) } diff --git a/server/backend/movie_test.go b/server/backend/movie_test.go index 5144a6cb..04f9b00d 100644 --- a/server/backend/movie_test.go +++ b/server/backend/movie_test.go @@ -3,6 +3,7 @@ package backend import ( "context" "database/sql" + "regexp" "testing" "time" @@ -77,11 +78,11 @@ var ( } ) -const ListMoviesQuery = "SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`kino`.`location`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ?" +const ListMoviesQuery = "SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`kino`.`location`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ? ORDER BY date DESC" func (s *MovieSuite) Test_ListMoviesAll() { server := CampusServer{db: s.DB} - s.mock.ExpectQuery(ListMoviesQuery). + s.mock.ExpectQuery(regexp.QuoteMeta(ListMoviesQuery)). WithArgs(-1). WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "location", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"}). AddRow(movie2.MovieId, movie2.Date.AsTime(), movie2.Created.AsTime(), movie2.Title, movie2.ReleaseYear, movie2.Runtime, movie2.Genre, movie2.Director, movie2.Actors, movie2.ImdbRating, movie2.Description, nil, movie2.CoverId, movie2.AdditionalInformationUrl, movie2.Location, movie2.CoverId, "mission_impossible_5.jpg", "movie/", 1, "", 1). @@ -93,7 +94,7 @@ func (s *MovieSuite) Test_ListMoviesAll() { func (s *MovieSuite) Test_ListMoviesOne() { server := CampusServer{db: s.DB} - s.mock.ExpectQuery(ListMoviesQuery). + s.mock.ExpectQuery(regexp.QuoteMeta(ListMoviesQuery)). WithArgs(1). WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "location", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"}). AddRow(movie1.MovieId, movie1.Date.AsTime(), movie1.Created.AsTime(), movie1.Title, movie1.ReleaseYear, movie1.Runtime, movie1.Genre, movie1.Director, movie1.Actors, movie1.ImdbRating, movie1.Description, nil, movie1.CoverId, movie1.AdditionalInformationUrl, movie1.Location, movie1.CoverId, "mission_impossible_4.jpg", "movie/", 1, "", 1)) @@ -104,7 +105,7 @@ func (s *MovieSuite) Test_ListMoviesOne() { func (s *MovieSuite) Test_ListMoviesNone() { server := CampusServer{db: s.DB} - s.mock.ExpectQuery(ListMoviesQuery). + s.mock.ExpectQuery(regexp.QuoteMeta(ListMoviesQuery)). WithArgs(42). WillReturnRows(sqlmock.NewRows([]string{"kino", "date", "created", "title", "year", "runtime", "genre", "director", "actors", "rating", "description", "trailer", "cover", "link", "location", "File__file", "File__name", "File__path", "File__downloads", "File__url", "File__downloaded"})) response, err := server.ListMovies(context.Background(), &pb.ListMoviesRequest{LastId: 42}) From 689a204f384e9064a60a195ea19b3db9d6dd04e7 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 01:50:11 +0100 Subject: [PATCH 05/43] made sure that the tu film does download only the bigger resolution images --- server/backend/cron/movie_parsers/tufilm.go | 4 +++- server/backend/cron/movie_parsers/tufilm_test.go | 8 ++++---- server/backend/cron/movies.go | 11 ++++++++--- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/server/backend/cron/movie_parsers/tufilm.go b/server/backend/cron/movie_parsers/tufilm.go index 0024fdc8..5daee1d4 100644 --- a/server/backend/cron/movie_parsers/tufilm.go +++ b/server/backend/cron/movie_parsers/tufilm.go @@ -136,9 +136,11 @@ func parseShortenedDescription(doc *goquery.Document) string { func parseImageUrl(doc *goquery.Document) string { href, exists := doc.Find("img.poster").First().Attr("src") if !exists { - return "https://www.tu-film.de/img/film/poster/.sized.berraschungsfilm.jpg" + return "https://www.tu-film.de/img/film/poster/berraschungsfilm.jpg" } sanitisedHref := bluemonday.StrictPolicy().Sanitize(href) + sanitisedHref = strings.ReplaceAll(sanitisedHref, "/img/film/poster/.sized.", "/img/film/poster/") + sanitisedHref = strings.ReplaceAll(sanitisedHref, "/img/film/poster/.thumb.", "/img/film/poster/") return "https://www.tu-film.de" + sanitisedHref } diff --git a/server/backend/cron/movie_parsers/tufilm_test.go b/server/backend/cron/movie_parsers/tufilm_test.go index ee30dc81..27d27a8a 100644 --- a/server/backend/cron/movie_parsers/tufilm_test.go +++ b/server/backend/cron/movie_parsers/tufilm_test.go @@ -29,7 +29,7 @@ func TestOppenheimer(t *testing.T) { "In the further course of the film Lewis Strauss is to be confirmed as Secretary of Commerce in the cabinet of President Dwight D. Eisenhower. Soon it is also about his relations with Oppenheimer after the war, to whom he was superior as head of the Atomic Energy Authority. Thereby it concerns above all the reproaches to old connection to the communism which Oppenheimer is accused of." comment := "An intellectual thriller that is a masterpiece of image and word, of complex ideas made manifest, and all kept at a very human level to maintain constant immediacy. (Andrea Chase, Killer Movie Reviews)" expected := TuFilmWebsiteInformation{ - ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.Oppenheimer.jpg", + ImageUrl: "https://www.tu-film.de/img/film/poster/Oppenheimer.jpg", ShortenedDescription: fmt.Sprintf("<b>%s<b>\n\n%s\n\n<i>%s<i>", header, description, comment), Director: null.StringFrom("Christopher Nolan"), Actors: null.StringFrom("Cillian Murphy, Emily Blunt, Matt Damon"), @@ -52,7 +52,7 @@ func TestBabylon(t *testing.T) { "In the end, there is one thing Hollywood does best: Make movies about themselves. Did they forget to mention that these movies were made for nazi germany? Is all this crime and perversion really ok because the movies are just that good? Don't think about it too much, you will still enjoy it." comment := "Chazelle’s film commemorates the era’s hubris as it indulges in a bit of its own. This is how a world ends. Not with a whimper but a great deal of banging, baby. And vomiting. And snorting. (Irish Times)" expected := TuFilmWebsiteInformation{ - ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.Babylon.jpg", + ImageUrl: "https://www.tu-film.de/img/film/poster/Babylon.jpg", ShortenedDescription: fmt.Sprintf("<b>%s<b>\n\n%s\n\n<i>%s<i>", header, description, comment), Director: null.StringFrom("Damien Chazelle"), Actors: null.StringFrom("Brad Pitt, Margot Robbie, Jean Smart"), @@ -74,7 +74,7 @@ func TestSurpriseFilm(t *testing.T) { "Seid also gespannt, welche Perle wir für euch aus dem Zauberhut ziehen! Der Film wird zwei Wochen davor über unsere üblichen Informationskanäle bekannt gegeben.\n" + "Habt ihr Meinungen dazu? Dann lasst es uns wissen und schreibt uns an ueberraschungsfilm@tu-film.de" expected := TuFilmWebsiteInformation{ - ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.berraschungsfilm.jpg", + ImageUrl: "https://www.tu-film.de/img/film/poster/berraschungsfilm.jpg", ShortenedDescription: fmt.Sprintf("<b>%s<b>\n\n%s", header, description), } info, err := parseWebsiteInformation(doc) @@ -86,7 +86,7 @@ func TestNoExtration(t *testing.T) { doc, err := goquery.NewDocumentFromReader(strings.NewReader("<html></html>")) require.NoError(t, err) expected := TuFilmWebsiteInformation{ - ImageUrl: "https://www.tu-film.de/img/film/poster/.sized.berraschungsfilm.jpg", + ImageUrl: "https://www.tu-film.de/img/film/poster/berraschungsfilm.jpg", ShortenedDescription: "Surprise yourself", } info, err := parseWebsiteInformation(doc) diff --git a/server/backend/cron/movies.go b/server/backend/cron/movies.go index 3de7a1cf..78b84493 100644 --- a/server/backend/cron/movies.go +++ b/server/backend/cron/movies.go @@ -1,8 +1,10 @@ package cron import ( + "fmt" "regexp" "slices" + "strings" "time" "github.com/TUM-Dev/Campus-Backend/server/backend/cron/movie_parsers" @@ -68,10 +70,13 @@ func (c *CronService) movieCron() error { Trailer: movieInformation.TrailerUrl, Link: item.Link, } + // register the preview file for download + seps := strings.SplitAfter(item.Enclosure.Url, ".") previewFile := model.File{ - Name: item.Title, - Path: MovieImageDirectory, - URL: null.StringFrom(item.Enclosure.Url), + Name: fmt.Sprintf("%s.%s", strings.TrimSpace(item.Title), seps[len(seps)-1]), + Path: MovieImageDirectory, + URL: null.StringFrom(item.Enclosure.Url), + Downloaded: null.BoolFrom(false), } if movieInformation.ImdbID.ValueOrZero() != "" { omdbMovie, err := movie_parsers.GetOmdbMovie(movieInformation.ImdbID.ValueOrZero()) From 8611f8149ecfec67c318bbe040fb53d4b6980a34 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 02:36:30 +0100 Subject: [PATCH 06/43] made sure that files are successfully marked as done once done --- server/backend/cron/file_download.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/backend/cron/file_download.go b/server/backend/cron/file_download.go index 8b2706a0..ba8d9e3d 100644 --- a/server/backend/cron/file_download.go +++ b/server/backend/cron/file_download.go @@ -2,6 +2,7 @@ package cron import ( "errors" + "github.com/guregu/null" "io" "net/http" "os" @@ -30,7 +31,8 @@ func (c *CronService) fileDownloadCron() error { fields := log.Fields{"url": file.URL.String, "dstPath": dstPath} log.WithFields(fields).Info("downloading file") - if err = tx.Model(&model.File{File: file.File}).Update("downloads", file.Downloads+1).Error; err != nil { + file.Downloads = file.Downloads + 1 + if err = tx.Save(&file).Error; err != nil { log.WithError(err).WithFields(fields).Error("Could not set update the download-count") continue } @@ -48,7 +50,8 @@ func (c *CronService) fileDownloadCron() error { continue } // everything went well => we can mark the file as downloaded - if err = tx.Model(&model.File{URL: file.URL}).Update("downloaded", true).Error; err != nil { + file.Downloaded = null.BoolFrom(true) + if err = tx.Save(&file).Error; err != nil { log.WithError(err).WithFields(fields).Error("Could not set image to downloaded.") continue } From d256ed3c8589d33c4b6f8ef72181a6e9bfb98698 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 02:40:44 +0100 Subject: [PATCH 07/43] simplified the way hrefs for tufilms are parsed --- server/backend/cron/movie_parsers/tufilm.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/backend/cron/movie_parsers/tufilm.go b/server/backend/cron/movie_parsers/tufilm.go index 5daee1d4..c6a56a00 100644 --- a/server/backend/cron/movie_parsers/tufilm.go +++ b/server/backend/cron/movie_parsers/tufilm.go @@ -139,8 +139,8 @@ func parseImageUrl(doc *goquery.Document) string { return "https://www.tu-film.de/img/film/poster/berraschungsfilm.jpg" } sanitisedHref := bluemonday.StrictPolicy().Sanitize(href) - sanitisedHref = strings.ReplaceAll(sanitisedHref, "/img/film/poster/.sized.", "/img/film/poster/") - sanitisedHref = strings.ReplaceAll(sanitisedHref, "/img/film/poster/.thumb.", "/img/film/poster/") + sanitisedHref = strings.ReplaceAll(sanitisedHref, "poster/.sized.", "poster/") + sanitisedHref = strings.ReplaceAll(sanitisedHref, "poster/.thumb.", "poster/") return "https://www.tu-film.de" + sanitisedHref } From 81cb35398ee18a3fcdd7dc56ec9f221c93657a37 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 02:47:00 +0100 Subject: [PATCH 08/43] fixed info logs always being posted as warn --- server/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.go b/server/main.go index 6fd3c114..9b62bd22 100644 --- a/server/main.go +++ b/server/main.go @@ -116,7 +116,7 @@ func UnaryRequestLogger(ctx context.Context, req interface{}, info *grpc.UnarySe start := time.Now() resp, err := handler(ctx, req) fields := log.Fields{"elapsed": time.Since(start), "method": strings.TrimPrefix(info.FullMethod, "/api.Campus/")} - if err != nil { + if err == nil { log.WithFields(fields).Info("request") } else { log.WithFields(fields).WithError(err).Warn("request") From 79c664ab914592a24fb7120fd48ece2321e008af Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 17:34:47 +0100 Subject: [PATCH 09/43] changed the movie sort order --- server/backend/movie.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/backend/movie.go b/server/backend/movie.go index 2e6f7df4..94216bfc 100644 --- a/server/backend/movie.go +++ b/server/backend/movie.go @@ -13,7 +13,7 @@ import ( func (s *CampusServer) ListMovies(ctx context.Context, req *pb.ListMoviesRequest) (*pb.ListMoviesReply, error) { var movies []model.Kino - tx := s.db.WithContext(ctx).Joins("File").Order("date DESC") + tx := s.db.WithContext(ctx).Joins("File").Order("date ASC") if req.OldestDateAt.GetSeconds() != 0 || req.OldestDateAt.GetNanos() != 0 { tx = tx.Where("date > ?", req.OldestDateAt.AsTime()) } From 8b2c28cd44d5e4f093bc695cd9e808148531bf37 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 19:00:59 +0100 Subject: [PATCH 10/43] fixed a typo in the testcases --- server/backend/movie_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/backend/movie_test.go b/server/backend/movie_test.go index 04f9b00d..c6049628 100644 --- a/server/backend/movie_test.go +++ b/server/backend/movie_test.go @@ -78,7 +78,7 @@ var ( } ) -const ListMoviesQuery = "SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`kino`.`location`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ? ORDER BY date DESC" +const ListMoviesQuery = "SELECT `kino`.`kino`,`kino`.`date`,`kino`.`created`,`kino`.`title`,`kino`.`year`,`kino`.`runtime`,`kino`.`genre`,`kino`.`director`,`kino`.`actors`,`kino`.`rating`,`kino`.`description`,`kino`.`trailer`,`kino`.`cover`,`kino`.`link`,`kino`.`location`,`File`.`file` AS `File__file`,`File`.`name` AS `File__name`,`File`.`path` AS `File__path`,`File`.`downloads` AS `File__downloads`,`File`.`url` AS `File__url`,`File`.`downloaded` AS `File__downloaded` FROM `kino` LEFT JOIN `files` `File` ON `kino`.`cover` = `File`.`file` WHERE kino > ? ORDER BY date ASC" func (s *MovieSuite) Test_ListMoviesAll() { server := CampusServer{db: s.DB} From 85309ded0612023863176b45b87d2061350667d9 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Wed, 1 Nov 2023 19:06:15 +0100 Subject: [PATCH 11/43] fixed a linting issue --- server/backend/cron/file_download.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/backend/cron/file_download.go b/server/backend/cron/file_download.go index ba8d9e3d..2a051666 100644 --- a/server/backend/cron/file_download.go +++ b/server/backend/cron/file_download.go @@ -2,13 +2,14 @@ package cron import ( "errors" - "github.com/guregu/null" "io" "net/http" "os" "path" "strings" + "github.com/guregu/null" + "github.com/TUM-Dev/Campus-Backend/server/model" "github.com/disintegration/imaging" "github.com/gabriel-vasile/mimetype" From 1235b55115e3d8b372199bb6ae3076bc6a202632 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:08:48 +0000 Subject: [PATCH 12/43] Bump ls-lint/action from 2.0.1 to 2.2.2 (#283) Bumps [ls-lint/action](https://github.com/ls-lint/action) from 2.0.1 to 2.2.2. - [Release notes](https://github.com/ls-lint/action/releases) - [Commits](https://github.com/ls-lint/action/compare/v2.0.1...v2.2.2) --- updated-dependencies: - dependency-name: ls-lint/action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d2ed4b49..1b4c1a81 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -31,6 +31,6 @@ jobs: - run: bash server/api/installBuf.bash - name: pre-commit uses: pre-commit/action@v3.0.0 - - uses: ls-lint/action@v2.0.1 + - uses: ls-lint/action@v2.2.2 with: config: .ls-lint.yaml From d8f75aef4bcc1b7d1839a69decd9b4c234e561c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:12:48 +0100 Subject: [PATCH 13/43] Bump actions/checkout from 3 to 4 (#282) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga <frank@elsinga.de> --- .github/workflows/client_update.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/client_update.yml b/.github/workflows/client_update.yml index c0ed831d..a91a0256 100644 --- a/.github/workflows/client_update.yml +++ b/.github/workflows/client_update.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Fetch Changes - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # Checkout everything to get access to the tags ref: main From fd853d7d99f579b520f209b06ca7a1ca0913bdcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:14:49 +0000 Subject: [PATCH 14/43] Bump google.golang.org/grpc from 1.58.3 to 1.59.0 in /client (#284) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.3 to 1.59.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.58.3...v1.59.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- client/go.mod | 2 +- client/go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/go.mod b/client/go.mod index c848300e..534f165c 100644 --- a/client/go.mod +++ b/client/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/TUM-Dev/Campus-Backend/server v0.0.0-20231009133538-1a7f37e5f27c github.com/sirupsen/logrus v1.9.3 - google.golang.org/grpc v1.58.3 + google.golang.org/grpc v1.59.0 ) require ( diff --git a/client/go.sum b/client/go.sum index 65f8111a..30d9ed58 100644 --- a/client/go.sum +++ b/client/go.sum @@ -3,8 +3,8 @@ github.com/TUM-Dev/Campus-Backend/server v0.0.0-20231009133538-1a7f37e5f27c/go.m github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -35,8 +35,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1: google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From 4b67bd4d8efa8b49a7fa2ede5183ecb59dd98cef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:17:05 +0000 Subject: [PATCH 15/43] Bump github.com/gabriel-vasile/mimetype from 1.4.2 to 1.4.3 in /server (#285) Bumps [github.com/gabriel-vasile/mimetype](https://github.com/gabriel-vasile/mimetype) from 1.4.2 to 1.4.3. - [Release notes](https://github.com/gabriel-vasile/mimetype/releases) - [Commits](https://github.com/gabriel-vasile/mimetype/compare/v1.4.2...v1.4.3) --- updated-dependencies: - dependency-name: github.com/gabriel-vasile/mimetype dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index 0938af4c..b8050394 100644 --- a/server/go.mod +++ b/server/go.mod @@ -6,7 +6,7 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/PuerkitoBio/goquery v1.8.1 github.com/disintegration/imaging v1.6.2 - github.com/gabriel-vasile/mimetype v1.4.2 + github.com/gabriel-vasile/mimetype v1.4.3 github.com/getsentry/sentry-go v0.24.1 github.com/go-gormigrate/gormigrate/v2 v2.1.1 github.com/gofrs/uuid/v5 v5.0.0 diff --git a/server/go.sum b/server/go.sum index 6a6d7059..bb87cb8e 100644 --- a/server/go.sum +++ b/server/go.sum @@ -112,8 +112,8 @@ github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= -github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= github.com/getsentry/sentry-go v0.24.1 h1:W6/0GyTy8J6ge6lVCc94WB6Gx2ZuLrgopnn9w8Hiwuk= github.com/getsentry/sentry-go v0.24.1/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= From 6f5afe67579bc1659f39ee92c6bcfe4172dc1637 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:20:20 +0100 Subject: [PATCH 16/43] Bump github.com/microcosm-cc/bluemonday from 1.0.25 to 1.0.26 in /server (#289) Bumps [github.com/microcosm-cc/bluemonday](https://github.com/microcosm-cc/bluemonday) from 1.0.25 to 1.0.26. - [Release notes](https://github.com/microcosm-cc/bluemonday/releases) - [Commits](https://github.com/microcosm-cc/bluemonday/compare/v1.0.25...v1.0.26) --- updated-dependencies: - dependency-name: github.com/microcosm-cc/bluemonday dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga <frank@elsinga.de> --- server/go.mod | 4 ++-- server/go.sum | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/server/go.mod b/server/go.mod index b8050394..3f231eec 100644 --- a/server/go.mod +++ b/server/go.mod @@ -14,7 +14,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 github.com/guregu/null v4.0.0+incompatible github.com/makasim/sentryhook v0.4.2 - github.com/microcosm-cc/bluemonday v1.0.25 + github.com/microcosm-cc/bluemonday v1.0.26 github.com/mmcdole/gofeed v1.2.1 github.com/onrik/gorm-logrus v0.5.0 github.com/prometheus/client_golang v1.17.0 @@ -32,7 +32,7 @@ require ( ) require ( - github.com/andybalholm/cascadia v1.3.1 // indirect + github.com/andybalholm/cascadia v1.3.2 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/server/go.sum b/server/go.sum index bb87cb8e..e30944a0 100644 --- a/server/go.sum +++ b/server/go.sum @@ -51,8 +51,9 @@ github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJs github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= +github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= +github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= @@ -324,8 +325,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfr github.com/mediocregopher/radix/v3 v3.8.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= -github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= -github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= +github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= +github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -556,6 +557,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -606,7 +608,9 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -634,6 +638,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -709,11 +714,13 @@ golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -725,6 +732,7 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -788,6 +796,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From d15236dc50b1f896987948ef9a3d30b744b4fe0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:22:20 +0100 Subject: [PATCH 17/43] Bump gorm.io/driver/mysql from 1.5.1 to 1.5.2 in /server (#286) Bumps [gorm.io/driver/mysql](https://github.com/go-gorm/mysql) from 1.5.1 to 1.5.2. - [Commits](https://github.com/go-gorm/mysql/compare/v1.5.1...v1.5.2) --- updated-dependencies: - dependency-name: gorm.io/driver/mysql dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga <frank@elsinga.de> --- server/go.mod | 2 +- server/go.sum | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/server/go.mod b/server/go.mod index 3f231eec..e9242cbb 100644 --- a/server/go.mod +++ b/server/go.mod @@ -27,7 +27,7 @@ require ( google.golang.org/grpc v1.58.3 google.golang.org/protobuf v1.31.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df - gorm.io/driver/mysql v1.5.1 + gorm.io/driver/mysql v1.5.2 gorm.io/gorm v1.25.4 ) diff --git a/server/go.sum b/server/go.sum index e30944a0..aa6b2ebf 100644 --- a/server/go.sum +++ b/server/go.sum @@ -940,9 +940,9 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= -gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= -gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs= +gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8= +gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From f710b58685b5c83115a4668a18467cd800450e8a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:25:43 +0000 Subject: [PATCH 18/43] Bump google.golang.org/grpc from 1.58.3 to 1.59.0 in /server (#288) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.58.3 to 1.59.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.58.3...v1.59.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga <frank@elsinga.de> --- server/go.mod | 4 ++-- server/go.sum | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/server/go.mod b/server/go.mod index e9242cbb..1699f52d 100644 --- a/server/go.mod +++ b/server/go.mod @@ -24,7 +24,7 @@ require ( golang.org/x/net v0.17.0 golang.org/x/sync v0.3.0 google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb - google.golang.org/grpc v1.58.3 + google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.5.2 @@ -54,7 +54,7 @@ require ( golang.org/x/image v0.5.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/server/go.sum b/server/go.sum index aa6b2ebf..b3d3d291 100644 --- a/server/go.sum +++ b/server/go.sum @@ -151,8 +151,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -871,8 +871,8 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= @@ -897,8 +897,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From 8efc4bec6fdd68c06aec8b42abe51f8d092ffcda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Nov 2023 18:29:12 +0000 Subject: [PATCH 19/43] Bump github.com/getsentry/sentry-go from 0.24.1 to 0.25.0 in /server (#287) Bumps [github.com/getsentry/sentry-go](https://github.com/getsentry/sentry-go) from 0.24.1 to 0.25.0. - [Release notes](https://github.com/getsentry/sentry-go/releases) - [Changelog](https://github.com/getsentry/sentry-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-go/compare/v0.24.1...v0.25.0) --- updated-dependencies: - dependency-name: github.com/getsentry/sentry-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index 1699f52d..4210c27e 100644 --- a/server/go.mod +++ b/server/go.mod @@ -7,7 +7,7 @@ require ( github.com/PuerkitoBio/goquery v1.8.1 github.com/disintegration/imaging v1.6.2 github.com/gabriel-vasile/mimetype v1.4.3 - github.com/getsentry/sentry-go v0.24.1 + github.com/getsentry/sentry-go v0.25.0 github.com/go-gormigrate/gormigrate/v2 v2.1.1 github.com/gofrs/uuid/v5 v5.0.0 github.com/golang-jwt/jwt v3.2.2+incompatible diff --git a/server/go.sum b/server/go.sum index b3d3d291..7209d332 100644 --- a/server/go.sum +++ b/server/go.sum @@ -116,8 +116,8 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= -github.com/getsentry/sentry-go v0.24.1 h1:W6/0GyTy8J6ge6lVCc94WB6Gx2ZuLrgopnn9w8Hiwuk= -github.com/getsentry/sentry-go v0.24.1/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= +github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= From b2895ed1cb5a50048e81b5f33ad03917b47ad5cd Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Fri, 3 Nov 2023 08:54:57 +0100 Subject: [PATCH 20/43] reduced the requested resources --- .../charts/backend/templates/deployments/backend-v2.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/charts/backend/templates/deployments/backend-v2.yaml b/deployment/charts/backend/templates/deployments/backend-v2.yaml index a96ffd80..fee6eee3 100644 --- a/deployment/charts/backend/templates/deployments/backend-v2.yaml +++ b/deployment/charts/backend/templates/deployments/backend-v2.yaml @@ -91,8 +91,8 @@ spec: readOnlyRootFilesystem: true resources: requests: - cpu: 1000m - memory: 100Mi + cpu: 100m + memory: 50Mi limits: memory: 500Mi livenessProbe: From 22203e1a36e0fc94878d0d17a0f168fa5fdae98d Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Fri, 3 Nov 2023 08:58:20 +0100 Subject: [PATCH 21/43] added a priority class --- .../charts/backend/templates/deployments/backend-v1.yaml | 1 + .../charts/backend/templates/deployments/backend-v2.yaml | 1 + deployment/charts/backend/templates/priority-class.yaml | 7 +++++++ 3 files changed, 9 insertions(+) create mode 100644 deployment/charts/backend/templates/priority-class.yaml diff --git a/deployment/charts/backend/templates/deployments/backend-v1.yaml b/deployment/charts/backend/templates/deployments/backend-v1.yaml index fdf2b976..ff0dd734 100644 --- a/deployment/charts/backend/templates/deployments/backend-v1.yaml +++ b/deployment/charts/backend/templates/deployments/backend-v1.yaml @@ -7,6 +7,7 @@ metadata: app.kubernetes.io/name: backend-v1 namespace: {{ $.Values.namespace }} spec: + priorityClassName: tca-backend revisionHistoryLimit: 0 selector: matchLabels: diff --git a/deployment/charts/backend/templates/deployments/backend-v2.yaml b/deployment/charts/backend/templates/deployments/backend-v2.yaml index fee6eee3..b9dca313 100644 --- a/deployment/charts/backend/templates/deployments/backend-v2.yaml +++ b/deployment/charts/backend/templates/deployments/backend-v2.yaml @@ -8,6 +8,7 @@ metadata: app.kubernetes.io/name: backend-v2 namespace: {{ $.Values.namespace }} spec: + priorityClassName: tca-backend revisionHistoryLimit: 0 selector: matchLabels: diff --git a/deployment/charts/backend/templates/priority-class.yaml b/deployment/charts/backend/templates/priority-class.yaml new file mode 100644 index 00000000..928ab40c --- /dev/null +++ b/deployment/charts/backend/templates/priority-class.yaml @@ -0,0 +1,7 @@ +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: tca-backend +value: 1000 +globalDefault: false +description: This priority class should be used for the tca-backend. From 283e58b514ae2464f1ac018973f5c19044d7b14f Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Fri, 3 Nov 2023 09:01:41 +0100 Subject: [PATCH 22/43] fixed the indent level of priorityClassName --- deployment/charts/backend/templates/deployments/backend-v1.yaml | 2 +- deployment/charts/backend/templates/deployments/backend-v2.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/charts/backend/templates/deployments/backend-v1.yaml b/deployment/charts/backend/templates/deployments/backend-v1.yaml index ff0dd734..4371a432 100644 --- a/deployment/charts/backend/templates/deployments/backend-v1.yaml +++ b/deployment/charts/backend/templates/deployments/backend-v1.yaml @@ -7,7 +7,6 @@ metadata: app.kubernetes.io/name: backend-v1 namespace: {{ $.Values.namespace }} spec: - priorityClassName: tca-backend revisionHistoryLimit: 0 selector: matchLabels: @@ -24,6 +23,7 @@ spec: app.kubernetes.io/part-of: tum-campus-app app.kubernetes.io/name: backend-v1 spec: + priorityClassName: tca-backend volumes: - name: legacybackend-config secret: diff --git a/deployment/charts/backend/templates/deployments/backend-v2.yaml b/deployment/charts/backend/templates/deployments/backend-v2.yaml index b9dca313..725a40c4 100644 --- a/deployment/charts/backend/templates/deployments/backend-v2.yaml +++ b/deployment/charts/backend/templates/deployments/backend-v2.yaml @@ -8,7 +8,6 @@ metadata: app.kubernetes.io/name: backend-v2 namespace: {{ $.Values.namespace }} spec: - priorityClassName: tca-backend revisionHistoryLimit: 0 selector: matchLabels: @@ -25,6 +24,7 @@ spec: app.kubernetes.io/part-of: tum-campus-app app.kubernetes.io/name: backend-v2 spec: + priorityClassName: tca-backend volumes: - name: storage-vol persistentVolumeClaim: From 03a96082bfbcb6d08fa82f9194a1ce12d6a8e29e Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Fri, 3 Nov 2023 09:06:48 +0100 Subject: [PATCH 23/43] fixed the size of the pvc being too small --- deployment/charts/backend/templates/backend-pvc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/charts/backend/templates/backend-pvc.yaml b/deployment/charts/backend/templates/backend-pvc.yaml index 92b71c67..702e26dc 100644 --- a/deployment/charts/backend/templates/backend-pvc.yaml +++ b/deployment/charts/backend/templates/backend-pvc.yaml @@ -12,4 +12,4 @@ spec: - ReadWriteMany resources: requests: - storage: 1Gi + storage: 3Gi From 9257a8407c24b38cec8b2ac700d0677249043ff3 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Fri, 3 Nov 2023 11:03:44 +0100 Subject: [PATCH 24/43] fixed the movie cronjob not handling duplicate image urls correctly --- server/backend/cron/movies.go | 60 +++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/server/backend/cron/movies.go b/server/backend/cron/movies.go index 78b84493..c8e2ac49 100644 --- a/server/backend/cron/movies.go +++ b/server/backend/cron/movies.go @@ -1,12 +1,16 @@ package cron import ( + "crypto/md5" + "errors" "fmt" "regexp" "slices" "strings" "time" + "gorm.io/gorm" + "github.com/TUM-Dev/Campus-Backend/server/backend/cron/movie_parsers" "github.com/guregu/null" @@ -52,7 +56,7 @@ func (c *CronService) movieCron() error { } item.Title = matches[re.SubexpIndex("title")] - // populate extra data from omdb + // populate extra data from tu-film website movieInformation, err := movie_parsers.GetTuFilmWebsiteInformation(item.Link) if err != nil { log.WithFields(logFields).WithError(err).Error("error while finding imdb id") @@ -70,14 +74,6 @@ func (c *CronService) movieCron() error { Trailer: movieInformation.TrailerUrl, Link: item.Link, } - // register the preview file for download - seps := strings.SplitAfter(item.Enclosure.Url, ".") - previewFile := model.File{ - Name: fmt.Sprintf("%s.%s", strings.TrimSpace(item.Title), seps[len(seps)-1]), - Path: MovieImageDirectory, - URL: null.StringFrom(item.Enclosure.Url), - Downloaded: null.BoolFrom(false), - } if movieInformation.ImdbID.ValueOrZero() != "" { omdbMovie, err := movie_parsers.GetOmdbMovie(movieInformation.ImdbID.ValueOrZero()) if err != nil { @@ -95,17 +91,47 @@ func (c *CronService) movieCron() error { } // save the result of the previous steps (🎉) - if err := c.db.Create(&previewFile).Error; err != nil { - log.WithFields(logFields).WithError(err).Error("error while creating file") - continue - } - // assign the file_id to make sure the id is assigned - movie.File = previewFile - movie.FileID = previewFile.File - if err := c.db.Create(&movie).Error; err != nil { + if err := c.db.Transaction(func(tx *gorm.DB) error { + file, err := saveImage(tx, movieInformation.ImageUrl) + if err != nil { + return err + } + // assign the file_id to make sure the id is assigned + movie.File = *file + movie.FileID = file.File + return tx.Create(&movie).Error + }); err != nil { log.WithFields(logFields).WithError(err).Error("error while creating movie") } } } return nil } + +// saveImage saves an image to the database, so it can be downloaded by another cronjob and returns the file +func saveImage(tx *gorm.DB, url string) (*model.File, error) { + seps := strings.SplitAfter(url, ".") + fileExtension := seps[len(seps)-1] + targetFileName := fmt.Sprintf("%x.%s", md5.Sum([]byte(url)), fileExtension) + var file model.File + // path intentionally omitted in query to allow for deduplication + if err := tx.First(&file, "name = ?", targetFileName).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + log.WithError(err).WithField("targetFileName", targetFileName).Error("Couldn't query database for file") + return nil, err + } else if err == nil { + return &file, nil + } + + // does not exist, store in database + file = model.File{ + Name: targetFileName, + Path: MovieImageDirectory, + URL: null.StringFrom(url), + Downloaded: null.BoolFrom(false), + } + if err := tx.Create(&file).Error; err != nil { + log.WithError(err).Error("Could not store new file to database") + return nil, err + } + return &file, nil +} From f5260e0db54c8015c99eb9c889ec664b97d6c23a Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Tue, 21 Nov 2023 22:40:46 +0100 Subject: [PATCH 25/43] fixed having `api-test-v1.tum.app` as an domain --- deployment/charts/backend/templates/networking/https-cert.yaml | 2 +- deployment/charts/backend/values.yaml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/deployment/charts/backend/templates/networking/https-cert.yaml b/deployment/charts/backend/templates/networking/https-cert.yaml index bb0d086c..9fa05850 100644 --- a/deployment/charts/backend/templates/networking/https-cert.yaml +++ b/deployment/charts/backend/templates/networking/https-cert.yaml @@ -6,7 +6,7 @@ metadata: app.kubernetes.io/part-of: tum-campus-app namespace: {{ $.Values.namespace }} spec: - commonName: api-test-v1.tum.app + commonName: app.tum.de secretName: app.tum.de issuerRef: name: letsencrypt-production diff --git a/deployment/charts/backend/values.yaml b/deployment/charts/backend/values.yaml index 9ac3673b..bb0db453 100644 --- a/deployment/charts/backend/values.yaml +++ b/deployment/charts/backend/values.yaml @@ -2,7 +2,6 @@ namespace: tca-backend tag: latest urls: v1: - - api-test-v1.tum.app - app.tum.app - app.tum.de - www.app.tum.de From 3db8ff495fbd611e682b9fe0d32a177e65198bc9 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Tue, 21 Nov 2023 23:00:16 +0100 Subject: [PATCH 26/43] added the ability to configure smtp --- .../templates/deployments/backend-v2.yaml | 24 +++++++++++++++++++ deployment/charts/backend/values.yaml | 5 ++++ 2 files changed, 29 insertions(+) diff --git a/deployment/charts/backend/templates/deployments/backend-v2.yaml b/deployment/charts/backend/templates/deployments/backend-v2.yaml index 725a40c4..eacfbd10 100644 --- a/deployment/charts/backend/templates/deployments/backend-v2.yaml +++ b/deployment/charts/backend/templates/deployments/backend-v2.yaml @@ -62,6 +62,26 @@ spec: secretKeyRef: name: backend-api-keys key: CAMPUS_API_TOKEN + - name: SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: backend-api-keys + key: SMTP_PASSWORD + - name: SMTP_URL + valueFrom: + secretKeyRef: + name: backend-api-keys + key: SMTP_URL + - name: SMTP_USERNAME + valueFrom: + secretKeyRef: + name: backend-api-keys + key: SMTP_USERNAME + - name: SMTP_PORT + valueFrom: + secretKeyRef: + name: backend-api-keys + key: SMTP_PORT - name: DB_DSN value: "{{ $db.username }}:{{ $db.password }}@tcp(tca-backend-mariadb.{{ $.Values.namespace }}.svc.cluster.local:3306)/{{ $db.database }}?charset=utf8mb4&parseTime=True&loc=Local" - name: APNS_KEY_ID @@ -159,6 +179,10 @@ data: apns_auth_key.p8: {{ $.Values.backend.apns.auth_key }} APNS_KEY_ID: {{ $.Values.backend.apns.key_id | b64enc }} APNS_TEAM_ID: {{ $.Values.backend.apns.team_id | b64enc }} + SMTP_PASSWORD: {{ $.Values.backend.smtp.password | b64enc }} + SMTP_URL: {{ $.Values.backend.smtp.url | b64enc }} + SMTP_USERNAME: {{ $.Values.backend.smtp.username | b64enc }} + SMTP_PORT: {{ $.Values.backend.smtp.port | b64enc }} --- apiVersion: v1 kind: ConfigMap diff --git a/deployment/charts/backend/values.yaml b/deployment/charts/backend/values.yaml index bb0db453..7491ab13 100644 --- a/deployment/charts/backend/values.yaml +++ b/deployment/charts/backend/values.yaml @@ -48,6 +48,11 @@ backend: auth_key: changeme-changeme-changeme key_id: changeme-changeme-changeme team_id: changeme-changeme-changeme + smtp: + password: change-me + url: smtp.gmail.com + username: change-me + port: 465 legacy: config: changeme-changeme-changeme imagepullsecret: changeme-changeme-changeme From c416adf9e24acfa57ddafa9231d6909bfc08fa13 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Tue, 21 Nov 2023 23:02:07 +0100 Subject: [PATCH 27/43] another test of the smtp.port --- deployment/charts/backend/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/charts/backend/values.yaml b/deployment/charts/backend/values.yaml index 7491ab13..0c4bcf58 100644 --- a/deployment/charts/backend/values.yaml +++ b/deployment/charts/backend/values.yaml @@ -52,7 +52,7 @@ backend: password: change-me url: smtp.gmail.com username: change-me - port: 465 + port: "465" legacy: config: changeme-changeme-changeme imagepullsecret: changeme-changeme-changeme From daf1fb519e70ad71f8356818eaa38781c610c32b Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Thu, 23 Nov 2023 13:09:39 +0100 Subject: [PATCH 28/43] tested a different way of configuring send mail --- server/backend/cron/feedback_email.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/backend/cron/feedback_email.go b/server/backend/cron/feedback_email.go index c1ffa02f..0f4354c1 100644 --- a/server/backend/cron/feedback_email.go +++ b/server/backend/cron/feedback_email.go @@ -127,7 +127,7 @@ func (c *CronService) feedbackEmailCron() error { log.Tracef("sending feedback %d to %v successfull", i, feedback.Recipient) // prevent the message being send the next time around - if err := c.db.Find(model.Feedback{}, "id = ?", feedback.Id).Update("processed", "true").Error; err != nil { + if err := c.db.Find(model.Feedback{}, "id = ?", feedback.Id).Update("processed", true).Error; err != nil { log.WithError(err).Error("could not prevent mail from being send again") } } From 39ee8509c89cecf2d863726f521d73d3598b2707 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Thu, 23 Nov 2023 13:23:07 +0100 Subject: [PATCH 29/43] tested differnt way of setting feedback to processed --- server/backend/cron/feedback_email.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/backend/cron/feedback_email.go b/server/backend/cron/feedback_email.go index 0f4354c1..3e4c770e 100644 --- a/server/backend/cron/feedback_email.go +++ b/server/backend/cron/feedback_email.go @@ -127,7 +127,8 @@ func (c *CronService) feedbackEmailCron() error { log.Tracef("sending feedback %d to %v successfull", i, feedback.Recipient) // prevent the message being send the next time around - if err := c.db.Find(model.Feedback{}, "id = ?", feedback.Id).Update("processed", true).Error; err != nil { + feedback.Processed = true + if err := c.db.Save(&feedback).Error; err != nil { log.WithError(err).Error("could not prevent mail from being send again") } } From ce122bf66d61080669d8b91124d81a17940d5cb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:42:43 +0100 Subject: [PATCH 30/43] Bump golang.org/x/image from 0.5.0 to 0.10.0 in /server (#290) Bumps [golang.org/x/image](https://github.com/golang/image) from 0.5.0 to 0.10.0. - [Commits](https://github.com/golang/image/compare/v0.5.0...v0.10.0) --- updated-dependencies: - dependency-name: golang.org/x/image dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 2 +- server/go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index 4210c27e..e0353395 100644 --- a/server/go.mod +++ b/server/go.mod @@ -51,7 +51,7 @@ require ( github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect - golang.org/x/image v0.5.0 // indirect + golang.org/x/image v0.10.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/server/go.sum b/server/go.sum index 7209d332..afaeeb71 100644 --- a/server/go.sum +++ b/server/go.sum @@ -531,8 +531,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= -golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= +golang.org/x/image v0.10.0 h1:gXjUUtwtx5yOE0VKWq1CH4IJAClq4UGgUA3i+rpON9M= +golang.org/x/image v0.10.0/go.mod h1:jtrku+n79PfroUbvDdeUWMAI+heR786BofxrbiSF+J0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -733,6 +733,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 97ec5a17c695f7f2aa61b4cda062a02ff4de0fe8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:44:05 +0100 Subject: [PATCH 31/43] Bump golang.org/x/net from 0.17.0 to 0.19.0 in /server (#293) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.19.0. - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.19.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 6 +++--- server/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server/go.mod b/server/go.mod index e0353395..1c2b382a 100644 --- a/server/go.mod +++ b/server/go.mod @@ -21,7 +21,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/soheilhy/cmux v0.1.5 github.com/stretchr/testify v1.8.4 - golang.org/x/net v0.17.0 + golang.org/x/net v0.19.0 golang.org/x/sync v0.3.0 google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb google.golang.org/grpc v1.59.0 @@ -52,8 +52,8 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.11.1 // indirect golang.org/x/image v0.10.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect diff --git a/server/go.sum b/server/go.sum index afaeeb71..a3229f2d 100644 --- a/server/go.sum +++ b/server/go.sum @@ -611,8 +611,8 @@ golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -715,8 +715,8 @@ golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -734,8 +734,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From eca9f3665926e058b34a3f3ec67f64da858f15e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:44:42 +0100 Subject: [PATCH 32/43] Bump gorm.io/gorm from 1.25.4 to 1.25.5 in /server (#292) Bumps [gorm.io/gorm](https://github.com/go-gorm/gorm) from 1.25.4 to 1.25.5. - [Release notes](https://github.com/go-gorm/gorm/releases) - [Commits](https://github.com/go-gorm/gorm/compare/v1.25.4...v1.25.5) --- updated-dependencies: - dependency-name: gorm.io/gorm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index 1c2b382a..013d110a 100644 --- a/server/go.mod +++ b/server/go.mod @@ -28,7 +28,7 @@ require ( google.golang.org/protobuf v1.31.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.5.2 - gorm.io/gorm v1.25.4 + gorm.io/gorm v1.25.5 ) require ( diff --git a/server/go.sum b/server/go.sum index a3229f2d..820c2d64 100644 --- a/server/go.sum +++ b/server/go.sum @@ -944,8 +944,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs= gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8= gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= -gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= -gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= +gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From caeeddb18989dbd0097d1666d39ed62195cd3939 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 16:45:12 +0100 Subject: [PATCH 33/43] Bump github.com/grpc-ecosystem/grpc-gateway/v2 in /server (#294) Bumps [github.com/grpc-ecosystem/grpc-gateway/v2](https://github.com/grpc-ecosystem/grpc-gateway) from 2.18.0 to 2.18.1. - [Release notes](https://github.com/grpc-ecosystem/grpc-gateway/releases) - [Changelog](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/.goreleaser.yml) - [Commits](https://github.com/grpc-ecosystem/grpc-gateway/compare/v2.18.0...v2.18.1) --- updated-dependencies: - dependency-name: github.com/grpc-ecosystem/grpc-gateway/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 8 ++++---- server/go.sum | 21 ++++++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/server/go.mod b/server/go.mod index 013d110a..45c24ce3 100644 --- a/server/go.mod +++ b/server/go.mod @@ -11,7 +11,7 @@ require ( github.com/go-gormigrate/gormigrate/v2 v2.1.1 github.com/gofrs/uuid/v5 v5.0.0 github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 github.com/guregu/null v4.0.0+incompatible github.com/makasim/sentryhook v0.4.2 github.com/microcosm-cc/bluemonday v1.0.26 @@ -23,7 +23,7 @@ require ( github.com/stretchr/testify v1.8.4 golang.org/x/net v0.19.0 golang.org/x/sync v0.3.0 - google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb + google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df @@ -54,8 +54,8 @@ require ( golang.org/x/image v0.10.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/server/go.sum b/server/go.sum index 820c2d64..0967d704 100644 --- a/server/go.sum +++ b/server/go.sum @@ -151,8 +151,6 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -200,8 +198,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -231,8 +230,8 @@ github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y= github.com/guregu/null v4.0.0+incompatible h1:4zw0ckM7ECd6FNNddc3Fu4aty9nTlpkkzH7dPn4/4Gw= github.com/guregu/null v4.0.0+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= @@ -872,12 +871,12 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405 h1:I6WNifs6pF9tNdSob2W24JtyxIYjzFB9qDlpUC76q+U= +google.golang.org/genproto v0.0.0-20231030173426-d783a09b4405/go.mod h1:3WDQMjmJk36UQhjQ89emUzb1mdaHcPeeAh4SCBKznB4= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= +google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 h1:AB/lmRny7e2pLhFEYIbl5qkDAUt2h0ZRO4wGPhZf+ik= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405/go.mod h1:67X1fPuzjcrkymZzZV1vvkFeTn2Rvc6lYF9MYFGCcwE= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= From fc4be56d516fb6b4ca9306d2c6c9ddf0c91bb7bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:02:52 +0100 Subject: [PATCH 34/43] Bump actions/setup-go from 4 to 5 (#301) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/test_migration.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1b4c1a81..bccef8b9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: '1.21' cache: false diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 56123e25..d5675778 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: '1.21' cache-dependency-path: | diff --git a/.github/workflows/test_migration.yml b/.github/workflows/test_migration.yml index a8b9b51b..422affb1 100644 --- a/.github/workflows/test_migration.yml +++ b/.github/workflows/test_migration.yml @@ -25,7 +25,7 @@ jobs: MARIADB_DATABASE: campus_db steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: '1.21' cache-dependency-path: | From de0db1b6f195153c115f912301dc017e5a04293d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:03:28 +0100 Subject: [PATCH 35/43] Bump google.golang.org/grpc from 1.59.0 to 1.60.1 in /server (#300) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.59.0 to 1.60.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.59.0...v1.60.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 4 ++-- server/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server/go.mod b/server/go.mod index 45c24ce3..69bb76f5 100644 --- a/server/go.mod +++ b/server/go.mod @@ -22,9 +22,9 @@ require ( github.com/soheilhy/cmux v0.1.5 github.com/stretchr/testify v1.8.4 golang.org/x/net v0.19.0 - golang.org/x/sync v0.3.0 + golang.org/x/sync v0.4.0 google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 - google.golang.org/grpc v1.59.0 + google.golang.org/grpc v1.60.1 google.golang.org/protobuf v1.31.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.5.2 diff --git a/server/go.sum b/server/go.sum index 0967d704..eb4a8837 100644 --- a/server/go.sum +++ b/server/go.sum @@ -638,8 +638,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -897,8 +897,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From b3c05f1f3024e1d966e11229306a2b14bb1dafb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:10:12 +0100 Subject: [PATCH 36/43] Bump github.com/prometheus/client_golang in /server (#299) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.17.0 to 1.18.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.17.0...v1.18.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 10 +++++----- server/go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/server/go.mod b/server/go.mod index 69bb76f5..bd5b7750 100644 --- a/server/go.mod +++ b/server/go.mod @@ -17,7 +17,7 @@ require ( github.com/microcosm-cc/bluemonday v1.0.26 github.com/mmcdole/gofeed v1.2.1 github.com/onrik/gorm-logrus v0.5.0 - github.com/prometheus/client_golang v1.17.0 + github.com/prometheus/client_golang v1.18.0 github.com/sirupsen/logrus v1.9.3 github.com/soheilhy/cmux v0.1.5 github.com/stretchr/testify v1.8.4 @@ -43,14 +43,14 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mmcdole/goxpp v1.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.11.1 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect golang.org/x/image v0.10.0 // indirect golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/server/go.sum b/server/go.sum index eb4a8837..a7bccca8 100644 --- a/server/go.sum +++ b/server/go.sum @@ -319,8 +319,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mediocregopher/radix/v3 v3.8.0/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= @@ -387,15 +387,15 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM= -github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= From 0b78b106e1ce1340ab7fe0528888183ed59db7b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:11:19 +0100 Subject: [PATCH 37/43] Bump google.golang.org/protobuf from 1.31.0 to 1.32.0 in /server (#298) Bumps google.golang.org/protobuf from 1.31.0 to 1.32.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index bd5b7750..b113ca32 100644 --- a/server/go.mod +++ b/server/go.mod @@ -25,7 +25,7 @@ require ( golang.org/x/sync v0.4.0 google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 google.golang.org/grpc v1.60.1 - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gorm.io/driver/mysql v1.5.2 gorm.io/gorm v1.25.5 diff --git a/server/go.sum b/server/go.sum index a7bccca8..317add60 100644 --- a/server/go.sum +++ b/server/go.sum @@ -913,8 +913,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From a65b708fc1d5d10fc9e4edbddddd2d6b00bf987a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:13:00 +0100 Subject: [PATCH 38/43] Bump google.golang.org/grpc from 1.59.0 to 1.60.1 in /client (#296) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.59.0 to 1.60.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.59.0...v1.60.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- client/go.mod | 8 ++++---- client/go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/client/go.mod b/client/go.mod index 534f165c..d7de7e0b 100644 --- a/client/go.mod +++ b/client/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( github.com/TUM-Dev/Campus-Backend/server v0.0.0-20231009133538-1a7f37e5f27c github.com/sirupsen/logrus v1.9.3 - google.golang.org/grpc v1.59.0 + google.golang.org/grpc v1.60.1 ) require ( @@ -14,8 +14,8 @@ require ( golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb // indirect + google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect google.golang.org/protobuf v1.31.0 // indirect ) diff --git a/client/go.sum b/client/go.sum index 30d9ed58..25afeef9 100644 --- a/client/go.sum +++ b/client/go.sum @@ -29,14 +29,14 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA= -google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb h1:lK0oleSc7IQsUxO3U5TjL9DWlsxpEBemh+zpB7IqhWI= -google.golang.org/genproto/googleapis/api v0.0.0-20230913181813-007df8e322eb/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb h1:Isk1sSH7bovx8Rti2wZK0UZF6oraBDK74uoyLEEVFN0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230913181813-007df8e322eb/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= +google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU= +google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From 1a85df5b4378159ff7672fd394427696d2796d00 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:14:45 +0100 Subject: [PATCH 39/43] Bump golang.org/x/sync from 0.3.0 to 0.5.0 in /server (#295) Bumps [golang.org/x/sync](https://github.com/golang/sync) from 0.3.0 to 0.5.0. - [Commits](https://github.com/golang/sync/compare/v0.3.0...v0.5.0) --- updated-dependencies: - dependency-name: golang.org/x/sync dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index b113ca32..4602af4d 100644 --- a/server/go.mod +++ b/server/go.mod @@ -22,7 +22,7 @@ require ( github.com/soheilhy/cmux v0.1.5 github.com/stretchr/testify v1.8.4 golang.org/x/net v0.19.0 - golang.org/x/sync v0.4.0 + golang.org/x/sync v0.5.0 google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 google.golang.org/grpc v1.60.1 google.golang.org/protobuf v1.32.0 diff --git a/server/go.sum b/server/go.sum index 317add60..4b9cec79 100644 --- a/server/go.sum +++ b/server/go.sum @@ -638,8 +638,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From e0ba5c92394c3835619d522771685cd429890f87 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:36:12 +0100 Subject: [PATCH 40/43] Bump github.com/DATA-DOG/go-sqlmock from 1.5.0 to 1.5.1 in /server (#297) * Bump github.com/DATA-DOG/go-sqlmock from 1.5.0 to 1.5.1 in /server Bumps [github.com/DATA-DOG/go-sqlmock](https://github.com/DATA-DOG/go-sqlmock) from 1.5.0 to 1.5.1. - [Release notes](https://github.com/DATA-DOG/go-sqlmock/releases) - [Commits](https://github.com/DATA-DOG/go-sqlmock/compare/v1.5.0...v1.5.1) --- updated-dependencies: - dependency-name: github.com/DATA-DOG/go-sqlmock dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fixed the testcases --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Frank Elsinga <frank@elsinga.de> --- server/backend/update_note_test.go | 6 +++++- server/go.mod | 2 +- server/go.sum | 5 +++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/server/backend/update_note_test.go b/server/backend/update_note_test.go index e4e635af..8ce43dfd 100644 --- a/server/backend/update_note_test.go +++ b/server/backend/update_note_test.go @@ -50,6 +50,7 @@ const ExpectedGetUpdateNoteQuery = "SELECT * FROM `update_note` WHERE `update_no func (s *UpdateNoteSuite) Test_GetUpdateNoteOne() { s.mock.ExpectQuery(regexp.QuoteMeta(ExpectedGetUpdateNoteQuery)). + WithArgs(1). WillReturnRows(sqlmock.NewRows([]string{"version_code", "version_name", "message"}). AddRow(1, "1.0.0", "Test Message")) @@ -66,6 +67,7 @@ func (s *UpdateNoteSuite) Test_GetUpdateNoteOne() { func (s *UpdateNoteSuite) Test_GetUpdateNoteNone() { s.mock.ExpectQuery(regexp.QuoteMeta(ExpectedGetUpdateNoteQuery)). + WithArgs(1). WillReturnRows(sqlmock.NewRows([]string{"version_code", "version_name", "message"})) meta := metadata.MD{} @@ -76,7 +78,9 @@ func (s *UpdateNoteSuite) Test_GetUpdateNoteNone() { } func (s *UpdateNoteSuite) Test_GetUpdateNoteError() { - s.mock.ExpectQuery(regexp.QuoteMeta(ExpectedGetUpdateNoteQuery)).WillReturnError(gorm.ErrInvalidDB) + s.mock.ExpectQuery(regexp.QuoteMeta(ExpectedGetUpdateNoteQuery)). + WithArgs(1). + WillReturnError(gorm.ErrInvalidDB) meta := metadata.MD{} server := CampusServer{db: s.DB, deviceBuf: s.deviceBuf} diff --git a/server/go.mod b/server/go.mod index 4602af4d..a0892d89 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,7 +3,7 @@ module github.com/TUM-Dev/Campus-Backend/server go 1.21 require ( - github.com/DATA-DOG/go-sqlmock v1.5.0 + github.com/DATA-DOG/go-sqlmock v1.5.1 github.com/PuerkitoBio/goquery v1.8.1 github.com/disintegration/imaging v1.6.2 github.com/gabriel-vasile/mimetype v1.4.3 diff --git a/server/go.sum b/server/go.sum index 4b9cec79..2b595129 100644 --- a/server/go.sum +++ b/server/go.sum @@ -42,8 +42,8 @@ github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= github.com/CloudyKit/jet/v6 v6.1.0/go.mod h1:d3ypHeIRNo2+XyqnGA8s+aphtcVpjP5hPwP/Lzo7Ro4= -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/DATA-DOG/go-sqlmock v1.5.1 h1:FK6RCIUSfmbnI/imIICmboyQBkOckutaa6R5YYlLZyo= +github.com/DATA-DOG/go-sqlmock v1.5.1/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= @@ -286,6 +286,7 @@ github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIR github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= From 06af0cdb0b00b3942dd494bc92c5546e2ddb6d1a Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Tue, 2 Jan 2024 17:17:50 +0100 Subject: [PATCH 41/43] Addded a migration to not have cards anymore (#302) * addded a migration to not have cards anymore * tested different order --- server/backend/migration/20240102000000.go | 163 +++++++++++++++++++++ server/backend/migration/migration.go | 1 + 2 files changed, 164 insertions(+) create mode 100644 server/backend/migration/20240102000000.go diff --git a/server/backend/migration/20240102000000.go b/server/backend/migration/20240102000000.go new file mode 100644 index 00000000..7584b19f --- /dev/null +++ b/server/backend/migration/20240102000000.go @@ -0,0 +1,163 @@ +package migration + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +// migrate20240102000000 +// removes the option to create learning cards from the db as it has been removed from the api a long time ago +func migrate20240102000000() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "20240102000000", + Migrate: func(tx *gorm.DB) error { + //history+comments + if err := tx.Exec("DROP table members_card").Error; err != nil { + return err + } + if err := tx.Exec("DROP table members_card_answer_history").Error; err != nil { + return err + } + if err := tx.Exec("DROP table card_box").Error; err != nil { + return err + } + if err := tx.Exec("DROP table card_comment").Error; err != nil { + return err + } + // tags + if err := tx.Exec("DROP table card2tag").Error; err != nil { + return err + } + if err := tx.Exec("DROP table tag").Error; err != nil { + return err + } + //cards + if err := tx.Exec("DROP table card_option").Error; err != nil { + return err + } + if err := tx.Exec("DROP table card").Error; err != nil { + return err + } + // things that dangle of card + if err := tx.Exec("DROP table lecture").Error; err != nil { + return err + } + if err := tx.Exec("DROP table card_type").Error; err != nil { + return err + } + return nil + }, + Rollback: func(tx *gorm.DB) error { + if err := tx.Exec(`create table if not exists card_type( + card_type int auto_increment primary key, + title varchar(255) null +) auto_increment = 2;`).Error; err != nil { + return err + } + if err := tx.Exec(`create table if not exists lecture( + lecture int auto_increment primary key, + title varchar(255) null + );`).Error; err != nil { + return err + } + // cards + if err := tx.Exec(`create table if not exists card( + card int auto_increment primary key, + member int null, + lecture int null, + card_type int null, + title varchar(255) null, + front_text varchar(2000) null, + front_image varchar(2000) null, + back_text varchar(2000) null, + back_image varchar(2000) null, + can_shift tinyint(1) default 0 null, + created_at date not null, + updated_at date not null, + duplicate_card int null, + aggr_rating float default 0 null, + constraint card_ibfk_1 foreign key (member) references member (member) on delete set null, + constraint card_ibfk_2 foreign key (lecture) references lecture (lecture) on delete set null, + constraint card_ibfk_3 foreign key (card_type) references card_type (card_type) on delete set null, + constraint card_ibfk_4 foreign key (duplicate_card) references card (card) on delete set null + );`).Error; err != nil { + return err + } + if err := tx.Exec(`create table if not exists card_option( + card_option int auto_increment primary key, + card int not null, + text varchar(2000) default '' null, + is_correct_answer tinyint(1) default 0 null, + sort_order int default 0 not null, + image varchar(2000) null, + constraint card_option_ibfk_1 foreign key (card) references card (card) on delete cascade +);`).Error; err != nil { + return err + } + // tags + if err := tx.Exec(`create table if not exists tag( + tag int auto_increment primary key, + title varchar(255) null +);`).Error; err != nil { + return err + } + if err := tx.Exec(`create table if not exists card2tag( + tag int not null, + card int not null, + primary key (tag, card), + constraint card2tag_ibfk_1 foreign key (tag) references tag (tag) on delete cascade, + constraint card2tag_ibfk_2 foreign key (card) references card (card) on delete cascade +);`).Error; err != nil { + return err + } + //comments + history + if err := tx.Exec(`create table if not exists card_comment( + card_comment int auto_increment primary key, + member int null, + card int not null, + rating int default 0 null, + created_at date not null, + constraint card_comment_ibfk_1 foreign key (member) references member (member) on delete set null, + constraint card_comment_ibfk_2 foreign key (card) references card (card) on delete cascade + );`).Error; err != nil { + return err + } + if err := tx.Exec(`create table if not exists card_box( + card_box int auto_increment primary key, + member int null, + title varchar(255) null, + duration int not null, + constraint card_box_ibfk_1 foreign key (member) references member (member) on delete cascade + ) auto_increment = 6;`).Error; err != nil { + return err + } + if err := tx.Exec(`create table if not exists members_card( + member int not null, + card int not null, + card_box int null, + last_answered_active_day int null, + primary key (member, card), + constraint members_card_ibfk_1 foreign key (member) references member (member) on delete cascade, + constraint members_card_ibfk_2 foreign key (card) references card (card) on delete cascade, + constraint members_card_ibfk_3 foreign key (card_box) references card_box (card_box) on delete set null + );`).Error; err != nil { + return err + } + if err := tx.Exec(`create table if not exists members_card_answer_history( + members_card_answer_history int auto_increment primary key, + member int not null, + card int null, + card_box int null, + answer varchar(2000) null, + answer_score float(10, 2) default 0.00 null, + created_at date not null, + constraint members_card_answer_history_ibfk_1 foreign key (member) references member (member) on delete cascade, + constraint members_card_answer_history_ibfk_2 foreign key (card) references card (card) on delete set null, + constraint members_card_answer_history_ibfk_3 foreign key (card_box) references card_box (card_box) on delete set null + );`).Error; err != nil { + return err + } + return nil + }, + } +} diff --git a/server/backend/migration/migration.go b/server/backend/migration/migration.go index e21f84cb..c870ca87 100644 --- a/server/backend/migration/migration.go +++ b/server/backend/migration/migration.go @@ -80,6 +80,7 @@ func manualMigrate(db *gorm.DB) error { migrate20230826000000(), migrate20231003000000(), migrate20231023000000(), + migrate20240102000000(), } return gormigrate.New(db, gormigrateOptions, migrations).Migrate() } From ee8e57164013345cd0e56a09037db9fb700e8716 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Tue, 2 Jan 2024 21:53:38 +0100 Subject: [PATCH 42/43] added a missing fk-relationship for question2answer --- server/backend/migration/20240103000000.go | 44 ++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 server/backend/migration/20240103000000.go diff --git a/server/backend/migration/20240103000000.go b/server/backend/migration/20240103000000.go new file mode 100644 index 00000000..c6a2f2c9 --- /dev/null +++ b/server/backend/migration/20240103000000.go @@ -0,0 +1,44 @@ +package migration + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +// migrate20240103000000 +// made sure that question2answer have the correct fk-relationships +func migrate20240103000000() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "20240103000000", + Migrate: func(tx *gorm.DB) error { + if err := tx.Exec(`alter table question2answer + add constraint question2answer_member_member_fk + foreign key (member) references member (member);`).Error; err != nil { + return err + } + if err := tx.Exec(`alter table question2answer + add constraint question2answer_questionAnswers_answer_fk + foreign key (answer) references questionAnswers (answer);`).Error; err != nil { + return err + } + if err := tx.Exec(`alter table question2answer + add constraint question2answer_question_question_fk + foreign key (question) references question (question);`).Error; err != nil { + return err + } + return nil + }, + Rollback: func(tx *gorm.DB) error { + if err := tx.Exec(`alter table question2answer drop constraint question2answer_member_member_fk;`).Error; err != nil { + return err + } + if err := tx.Exec(`alter table question2answer drop constraint question2answer_questionAnswers_answer_fk;`).Error; err != nil { + return err + } + if err := tx.Exec(`alter table question2answer drop constraint question2answer_question_question_fk;`).Error; err != nil { + return err + } + return nil + }, + } +} From 8fa7b6b631ef3955060e60f230afcb4306981dd1 Mon Sep 17 00:00:00 2001 From: Frank Elsinga <frank@elsinga.de> Date: Tue, 2 Jan 2024 21:58:24 +0100 Subject: [PATCH 43/43] removed the scheduling configuration from the db and moved it to commented code (#303) --- server/backend/cron/ios_notifications.go | 3 +- .../scheduling/repository.go | 23 ------- .../ios_notifications/scheduling/service.go | 54 ++++----------- server/backend/migration/20240101000000.go | 63 +++++++++++++++++ server/backend/migration/migration.go | 3 +- .../scheduling/service.go | 2 - server/model/ios_scheduling_priority.go | 67 ------------------- 7 files changed, 80 insertions(+), 135 deletions(-) delete mode 100644 server/backend/ios_notifications/scheduling/repository.go create mode 100644 server/backend/migration/20240101000000.go delete mode 100644 server/model/ios_scheduling_priority.go diff --git a/server/backend/cron/ios_notifications.go b/server/backend/cron/ios_notifications.go index 99c51161..fa39a0e4 100644 --- a/server/backend/cron/ios_notifications.go +++ b/server/backend/cron/ios_notifications.go @@ -14,11 +14,10 @@ func (c *CronService) iosNotificationsCron() error { return nil } - repo := scheduling.NewRepository(c.db) devicesRepo := device.NewRepository(c.db) schedulerRepo := scheduled_update_log.NewRepository(c.db) - service := scheduling.NewService(repo, devicesRepo, schedulerRepo, c.APNs) + service := scheduling.NewService(devicesRepo, schedulerRepo, c.APNs) return service.HandleScheduledCron() } diff --git a/server/backend/ios_notifications/scheduling/repository.go b/server/backend/ios_notifications/scheduling/repository.go deleted file mode 100644 index fb78f528..00000000 --- a/server/backend/ios_notifications/scheduling/repository.go +++ /dev/null @@ -1,23 +0,0 @@ -package scheduling - -import ( - "github.com/TUM-Dev/Campus-Backend/server/model" - "gorm.io/gorm" -) - -type Repository struct { - DB *gorm.DB -} - -func (repository *Repository) FindSchedulingPriorities() ([]model.IOSSchedulingPriority, error) { - var priorities []model.IOSSchedulingPriority - err := repository.DB.Find(&priorities).Error - - return priorities, err -} - -func NewRepository(db *gorm.DB) *Repository { - return &Repository{ - DB: db, - } -} diff --git a/server/backend/ios_notifications/scheduling/service.go b/server/backend/ios_notifications/scheduling/service.go index bec9256b..e3c40cb2 100644 --- a/server/backend/ios_notifications/scheduling/service.go +++ b/server/backend/ios_notifications/scheduling/service.go @@ -4,6 +4,7 @@ package scheduling import ( "sync" + "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -21,21 +22,12 @@ var devicesToUpdate = promauto.NewGauge(prometheus.GaugeOpts{ }) type Service struct { - Repository *Repository DevicesRepository *device.Repository SchedulerLogRepository *scheduled_update_log.Repository - Priority *model.IOSSchedulingPriority APNs *apns.Service } func (service *Service) HandleScheduledCron() error { - priorities, err := service.Repository.FindSchedulingPriorities() - if err != nil { - return err - } - - currentPriority := findIOSSchedulingPriorityForNow(priorities) - devices, err := service.DevicesRepository.GetDevicesThatShouldUpdateGrades() if err != nil { log.WithError(err).Error("can't get devices") @@ -49,7 +41,8 @@ func (service *Service) HandleScheduledCron() error { return nil } - devices = service.selectDevicesToUpdate(devices, currentPriority.Priority) + priority := findSchedulingPriority() + devices = service.selectDevicesToUpdate(devices, priority) log.Infof("Updating %d devices", len(devices)) @@ -122,50 +115,31 @@ func (service *Service) selectDevicesToUpdate(devices []model.IOSDeviceLastUpdat return devices[:maxDevicesToCheck] } +func findSchedulingPriority() int { + now := time.Now() -func findIOSSchedulingPriorityForNow(priorities []model.IOSSchedulingPriority) *model.IOSSchedulingPriority { - var prioritiesThatAreInRange []model.IOSSchedulingPriority - - for _, priority := range priorities { - if priority.IsCurrentlyInRange() { - prioritiesThatAreInRange = append(prioritiesThatAreInRange, priority) - } + isNight := 1 <= now.Hour() && now.Hour() <= 6 + if isNight { + return 1 } - if len(prioritiesThatAreInRange) == 0 { - return model.DefaultIOSSchedulingPriority() + isDuringSummerSemester := 32 <= now.YearDay() && now.YearDay() <= 106 + isDuringWinterSemester := 152 <= now.YearDay() && now.YearDay() <= 288 + if isDuringWinterSemester || isDuringSummerSemester { + return 10 } - return mergeIOSSchedulingPriorities(prioritiesThatAreInRange) -} - -func mergeIOSSchedulingPriorities(priorities []model.IOSSchedulingPriority) *model.IOSSchedulingPriority { - mergedPriority := model.DefaultIOSSchedulingPriority() - prioritiesSum := 0 - - for _, priority := range priorities { - if priority.IsMorePreciseThan(mergedPriority) { - mergedPriority = &priority - } - - prioritiesSum += priority.Priority - } - - mergedPriority.Priority = prioritiesSum / len(priorities) - - return mergedPriority + return 5 } -func NewService(repository *Repository, +func NewService( devicesRepository *device.Repository, schedulerRepository *scheduled_update_log.Repository, apnsService *apns.Service, ) *Service { return &Service{ - Repository: repository, DevicesRepository: devicesRepository, SchedulerLogRepository: schedulerRepository, - Priority: model.DefaultIOSSchedulingPriority(), APNs: apnsService, } } diff --git a/server/backend/migration/20240101000000.go b/server/backend/migration/20240101000000.go new file mode 100644 index 00000000..03bc744a --- /dev/null +++ b/server/backend/migration/20240101000000.go @@ -0,0 +1,63 @@ +package migration + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +// IOSSchedulingPriority stores some default priorities for the scheduling of grade updates. +type IOSSchedulingPriority struct { + ID int64 `gorm:"primary_key;auto_increment;not_null" json:"id"` + FromDay int `gorm:"not null" json:"from_day"` + ToDay int `gorm:"not null" json:"to_day"` + FromHour int `gorm:"not null" json:"from_hour"` + ToHour int `gorm:"not null" json:"to_hour"` + Priority int `gorm:"not null" json:"priority"` +} + +// migrate20240101000000 +// inlined the scheduling priorities to not be configured in the DB +func migrate20240101000000() *gormigrate.Migration { + return &gormigrate.Migration{ + ID: "20240101000000", + Migrate: func(tx *gorm.DB) error { + return tx.Exec("DROP table ios_scheduling_priorities").Error + }, + Rollback: func(tx *gorm.DB) error { + if err := tx.Migrator().AutoMigrate(&IOSSchedulingPriority{}); err != nil { + return err + } + if err := tx.Create(&IOSSchedulingPriority{ + ID: 1, + FromDay: 152, + ToDay: 288, + FromHour: 0, + ToHour: 23, + Priority: 10, + }).Error; err != nil { + return err + } + if err := tx.Create(&IOSSchedulingPriority{ + ID: 2, + FromDay: 32, + ToDay: 106, + FromHour: 0, + ToHour: 23, + Priority: 10, + }).Error; err != nil { + return err + } + if err := tx.Create(&IOSSchedulingPriority{ + ID: 3, + FromDay: 1, + ToDay: 365, + FromHour: 1, + ToHour: 6, + Priority: 5, + }).Error; err != nil { + return err + } + return nil + }, + } +} diff --git a/server/backend/migration/migration.go b/server/backend/migration/migration.go index c870ca87..dc1e68f2 100644 --- a/server/backend/migration/migration.go +++ b/server/backend/migration/migration.go @@ -44,7 +44,6 @@ func autoMigrate(db *gorm.DB) error { //&model.IOSGrade{}, -- not a gorm model //&model.IOSRemoteNotification...{}, -- wtf??? &model.IOSScheduledUpdateLog{}, - &model.IOSSchedulingPriority{}, &model.Kino{}, &model.NewExamResultsSubscriber{}, &model.News{}, @@ -80,7 +79,9 @@ func manualMigrate(db *gorm.DB) error { migrate20230826000000(), migrate20231003000000(), migrate20231023000000(), + migrate20240101000000(), migrate20240102000000(), + migrate20240103000000(), } return gormigrate.New(db, gormigrateOptions, migrations).Migrate() } diff --git a/server/backend/new_exam_results_hook/scheduling/service.go b/server/backend/new_exam_results_hook/scheduling/service.go index 917f3dad..4720ee71 100644 --- a/server/backend/new_exam_results_hook/scheduling/service.go +++ b/server/backend/new_exam_results_hook/scheduling/service.go @@ -12,7 +12,6 @@ import ( type Service struct { Repository *Repository DevicesRepository *device.Repository - Priority *model.IOSSchedulingPriority APNs *apns.Service } @@ -87,7 +86,6 @@ func NewService(repository *Repository, return &Service{ Repository: repository, DevicesRepository: devicesRepository, - Priority: model.DefaultIOSSchedulingPriority(), APNs: apnsService, } } diff --git a/server/model/ios_scheduling_priority.go b/server/model/ios_scheduling_priority.go deleted file mode 100644 index 39bd9ab5..00000000 --- a/server/model/ios_scheduling_priority.go +++ /dev/null @@ -1,67 +0,0 @@ -package model - -import ( - "fmt" - "time" -) - -// IOSSchedulingPriority stores some default priorities for the scheduling of -// grade updates. -type IOSSchedulingPriority struct { - ID int64 `gorm:"primary_key;auto_increment;not_null" json:"id"` - FromDay int `gorm:"not null" json:"from_day"` - ToDay int `gorm:"not null" json:"to_day"` - FromHour int `gorm:"not null" json:"from_hour"` - ToHour int `gorm:"not null" json:"to_hour"` - Priority int `gorm:"not null" json:"priority"` -} - -// IsCurrentlyInRange returns true if the current time is in the range of the -// scheduling priority. -func (p *IOSSchedulingPriority) IsCurrentlyInRange() bool { - now := time.Now() - yearDay := now.YearDay() - - if p.FromDay <= yearDay && p.ToDay >= yearDay { - hour := now.Hour() - - if p.FromHour <= hour && p.ToHour >= hour { - return true - } - } - - return false -} - -// IsMorePreciseThan compares two Priorities and returns true if the current -// priority is more precise than the other one. -// -// Example: -// A priority with FromDay=1, ToDay=365, FromHour=6, ToHour=8 is more precise -// than a priority with FromDay=1, ToDay=365, FromHour=0, ToHour=23. -// In case the current hour is between 6 and 8. -func (p *IOSSchedulingPriority) IsMorePreciseThan(other *IOSSchedulingPriority) bool { - if p.FromDay == other.FromDay && p.ToDay == other.ToDay { - if p.FromHour == other.FromHour && p.ToHour == other.ToHour { - return p.Priority > other.Priority - } - - return p.FromHour > other.FromHour && p.ToHour < other.ToHour - } - - return p.FromDay > other.FromDay && p.ToDay < other.ToDay -} - -func (p *IOSSchedulingPriority) String() string { - return fmt.Sprintf("Day: %d-%d, Hour: %d-%d, Priority: %d", p.FromDay, p.ToDay, p.FromHour, p.ToHour, p.Priority) -} - -func DefaultIOSSchedulingPriority() *IOSSchedulingPriority { - return &IOSSchedulingPriority{ - FromDay: 1, - ToDay: 365, - FromHour: 0, - ToHour: 23, - Priority: 5, - } -}