proto: added more proto for subreddits

This commit is contained in:
Tigor Hutasuhut 2024-08-15 14:13:40 +07:00
parent 5dc4ccdf70
commit a17325bfed
10 changed files with 163 additions and 55 deletions

View file

@ -109,32 +109,33 @@ func (e *Err) Details(keysAndValues ...any) Error {
// discarding any empty and duplicate messages in the chain. // discarding any empty and duplicate messages in the chain.
// //
// The error messages are concatenated with a colon and a space. // The error messages are concatenated with a colon and a space.
//
// The message does not expose the origin error message.
//
// To get them, errors.Unwrap have to be called against this error
// or view them in the logs.
func (e *Err) Error() string { func (e *Err) Error() string {
s := strings.Builder{} s := strings.Builder{}
if e.message != "" { if e.message != "" {
s.WriteString(e.message) s.WriteString(e.message)
if e.origin != nil {
s.WriteString(": ")
}
} }
unwrap := errors.Unwrap(e) unwrap := errors.Unwrap(e)
for unwrap != nil { for unwrap != nil {
var current string var current string
if e, ok := unwrap.(Error); ok && e.GetMessage() != "" { if e, ok := unwrap.(Error); ok {
current = e.GetMessage() if msg := e.GetMessage(); msg != "" {
} else { current = msg
current = unwrap.Error() }
} }
next := errors.Unwrap(unwrap) next := errors.Unwrap(unwrap)
if next != nil { if next != nil {
current, _ = strings.CutSuffix(current, next.Error()) current, _ = strings.CutSuffix(current, next.Error())
current, _ = strings.CutSuffix(current, ": ")
} }
if current != "" { if current != "" {
s.WriteString(current) if _, ok := next.(Error); ok {
if next != nil {
s.WriteString(": ") s.WriteString(": ")
} }
s.WriteString(current)
} }
unwrap = next unwrap = next

View file

@ -61,8 +61,10 @@ func ErrorMessageInterceptor() connect.UnaryInterceptorFunc {
if cerr := new(connect.Error); errors.As(err, &cerr) { if cerr := new(connect.Error); errors.As(err, &cerr) {
if e := errs.FindError(cerr); e != nil { if e := errs.FindError(cerr); e != nil {
msg := e.GetMessage() msg := e.Error()
e.Message("[%s] %s", span.SpanContext().SpanID().String(), msg) spanContext := span.SpanContext()
traceId := spanContext.TraceID().String()
e.Message("%s|%s", traceId, msg)
} }
} }

View file

@ -2,7 +2,7 @@
-- +goose StatementBegin -- +goose StatementBegin
CREATE TABLE subreddits ( CREATE TABLE subreddits (
name VARCHAR(30) NOT NULL PRIMARY KEY COLLATE NOCASE, name VARCHAR(30) NOT NULL PRIMARY KEY COLLATE NOCASE,
disable_scheduler TINYINT NOT NULL DEFAULT 0, disabled TINYINT NOT NULL DEFAULT 0,
"type" VARCHAR(5) NOT NULL DEFAULT 'r', "type" VARCHAR(5) NOT NULL DEFAULT 'r',
schedule VARCHAR(20) NOT NULL DEFAULT '@daily', schedule VARCHAR(20) NOT NULL DEFAULT '@daily',
countback BIGINT NOT NULL DEFAULT 300, countback BIGINT NOT NULL DEFAULT 300,

View file

@ -7,7 +7,7 @@ import "device/v1/list.proto";
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/device/v1"; option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/device/v1";
message CountDevicesRequest { message CountDevicesRequest {
// Limits the counts to devices that have the given name. // Limits the counts to devices that contains the given name.
// case insensitive. // case insensitive.
// //
// Ignored if empty. // Ignored if empty.

View file

@ -16,9 +16,11 @@ message ListDevicesRequest {
// default: empty string. // default: empty string.
string search = 1; string search = 1;
// disabled limit the listing devides only // disabled, if true, limit the listing devides only
// to disabled devices. // to disabled devices.
// //
// if enabled, lists only enabled devices.
//
// If unspecified, devices with either status will be received. // If unspecified, devices with either status will be received.
DisabledFilter disabled = 2; DisabledFilter disabled = 2;
@ -36,12 +38,13 @@ message ListDevicesRequest {
// order_by is the field to order the devices by. // order_by is the field to order the devices by.
// //
// If not given, the default is `created_at`. // If unspecified, the default is `created_at` and sort is forced to DESC.
// regardless even if `sort` is set.
OrderBy order_by = 5; OrderBy order_by = 5;
// sort is the direction of the order_by result. // sort is the direction of the order_by result.
// //
// If not given, the default is `ascending`. // If unspecified, the default is `ascending`.
Sort sort = 6; Sort sort = 6;
} }

View file

@ -0,0 +1,26 @@
syntax = "proto3";
package subreddits.v1;
import "subreddits/v1/types.proto";
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
message CountSubredditsRequest {
// Limits the counts to subreddits that contains the given name.
// case insensitive.
//
// Ignored if empty.
//
// default: empty string.
string search = 1;
// disabled limit the counting to subreddits with the given status.
//
// If unspecified, subreddits with either status will be counted.
DisabledFilter disabled = 2;
}
message CountSubredditsResponse {
int64 count = 1;
}

View file

@ -3,6 +3,7 @@ syntax = "proto3";
package subreddits.v1; package subreddits.v1;
import "buf/validate/validate.proto"; import "buf/validate/validate.proto";
import "subreddits/v1/types.proto";
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"; option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
@ -13,7 +14,10 @@ message CreateSubredditRequest {
// will change to what Reddit has for // will change to what Reddit has for
// consistency. // consistency.
string name = 1 [(buf.validate.field).string.min_len = 1]; string name = 1 [(buf.validate.field).string.min_len = 1];
bool disable_scheduler = 2; // disabled disable the subreddit.
//
// disabled subreddit is left out from the scheduler.
bool disabled = 2;
SubredditType type = 3; SubredditType type = 3;
// schedule is cron job spec to set schedule on when // schedule is cron job spec to set schedule on when
// the runner for this subreddit runs. // the runner for this subreddit runs.
@ -21,12 +25,6 @@ message CreateSubredditRequest {
int64 countback = 5 [(buf.validate.field).int64.gt = 0]; int64 countback = 5 [(buf.validate.field).int64.gt = 0];
} }
enum SubredditType {
SUBREDDIT_TYPE_UNSPECIFIED = 0;
SUBREDDIT_TYPE_SUBREDDIT = 1;
SUBREDDIT_TYPE_USER = 2;
}
message CreateSubredditResponse { message CreateSubredditResponse {
string name = 1; string name = 1;
} }

View file

@ -3,7 +3,7 @@ syntax = "proto3";
package subreddits.v1; package subreddits.v1;
import "buf/validate/validate.proto"; import "buf/validate/validate.proto";
import "subreddits/v1/create.proto"; import "subreddits/v1/types.proto";
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"; option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
@ -15,28 +15,5 @@ message GetSubredditRequest {
} }
message GetSubredditResponse { message GetSubredditResponse {
string name = 1; Subreddit subreddit = 1;
bool disable_scheduler = 2;
// type is never unspecified for this response.
//
// It's always either `SUBREDDIT_TYPE_SUBREDDIT`
// or `SUBREDDIT_TYPE_USER`.
SubredditType type = 3;
string schedule = 4;
uint32 countback = 5;
// cover_image_id is the id of an image that
// acts as the cover for this subreddit.
//
// May not be present in these kind of situations:
//
// - The background task runner has not run for this subreddit.
// - The image that is used as cover is deleted.
// - The subreddit does not contain any images.
//
// cover_image_id changes after every insert of
// new images in that subreddit, so avoid
// caching the image for too long.
optional uint32 cover_image_id = 6;
int64 created_at = 7;
int64 updated_at = 8;
} }

View file

@ -2,18 +2,52 @@ syntax = "proto3";
package subreddits.v1; package subreddits.v1;
import "buf/validate/validate.proto"; import "subreddits/v1/types.proto";
import "subreddits/v1/get.proto";
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"; option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
message ListSubredditsRequest { message ListSubredditsRequest {
// name of the subreddit. Case insensitive. // Searches the name of the Subreddit.
// case insensitive.
// //
// Returns error on not found. // If empty or not given, lists all devices.
string name = 1 [(buf.validate.field).string.min_len = 1]; // (Limit, Offset, Order, Sort still applies).
//
// default: empty string.
string search = 1;
// disabled, if true, limit the listing subreddits to only
// to disabled subreddits.
//
// if enabled, lists only enabled subreddits.
//
// If unspecified, subreddits with either status will be received.
DisabledFilter disabled = 2;
// limits the number of results.
//
// if value is 0, negative value, or not given, limit is set to 25.
//
// if limit is higher than 100, it is clamped to 100.
int64 limit = 3;
// offset for the given data.
//
// If offset is 0, negative value, or not given, the query begins from start.
int64 offset = 4;
// order_by is the field to order the subreddits by.
//
// If unspecified, the default is `created_at` and sort is forced to DESC.
// regardless even if `sort` is set.
OrderBy order_by = 5;
// sort is the direction of the order_by result.
//
// If unspecified, the default is `ascending`.
Sort sort = 6;
} }
message ListSubredditsResponse { message ListSubredditsResponse {
repeated GetSubredditResponse images = 1; repeated Subreddit subreddits = 1;
} }

View file

@ -0,0 +1,67 @@
syntax = "proto3";
package subreddits.v1;
option go_package = "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1";
message Subreddit {
string name = 1;
bool disable_scheduler = 2;
// type is never unspecified for this response.
//
// It's always either `SUBREDDIT_TYPE_SUBREDDIT`
// or `SUBREDDIT_TYPE_USER`.
SubredditType type = 3;
string schedule = 4;
uint32 countback = 5;
// cover_image_id is the id of an image that
// acts as the cover for this subreddit.
//
// May not be present in these kind of situations:
//
// - The background task runner has not run for this subreddit.
// - The image that is used as cover is deleted.
// - The subreddit does not contain any images.
//
// cover_image_id changes after every insert of
// new images in that subreddit, so avoid
// caching the image for too long.
optional uint32 cover_image_id = 6;
int64 created_at = 7;
int64 updated_at = 8;
}
enum SubredditType {
SUBREDDIT_TYPE_UNSPECIFIED = 0;
SUBREDDIT_TYPE_SUBREDDIT = 1;
SUBREDDIT_TYPE_USER = 2;
}
enum DisabledFilter {
DISABLED_FILTER_UNSPECIFIED = 0;
DISABLED_FILTER_TRUE = 1;
DISABLED_FILTER_FALSE = 2;
}
enum OrderBy {
ORDER_BY_UNSPECIFIED = 0;
ORDER_BY_NAME = 1;
// Sorting by Type only guarantee the order is subreddit type first
// or user first.
//
// It does not do any ordering further.
ORDER_BY_TYPE = 2;
// Sorting by countback only orders by countback value.
//
// There are no guarantee order when multiple values
// are the same.
ORDER_BY_COUNTBACK = 3;
ORDER_BY_CREATED_AT = 4;
ORDER_BY_UPDATED_AT = 5;
}
enum Sort {
SORT_UNSPECIFIED = 0;
SORT_ASCENDING = 1;
SORT_DESCENDING = 2;
}