replace timezone with time

This commit is contained in:
Asim Aslam
2021-06-21 19:42:12 +01:00
parent f920ed4558
commit 9f1e0f3778
19 changed files with 812 additions and 550 deletions

3
time/Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM alpine
ADD time /time
ENTRYPOINT [ "/time" ]

View File

@@ -9,15 +9,15 @@ init:
.PHONY: api .PHONY: api
api: api:
protoc --openapi_out=. --proto_path=. proto/timezone.proto protoc --openapi_out=. --proto_path=. proto/time.proto
.PHONY: proto .PHONY: proto
proto: proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/timezone.proto protoc --proto_path=. --micro_out=. --go_out=:. proto/time.proto
.PHONY: build .PHONY: build
build: build:
go build -o timezone *.go go build -o time *.go
.PHONY: test .PHONY: test
test: test:
@@ -25,4 +25,4 @@ test:
.PHONY: docker .PHONY: docker
docker: docker:
docker build . -t timezone:latest docker build . -t time:latest

View File

@@ -1,6 +1,6 @@
Time, date and timezone info Time, date and timezone info
# Timezone Service # Time Service
Get the time, date and timezone info for any given location in the world. Get the time, date and timezone info for any given location in the world.

148
time/handler/time.go Normal file
View File

@@ -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
}

View File

@@ -3,19 +3,19 @@ package main
import ( import (
"github.com/micro/micro/v3/service" "github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger" "github.com/micro/micro/v3/service/logger"
"github.com/micro/services/timezone/handler" "github.com/micro/services/time/handler"
pb "github.com/micro/services/timezone/proto" pb "github.com/micro/services/time/proto"
) )
func main() { func main() {
// Create service // Create service
srv := service.New( srv := service.New(
service.Name("timezone"), service.Name("time"),
service.Version("latest"), service.Version("latest"),
) )
// Register handler // Register handler
pb.RegisterTimezoneHandler(srv.Server(), handler.New()) pb.RegisterTimeHandler(srv.Server(), handler.New())
// Run service // Run service
if err := srv.Run(); err != nil { if err := srv.Run(); err != nil {

1
time/micro.mu Normal file
View File

@@ -0,0 +1 @@
service time

475
time/proto/time.pb.go Normal file
View File

@@ -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
}

110
time/proto/time.pb.micro.go Normal file
View File

@@ -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)
}

58
time/proto/time.proto Normal file
View File

@@ -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;
}

8
time/publicapi.json Normal file
View File

@@ -0,0 +1,8 @@
{
"name": "time",
"icon": "🌐",
"category": "timezone",
"pricing": {
"Time.Zone": 5
}
}

View File

@@ -1,3 +0,0 @@
FROM alpine
ADD timezone /timezone
ENTRYPOINT [ "/timezone" ]

View File

@@ -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
}

View File

@@ -1 +0,0 @@
service timezone

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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;
}

View File

@@ -1,8 +0,0 @@
{
"name": "timezone",
"icon": "🌐",
"category": "time",
"pricing": {
"Timezone.Info": 5
}
}