-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0cdb65d
commit f548f96
Showing
2 changed files
with
135 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
local extension = ... | ||
|
||
local logger = extension:getLogger() | ||
local Promise = require('jls.lang.Promise') | ||
local HttpClient = require('jls.net.http.HttpClient') | ||
local Url = require('jls.net.Url') | ||
local Date = require('jls.util.Date') | ||
|
||
local Thing = require('lha.Thing') | ||
|
||
local function concatPath(a, b) | ||
if string.find(a, '/$') then | ||
return a..b | ||
end | ||
return a..'/'..b | ||
end | ||
|
||
local function createThing() | ||
return Thing:new('School Calendar', 'French school calendar', 'BinarySensor'):addProperty('holiday', { | ||
['@type'] = 'BooleanProperty', | ||
title = 'Holiday', | ||
type = 'boolean', | ||
description = 'Holiday', | ||
readOnly = true | ||
}, '') | ||
end | ||
|
||
local function whereIn(name, year) | ||
return string.format("%s > date'%s-01-01' and %s < date'%s-12-31'", name, year, name, year) | ||
end | ||
|
||
local function getRecords(year) | ||
local configuration = extension:getConfiguration() | ||
local url = Url:new(configuration.apiUrl) -- https://data.opendatasoft.com/api/explore/v2.1/ | ||
local path = concatPath(url:getPath(), 'catalog/datasets/'..configuration.datasetId..'/records') | ||
local resource = path..'?'..Url.mapToQuery({limit = 20, refine = { | ||
'location:"'..configuration.location..'"', 'population:"-"' | ||
}, where = string.format("(%s) or (%s)", whereIn('start_date', year), whereIn('end_date', year))}) | ||
logger:fine('fetching %s', resource) | ||
local client = HttpClient:new(url) | ||
return client:fetch(resource):next(function(response) | ||
if response:getStatusCode() == 200 then | ||
return response:json() | ||
end | ||
return Promise.reject('Response status is '..response:getStatusCode()) | ||
end):next(function(records) | ||
if type(records) == 'table' and type(records.results) == 'table' and #records.results == records.total_count and records.total_count > 0 then | ||
return records.results | ||
end | ||
return Promise.reject('Invalid response') | ||
end):finally(function() | ||
client:close() | ||
end) | ||
end | ||
|
||
local function findRecord(records, time) | ||
for _, record in ipairs(records) do | ||
local startTime = Date.fromISOString(record.start_date, true) | ||
local endTime = Date.fromISOString(record.end_date, true) | ||
if time >= startTime and time < endTime then | ||
return record | ||
end | ||
end | ||
end | ||
|
||
local function updateThing(thing, records) | ||
local holiday = findRecord(records, Date.now()) ~= nil | ||
--logger:info('updateThing() christmas: %s, holiday: %s', findRecord(records, Date.fromISOString('2025-12-25', true)) ~= nil, holiday) | ||
logger:fine('updateThing() holiday: %s', holiday) | ||
thing:updatePropertyValue('holiday', holiday) | ||
end | ||
|
||
local year | ||
local records | ||
local thing | ||
|
||
local function update() | ||
if thing then | ||
local y = os.date('%Y') | ||
if records and y == year then | ||
updateThing(thing, records) | ||
else | ||
getRecords(y):next(function(r) | ||
logger:fine('records %T', r) | ||
records = r | ||
year = y | ||
if logger:isLoggable(logger.INFO) then | ||
for _, record in ipairs(records) do | ||
logger:info('%s %s %s', record.start_date, record.end_date, record.description) | ||
end | ||
end | ||
updateThing(thing, records) | ||
end):catch(function(reason) | ||
logger:warn('Fail to fetch records due to %s', reason) | ||
end) | ||
end | ||
end | ||
end | ||
|
||
extension:subscribeEvent('things', function() | ||
thing = extension:syncDiscoveredThingByKey('calendrier-scolaire', createThing) | ||
update() | ||
end) | ||
|
||
extension:subscribeEvent('refresh', update) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"name": "Calendrier Scolaire", | ||
"description": "Retrieve french school calendar", | ||
"version": "0.1", | ||
"script": "calendrier-scolaire.lua", | ||
"schema": { | ||
"type": "object", | ||
"properties": { | ||
"apiUrl": { | ||
"title": "API URL", | ||
"type": "string", | ||
"pattern": "^https?://.+$", | ||
"default": "https://data.opendatasoft.com/api/explore/v2.1/" | ||
}, | ||
"datasetId": { | ||
"title": "Dataset", | ||
"type": "string", | ||
"pattern": "^[%w%-@_]+$", | ||
"required": true, | ||
"default": "fr-en-calendrier-scolaire@dataeducation" | ||
}, | ||
"location": { | ||
"title": "Location", | ||
"type": "string", | ||
"required": true, | ||
"default": "Normandie" | ||
} | ||
} | ||
} | ||
} |