Public holidays API (#212)

This commit is contained in:
Dominic Wong
2021-09-21 18:51:19 +01:00
committed by GitHub
parent 09b06bd66f
commit 33653f7698
29 changed files with 1816 additions and 7 deletions

69
clients/go/holidays/holidays.go Executable file
View File

@@ -0,0 +1,69 @@
package holidays
import (
"github.com/m3o/m3o-go/client"
)
func NewHolidaysService(token string) *HolidaysService {
return &HolidaysService{
client: client.NewClient(&client.Options{
Token: token,
}),
}
}
type HolidaysService struct {
client *client.Client
}
//
func (t *HolidaysService) Countries(request *CountriesRequest) (*CountriesResponse, error) {
rsp := &CountriesResponse{}
return rsp, t.client.Call("holidays", "Countries", request, rsp)
}
//
func (t *HolidaysService) List(request *ListRequest) (*ListResponse, error) {
rsp := &ListResponse{}
return rsp, t.client.Call("holidays", "List", request, rsp)
}
type CountriesRequest struct {
}
type CountriesResponse struct {
Countries []Country `json:"countries"`
}
type Country struct {
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
Code string `json:"code"`
// The English name of the country
Name string `json:"name"`
}
type Holiday struct {
// the country this holiday occurs in
CountryCode string `json:"countryCode"`
// date of the holiday in yyyy-mm-dd format
Date string `json:"date"`
// the local name of the holiday
LocalName string `json:"localName"`
// the name of the holiday in English
Name string `json:"name"`
// the regions within the country that observe this holiday (if not all of them)
Regions []string `json:"regions"`
// the type of holiday Public, Bank, School, Authorities, Optional, Observance
Types []string `json:"types"`
}
type ListRequest struct {
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
CountryCode string `json:"countryCode"`
// The year to list holidays for
Year int64 `json:"year"`
}
type ListResponse struct {
Holidays []Holiday `json:"holidays"`
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/micro/services/clients/go/forex" "github.com/micro/services/clients/go/forex"
"github.com/micro/services/clients/go/geocoding" "github.com/micro/services/clients/go/geocoding"
"github.com/micro/services/clients/go/helloworld" "github.com/micro/services/clients/go/helloworld"
"github.com/micro/services/clients/go/holidays"
"github.com/micro/services/clients/go/id" "github.com/micro/services/clients/go/id"
"github.com/micro/services/clients/go/image" "github.com/micro/services/clients/go/image"
"github.com/micro/services/clients/go/ip" "github.com/micro/services/clients/go/ip"
@@ -52,6 +53,7 @@ func NewClient(token string) *Client {
ForexService: forex.NewForexService(token), ForexService: forex.NewForexService(token),
GeocodingService: geocoding.NewGeocodingService(token), GeocodingService: geocoding.NewGeocodingService(token),
HelloworldService: helloworld.NewHelloworldService(token), HelloworldService: helloworld.NewHelloworldService(token),
HolidaysService: holidays.NewHolidaysService(token),
IdService: id.NewIdService(token), IdService: id.NewIdService(token),
ImageService: image.NewImageService(token), ImageService: image.NewImageService(token),
IpService: ip.NewIpService(token), IpService: ip.NewIpService(token),
@@ -91,6 +93,7 @@ type Client struct {
ForexService *forex.ForexService ForexService *forex.ForexService
GeocodingService *geocoding.GeocodingService GeocodingService *geocoding.GeocodingService
HelloworldService *helloworld.HelloworldService HelloworldService *helloworld.HelloworldService
HolidaysService *holidays.HolidaysService
IdService *id.IdService IdService *id.IdService
ImageService *image.ImageService ImageService *image.ImageService
IpService *ip.IpService IpService *ip.IpService

View File

@@ -87,7 +87,7 @@ type Result struct {
// The associated arabic text // The associated arabic text
Text string `json:"text"` Text string `json:"text"`
// The related translations to the text // The related translations to the text
Translations []Translation `json:"translations"` Translations []Interpretation `json:"translations"`
// The unique verse id across the Quran // The unique verse id across the Quran
VerseId int32 `json:"verseId"` VerseId int32 `json:"verseId"`
// The verse key e.g 1:1 // The verse key e.g 1:1
@@ -161,7 +161,7 @@ type Verse struct {
// The basic translation of the verse // The basic translation of the verse
TranslatedText string `json:"translatedText"` TranslatedText string `json:"translatedText"`
// The alternative translations for the verse // The alternative translations for the verse
Translations []Translation `json:"translations"` Translations []Interpretation `json:"translations"`
// The phonetic transliteration from arabic // The phonetic transliteration from arabic
Transliteration string `json:"transliteration"` Transliteration string `json:"transliteration"`
// The individual words within the verse (Ayah) // The individual words within the verse (Ayah)

64
clients/ts/holidays/index.ts Executable file
View File

@@ -0,0 +1,64 @@
import * as m3o from "@m3o/m3o-node";
export class HolidaysService {
private client: m3o.Client;
constructor(token: string) {
this.client = new m3o.Client({ token: token });
}
//
countries(request: CountriesRequest): Promise<CountriesResponse> {
return this.client.call(
"holidays",
"Countries",
request
) as Promise<CountriesResponse>;
}
//
list(request: ListRequest): Promise<ListResponse> {
return this.client.call(
"holidays",
"List",
request
) as Promise<ListResponse>;
}
}
export interface CountriesRequest {}
export interface CountriesResponse {
countries?: Country[];
}
export interface Country {
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
code?: string;
// The English name of the country
name?: string;
}
export interface Holiday {
// the country this holiday occurs in
countryCode?: string;
// date of the holiday in yyyy-mm-dd format
date?: string;
// the local name of the holiday
localName?: string;
// the name of the holiday in English
name?: string;
// the regions within the country that observe this holiday (if not all of them)
regions?: string[];
// the type of holiday Public, Bank, School, Authorities, Optional, Observance
types?: string[];
}
export interface ListRequest {
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
countryCode?: string;
// The year to list holidays for
year?: number;
}
export interface ListResponse {
holidays?: Holiday[];
}

View File

@@ -10,6 +10,7 @@ import * as file from "./file";
import * as forex from "./forex"; import * as forex from "./forex";
import * as geocoding from "./geocoding"; import * as geocoding from "./geocoding";
import * as helloworld from "./helloworld"; import * as helloworld from "./helloworld";
import * as holidays from "./holidays";
import * as id from "./id"; import * as id from "./id";
import * as image from "./image"; import * as image from "./image";
import * as ip from "./ip"; import * as ip from "./ip";
@@ -46,6 +47,7 @@ export class Client {
this.forexService = new forex.ForexService(token); this.forexService = new forex.ForexService(token);
this.geocodingService = new geocoding.GeocodingService(token); this.geocodingService = new geocoding.GeocodingService(token);
this.helloworldService = new helloworld.HelloworldService(token); this.helloworldService = new helloworld.HelloworldService(token);
this.holidaysService = new holidays.HolidaysService(token);
this.idService = new id.IdService(token); this.idService = new id.IdService(token);
this.imageService = new image.ImageService(token); this.imageService = new image.ImageService(token);
this.ipService = new ip.IpService(token); this.ipService = new ip.IpService(token);
@@ -81,6 +83,7 @@ export class Client {
forexService: forex.ForexService; forexService: forex.ForexService;
geocodingService: geocoding.GeocodingService; geocodingService: geocoding.GeocodingService;
helloworldService: helloworld.HelloworldService; helloworldService: helloworld.HelloworldService;
holidaysService: holidays.HolidaysService;
idService: id.IdService; idService: id.IdService;
imageService: image.ImageService; imageService: image.ImageService;
ipService: ip.IpService; ipService: ip.IpService;

View File

@@ -21,6 +21,7 @@
"./forex": "./dist/forex/index.js", "./forex": "./dist/forex/index.js",
"./geocoding": "./dist/geocoding/index.js", "./geocoding": "./dist/geocoding/index.js",
"./helloworld": "./dist/helloworld/index.js", "./helloworld": "./dist/helloworld/index.js",
"./holidays": "./dist/holidays/index.js",
"./id": "./dist/id/index.js", "./id": "./dist/id/index.js",
"./image": "./dist/image/index.js", "./image": "./dist/image/index.js",
"./ip": "./dist/ip/index.js", "./ip": "./dist/ip/index.js",
@@ -59,5 +60,5 @@
}, },
"type": "module", "type": "module",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"version": "1.0.521" "version": "1.0.522"
} }

View File

@@ -87,7 +87,7 @@ export interface Result {
// The associated arabic text // The associated arabic text
text?: string; text?: string;
// The related translations to the text // The related translations to the text
translations?: Translation[]; translations?: Interpretation[];
// The unique verse id across the Quran // The unique verse id across the Quran
verseId?: number; verseId?: number;
// The verse key e.g 1:1 // The verse key e.g 1:1
@@ -149,7 +149,7 @@ export interface Verse {
// The unique id of the verse in the whole book // The unique id of the verse in the whole book
id?: number; id?: number;
// The interpretations of the verse // The interpretations of the verse
interpretations?: Translation[]; interpretations?: Interpretation[];
// The key of this verse (chapter:verse) e.g 1:1 // The key of this verse (chapter:verse) e.g 1:1
key?: string; key?: string;
// The verse number in this chapter // The verse number in this chapter
@@ -161,7 +161,7 @@ export interface Verse {
// The basic translation of the verse // The basic translation of the verse
translatedText?: string; translatedText?: string;
// The alternative translations for the verse // The alternative translations for the verse
translations?: Translation[]; translations?: Interpretation[];
// The phonetic transliteration from arabic // The phonetic transliteration from arabic
transliteration?: string; transliteration?: string;
// The individual words within the verse (Ayah) // The individual words within the verse (Ayah)

View File

@@ -0,0 +1,4 @@
curl "https://api.m3o.com/v1/holidays/Countries" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MICRO_API_TOKEN" \
-d '{}'

View File

@@ -0,0 +1,14 @@
package example
import (
"fmt"
"github.com/micro/services/clients/go/holidays"
"os"
)
//
func ListCountries() {
holidaysService := holidays.NewHolidaysService(os.Getenv("MICRO_API_TOKEN"))
rsp, err := holidaysService.Countries(&holidays.CountriesRequest{})
fmt.Println(rsp, err)
}

View File

@@ -0,0 +1,12 @@
import * as holidays from "m3o/holidays";
//
async function ListCountries() {
let holidaysService = new holidays.HolidaysService(
process.env.MICRO_API_TOKEN
);
let rsp = await holidaysService.countries({});
console.log(rsp);
}
await ListCountries();

View File

@@ -0,0 +1,7 @@
curl "https://api.m3o.com/v1/holidays/List" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MICRO_API_TOKEN" \
-d '{
"country_code": "GB",
"year": 2022
}'

View File

@@ -0,0 +1,16 @@
package example
import (
"fmt"
"github.com/micro/services/clients/go/holidays"
"os"
)
//
func GetHolidays() {
holidaysService := holidays.NewHolidaysService(os.Getenv("MICRO_API_TOKEN"))
rsp, err := holidaysService.List(&holidays.ListRequest{
Year: 2022,
})
fmt.Println(rsp, err)
}

View File

@@ -0,0 +1,15 @@
import * as holidays from "m3o/holidays";
//
async function GetHolidays() {
let holidaysService = new holidays.HolidaysService(
process.env.MICRO_API_TOKEN
);
let rsp = await holidaysService.list({
country_code: "GB",
year: 2022,
});
console.log(rsp);
}
await GetHolidays();

View File

@@ -11,9 +11,9 @@ func PublishAmessage() {
streamService := stream.NewStreamService(os.Getenv("MICRO_API_TOKEN")) streamService := stream.NewStreamService(os.Getenv("MICRO_API_TOKEN"))
rsp, err := streamService.Publish(&stream.PublishRequest{ rsp, err := streamService.Publish(&stream.PublishRequest{
Message: map[string]interface{}{ Message: map[string]interface{}{
"type": "signup",
"user": "john", "user": "john",
"id": "1", "id": "1",
"type": "signup",
}, },
Topic: "events", Topic: "events",
}) })

1
go.sum
View File

@@ -693,6 +693,7 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=

2
holidays/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
holidays

3
holidays/Dockerfile Normal file
View File

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

28
holidays/Makefile Normal file
View File

@@ -0,0 +1,28 @@
GOPATH:=$(shell go env GOPATH)
.PHONY: init
init:
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
go get github.com/micro/micro/v3/cmd/protoc-gen-micro
go get github.com/micro/micro/v3/cmd/protoc-gen-openapi
.PHONY: api
api:
protoc --openapi_out=. --proto_path=. proto/holidays.proto
.PHONY: proto
proto:
protoc --proto_path=. --micro_out=. --go_out=:. proto/holidays.proto
.PHONY: build
build:
go build -o holidays *.go
.PHONY: test
test:
go test -v ./... -cover
.PHONY: docker
docker:
docker build . -t holidays:latest

15
holidays/README.md Normal file
View File

@@ -0,0 +1,15 @@
Find the holidays observed in a particular country
# Holidays Service
List holidays observed in a country. Holidays may be at the country or region level.
Holiday types are:
- Public - public holiday
- Bank - banks and offices are closed
- School - schools are closed
- Authorities - Government or other authorities are closed
- Optional - A day where a majority of people take the day off
- Observance - Optional day off, typically unpaid
Powered by [Nager.Date](https://github.com/nager/Nager.Date/)

647
holidays/examples.json Normal file
View File

@@ -0,0 +1,647 @@
{
"countries": [{
"title": "List countries",
"run_check": true,
"request": {},
"response": {
"countries": [
{
"code": "AD",
"name": "Andorra"
},
{
"code": "AL",
"name": "Albania"
},
{
"code": "AR",
"name": "Argentina"
},
{
"code": "AT",
"name": "Austria"
},
{
"code": "AU",
"name": "Australia"
},
{
"code": "AX",
"name": "Åland Islands"
},
{
"code": "BA",
"name": "Bosnia and Herzegovina"
},
{
"code": "BB",
"name": "Barbados"
},
{
"code": "BE",
"name": "Belgium"
},
{
"code": "BG",
"name": "Bulgaria"
},
{
"code": "BJ",
"name": "Benin"
},
{
"code": "BO",
"name": "Bolivia"
},
{
"code": "BR",
"name": "Brazil"
},
{
"code": "BS",
"name": "Bahamas"
},
{
"code": "BW",
"name": "Botswana"
},
{
"code": "BY",
"name": "Belarus"
},
{
"code": "BZ",
"name": "Belize"
},
{
"code": "CA",
"name": "Canada"
},
{
"code": "CH",
"name": "Switzerland"
},
{
"code": "CL",
"name": "Chile"
},
{
"code": "CN",
"name": "China"
},
{
"code": "CO",
"name": "Colombia"
},
{
"code": "CR",
"name": "Costa Rica"
},
{
"code": "CU",
"name": "Cuba"
},
{
"code": "CY",
"name": "Cyprus"
},
{
"code": "CZ",
"name": "Czechia"
},
{
"code": "DE",
"name": "Germany"
},
{
"code": "DK",
"name": "Denmark"
},
{
"code": "DO",
"name": "Dominican Republic"
},
{
"code": "EC",
"name": "Ecuador"
},
{
"code": "EE",
"name": "Estonia"
},
{
"code": "EG",
"name": "Egypt"
},
{
"code": "ES",
"name": "Spain"
},
{
"code": "FI",
"name": "Finland"
},
{
"code": "FO",
"name": "Faroe Islands"
},
{
"code": "FR",
"name": "France"
},
{
"code": "GA",
"name": "Gabon"
},
{
"code": "GB",
"name": "United Kingdom"
},
{
"code": "GD",
"name": "Grenada"
},
{
"code": "GG",
"name": "Guernsey"
},
{
"code": "GI",
"name": "Gibraltar"
},
{
"code": "GL",
"name": "Greenland"
},
{
"code": "GM",
"name": "Gambia"
},
{
"code": "GR",
"name": "Greece"
},
{
"code": "GT",
"name": "Guatemala"
},
{
"code": "GY",
"name": "Guyana"
},
{
"code": "HN",
"name": "Honduras"
},
{
"code": "HR",
"name": "Croatia"
},
{
"code": "HT",
"name": "Haiti"
},
{
"code": "HU",
"name": "Hungary"
},
{
"code": "ID",
"name": "Indonesia"
},
{
"code": "IE",
"name": "Ireland"
},
{
"code": "IM",
"name": "Isle of Man"
},
{
"code": "IS",
"name": "Iceland"
},
{
"code": "IT",
"name": "Italy"
},
{
"code": "JE",
"name": "Jersey"
},
{
"code": "JM",
"name": "Jamaica"
},
{
"code": "JP",
"name": "Japan"
},
{
"code": "KR",
"name": "South Korea"
},
{
"code": "LI",
"name": "Liechtenstein"
},
{
"code": "LS",
"name": "Lesotho"
},
{
"code": "LT",
"name": "Lithuania"
},
{
"code": "LU",
"name": "Luxembourg"
},
{
"code": "LV",
"name": "Latvia"
},
{
"code": "MA",
"name": "Morocco"
},
{
"code": "MC",
"name": "Monaco"
},
{
"code": "MD",
"name": "Moldova"
},
{
"code": "ME",
"name": "Montenegro"
},
{
"code": "MG",
"name": "Madagascar"
},
{
"code": "MK",
"name": "North Macedonia"
},
{
"code": "MN",
"name": "Mongolia"
},
{
"code": "MS",
"name": "Montserrat"
},
{
"code": "MT",
"name": "Malta"
},
{
"code": "MX",
"name": "Mexico"
},
{
"code": "MZ",
"name": "Mozambique"
},
{
"code": "NA",
"name": "Namibia"
},
{
"code": "NE",
"name": "Niger"
},
{
"code": "NG",
"name": "Nigeria"
},
{
"code": "NI",
"name": "Nicaragua"
},
{
"code": "NL",
"name": "Netherlands"
},
{
"code": "NO",
"name": "Norway"
},
{
"code": "NZ",
"name": "New Zealand"
},
{
"code": "PA",
"name": "Panama"
},
{
"code": "PE",
"name": "Peru"
},
{
"code": "PG",
"name": "Papua New Guinea"
},
{
"code": "PL",
"name": "Poland"
},
{
"code": "PR",
"name": "Puerto Rico"
},
{
"code": "PT",
"name": "Portugal"
},
{
"code": "PY",
"name": "Paraguay"
},
{
"code": "RO",
"name": "Romania"
},
{
"code": "RS",
"name": "Serbia"
},
{
"code": "RU",
"name": "Russia"
},
{
"code": "SE",
"name": "Sweden"
},
{
"code": "SG",
"name": "Singapore"
},
{
"code": "SI",
"name": "Slovenia"
},
{
"code": "SJ",
"name": "Svalbard and Jan Mayen"
},
{
"code": "SK",
"name": "Slovakia"
},
{
"code": "SM",
"name": "San Marino"
},
{
"code": "SR",
"name": "Suriname"
},
{
"code": "SV",
"name": "El Salvador"
},
{
"code": "TN",
"name": "Tunisia"
},
{
"code": "TR",
"name": "Turkey"
},
{
"code": "UA",
"name": "Ukraine"
},
{
"code": "US",
"name": "United States"
},
{
"code": "UY",
"name": "Uruguay"
},
{
"code": "VA",
"name": "Vatican City"
},
{
"code": "VE",
"name": "Venezuela"
},
{
"code": "VN",
"name": "Vietnam"
},
{
"code": "ZA",
"name": "South Africa"
},
{
"code": "ZW",
"name": "Zimbabwe"
}
]
}
}],
"list": [
{
"title": "Get holidays",
"run_check": true,
"request": {"country_code": "GB", "year": 2022},
"response": {
"holidays": [
{
"date": "2022-01-01",
"name": "New Year's Day",
"local_name": "New Year's Day",
"country_code": "GB",
"regions": [
"GB-NIR"
],
"types": [
"Public"
]
},
{
"date": "2022-01-03",
"name": "New Year's Day",
"local_name": "New Year's Day",
"country_code": "GB",
"regions": [
"GB-ENG",
"GB-WLS"
],
"types": [
"Public"
]
},
{
"date": "2022-01-03",
"name": "New Year's Day",
"local_name": "New Year's Day",
"country_code": "GB",
"regions": [
"GB-SCT"
],
"types": [
"Public"
]
},
{
"date": "2022-01-04",
"name": "New Year's Day",
"local_name": "New Year's Day",
"country_code": "GB",
"regions": [
"GB-SCT"
],
"types": [
"Public"
]
},
{
"date": "2022-03-17",
"name": "Saint Patrick's Day",
"local_name": "Saint Patrick's Day",
"country_code": "GB",
"regions": [
"GB-NIR"
],
"types": [
"Public"
]
},
{
"date": "2022-04-15",
"name": "Good Friday",
"local_name": "Good Friday",
"country_code": "GB",
"regions": [],
"types": [
"Public"
]
},
{
"date": "2022-04-18",
"name": "Easter Monday",
"local_name": "Easter Monday",
"country_code": "GB",
"regions": [
"GB-ENG",
"GB-WLS",
"GB-NIR"
],
"types": [
"Public"
]
},
{
"date": "2022-05-02",
"name": "Early May Bank Holiday",
"local_name": "Early May Bank Holiday",
"country_code": "GB",
"regions": [],
"types": [
"Public"
]
},
{
"date": "2022-06-02",
"name": "Spring Bank Holiday",
"local_name": "Spring Bank Holiday",
"country_code": "GB",
"regions": [],
"types": [
"Public"
]
},
{
"date": "2022-06-03",
"name": "Queens Platinum Jubilee",
"local_name": "Queens Platinum Jubilee",
"country_code": "GB",
"regions": [],
"types": [
"Public"
]
},
{
"date": "2022-07-12",
"name": "Battle of the Boyne",
"local_name": "Battle of the Boyne",
"country_code": "GB",
"regions": [
"GB-NIR"
],
"types": [
"Public"
]
},
{
"date": "2022-08-01",
"name": "Summer Bank Holiday",
"local_name": "Summer Bank Holiday",
"country_code": "GB",
"regions": [
"GB-SCT"
],
"types": [
"Public"
]
},
{
"date": "2022-08-29",
"name": "Summer Bank Holiday",
"local_name": "Summer Bank Holiday",
"country_code": "GB",
"regions": [
"GB-ENG",
"GB-WLS",
"GB-NIR"
],
"types": [
"Public"
]
},
{
"date": "2022-11-30",
"name": "Saint Andrew's Day",
"local_name": "Saint Andrew's Day",
"country_code": "GB",
"regions": [
"GB-SCT"
],
"types": [
"Public"
]
},
{
"date": "2022-12-26",
"name": "St. Stephen's Day",
"local_name": "Boxing Day",
"country_code": "GB",
"regions": [],
"types": [
"Public"
]
},
{
"date": "2022-12-27",
"name": "Christmas Day",
"local_name": "Christmas Day",
"country_code": "GB",
"regions": [],
"types": [
"Public"
]
}
]
}
}
]
}

2
holidays/generate.go Normal file
View File

@@ -0,0 +1,2 @@
package main
//go:generate make proto

View File

@@ -0,0 +1,126 @@
package handler
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"github.com/micro/micro/v3/service/config"
"github.com/micro/micro/v3/service/errors"
log "github.com/micro/micro/v3/service/logger"
pb "github.com/micro/services/holidays/proto"
)
type Holidays struct {
conf conf
}
type conf struct {
NagerHost string `json:"nager_host"`
}
func New() *Holidays {
val, err := config.Get("micro.holidays")
if err != nil {
log.Fatalf("Failed to load config %s", err)
}
var conf conf
if err := val.Scan(&conf); err != nil {
log.Fatalf("Failed to load config %s", err)
}
if len(conf.NagerHost) == 0 {
log.Fatalf("Nager host not configured")
}
return &Holidays{conf: conf}
}
type nagerCountry struct {
CountryCode string `json:"countryCode"`
Name string `json:"name"`
}
func (h *Holidays) Countries(ctx context.Context, request *pb.CountriesRequest, response *pb.CountriesResponse) error {
rsp, err := http.Get(h.conf.NagerHost + "/api/v3/AvailableCountries")
if err != nil {
log.Errorf("Error listing available countries %s", err)
return errors.InternalServerError("holidays.countries", "Error retrieving country list")
}
defer rsp.Body.Close()
if rsp.StatusCode != 200 {
log.Errorf("Error listing available countries %s", rsp.Status)
return errors.InternalServerError("holidays.countries", "Error retrieving country list")
}
b, err := ioutil.ReadAll(rsp.Body)
if err != nil {
log.Errorf("Error processing available countries %s", err)
return errors.InternalServerError("holidays.countries", "Error retrieving country list")
}
var rspArr []nagerCountry
if err := json.Unmarshal(b, &rspArr); err != nil {
log.Errorf("Error processing available countries %s", err)
return errors.InternalServerError("holidays.countries", "Error retrieving country list")
}
response.Countries = make([]*pb.Country, len(rspArr))
for i, c := range rspArr {
response.Countries[i] = &pb.Country{
Code: c.CountryCode,
Name: c.Name,
}
}
return nil
}
type nagerHoliday struct {
Date string `json:"date"`
LocalName string `json:"localName"`
Name string `json:"name"`
CountryCode string `json:"countryCode"`
Counties []string `json:"counties"`
Types []string `json:"types"`
}
func (h Holidays) List(ctx context.Context, request *pb.ListRequest, response *pb.ListResponse) error {
if request.Year == 0 {
return errors.BadRequest("holidays.list", "Missing year argument")
}
if len(request.CountryCode) == 0 {
return errors.BadRequest("holidays.list", "Missing country code argument")
}
rsp, err := http.Get(fmt.Sprintf("%s/api/v3/PublicHolidays/%d/%s", h.conf.NagerHost, request.Year, request.CountryCode))
if err != nil {
log.Errorf("Error listing available countries %s", err)
return errors.InternalServerError("holidays.list", "Error retrieving holidays list")
}
defer rsp.Body.Close()
if rsp.StatusCode != 200 {
log.Errorf("Error listing holidays %s", rsp.Status)
return errors.InternalServerError("holidays.list", "Error retrieving holidays list")
}
b, err := ioutil.ReadAll(rsp.Body)
if err != nil {
log.Errorf("Error processing holidays %s", err)
return errors.InternalServerError("holidays.countries", "Error retrieving holidays list")
}
var rspArr []nagerHoliday
if err := json.Unmarshal(b, &rspArr); err != nil {
log.Errorf("Error processing holidays %s", err)
return errors.InternalServerError("holidays.countries", "Error retrieving holidays list")
}
response.Holidays = make([]*pb.Holiday, len(rspArr))
for i, c := range rspArr {
response.Holidays[i] = &pb.Holiday{
Date: c.Date,
Name: c.Name,
LocalName: c.LocalName,
CountryCode: c.CountryCode,
Regions: c.Counties,
Types: c.Types,
}
}
return nil
}

25
holidays/main.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"github.com/micro/services/holidays/handler"
pb "github.com/micro/services/holidays/proto"
"github.com/micro/micro/v3/service"
"github.com/micro/micro/v3/service/logger"
)
func main() {
// Create service
srv := service.New(
service.Name("holidays"),
service.Version("latest"),
)
// Register handler
pb.RegisterHolidaysHandler(srv.Server(), handler.New())
// Run service
if err := srv.Run(); err != nil {
logger.Fatal(err)
}
}

1
holidays/micro.mu Normal file
View File

@@ -0,0 +1 @@
service holidays

40
holidays/nager-k8s.yaml Normal file
View File

@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: nager-latest
labels:
app: nager
spec:
replicas: 2
selector:
matchLabels:
app: nager
template:
metadata:
labels:
app: nager
spec:
containers:
- name: nager
image: nager/nager-date:latest
ports:
- containerPort: 80
env:
- name: EnableCors
value: "true"
- name: EnableIpRateLimiting
value: "false"
---
apiVersion: v1
kind: Service
metadata:
name: nager
spec:
selector:
app: nager
ports:
- protocol: TCP
port: 80
targetPort: 80

View File

@@ -0,0 +1,540 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.26.0
// protoc v3.15.5
// source: proto/holidays.proto
package holidays
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)
)
type CountriesRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *CountriesRequest) Reset() {
*x = CountriesRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_holidays_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CountriesRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CountriesRequest) ProtoMessage() {}
func (x *CountriesRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_holidays_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 CountriesRequest.ProtoReflect.Descriptor instead.
func (*CountriesRequest) Descriptor() ([]byte, []int) {
return file_proto_holidays_proto_rawDescGZIP(), []int{0}
}
type CountriesResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Countries []*Country `protobuf:"bytes,1,rep,name=countries,proto3" json:"countries,omitempty"`
}
func (x *CountriesResponse) Reset() {
*x = CountriesResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_holidays_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CountriesResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CountriesResponse) ProtoMessage() {}
func (x *CountriesResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_holidays_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 CountriesResponse.ProtoReflect.Descriptor instead.
func (*CountriesResponse) Descriptor() ([]byte, []int) {
return file_proto_holidays_proto_rawDescGZIP(), []int{1}
}
func (x *CountriesResponse) GetCountries() []*Country {
if x != nil {
return x.Countries
}
return nil
}
type Country struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
// The English name of the country
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *Country) Reset() {
*x = Country{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_holidays_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Country) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Country) ProtoMessage() {}
func (x *Country) ProtoReflect() protoreflect.Message {
mi := &file_proto_holidays_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 Country.ProtoReflect.Descriptor instead.
func (*Country) Descriptor() ([]byte, []int) {
return file_proto_holidays_proto_rawDescGZIP(), []int{2}
}
func (x *Country) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
func (x *Country) GetName() string {
if x != nil {
return x.Name
}
return ""
}
type ListRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
CountryCode string `protobuf:"bytes,1,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
// The year to list holidays for
Year int64 `protobuf:"varint,2,opt,name=year,proto3" json:"year,omitempty"`
}
func (x *ListRequest) Reset() {
*x = ListRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_holidays_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListRequest) ProtoMessage() {}
func (x *ListRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_holidays_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 ListRequest.ProtoReflect.Descriptor instead.
func (*ListRequest) Descriptor() ([]byte, []int) {
return file_proto_holidays_proto_rawDescGZIP(), []int{3}
}
func (x *ListRequest) GetCountryCode() string {
if x != nil {
return x.CountryCode
}
return ""
}
func (x *ListRequest) GetYear() int64 {
if x != nil {
return x.Year
}
return 0
}
type ListResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Holidays []*Holiday `protobuf:"bytes,1,rep,name=holidays,proto3" json:"holidays,omitempty"`
}
func (x *ListResponse) Reset() {
*x = ListResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_holidays_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ListResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ListResponse) ProtoMessage() {}
func (x *ListResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_holidays_proto_msgTypes[4]
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 ListResponse.ProtoReflect.Descriptor instead.
func (*ListResponse) Descriptor() ([]byte, []int) {
return file_proto_holidays_proto_rawDescGZIP(), []int{4}
}
func (x *ListResponse) GetHolidays() []*Holiday {
if x != nil {
return x.Holidays
}
return nil
}
type Holiday struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// date of the holiday in yyyy-mm-dd format
Date string `protobuf:"bytes,1,opt,name=date,proto3" json:"date,omitempty"`
// the name of the holiday in English
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
// the local name of the holiday
LocalName string `protobuf:"bytes,3,opt,name=local_name,json=localName,proto3" json:"local_name,omitempty"`
// the country this holiday occurs in
CountryCode string `protobuf:"bytes,4,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
// the regions within the country that observe this holiday (if not all of them)
Regions []string `protobuf:"bytes,5,rep,name=regions,proto3" json:"regions,omitempty"`
// the type of holiday Public, Bank, School, Authorities, Optional, Observance
Types []string `protobuf:"bytes,6,rep,name=types,proto3" json:"types,omitempty"`
}
func (x *Holiday) Reset() {
*x = Holiday{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_holidays_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Holiday) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Holiday) ProtoMessage() {}
func (x *Holiday) ProtoReflect() protoreflect.Message {
mi := &file_proto_holidays_proto_msgTypes[5]
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 Holiday.ProtoReflect.Descriptor instead.
func (*Holiday) Descriptor() ([]byte, []int) {
return file_proto_holidays_proto_rawDescGZIP(), []int{5}
}
func (x *Holiday) GetDate() string {
if x != nil {
return x.Date
}
return ""
}
func (x *Holiday) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Holiday) GetLocalName() string {
if x != nil {
return x.LocalName
}
return ""
}
func (x *Holiday) GetCountryCode() string {
if x != nil {
return x.CountryCode
}
return ""
}
func (x *Holiday) GetRegions() []string {
if x != nil {
return x.Regions
}
return nil
}
func (x *Holiday) GetTypes() []string {
if x != nil {
return x.Types
}
return nil
}
var File_proto_holidays_proto protoreflect.FileDescriptor
var file_proto_holidays_proto_rawDesc = []byte{
0x0a, 0x14, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73,
0x22, 0x12, 0x0a, 0x10, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x22, 0x44, 0x0a, 0x11, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65,
0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x68,
0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x52,
0x09, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x31, 0x0a, 0x07, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x44, 0x0a,
0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x79, 0x65, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x79,
0x65, 0x61, 0x72, 0x22, 0x3d, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73,
0x2e, 0x48, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x52, 0x08, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61,
0x79, 0x73, 0x22, 0xa3, 0x01, 0x0a, 0x07, 0x48, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x12, 0x12,
0x0a, 0x04, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61,
0x74, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f,
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x6f, 0x63, 0x61,
0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79,
0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x67, 0x69,
0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x67, 0x69, 0x6f,
0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
0x09, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x32, 0x8b, 0x01, 0x0a, 0x08, 0x48, 0x6f, 0x6c,
0x69, 0x64, 0x61, 0x79, 0x73, 0x12, 0x46, 0x0a, 0x09, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x69,
0x65, 0x73, 0x12, 0x1a, 0x2e, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x2e, 0x43, 0x6f,
0x75, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b,
0x2e, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72,
0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x37, 0x0a,
0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73,
0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68,
0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x12, 0x5a, 0x10, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x3b, 0x68, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_proto_holidays_proto_rawDescOnce sync.Once
file_proto_holidays_proto_rawDescData = file_proto_holidays_proto_rawDesc
)
func file_proto_holidays_proto_rawDescGZIP() []byte {
file_proto_holidays_proto_rawDescOnce.Do(func() {
file_proto_holidays_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_holidays_proto_rawDescData)
})
return file_proto_holidays_proto_rawDescData
}
var file_proto_holidays_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_holidays_proto_goTypes = []interface{}{
(*CountriesRequest)(nil), // 0: holidays.CountriesRequest
(*CountriesResponse)(nil), // 1: holidays.CountriesResponse
(*Country)(nil), // 2: holidays.Country
(*ListRequest)(nil), // 3: holidays.ListRequest
(*ListResponse)(nil), // 4: holidays.ListResponse
(*Holiday)(nil), // 5: holidays.Holiday
}
var file_proto_holidays_proto_depIdxs = []int32{
2, // 0: holidays.CountriesResponse.countries:type_name -> holidays.Country
5, // 1: holidays.ListResponse.holidays:type_name -> holidays.Holiday
0, // 2: holidays.Holidays.Countries:input_type -> holidays.CountriesRequest
3, // 3: holidays.Holidays.List:input_type -> holidays.ListRequest
1, // 4: holidays.Holidays.Countries:output_type -> holidays.CountriesResponse
4, // 5: holidays.Holidays.List:output_type -> holidays.ListResponse
4, // [4:6] is the sub-list for method output_type
2, // [2:4] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proto_holidays_proto_init() }
func file_proto_holidays_proto_init() {
if File_proto_holidays_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_holidays_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CountriesRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_holidays_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CountriesResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_holidays_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Country); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_holidays_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_holidays_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ListResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_holidays_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Holiday); 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_holidays_proto_rawDesc,
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_holidays_proto_goTypes,
DependencyIndexes: file_proto_holidays_proto_depIdxs,
MessageInfos: file_proto_holidays_proto_msgTypes,
}.Build()
File_proto_holidays_proto = out.File
file_proto_holidays_proto_rawDesc = nil
file_proto_holidays_proto_goTypes = nil
file_proto_holidays_proto_depIdxs = nil
}

View File

@@ -0,0 +1,114 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: proto/holidays.proto
package holidays
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 Holidays service
func NewHolidaysEndpoints() []*api.Endpoint {
return []*api.Endpoint{}
}
// Client API for Holidays service
type HolidaysService interface {
// Get the list of countries that are supported by this API
Countries(ctx context.Context, in *CountriesRequest, opts ...client.CallOption) (*CountriesResponse, error)
// List the holiday dates for a given country and year
List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error)
}
type holidaysService struct {
c client.Client
name string
}
func NewHolidaysService(name string, c client.Client) HolidaysService {
return &holidaysService{
c: c,
name: name,
}
}
func (c *holidaysService) Countries(ctx context.Context, in *CountriesRequest, opts ...client.CallOption) (*CountriesResponse, error) {
req := c.c.NewRequest(c.name, "Holidays.Countries", in)
out := new(CountriesResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *holidaysService) List(ctx context.Context, in *ListRequest, opts ...client.CallOption) (*ListResponse, error) {
req := c.c.NewRequest(c.name, "Holidays.List", in)
out := new(ListResponse)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Holidays service
type HolidaysHandler interface {
// Get the list of countries that are supported by this API
Countries(context.Context, *CountriesRequest, *CountriesResponse) error
// List the holiday dates for a given country and year
List(context.Context, *ListRequest, *ListResponse) error
}
func RegisterHolidaysHandler(s server.Server, hdlr HolidaysHandler, opts ...server.HandlerOption) error {
type holidays interface {
Countries(ctx context.Context, in *CountriesRequest, out *CountriesResponse) error
List(ctx context.Context, in *ListRequest, out *ListResponse) error
}
type Holidays struct {
holidays
}
h := &holidaysHandler{hdlr}
return s.Handle(s.NewHandler(&Holidays{h}, opts...))
}
type holidaysHandler struct {
HolidaysHandler
}
func (h *holidaysHandler) Countries(ctx context.Context, in *CountriesRequest, out *CountriesResponse) error {
return h.HolidaysHandler.Countries(ctx, in, out)
}
func (h *holidaysHandler) List(ctx context.Context, in *ListRequest, out *ListResponse) error {
return h.HolidaysHandler.List(ctx, in, out)
}

View File

@@ -0,0 +1,52 @@
syntax = "proto3";
package holidays;
option go_package = "./proto;holidays";
service Holidays {
// Get the list of countries that are supported by this API
rpc Countries(CountriesRequest) returns (CountriesResponse) {}
// List the holiday dates for a given country and year
rpc List(ListRequest) returns (ListResponse) {}
}
message CountriesRequest {
}
message CountriesResponse {
repeated Country countries = 1;
}
message Country {
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
string code = 1;
// The English name of the country
string name = 2;
}
message ListRequest {
// The 2 letter country code (as defined in ISO 3166-1 alpha-2)
string country_code = 1;
// The year to list holidays for
int64 year = 2;
}
message ListResponse {
repeated Holiday holidays = 1;
}
message Holiday {
// date of the holiday in yyyy-mm-dd format
string date = 1;
// the name of the holiday in English
string name = 2;
// the local name of the holiday
string local_name = 3;
// the country this holiday occurs in
string country_code = 4;
// the regions within the country that observe this holiday (if not all of them)
repeated string regions = 5;
// the type of holiday Public, Bank, School, Authorities, Optional, Observance
repeated string types = 6;
}

5
holidays/publicapi.json Normal file
View File

@@ -0,0 +1,5 @@
{
"name": "holidays",
"icon": "🏖️",
"category": "util"
}