Commit 30cb9fff authored by Rémi PAPIN's avatar Rémi PAPIN
Browse files

add files

parent 3c788727
# editorconfig.org
# editorconfig is a unified configuration file that all editors can take
# into account
root = true
[*]
charset = utf-8
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
build
node_modules
package.json
language: node_js
node_js:
- '12'
env:
global:
- MATTERMOST_CHANNEL=publication
# Token to access Cozy Registry, you should replace it with a token specific to this konnector
- secure: CQ44ZVjPAIVRvGgMcduSAX4VmaOrzF3nrJXPFUsNQ2tMVVdaAlI1zTNkdfntqigZgz6Mpk9x+2FcA8qrkNzQ4cW0lPP9f5dBtSH1xetfpXDFKprW4bqzmhgXSXJFTOYxkChOBPmCYJr+Vv4XqDkv/dBEPdfRSgvVyd5YxHSd5HBU91rKyR+Hox7LTnhmlXleLIs11EQgp7RK+L28MBCtCqAa2niFlKKRlqupm2FSpZzxCh9qeY0wKCQzPE+QZUm4waJ1SUGKQwbzAfyOxu2O6rwzaTSknfdJoSX6AMxjRTWBC9c3VfUGM3wjVJIqMhiUj2FQhVIjiDyX/W60/q3UMC5WYzSvEDDfhnKCPwiUKSU7HvSxx9q2YP34evxKo7KPahz9zLlQZvW+GBMyI9hbMDBTALuQVVzhftsvqfrogyYhkEPviiYiVADWNxhacsbUjRA5svXnZvtmCPo7fLFwel/krgC5Z8AwAY0YxWjSHNVScUkieSDCrlxrC09vTtG60unt9gtXbD5ruUkDLWSUwHBv2p0WY1TdP+2Vlf3yYfBvEVbqi59AxG+T17bq7Xv3QZnkrwC+UOCNCeg+gHPv+fRpUaYWzCO4uaoY/nlJa7RulQFhGca3A//6xRo/KgWw9JJnOXJelNjE9oHCUu9xShotUZKOF+O93V/BRqs9ITo=
cache:
yarn: true
directories:
- node_modules
branches:
except:
- build
- build-debug
script:
- yarn lint
- yarn build
- yarn run check
deploy:
- provider: script
skip-cleanup: true
script: DEPLOY_BRANCH=build yarn deploy && yarn cozyPublish
on:
branch: master
- provider: script
skip-cleanup: true
script: DEPLOY_BRANCH=build yarn deploy && yarn cozyPublish
on:
tags: true
before_install:
# run the yarn travisDeployKey command to genrate this
# - openssl aes-256-cbc -K $encrypted_0b21ecdcf920_key -iv $encrypted_0b21ecdcf920_iv
# -in github_deploy_key.enc -out /tmp/github_deploy_key -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/github_deploy_key
- ssh-add /tmp/github_deploy_key
after_deploy:
- rm /tmp/github_deploy_key
- ssh-add -D
# grdf-adict-konnector
[Cozy][cozy] <YOUR SUPER NEW KONNECTOR NAME>
=======================================
What's Cozy?
------------
![Cozy Logo](https://cdn.rawgit.com/cozy/cozy-guidelines/master/templates/cozy_logo_small.svg)
[Cozy] is a personal data platform that brings all your web services in the same private space. With it, your webapps and your devices can share data easily, providing you with a new experience. You can install Cozy on your own hardware where no one's tracking you.
What is this konnector about ?
------------------------------
This konnector retrieves your <SOME DATA> and <SOME OTHER DATA> from <SERVICE>
<YOUR DESCRIPTION HERE>
### Open a Pull-Request
If you want to work on this konnector and submit code modifications, feel free to open pull-requests!
</br>See :
* the [contributing guide][contribute] for more information about how to properly open pull-requests.
* the [konnectors development guide](https://docs.cozy.io/en/tutorials/konnector/)
### Run and test
Create a `konnector-dev-config.json` file at the root with your test credentials :
```javascript
{
"COZY_URL": "http://cozy.tools:8080",
"fields": {"login":"zuck.m@rk.fb", "password":"123456"}
}
```
Then :
```sh
yarn
yarn standalone
```
For running the konnector connected to a Cozy server and more details see [konnectors tutorial](https://docs.cozy.io/en/tutorials/konnector/)
### Cozy-konnector-libs
This connector uses [cozy-konnector-libs](https://github.com/cozy/cozy-konnector-libs). It brings a bunch of helpers to interact with the Cozy server and to fetch data from an online service.
### Maintainer
The lead maintainers for this konnector is <YOUR NAME>
### Get in touch
You can reach the Cozy Community by:
- [Konnectors tutorial](https://docs.cozy.io/en/tutorials/konnector/)
- Chatting with us on IRC [#cozycloud on Freenode][freenode]
- Posting on our [Forum]
- Posting issues on the [Github repos][github]
- Say Hi! on [Twitter]
License
-------
<YOUR KONNECTOR NAME> is developed by <your name> and distributed under the [AGPL v3 license][agpl-3.0].
[cozy]: https://cozy.io "Cozy Cloud"
[agpl-3.0]: https://www.gnu.org/licenses/agpl-3.0.html
[freenode]: http://webchat.freenode.net/?randomnick=1&channels=%23cozycloud&uio=d4
[forum]: https://forum.cozy.io/
[github]: https://github.com/cozy/
[nodejs]: https://nodejs.org/
[standard]: https://standardjs.com
[twitter]: https://twitter.com/mycozycloud
[webpack]: https://webpack.js.org
[yarn]: https://yarnpkg.com
[travis]: https://travis-ci.org
[contribute]: CONTRIBUTING.md
{
"COZY_URL": "http://cozy.tools:8080",
"fields": {
"login": "grdf_adict_bas",
"password": "wGe0MW13k"
"login": "metropole_de_lyon_grdf",
"password": "P-tndq12i+c?"
}
}
\ No newline at end of file
......@@ -40,7 +40,8 @@
"axios": "^0.20.0",
"cozy-konnector-libs": "4.34.5",
"moment": "^2.29.0",
"moment-timezone": "^0.5.31"
"moment-timezone": "^0.5.31",
"husky": "4.3.0"
},
"devDependencies": {
"copy-webpack-plugin": "6.1.1",
......
{
"extends": ["cozy-konnector"]
}
const {
cozyClient,
BaseKonnector,
addData,
hydrateAndFilter,
log,
utils
log
} = require('cozy-konnector-libs')
const axios = require('axios');
const https = require("https"); //optional for ssl issue
const https = require('https') //optional for ssl issue
const moment = require('moment')
require('moment-timezone')
......@@ -20,7 +19,7 @@ const startDate = moment()
.subtract(1, 'day')
.format('MM/DD/YYYY')
const endDate = moment().format('MM/DD/YYYY')
const timeRange = ['day', 'month', 'year']
/*const timeRange = ['day', 'month', 'year']
const rangeDate = {
day: {
doctype: 'com.grandlyon.grdf.day',
......@@ -36,6 +35,8 @@ const rangeDate = {
}
}
const client_id = 'metropole_de_lyon_grdf'
const redirectUrl = 'https://grdf.pchugo.wf.alpha.grandlyon.com'*/
module.exports = new BaseKonnector(start)
......@@ -46,16 +47,17 @@ module.exports = new BaseKonnector(start)
// secret api key.
async function start(fields, cozyParameters) {
log('info', 'Authenticating ...')
if (cozyParameters) log('debug', 'Found COZY_PARAMETERS')
if (cozyParameters) log('info', 'CozyParameters found')
const grdfToken = await authenticate(fields.login, fields.password)
log('info', 'Successfully logged in')
//Get the PCE of the client
log('info', 'Retrieve the PCE')
const grdfPCE = await getPCE(grdfToken)
// log('info', 'Retrieve the PCE')
// const grdfPCE = await getPCE(grdfToken)
// The BaseKonnector instance expects a Promise as return of the function
log('info', 'Fetching the data')
const periodeValeur = '' //TO REPLACE
const periodeValeur = 2020
const grdfPCE = 19108248691849 //FOR TESTING PURPOSE
const grdfData = await getData(grdfToken, grdfPCE, periodeValeur)
if (grdfData && grdfData.length > 0) {
......@@ -73,61 +75,65 @@ async function start(fields, cozyParameters) {
// Here we use the saveBills function even if what we fetch are not bills,
// but this is the most common case in connectors
log('info', 'Saving data to Cozy')
}
// This shows authentication using the [signin function](https://github.com/konnectors/libs/blob/master/packages/cozy-konnector-libs/docs/api.md#module_signin)
// even if this in another domain here, but it works as an example
async function authenticate(username, password) {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
var urlencoded = new URLSearchParams();
urlencoded.append("grant_type", "client_credentials");
urlencoded.append("client_id", username);
urlencoded.append("client_secret", password);
urlencoded.append("scope", "/adict/bas/v1");
//optional for ssl issue
//optional for ssl issue
const agent = new https.Agent({
rejectUnauthorized: false
})
var myHeaders = new Headers()
myHeaders.append('Content-Type', 'application/x-www-form-urlencoded')
myHeaders.append('Authorization', 'Basic cG9jX2FwaTpwb2NfYXBp')
var urlencoded = new URLSearchParams()
urlencoded.append('grant_type', 'client_credentials')
urlencoded.append('client_id', username) //metropole_de_lyon_grdf
urlencoded.append('client_secret', password) //P-tndq12i+c?
urlencoded.append('scope', '/adict/v1')
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow',
agent
};
}
const rep = await fetch("https://sofit-sso-oidc.grdf.fr/openam/oauth2/realms/externeGrdf/access_token", requestOptions).then(response => response.text())
const rep = await fetch(
'https://sofit-sso-oidc.grdf.fr/openam/oauth2/realms/externeGrdf/access_token',
requestOptions
)
.then(response => response.text())
.then(result => {
result = JSON.parse(result)
console.log(result.access_token)
log('info', result)
return result.access_token
})
.catch(error => {
throw new Error(error.message)
});
return rep
.catch(error => log('error', error))
return rep
}
async function getPCE(token){
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "Bearer " + token);
/*async function getPCE(token) {
var myHeaders = new Headers()
myHeaders.append('Content-Type', 'application/json')
myHeaders.append('Authorization', 'Bearer ' + token)
var urlencoded = new URLSearchParams();
var urlencoded = new URLSearchParams()
var requestOptions = {
method: 'GET',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
}
const rep = await fetch("https://api.grdf.fr/adict/bas/v2/droits_acces", requestOptions)
const rep = await fetch(
'https://api.grdf.fr/adict/bas/v2/droits_acces',
requestOptions
)
.then(response => response.text())
.then(result => {
result = JSON.parse(result)
......@@ -135,36 +141,42 @@ async function getPCE(token){
console.log(result.liste_acces[0].id_pce)
return result.liste_acces[0].id_pce
})
.catch(error => console.log('error', error));
return rep
}
.catch(error => console.log('error', error))
return rep
}*/
//Retrieve data from grdf API
async function getData(token, idPCE, periodeValeur){
async function getData(token, idPCE, periodeValeur) {
//LOG USE TO GET SOME DATA IN TEST MOD
periodeValeur = 2018;
idPCE = 11300000000002;
//REPLACE FOR PROD
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "Bearer " + token);
var myHeaders = new Headers()
myHeaders.append('Content-Type', 'application/x-ndjson')
myHeaders.append('Authorization', 'Bearer ' + token)
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
var urlFinal = periodeValeur.length == 0 ? "date_debut="+ startDate +"&date_fin=" + endDate : "periode="+ periodeValeur;
var url = "https://api.grdf.fr/adict/bas/v2/pce/"+ idPCE +"/donnees_consos_publiees?" + urlFinal;
}
var urlFinal =
periodeValeur.length == 0
? 'date_debut=' + startDate + '&date_fin=' + endDate
: 'periode=' + periodeValeur
var url =
'https://api.grdf.fr/adict/v1/pce/' +
idPCE +
'/donnees_consos_publiees?' +
urlFinal
const rep = await fetch(url, requestOptions)
.then(response => response.text())
.then(result => {
console.log(result)
//console.log(result)
return result
})
.catch(error => console.log('error', error));
return rep;
.catch(error => log('error', error))
return rep
}
/**
......@@ -175,11 +187,11 @@ async function getData(token, idPCE, periodeValeur){
*/
async function processData(data, doctype, filterKeys) {
const parsedData = JSON.parse(data)
console.log("parsedData")
console.log(parsedData)
log('info', 'parsedData')
log('info',parsedData)
const intervalData = parsedData.consommation
console.log("intervalData")
console.log(intervalData)
log('intervalData')
log('info',intervalData)
const formatedData = await formateData(intervalData, doctype)
// Remove data for existing days into the DB
const filteredData = await hydrateAndFilter(formatedData, doctype, {
......@@ -207,7 +219,7 @@ async function storeData(data, doctype, filterKeys) {
*/
async function formateData(data, doctype) {
log('info', 'Formating data')
return data.map(record => {
let date = moment(record.date, 'YYYY/MM/DD h:mm:ss')
if (record.value != -2) {
......@@ -233,7 +245,7 @@ async function formateData(data, doctype) {
/**
* Agregate data from load data (every 30 min) to Hourly data
*/
async function agregateHourlyData(data) {
/*async function agregateHourlyData(data) {
// Sum year and month values into object with year or year-month as keys
if (data && data.length > 0) {
let hourData = {}
......@@ -262,7 +274,7 @@ async function agregateHourlyData(data) {
'hour'
])
}
}
}*/
/**
* Agregate data from daily data to monthly and yearly data
*/
......@@ -297,8 +309,6 @@ async function agregateMonthAndYearData(data) {
}
}
/**
* Retrieve and remove old data for a specific doctype
* Return an Array of agregated data
......
var path = require('path')
const CopyPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
const fs = require('fs')
const SvgoInstance = require('svgo')
const entry = require('./package.json').main
const readManifest = () =>
JSON.parse(fs.readFileSync(path.join(__dirname, './manifest.konnector')))
const svgo = new SvgoInstance({
plugins: [
{
inlineStyles: { onlyMatchedOnce: false }
}
]
})
let iconName
try {
iconName = JSON.parse(fs.readFileSync('manifest.konnector', 'utf8')).icon
// we run optimize only on SVG
if (!iconName.match(/\.svg$/)) iconName = null
} catch (e) {
// console.error(`Unable to read the icon path from manifest: ${e}`)
}
const appIconRX = iconName && new RegExp(`[^/]*/${iconName}`)
module.exports = {
entry,
target: 'node',
mode: 'none',
output: {
path: path.join(__dirname, 'build'),
filename: 'index.js'
},
plugins: [
new CopyPlugin({
patterns: [
{ from: 'manifest.konnector' },
{ from: 'package.json' },
{ from: 'README.md' },
{ from: 'assets', transform: optimizeSVGIcon },
{ from: '.travis.yml' },
{ from: 'LICENSE' }
]
}),
new webpack.DefinePlugin({
__WEBPACK_PROVIDED_MANIFEST__: JSON.stringify(readManifest())
})
],
module: {
// to ignore the warnings like :
// WARNING in ../libs/node_modules/bindings/bindings.js 76:22-40
// Critical dependency: the request of a dependency is an expression
// Since we cannot change this dependency. I think it won't hide more important messages
exprContextCritical: false
}
}
function optimizeSVGIcon(buffer, path) {
if (appIconRX && path.match(appIconRX)) {
return svgo.optimize(buffer).then(resp => resp.data)
} else {
return buffer
}
}
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment