diff --git a/timezone/.gitignore b/time/.gitignore similarity index 100% rename from timezone/.gitignore rename to time/.gitignore diff --git a/time/Dockerfile b/time/Dockerfile new file mode 100644 index 0000000..fdd9f5c --- /dev/null +++ b/time/Dockerfile @@ -0,0 +1,3 @@ +FROM alpine +ADD time /time +ENTRYPOINT [ "/time" ] diff --git a/timezone/Makefile b/time/Makefile similarity index 67% rename from timezone/Makefile rename to time/Makefile index d5b6a94..fcdb5c9 100644 --- a/timezone/Makefile +++ b/time/Makefile @@ -9,15 +9,15 @@ init: .PHONY: api api: - protoc --openapi_out=. --proto_path=. proto/timezone.proto + protoc --openapi_out=. --proto_path=. proto/time.proto .PHONY: proto proto: - protoc --proto_path=. --micro_out=. --go_out=:. proto/timezone.proto + protoc --proto_path=. --micro_out=. --go_out=:. proto/time.proto .PHONY: build build: - go build -o timezone *.go + go build -o time *.go .PHONY: test test: @@ -25,4 +25,4 @@ test: .PHONY: docker docker: - docker build . -t timezone:latest + docker build . -t time:latest diff --git a/timezone/README.md b/time/README.md similarity index 89% rename from timezone/README.md rename to time/README.md index dc4c103..47ad64d 100644 --- a/timezone/README.md +++ b/time/README.md @@ -1,6 +1,6 @@ Time, date and timezone info -# Timezone Service +# Time Service Get the time, date and timezone info for any given location in the world. diff --git a/timezone/generate.go b/time/generate.go similarity index 100% rename from timezone/generate.go rename to time/generate.go diff --git a/time/handler/time.go b/time/handler/time.go new file mode 100644 index 0000000..5147427 --- /dev/null +++ b/time/handler/time.go @@ -0,0 +1,148 @@ +package handler + +import ( + "context" + "encoding/json" + "io/ioutil" + "net/http" + "net/url" + "time" + + "github.com/micro/micro/v3/service/config" + "github.com/micro/micro/v3/service/errors" + "github.com/micro/micro/v3/service/logger" + pb "github.com/micro/services/time/proto" + "github.com/tkuchiki/go-timezone" +) + +type Time struct { + Api string + Key string + TZ *timezone.Timezone +} + +func New() *Time { + // TODO: look for "weather.provider" to determine the handler + v, err := config.Get("weatherapi.api") + if err != nil { + logger.Fatalf("weatherapi.api config not found: %v", err) + } + api := v.String("") + if len(api) == 0 { + logger.Fatal("weatherapi.api config not found") + } + v, err = config.Get("weatherapi.key") + if err != nil { + logger.Fatalf("weatherapi.key config not found: %v", err) + } + key := v.String("") + if len(key) == 0 { + logger.Fatal("weatherapi.key config not found") + } + + return &Time{ + Api: api, + Key: key, + TZ: timezone.New(), + } +} + +func (t *Time) Now(ctx context.Context, req *pb.NowRequest, rsp *pb.NowResponse) error { + if len(req.Location) == 0 { + ti := time.Now().In(time.UTC) + rsp.Localtime = ti.Format("15:04:05") + rsp.Timestamp = ti.Format(time.RFC3339Nano) + rsp.Location = "Prime Meridian" + rsp.Timezone = "UTC" + rsp.Unix = ti.Unix() + return nil + } + + vals := url.Values{} + vals.Set("key", t.Key) + vals.Set("q", req.Location) + + resp, err := http.Get(t.Api + "timezone.json?" + vals.Encode()) + if err != nil { + logger.Errorf("Failed to get time zone: %v\n", err) + return errors.InternalServerError("time.now", "failed to get time") + } + defer resp.Body.Close() + + b, _ := ioutil.ReadAll(resp.Body) + + if resp.StatusCode != 200 { + logger.Errorf("Failed to get time zone (non 200): %d %v\n", resp.StatusCode, string(b)) + return errors.InternalServerError("time.now", "failed to get time") + } + + var respBody map[string]interface{} + + if err := json.Unmarshal(b, &respBody); err != nil { + logger.Errorf("Failed to unmarshal current: %v\n", err) + return errors.InternalServerError("time.now", "failed to get time") + } + + location := respBody["location"].(map[string]interface{}) + + loc, _ := time.LoadLocation(location["tz_id"].(string)) + ti := time.Now().In(loc) + isDST := t.TZ.IsDST(ti) + + rsp.Localtime = ti.Format("15:04:05") + rsp.Timezone, _ = t.TZ.GetTimezoneAbbreviation(location["tz_id"].(string), isDST) + rsp.Location = ti.Location().String() + rsp.Timestamp = ti.Format(time.RFC3339Nano) + rsp.Unix = ti.Unix() + + return nil +} + +func (t *Time) Zone(ctx context.Context, req *pb.ZoneRequest, rsp *pb.ZoneResponse) error { + if len(req.Location) == 0 { + return errors.BadRequest("time.zone", "invalid location") + } + + vals := url.Values{} + vals.Set("key", t.Key) + vals.Set("q", req.Location) + + resp, err := http.Get(t.Api + "timezone.json?" + vals.Encode()) + if err != nil { + logger.Errorf("Failed to get time zone: %v\n", err) + return errors.InternalServerError("time.zone", "failed to get time zone") + } + defer resp.Body.Close() + + b, _ := ioutil.ReadAll(resp.Body) + + if resp.StatusCode != 200 { + logger.Errorf("Failed to get time zone (non 200): %d %v\n", resp.StatusCode, string(b)) + return errors.InternalServerError("time.zone", "failed to get time zone") + } + + var respBody map[string]interface{} + + if err := json.Unmarshal(b, &respBody); err != nil { + logger.Errorf("Failed to unmarshal current: %v\n", err) + return errors.InternalServerError("time.zone", "failed to get current") + } + + location := respBody["location"].(map[string]interface{}) + + rsp.Location = location["name"].(string) + rsp.Region = location["region"].(string) + rsp.Country = location["country"].(string) + rsp.Latitude = location["lat"].(float64) + rsp.Longitude = location["lon"].(float64) + rsp.Timezone = location["tz_id"].(string) + rsp.Localtime = location["localtime"].(string) + + loc, _ := time.LoadLocation(rsp.Timezone) + ti := time.Now().In(loc) + isDST := t.TZ.IsDST(ti) + rsp.Abbreviation, _ = t.TZ.GetTimezoneAbbreviation(rsp.Timezone, isDST) + rsp.Dst = isDST + + return nil +} diff --git a/timezone/main.go b/time/main.go similarity index 62% rename from timezone/main.go rename to time/main.go index 5380975..9cc9088 100644 --- a/timezone/main.go +++ b/time/main.go @@ -3,19 +3,19 @@ package main import ( "github.com/micro/micro/v3/service" "github.com/micro/micro/v3/service/logger" - "github.com/micro/services/timezone/handler" - pb "github.com/micro/services/timezone/proto" + "github.com/micro/services/time/handler" + pb "github.com/micro/services/time/proto" ) func main() { // Create service srv := service.New( - service.Name("timezone"), + service.Name("time"), service.Version("latest"), ) // Register handler - pb.RegisterTimezoneHandler(srv.Server(), handler.New()) + pb.RegisterTimeHandler(srv.Server(), handler.New()) // Run service if err := srv.Run(); err != nil { diff --git a/time/micro.mu b/time/micro.mu new file mode 100644 index 0000000..0429d88 --- /dev/null +++ b/time/micro.mu @@ -0,0 +1 @@ +service time diff --git a/time/proto/time.pb.go b/time/proto/time.pb.go new file mode 100644 index 0000000..d67741c --- /dev/null +++ b/time/proto/time.pb.go @@ -0,0 +1,475 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.15.6 +// source: proto/time.proto + +package time + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Get the current time +type NowRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // optional location, otherwise returns UTC + Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` +} + +func (x *NowRequest) Reset() { + *x = NowRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_time_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NowRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NowRequest) ProtoMessage() {} + +func (x *NowRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_time_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NowRequest.ProtoReflect.Descriptor instead. +func (*NowRequest) Descriptor() ([]byte, []int) { + return file_proto_time_proto_rawDescGZIP(), []int{0} +} + +func (x *NowRequest) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +type NowResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // the current time as HH:MM:SS + Localtime string `protobuf:"bytes,1,opt,name=localtime,proto3" json:"localtime,omitempty"` + // timestamp as 2006-01-02T15:04:05.999999999Z07:00 + Timestamp string `protobuf:"bytes,2,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // the location as Europe/London + Location string `protobuf:"bytes,3,opt,name=location,proto3" json:"location,omitempty"` + // the timezone as BST + Timezone string `protobuf:"bytes,4,opt,name=timezone,proto3" json:"timezone,omitempty"` + // the unix timestamp + Unix int64 `protobuf:"varint,5,opt,name=unix,proto3" json:"unix,omitempty"` +} + +func (x *NowResponse) Reset() { + *x = NowResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_time_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NowResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NowResponse) ProtoMessage() {} + +func (x *NowResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_time_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NowResponse.ProtoReflect.Descriptor instead. +func (*NowResponse) Descriptor() ([]byte, []int) { + return file_proto_time_proto_rawDescGZIP(), []int{1} +} + +func (x *NowResponse) GetLocaltime() string { + if x != nil { + return x.Localtime + } + return "" +} + +func (x *NowResponse) GetTimestamp() string { + if x != nil { + return x.Timestamp + } + return "" +} + +func (x *NowResponse) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +func (x *NowResponse) GetTimezone() string { + if x != nil { + return x.Timezone + } + return "" +} + +func (x *NowResponse) GetUnix() int64 { + if x != nil { + return x.Unix + } + return 0 +} + +// Get the timezone info for a specific location +type ZoneRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // location to lookup e.g postcode, city, ip address + Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` +} + +func (x *ZoneRequest) Reset() { + *x = ZoneRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_time_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ZoneRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ZoneRequest) ProtoMessage() {} + +func (x *ZoneRequest) ProtoReflect() protoreflect.Message { + mi := &file_proto_time_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ZoneRequest.ProtoReflect.Descriptor instead. +func (*ZoneRequest) Descriptor() ([]byte, []int) { + return file_proto_time_proto_rawDescGZIP(), []int{2} +} + +func (x *ZoneRequest) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +type ZoneResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // location requested + Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` + // region of timezone + Region string `protobuf:"bytes,2,opt,name=region,proto3" json:"region,omitempty"` + // country of the timezone + Country string `protobuf:"bytes,3,opt,name=country,proto3" json:"country,omitempty"` + // e.g 51.42 + Latitude float64 `protobuf:"fixed64,4,opt,name=latitude,proto3" json:"latitude,omitempty"` + // e.g -0.37 + Longitude float64 `protobuf:"fixed64,5,opt,name=longitude,proto3" json:"longitude,omitempty"` + // the timezone e.g Europe/London + Timezone string `protobuf:"bytes,6,opt,name=timezone,proto3" json:"timezone,omitempty"` + // the abbreviated code e.g BST + Abbreviation string `protobuf:"bytes,7,opt,name=abbreviation,proto3" json:"abbreviation,omitempty"` + // the local time + Localtime string `protobuf:"bytes,8,opt,name=localtime,proto3" json:"localtime,omitempty"` + // is daylight savings + Dst bool `protobuf:"varint,9,opt,name=dst,proto3" json:"dst,omitempty"` +} + +func (x *ZoneResponse) Reset() { + *x = ZoneResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_proto_time_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ZoneResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ZoneResponse) ProtoMessage() {} + +func (x *ZoneResponse) ProtoReflect() protoreflect.Message { + mi := &file_proto_time_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ZoneResponse.ProtoReflect.Descriptor instead. +func (*ZoneResponse) Descriptor() ([]byte, []int) { + return file_proto_time_proto_rawDescGZIP(), []int{3} +} + +func (x *ZoneResponse) GetLocation() string { + if x != nil { + return x.Location + } + return "" +} + +func (x *ZoneResponse) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *ZoneResponse) GetCountry() string { + if x != nil { + return x.Country + } + return "" +} + +func (x *ZoneResponse) GetLatitude() float64 { + if x != nil { + return x.Latitude + } + return 0 +} + +func (x *ZoneResponse) GetLongitude() float64 { + if x != nil { + return x.Longitude + } + return 0 +} + +func (x *ZoneResponse) GetTimezone() string { + if x != nil { + return x.Timezone + } + return "" +} + +func (x *ZoneResponse) GetAbbreviation() string { + if x != nil { + return x.Abbreviation + } + return "" +} + +func (x *ZoneResponse) GetLocaltime() string { + if x != nil { + return x.Localtime + } + return "" +} + +func (x *ZoneResponse) GetDst() bool { + if x != nil { + return x.Dst + } + return false +} + +var File_proto_time_proto protoreflect.FileDescriptor + +var file_proto_time_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x28, 0x0a, 0x0a, 0x4e, 0x6f, 0x77, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x95, 0x01, 0x0a, 0x0b, 0x4e, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, + 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, + 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, + 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x75, 0x6e, 0x69, 0x78, 0x22, 0x29, 0x0a, 0x0b, 0x5a, 0x6f, + 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x86, 0x02, 0x0a, 0x0c, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, + 0x18, 0x04, 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, 0x05, 0x20, + 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x62, + 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, + 0x0a, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, + 0x64, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x64, 0x73, 0x74, 0x32, 0x65, + 0x0a, 0x04, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x4e, 0x6f, 0x77, 0x12, 0x10, 0x2e, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4e, 0x6f, 0x77, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x11, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x4e, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x2f, 0x0a, 0x04, 0x5a, 0x6f, 0x6e, 0x65, 0x12, 0x11, 0x2e, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x12, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x5a, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0e, 0x5a, 0x0c, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x3b, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_proto_time_proto_rawDescOnce sync.Once + file_proto_time_proto_rawDescData = file_proto_time_proto_rawDesc +) + +func file_proto_time_proto_rawDescGZIP() []byte { + file_proto_time_proto_rawDescOnce.Do(func() { + file_proto_time_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_time_proto_rawDescData) + }) + return file_proto_time_proto_rawDescData +} + +var file_proto_time_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_proto_time_proto_goTypes = []interface{}{ + (*NowRequest)(nil), // 0: time.NowRequest + (*NowResponse)(nil), // 1: time.NowResponse + (*ZoneRequest)(nil), // 2: time.ZoneRequest + (*ZoneResponse)(nil), // 3: time.ZoneResponse +} +var file_proto_time_proto_depIdxs = []int32{ + 0, // 0: time.Time.Now:input_type -> time.NowRequest + 2, // 1: time.Time.Zone:input_type -> time.ZoneRequest + 1, // 2: time.Time.Now:output_type -> time.NowResponse + 3, // 3: time.Time.Zone:output_type -> time.ZoneResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] 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 +} + +func init() { file_proto_time_proto_init() } +func file_proto_time_proto_init() { + if File_proto_time_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_proto_time_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NowRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_time_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NowResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_time_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ZoneRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_proto_time_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ZoneResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_proto_time_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_proto_time_proto_goTypes, + DependencyIndexes: file_proto_time_proto_depIdxs, + MessageInfos: file_proto_time_proto_msgTypes, + }.Build() + File_proto_time_proto = out.File + file_proto_time_proto_rawDesc = nil + file_proto_time_proto_goTypes = nil + file_proto_time_proto_depIdxs = nil +} diff --git a/time/proto/time.pb.micro.go b/time/proto/time.pb.micro.go new file mode 100644 index 0000000..3241a02 --- /dev/null +++ b/time/proto/time.pb.micro.go @@ -0,0 +1,110 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: proto/time.proto + +package time + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) + +import ( + context "context" + api "github.com/micro/micro/v3/service/api" + client "github.com/micro/micro/v3/service/client" + server "github.com/micro/micro/v3/service/server" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// Reference imports to suppress errors if they are not otherwise used. +var _ api.Endpoint +var _ context.Context +var _ client.Option +var _ server.Option + +// Api Endpoints for Time service + +func NewTimeEndpoints() []*api.Endpoint { + return []*api.Endpoint{} +} + +// Client API for Time service + +type TimeService interface { + Now(ctx context.Context, in *NowRequest, opts ...client.CallOption) (*NowResponse, error) + Zone(ctx context.Context, in *ZoneRequest, opts ...client.CallOption) (*ZoneResponse, error) +} + +type timeService struct { + c client.Client + name string +} + +func NewTimeService(name string, c client.Client) TimeService { + return &timeService{ + c: c, + name: name, + } +} + +func (c *timeService) Now(ctx context.Context, in *NowRequest, opts ...client.CallOption) (*NowResponse, error) { + req := c.c.NewRequest(c.name, "Time.Now", in) + out := new(NowResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *timeService) Zone(ctx context.Context, in *ZoneRequest, opts ...client.CallOption) (*ZoneResponse, error) { + req := c.c.NewRequest(c.name, "Time.Zone", in) + out := new(ZoneResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Time service + +type TimeHandler interface { + Now(context.Context, *NowRequest, *NowResponse) error + Zone(context.Context, *ZoneRequest, *ZoneResponse) error +} + +func RegisterTimeHandler(s server.Server, hdlr TimeHandler, opts ...server.HandlerOption) error { + type time interface { + Now(ctx context.Context, in *NowRequest, out *NowResponse) error + Zone(ctx context.Context, in *ZoneRequest, out *ZoneResponse) error + } + type Time struct { + time + } + h := &timeHandler{hdlr} + return s.Handle(s.NewHandler(&Time{h}, opts...)) +} + +type timeHandler struct { + TimeHandler +} + +func (h *timeHandler) Now(ctx context.Context, in *NowRequest, out *NowResponse) error { + return h.TimeHandler.Now(ctx, in, out) +} + +func (h *timeHandler) Zone(ctx context.Context, in *ZoneRequest, out *ZoneResponse) error { + return h.TimeHandler.Zone(ctx, in, out) +} diff --git a/time/proto/time.proto b/time/proto/time.proto new file mode 100644 index 0000000..068a23a --- /dev/null +++ b/time/proto/time.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package time; + +option go_package = "./proto;time"; + +service Time { + rpc Now(NowRequest) returns (NowResponse) {} + rpc Zone(ZoneRequest) returns (ZoneResponse) {} +} + +// Get the current time +message NowRequest { + // optional location, otherwise returns UTC + string location = 1; +} + +message NowResponse { + // the current time as HH:MM:SS + string localtime = 1; + // timestamp as 2006-01-02T15:04:05.999999999Z07:00 + string timestamp = 2; + // the location as Europe/London + string location = 3; + // the timezone as BST + string timezone = 4; + // the unix timestamp + int64 unix = 5; + +} + +// Get the timezone info for a specific location +message ZoneRequest { + // location to lookup e.g postcode, city, ip address + string location = 1; +} + +message ZoneResponse { + // location requested + string location = 1; + // region of timezone + string region = 2; + // country of the timezone + string country = 3; + // e.g 51.42 + double latitude = 4; + // e.g -0.37 + double longitude = 5; + // the timezone e.g Europe/London + string timezone = 6; + // the abbreviated code e.g BST + string abbreviation = 7; + // the local time + string localtime = 8; + // is daylight savings + bool dst = 9; +} + diff --git a/time/publicapi.json b/time/publicapi.json new file mode 100644 index 0000000..76aee06 --- /dev/null +++ b/time/publicapi.json @@ -0,0 +1,8 @@ +{ + "name": "time", + "icon": "🌐", + "category": "timezone", + "pricing": { + "Time.Zone": 5 + } +} diff --git a/timezone/Dockerfile b/timezone/Dockerfile deleted file mode 100644 index 9d052c5..0000000 --- a/timezone/Dockerfile +++ /dev/null @@ -1,3 +0,0 @@ -FROM alpine -ADD timezone /timezone -ENTRYPOINT [ "/timezone" ] diff --git a/timezone/handler/timezone.go b/timezone/handler/timezone.go deleted file mode 100644 index fc0cf3e..0000000 --- a/timezone/handler/timezone.go +++ /dev/null @@ -1,97 +0,0 @@ -package handler - -import ( - "context" - "encoding/json" - "io/ioutil" - "net/http" - "net/url" - "time" - - "github.com/micro/micro/v3/service/config" - "github.com/micro/micro/v3/service/errors" - "github.com/micro/micro/v3/service/logger" - pb "github.com/micro/services/timezone/proto" - "github.com/tkuchiki/go-timezone" -) - -type Timezone struct { - Api string - Key string - TZ *timezone.Timezone -} - -func New() *Timezone { - // TODO: look for "weather.provider" to determine the handler - v, err := config.Get("weatherapi.api") - if err != nil { - logger.Fatalf("weatherapi.api config not found: %v", err) - } - api := v.String("") - if len(api) == 0 { - logger.Fatal("weatherapi.api config not found") - } - v, err = config.Get("weatherapi.key") - if err != nil { - logger.Fatalf("weatherapi.key config not found: %v", err) - } - key := v.String("") - if len(key) == 0 { - logger.Fatal("weatherapi.key config not found") - } - - return &Timezone{ - Api: api, - Key: key, - TZ: timezone.New(), - } -} - -func (t *Timezone) Info(ctx context.Context, req *pb.InfoRequest, rsp *pb.InfoResponse) error { - if len(req.Location) == 0 { - return errors.BadRequest("timezone.info", "invalid location") - } - - vals := url.Values{} - vals.Set("key", t.Key) - vals.Set("q", req.Location) - - resp, err := http.Get(t.Api + "timezone.json?" + vals.Encode()) - if err != nil { - logger.Errorf("Failed to get timezone info: %v\n", err) - return errors.InternalServerError("weather.current", "failed to get timezone info") - } - defer resp.Body.Close() - - b, _ := ioutil.ReadAll(resp.Body) - - if resp.StatusCode != 200 { - logger.Errorf("Failed to get timezone info (non 200): %d %v\n", resp.StatusCode, string(b)) - return errors.InternalServerError("weather.current", "failed to get timezone info") - } - - var respBody map[string]interface{} - - if err := json.Unmarshal(b, &respBody); err != nil { - logger.Errorf("Failed to unmarshal current: %v\n", err) - return errors.InternalServerError("weather.current", "failed to get current") - } - - location := respBody["location"].(map[string]interface{}) - - rsp.Location = location["name"].(string) - rsp.Region = location["region"].(string) - rsp.Country = location["country"].(string) - rsp.Latitude = location["lat"].(float64) - rsp.Longitude = location["lon"].(float64) - rsp.Timezone = location["tz_id"].(string) - rsp.LocalTime = location["localtime"].(string) - - loc, _ := time.LoadLocation(rsp.Timezone) - ti := time.Now().In(loc) - isDST := t.TZ.IsDST(ti) - rsp.Abbreviation, _ = t.TZ.GetTimezoneAbbreviation(rsp.Timezone, isDST) - rsp.DaylightSavings = isDST - - return nil -} diff --git a/timezone/micro.mu b/timezone/micro.mu deleted file mode 100644 index ecca049..0000000 --- a/timezone/micro.mu +++ /dev/null @@ -1 +0,0 @@ -service timezone diff --git a/timezone/proto/timezone.pb.go b/timezone/proto/timezone.pb.go deleted file mode 100644 index a0b3b36..0000000 --- a/timezone/proto/timezone.pb.go +++ /dev/null @@ -1,302 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.15.6 -// source: proto/timezone.proto - -package timezone - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Get the timezone info for a specific location -type InfoRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // location to lookup e.g postcode, city, ip address - Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` -} - -func (x *InfoRequest) Reset() { - *x = InfoRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_timezone_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InfoRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InfoRequest) ProtoMessage() {} - -func (x *InfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_timezone_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InfoRequest.ProtoReflect.Descriptor instead. -func (*InfoRequest) Descriptor() ([]byte, []int) { - return file_proto_timezone_proto_rawDescGZIP(), []int{0} -} - -func (x *InfoRequest) GetLocation() string { - if x != nil { - return x.Location - } - return "" -} - -type InfoResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // location requested - Location string `protobuf:"bytes,1,opt,name=location,proto3" json:"location,omitempty"` - // region of timezone - Region string `protobuf:"bytes,2,opt,name=region,proto3" json:"region,omitempty"` - // country of the timezone - Country string `protobuf:"bytes,3,opt,name=country,proto3" json:"country,omitempty"` - // e.g 51.42 - Latitude float64 `protobuf:"fixed64,4,opt,name=latitude,proto3" json:"latitude,omitempty"` - // e.g -0.37 - Longitude float64 `protobuf:"fixed64,5,opt,name=longitude,proto3" json:"longitude,omitempty"` - // the timezone e.g Europe/London - Timezone string `protobuf:"bytes,6,opt,name=timezone,proto3" json:"timezone,omitempty"` - // the abbreviated code - Abbreviation string `protobuf:"bytes,7,opt,name=abbreviation,proto3" json:"abbreviation,omitempty"` - // the local time - LocalTime string `protobuf:"bytes,8,opt,name=local_time,json=localTime,proto3" json:"local_time,omitempty"` - // is daylight savings - DaylightSavings bool `protobuf:"varint,9,opt,name=daylight_savings,json=daylightSavings,proto3" json:"daylight_savings,omitempty"` -} - -func (x *InfoResponse) Reset() { - *x = InfoResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_proto_timezone_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *InfoResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*InfoResponse) ProtoMessage() {} - -func (x *InfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_timezone_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use InfoResponse.ProtoReflect.Descriptor instead. -func (*InfoResponse) Descriptor() ([]byte, []int) { - return file_proto_timezone_proto_rawDescGZIP(), []int{1} -} - -func (x *InfoResponse) GetLocation() string { - if x != nil { - return x.Location - } - return "" -} - -func (x *InfoResponse) GetRegion() string { - if x != nil { - return x.Region - } - return "" -} - -func (x *InfoResponse) GetCountry() string { - if x != nil { - return x.Country - } - return "" -} - -func (x *InfoResponse) GetLatitude() float64 { - if x != nil { - return x.Latitude - } - return 0 -} - -func (x *InfoResponse) GetLongitude() float64 { - if x != nil { - return x.Longitude - } - return 0 -} - -func (x *InfoResponse) GetTimezone() string { - if x != nil { - return x.Timezone - } - return "" -} - -func (x *InfoResponse) GetAbbreviation() string { - if x != nil { - return x.Abbreviation - } - return "" -} - -func (x *InfoResponse) GetLocalTime() string { - if x != nil { - return x.LocalTime - } - return "" -} - -func (x *InfoResponse) GetDaylightSavings() bool { - if x != nil { - return x.DaylightSavings - } - return false -} - -var File_proto_timezone_proto protoreflect.FileDescriptor - -var file_proto_timezone_proto_rawDesc = []byte{ - 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, - 0x22, 0x29, 0x0a, 0x0b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa0, 0x02, 0x0a, 0x0c, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, - 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, - 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, - 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x04, 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, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x67, 0x69, - 0x74, 0x75, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, - 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x62, 0x62, 0x72, 0x65, 0x76, 0x69, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x64, 0x61, 0x79, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, - 0x73, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x64, - 0x61, 0x79, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x53, 0x61, 0x76, 0x69, 0x6e, 0x67, 0x73, 0x32, 0x43, - 0x0a, 0x08, 0x54, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x15, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x2e, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x74, 0x69, 0x6d, 0x65, - 0x7a, 0x6f, 0x6e, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x42, 0x12, 0x5a, 0x10, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x74, - 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_proto_timezone_proto_rawDescOnce sync.Once - file_proto_timezone_proto_rawDescData = file_proto_timezone_proto_rawDesc -) - -func file_proto_timezone_proto_rawDescGZIP() []byte { - file_proto_timezone_proto_rawDescOnce.Do(func() { - file_proto_timezone_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_timezone_proto_rawDescData) - }) - return file_proto_timezone_proto_rawDescData -} - -var file_proto_timezone_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_proto_timezone_proto_goTypes = []interface{}{ - (*InfoRequest)(nil), // 0: timezone.InfoRequest - (*InfoResponse)(nil), // 1: timezone.InfoResponse -} -var file_proto_timezone_proto_depIdxs = []int32{ - 0, // 0: timezone.Timezone.Info:input_type -> timezone.InfoRequest - 1, // 1: timezone.Timezone.Info:output_type -> timezone.InfoResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_proto_timezone_proto_init() } -func file_proto_timezone_proto_init() { - if File_proto_timezone_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_proto_timezone_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InfoRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_proto_timezone_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*InfoResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_proto_timezone_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_timezone_proto_goTypes, - DependencyIndexes: file_proto_timezone_proto_depIdxs, - MessageInfos: file_proto_timezone_proto_msgTypes, - }.Build() - File_proto_timezone_proto = out.File - file_proto_timezone_proto_rawDesc = nil - file_proto_timezone_proto_goTypes = nil - file_proto_timezone_proto_depIdxs = nil -} diff --git a/timezone/proto/timezone.pb.micro.go b/timezone/proto/timezone.pb.micro.go deleted file mode 100644 index c7897b1..0000000 --- a/timezone/proto/timezone.pb.micro.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: proto/timezone.proto - -package timezone - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/micro/v3/service/api" - client "github.com/micro/micro/v3/service/client" - server "github.com/micro/micro/v3/service/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Timezone service - -func NewTimezoneEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Timezone service - -type TimezoneService interface { - Info(ctx context.Context, in *InfoRequest, opts ...client.CallOption) (*InfoResponse, error) -} - -type timezoneService struct { - c client.Client - name string -} - -func NewTimezoneService(name string, c client.Client) TimezoneService { - return &timezoneService{ - c: c, - name: name, - } -} - -func (c *timezoneService) Info(ctx context.Context, in *InfoRequest, opts ...client.CallOption) (*InfoResponse, error) { - req := c.c.NewRequest(c.name, "Timezone.Info", in) - out := new(InfoResponse) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Timezone service - -type TimezoneHandler interface { - Info(context.Context, *InfoRequest, *InfoResponse) error -} - -func RegisterTimezoneHandler(s server.Server, hdlr TimezoneHandler, opts ...server.HandlerOption) error { - type timezone interface { - Info(ctx context.Context, in *InfoRequest, out *InfoResponse) error - } - type Timezone struct { - timezone - } - h := &timezoneHandler{hdlr} - return s.Handle(s.NewHandler(&Timezone{h}, opts...)) -} - -type timezoneHandler struct { - TimezoneHandler -} - -func (h *timezoneHandler) Info(ctx context.Context, in *InfoRequest, out *InfoResponse) error { - return h.TimezoneHandler.Info(ctx, in, out) -} diff --git a/timezone/proto/timezone.proto b/timezone/proto/timezone.proto deleted file mode 100644 index 90b963d..0000000 --- a/timezone/proto/timezone.proto +++ /dev/null @@ -1,37 +0,0 @@ -syntax = "proto3"; - -package timezone; - -option go_package = "./proto;timezone"; - -service Timezone { - rpc Info(InfoRequest) returns (InfoResponse) {} -} - -// Get the timezone info for a specific location -message InfoRequest { - // location to lookup e.g postcode, city, ip address - string location = 1; -} - -message InfoResponse { - // location requested - string location = 1; - // region of timezone - string region = 2; - // country of the timezone - string country = 3; - // e.g 51.42 - double latitude = 4; - // e.g -0.37 - double longitude = 5; - // the timezone e.g Europe/London - string timezone = 6; - // the abbreviated code - string abbreviation = 7; - // the local time - string local_time = 8; - // is daylight savings - bool daylight_savings = 9; -} - diff --git a/timezone/publicapi.json b/timezone/publicapi.json deleted file mode 100644 index 7c5b5e0..0000000 --- a/timezone/publicapi.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "timezone", - "icon": "🌐", - "category": "time", - "pricing": { - "Timezone.Info": 5 - } -}