diff --git a/frontend/wizard-vue/src/components/SpecsForm.vue b/frontend/wizard-vue/src/components/SpecsForm.vue index be11b1e..54ea8a7 100644 --- a/frontend/wizard-vue/src/components/SpecsForm.vue +++ b/frontend/wizard-vue/src/components/SpecsForm.vue @@ -1,22 +1,34 @@ - store.updateSpec(field.name, event)" - > + + + store.updateSpec(field.name, event)" + > + + diff --git a/frontend/wizard-vue/src/urlmaker/proto/specs.ts b/frontend/wizard-vue/src/urlmaker/proto/specs.ts index 1cb981d..d644aeb 100644 --- a/frontend/wizard-vue/src/urlmaker/proto/specs.ts +++ b/frontend/wizard-vue/src/urlmaker/proto/specs.ts @@ -5,6 +5,10 @@ * git: https://github.com/thesayyn/protoc-gen-ts */ import * as pb_1 from "google-protobuf"; export namespace rssalchemy { + export enum ExtractFrom { + InnerText = 0, + Attribute = 1 + } export class Specs extends pb_1.Message { #one_of_decls: number[][] = []; constructor(data?: any[] | { @@ -15,6 +19,7 @@ export namespace rssalchemy { selector_description?: string; selector_author?: string; selector_created?: string; + created_extract_from?: ExtractFrom; selector_content?: string; selector_enclosure?: string; cache_lifetime?: string; @@ -43,6 +48,9 @@ export namespace rssalchemy { if ("selector_created" in data && data.selector_created != undefined) { this.selector_created = data.selector_created; } + if ("created_extract_from" in data && data.created_extract_from != undefined) { + this.created_extract_from = data.created_extract_from; + } if ("selector_content" in data && data.selector_content != undefined) { this.selector_content = data.selector_content; } @@ -96,6 +104,12 @@ export namespace rssalchemy { set selector_created(value: string) { pb_1.Message.setField(this, 7, value); } + get created_extract_from() { + return pb_1.Message.getFieldWithDefault(this, 11, ExtractFrom.InnerText) as ExtractFrom; + } + set created_extract_from(value: ExtractFrom) { + pb_1.Message.setField(this, 11, value); + } get selector_content() { return pb_1.Message.getFieldWithDefault(this, 8, "") as string; } @@ -122,6 +136,7 @@ export namespace rssalchemy { selector_description?: string; selector_author?: string; selector_created?: string; + created_extract_from?: ExtractFrom; selector_content?: string; selector_enclosure?: string; cache_lifetime?: string; @@ -148,6 +163,9 @@ export namespace rssalchemy { if (data.selector_created != null) { message.selector_created = data.selector_created; } + if (data.created_extract_from != null) { + message.created_extract_from = data.created_extract_from; + } if (data.selector_content != null) { message.selector_content = data.selector_content; } @@ -168,6 +186,7 @@ export namespace rssalchemy { selector_description?: string; selector_author?: string; selector_created?: string; + created_extract_from?: ExtractFrom; selector_content?: string; selector_enclosure?: string; cache_lifetime?: string; @@ -193,6 +212,9 @@ export namespace rssalchemy { if (this.selector_created != null) { data.selector_created = this.selector_created; } + if (this.created_extract_from != null) { + data.created_extract_from = this.created_extract_from; + } if (this.selector_content != null) { data.selector_content = this.selector_content; } @@ -222,6 +244,8 @@ export namespace rssalchemy { writer.writeString(6, this.selector_author); if (this.selector_created.length) writer.writeString(7, this.selector_created); + if (this.created_extract_from != ExtractFrom.InnerText) + writer.writeEnum(11, this.created_extract_from); if (this.selector_content.length) writer.writeString(8, this.selector_content); if (this.selector_enclosure.length) @@ -258,6 +282,9 @@ export namespace rssalchemy { case 7: message.selector_created = reader.readString(); break; + case 11: + message.created_extract_from = reader.readEnum(); + break; case 8: message.selector_content = reader.readString(); break; diff --git a/frontend/wizard-vue/src/urlmaker/specs.ts b/frontend/wizard-vue/src/urlmaker/specs.ts index 0307b53..24a459b 100644 --- a/frontend/wizard-vue/src/urlmaker/specs.ts +++ b/frontend/wizard-vue/src/urlmaker/specs.ts @@ -81,6 +81,16 @@ export const fields: SpecField[] = [ validate: validateSelector, group: 'created', }, + { + name: 'created_extract_from', + input_type: InputType.Radio, + enum_values: rssalchemy.ExtractFrom, + label: 'Extract from', + default: rssalchemy.ExtractFrom.InnerText, + validate: value => Object.values(rssalchemy.ExtractFrom).includes(value), + group: 'created', + show_if: specs => !!specs.selector_created, + }, { name: 'selector_content', diff --git a/internal/api/http/pb/specs.pb.go b/internal/api/http/pb/specs.pb.go index 4b6e77f..a69aa41 100644 --- a/internal/api/http/pb/specs.pb.go +++ b/internal/api/http/pb/specs.pb.go @@ -22,6 +22,52 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type ExtractFrom int32 + +const ( + ExtractFrom_InnerText ExtractFrom = 0 + ExtractFrom_Attribute ExtractFrom = 1 +) + +// Enum value maps for ExtractFrom. +var ( + ExtractFrom_name = map[int32]string{ + 0: "InnerText", + 1: "Attribute", + } + ExtractFrom_value = map[string]int32{ + "InnerText": 0, + "Attribute": 1, + } +) + +func (x ExtractFrom) Enum() *ExtractFrom { + p := new(ExtractFrom) + *p = x + return p +} + +func (x ExtractFrom) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExtractFrom) Descriptor() protoreflect.EnumDescriptor { + return file_proto_specs_proto_enumTypes[0].Descriptor() +} + +func (ExtractFrom) Type() protoreflect.EnumType { + return &file_proto_specs_proto_enumTypes[0] +} + +func (x ExtractFrom) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ExtractFrom.Descriptor instead. +func (ExtractFrom) EnumDescriptor() ([]byte, []int) { + return file_proto_specs_proto_rawDescGZIP(), []int{0} +} + type Specs struct { state protoimpl.MessageState `protogen:"open.v1"` Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url" validate:"url"` @@ -31,6 +77,7 @@ type Specs struct { SelectorDescription string `protobuf:"bytes,5,opt,name=selector_description,json=selectorDescription,proto3" json:"selector_description" validate:"omitempty,selector"` SelectorAuthor string `protobuf:"bytes,6,opt,name=selector_author,json=selectorAuthor,proto3" json:"selector_author" validate:"selector"` SelectorCreated string `protobuf:"bytes,7,opt,name=selector_created,json=selectorCreated,proto3" json:"selector_created" validate:"selector"` + CreatedExtractFrom ExtractFrom `protobuf:"varint,11,opt,name=created_extract_from,json=createdExtractFrom,proto3,enum=rssalchemy.ExtractFrom" json:"created_extract_from"` SelectorContent string `protobuf:"bytes,8,opt,name=selector_content,json=selectorContent,proto3" json:"selector_content" validate:"omitempty,selector"` SelectorEnclosure string `protobuf:"bytes,9,opt,name=selector_enclosure,json=selectorEnclosure,proto3" json:"selector_enclosure" validate:"selector"` CacheLifetime string `protobuf:"bytes,10,opt,name=cache_lifetime,json=cacheLifetime,proto3" json:"cache_lifetime"` @@ -117,6 +164,13 @@ func (x *Specs) GetSelectorCreated() string { return "" } +func (x *Specs) GetCreatedExtractFrom() ExtractFrom { + if x != nil { + return x.CreatedExtractFrom + } + return ExtractFrom_InnerText +} + func (x *Specs) GetSelectorContent() string { if x != nil { return x.SelectorContent @@ -144,7 +198,7 @@ var file_proto_specs_proto_rawDesc = string([]byte{ 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x70, 0x65, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x72, 0x73, 0x73, 0x61, 0x6c, 0x63, 0x68, 0x65, 0x6d, 0x79, 0x1a, 0x13, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xef, 0x06, 0x0a, 0x05, 0x53, 0x70, 0x65, 0x63, 0x73, 0x12, 0x30, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdc, 0x07, 0x0a, 0x05, 0x53, 0x70, 0x65, 0x63, 0x73, 0x12, 0x30, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0x9a, 0x84, 0x9e, 0x03, 0x19, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x75, 0x72, 0x6c, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x75, 0x72, 0x6c, 0x22, 0x52, 0x03, 0x75, 0x72, 0x6c, @@ -182,26 +236,35 @@ var file_proto_specs_proto_rawDesc = string([]byte{ 0x6e, 0x3a, 0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x52, 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x65, 0x0a, 0x10, 0x73, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x3a, 0x9a, 0x84, 0x9e, 0x03, 0x35, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, - 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x22, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x6f, 0x6d, 0x69, 0x74, - 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x52, - 0x0f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x12, 0x61, 0x0a, 0x12, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x65, 0x6e, 0x63, - 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x32, 0x9a, 0x84, - 0x9e, 0x03, 0x2d, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x22, 0x20, 0x76, 0x61, 0x6c, - 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, - 0x52, 0x11, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x63, 0x6c, 0x6f, 0x73, - 0x75, 0x72, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6c, 0x69, 0x66, - 0x65, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0x9a, 0x84, 0x9e, - 0x03, 0x15, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6c, 0x69, - 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4c, 0x69, - 0x66, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x42, 0x16, 0x5a, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x70, 0x62, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x72, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x12, 0x6b, 0x0a, 0x14, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x66, 0x72, 0x6f, + 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x72, 0x73, 0x73, 0x61, 0x6c, 0x63, + 0x68, 0x65, 0x6d, 0x79, 0x2e, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d, + 0x42, 0x20, 0x9a, 0x84, 0x9e, 0x03, 0x1b, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x66, 0x72, 0x6f, + 0x6d, 0x22, 0x52, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x45, 0x78, 0x74, 0x72, 0x61, + 0x63, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x65, 0x0a, 0x10, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x3a, 0x9a, 0x84, 0x9e, 0x03, 0x35, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x20, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x22, 0x6f, 0x6d, 0x69, 0x74, 0x65, 0x6d, 0x70, + 0x74, 0x79, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x52, 0x0f, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x61, 0x0a, + 0x12, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x73, + 0x75, 0x72, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x32, 0x9a, 0x84, 0x9e, 0x03, 0x2d, + 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x65, + 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, 0x22, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x3a, 0x22, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x52, 0x11, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x45, 0x6e, 0x63, 0x6c, 0x6f, 0x73, 0x75, 0x72, 0x65, + 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6c, 0x69, 0x66, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1a, 0x9a, 0x84, 0x9e, 0x03, 0x15, 0x6a, + 0x73, 0x6f, 0x6e, 0x3a, 0x22, 0x63, 0x61, 0x63, 0x68, 0x65, 0x5f, 0x6c, 0x69, 0x66, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x22, 0x52, 0x0d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x2a, 0x2b, 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x46, 0x72, + 0x6f, 0x6d, 0x12, 0x0d, 0x0a, 0x09, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, 0x10, + 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x10, 0x01, + 0x42, 0x16, 0x5a, 0x14, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var ( @@ -216,16 +279,19 @@ func file_proto_specs_proto_rawDescGZIP() []byte { return file_proto_specs_proto_rawDescData } +var file_proto_specs_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_proto_specs_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_proto_specs_proto_goTypes = []any{ - (*Specs)(nil), // 0: rssalchemy.Specs + (ExtractFrom)(0), // 0: rssalchemy.ExtractFrom + (*Specs)(nil), // 1: rssalchemy.Specs } var file_proto_specs_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 0, // 0: rssalchemy.Specs.created_extract_from:type_name -> rssalchemy.ExtractFrom + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_proto_specs_proto_init() } @@ -238,13 +304,14 @@ func file_proto_specs_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_specs_proto_rawDesc), len(file_proto_specs_proto_rawDesc)), - NumEnums: 0, + NumEnums: 1, NumMessages: 1, NumExtensions: 0, NumServices: 0, }, GoTypes: file_proto_specs_proto_goTypes, DependencyIndexes: file_proto_specs_proto_depIdxs, + EnumInfos: file_proto_specs_proto_enumTypes, MessageInfos: file_proto_specs_proto_msgTypes, }.Build() File_proto_specs_proto = out.File diff --git a/proto/specs.proto b/proto/specs.proto index f2a6875..e034114 100644 --- a/proto/specs.proto +++ b/proto/specs.proto @@ -6,6 +6,11 @@ import "tagger/tagger.proto"; option go_package = "internal/api/http/pb"; +enum ExtractFrom { + InnerText = 0; + Attribute = 1; +} + message Specs { string url = 1 [(tagger.tags) = "json:\"url\" validate:\"url\""]; string selector_post = 2 [(tagger.tags) = "json:\"selector_post\" validate:\"selector\""]; @@ -13,7 +18,10 @@ message Specs { string selector_link = 4 [(tagger.tags) = "json:\"selector_link\" validate:\"selector\""]; string selector_description = 5 [(tagger.tags) = "json:\"selector_description\" validate:\"omitempty,selector\""]; string selector_author = 6 [(tagger.tags) = "json:\"selector_author\" validate:\"selector\""]; + string selector_created = 7 [(tagger.tags) = "json:\"selector_created\" validate:\"selector\""]; + ExtractFrom created_extract_from = 11 [(tagger.tags) = "json:\"created_extract_from\""]; + string selector_content = 8 [(tagger.tags) = "json:\"selector_content\" validate:\"omitempty,selector\""]; string selector_enclosure = 9 [(tagger.tags) = "json:\"selector_enclosure\" validate:\"selector\""]; string cache_lifetime = 10 [(tagger.tags) = "json:\"cache_lifetime\""];