add month stat for done
This commit is contained in:
parent
9774c15d65
commit
ced08a36ac
193
app.js
193
app.js
|
@ -1,15 +1,18 @@
|
||||||
const fs = require('node-fs')
|
const fs = require('node-fs');
|
||||||
const sourceFilePath = './sources/tasks.json';
|
const sourceFilePath = './sources/tasks.json';
|
||||||
const stats = {
|
const stats = {
|
||||||
countAllTasks: 0,
|
countAllTasks: 0,
|
||||||
tasksByDay: {}
|
tasksByDay : [],
|
||||||
}
|
tasksByMonth : [],
|
||||||
|
tasksByYear : [],
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// const enableFilterByTag = true;
|
// const enableFilterByTag = true;
|
||||||
const enableFilterByTag = false;
|
const enableFilterByTag = false;
|
||||||
const filterByTag = "work";
|
const filterByTag = 'work';
|
||||||
// const outputFileName = "work_report";
|
// const outputFileName = "work_report";
|
||||||
const outputFileName = "all_tasks_report";
|
const outputFileName = 'all_tasks_report';
|
||||||
let countExcluded = 0;
|
let countExcluded = 0;
|
||||||
let countIncluded = 0;
|
let countIncluded = 0;
|
||||||
|
|
||||||
|
@ -19,10 +22,10 @@ console.log(` ### lecture de ${sourceFilePath}`);
|
||||||
fs.stat(sourceFilePath, function (err, stat) {
|
fs.stat(sourceFilePath, function (err, stat) {
|
||||||
if (err == null) {
|
if (err == null) {
|
||||||
console.log(`File ${sourceFilePath} exists`);
|
console.log(`File ${sourceFilePath} exists`);
|
||||||
sortTasksFromJson(stat)
|
sortTasksFromJson(stat);
|
||||||
} else if (err.code === 'ENOENT') {
|
} else if (err.code === 'ENOENT') {
|
||||||
// file does not exist
|
// file does not exist
|
||||||
console.error(`le fichier ${sourceFilePath} est introuvable. Impossible d en extraire des infos.`, err)
|
console.error(`le fichier ${sourceFilePath} est introuvable. Impossible d en extraire des infos.`, err);
|
||||||
} else {
|
} else {
|
||||||
console.log('Some other error: ', err.code);
|
console.log('Some other error: ', err.code);
|
||||||
}
|
}
|
||||||
|
@ -30,22 +33,21 @@ fs.stat(sourceFilePath, function (err, stat) {
|
||||||
|
|
||||||
// parcourir les tâches
|
// parcourir les tâches
|
||||||
function sortTasksFromJson(statObject) {
|
function sortTasksFromJson(statObject) {
|
||||||
console.log('sortTasksFromJson')
|
console.log('sortTasksFromJson');
|
||||||
fs.readFile(sourceFilePath, 'utf8', function (err, data) {
|
fs.readFile(sourceFilePath, 'utf8', function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return console.log(err);
|
return console.log(err);
|
||||||
}
|
}
|
||||||
let dataTransformed = JSON.parse(data);
|
let dataTransformed = JSON.parse(data);
|
||||||
// console.log('data keys ', Object.keys(dataTransformed))
|
// console.log('data keys ', Object.keys(dataTransformed))
|
||||||
if (dataTransformed["contents"]) {
|
if (dataTransformed['contents']) {
|
||||||
|
|
||||||
|
countTasks = dataTransformed['contents'].length;
|
||||||
countTasks = dataTransformed["contents"].length
|
|
||||||
stats.countAllTasks = countTasks;
|
stats.countAllTasks = countTasks;
|
||||||
|
|
||||||
console.log('yes data ! tasks:', countTasks)
|
console.log('yes data ! tasks:', countTasks);
|
||||||
|
|
||||||
dataTransformed["contents"].forEach((elem, index) => {
|
dataTransformed['contents'].forEach((elem, index) => {
|
||||||
|
|
||||||
// console.log('tâche ', index)
|
// console.log('tâche ', index)
|
||||||
// évacuer les sous tâches
|
// évacuer les sous tâches
|
||||||
|
@ -56,29 +58,28 @@ function sortTasksFromJson(statObject) {
|
||||||
// }
|
// }
|
||||||
// filtrer par tag les tâches
|
// filtrer par tag les tâches
|
||||||
if (enableFilterByTag) {
|
if (enableFilterByTag) {
|
||||||
console.log('filtre activé', filterByTag)
|
console.log('filtre activé', filterByTag);
|
||||||
if (!elem['drawer'] || !elem['properties']['tags']) {
|
if (!elem['drawer'] || !elem['properties']['tags']) {
|
||||||
|
|
||||||
|
console.log('on vire cette tâche n\'ayant pas de drawer :', elem);
|
||||||
console.log('on vire cette tâche n\'ayant pas de drawer :', elem)
|
|
||||||
countExcluded++;
|
countExcluded++;
|
||||||
return;
|
return;
|
||||||
} else if (
|
} else if (
|
||||||
elem['properties'] &&
|
elem['properties'] &&
|
||||||
typeof elem['properties']['tags'] !== "undefined" &&
|
typeof elem['properties']['tags'] !== 'undefined' &&
|
||||||
elem['properties']['tags'].indexOf(filterByTag) === -1
|
elem['properties']['tags'].indexOf(filterByTag) === -1
|
||||||
) {
|
) {
|
||||||
console.log('on vire cette tâche ayant les itags :', elem['drawer']['ARCHIVE_ITAGS'])
|
console.log('on vire cette tâche ayant les itags :', elem['drawer']['ARCHIVE_ITAGS']);
|
||||||
countExcluded++;
|
countExcluded++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(' - filtre désactivé')
|
console.log(' - filtre désactivé');
|
||||||
}
|
}
|
||||||
// après le filtre, on range les tâches
|
// après le filtre, on range les tâches
|
||||||
|
|
||||||
if (elem['properties']) {
|
if (elem['properties']) {
|
||||||
console.log(' - ref ', elem['ref'])
|
console.log(' - ref ', elem['ref']);
|
||||||
let title = elem['properties']['raw-value'];
|
let title = elem['properties']['raw-value'];
|
||||||
let tags = elem['tags'] ? elem['tags'] : [];
|
let tags = elem['tags'] ? elem['tags'] : [];
|
||||||
let closeDate = 'Indéfini';
|
let closeDate = 'Indéfini';
|
||||||
|
@ -101,44 +102,100 @@ function sortTasksFromJson(statObject) {
|
||||||
// jour, 11 premiers caractères
|
// jour, 11 premiers caractères
|
||||||
|
|
||||||
let day = closeDate.substring(0, 10);
|
let day = closeDate.substring(0, 10);
|
||||||
if (!stats.tasksByDay[day]) {
|
let month = closeDate.substring(0, 7);
|
||||||
stats.tasksByDay[day] = []
|
console.log('month', month)
|
||||||
}
|
let year = closeDate.substring(0, 4);
|
||||||
stats.tasksByDay[day].push({
|
let taskDescription = {
|
||||||
todoKeyword,
|
todoKeyword,
|
||||||
title,
|
title,
|
||||||
day,
|
day,
|
||||||
closeDate,
|
closeDate,
|
||||||
tags,
|
tags,
|
||||||
})
|
};
|
||||||
|
|
||||||
|
if (!stats.tasksByDay[day]) {
|
||||||
|
stats.tasksByDay[day] = [];
|
||||||
|
}
|
||||||
|
if (!stats.tasksByMonth[month]) {
|
||||||
|
stats.tasksByMonth[month] = {
|
||||||
|
period: month,
|
||||||
|
tasks : [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (!stats.tasksByYear[year]) {
|
||||||
|
stats.tasksByYear[year] = {
|
||||||
|
period: year,
|
||||||
|
tasks : [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.tasksByDay[day].push(taskDescription);
|
||||||
|
stats.tasksByMonth[month].tasks.push(taskDescription);
|
||||||
|
stats.tasksByYear[year].tasks.push(taskDescription);
|
||||||
// console.log(' ' + title)
|
// console.log(' ' + title)
|
||||||
countIncluded++;
|
countIncluded++;
|
||||||
} else {
|
} else {
|
||||||
console.log('no', elem['properties']['raw-value'])
|
console.log('no', elem['properties']['raw-value']);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
} else {
|
|
||||||
console.log('no content')
|
|
||||||
}
|
|
||||||
// console.log(data);
|
|
||||||
console.log('tâches inclues:', countIncluded)
|
|
||||||
writeHtmlOutput()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
console.log('no content');
|
||||||
|
}
|
||||||
|
// console.log(data);
|
||||||
|
console.log('tâches inclues:', countIncluded);
|
||||||
|
writeHtmlOutput();
|
||||||
|
});
|
||||||
|
|
||||||
// les répartir dans des tableaux selon les périodes de temps
|
// les répartir dans des tableaux selon les périodes de temps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retourne un html présentant le nombre de tâches réalisées pour chaque mois
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function RenderStatsMonth() {
|
||||||
|
|
||||||
|
let months = Object.keys(stats.tasksByMonth);
|
||||||
|
console.log('months.length', months.length);
|
||||||
|
|
||||||
|
let monthHTML = '';
|
||||||
|
|
||||||
|
|
||||||
|
months.forEach((elem) => {
|
||||||
|
|
||||||
|
monthData = stats.tasksByMonth[elem]
|
||||||
|
console.log('monthData.tasks.length', monthData.tasks.length)
|
||||||
|
|
||||||
|
monthHTML += `
|
||||||
|
<div class='columns'>
|
||||||
|
<div class='column'>
|
||||||
|
<h2 class='title is-2'>
|
||||||
|
${monthData.period}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<div class='column'>
|
||||||
|
${monthData.tasks.length}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
return `
|
||||||
|
<div class='box'>
|
||||||
|
<h1 class='title is-1'>Stats mensuelles</h1>
|
||||||
|
${monthHTML}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
// sortir un html présentant les périodes de temps et les tâches réalisées
|
// sortir un html présentant les périodes de temps et les tâches réalisées
|
||||||
function writeHtmlOutput() {
|
function writeHtmlOutput() {
|
||||||
console.log('writeHtmlOutput', stats.countAllTasks)
|
console.log('writeHtmlOutput', stats.countAllTasks);
|
||||||
|
|
||||||
let daysListRef = Object.keys(stats.tasksByDay).sort()
|
let daysListRef = Object.keys(stats.tasksByDay).sort();
|
||||||
let filterInfo = ``
|
let filterInfo = ``;
|
||||||
if (enableFilterByTag) {
|
if (enableFilterByTag) {
|
||||||
filterInfo = `<p class="is-info">Contenu filtré sur le tag: ${filterByTag}. ${countExcluded} tâches exclues, ${countIncluded} tâches inclues sur le total de ${countExcluded + countIncluded}</p>`
|
filterInfo = `<p class='is-info'>Contenu filtré sur le tag: ${filterByTag}. ${countExcluded} tâches exclues, ${countIncluded} tâches inclues sur le total de ${countExcluded + countIncluded}</p>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let htmlOut = `
|
let htmlOut = `
|
||||||
|
@ -147,25 +204,26 @@ function writeHtmlOutput() {
|
||||||
<title>
|
<title>
|
||||||
Rapport d'activité
|
Rapport d'activité
|
||||||
</title>
|
</title>
|
||||||
<meta charset="UTF-8" />
|
<meta charset='UTF-8' />
|
||||||
<style>
|
<style>
|
||||||
@import "https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css";
|
@import "https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css";
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="report_days" class="container content">
|
<div id='report_days' class='container content'>
|
||||||
<h1 class="title is-1">Feuille de rapport d'activité</h1>
|
<h1 class='title is-1'>Feuille de rapport d'activité</h1>
|
||||||
<p class="subtitle is-1">par <a href="https://www.cipherbliss.com">Tykayn</a> </p>
|
<p class='subtitle is-1'>par <a href='https://www.cipherbliss.com'>Tykayn</a> </p>
|
||||||
${filterInfo}
|
${filterInfo}
|
||||||
|
${RenderStatsMonth()}
|
||||||
|
|
||||||
`
|
`;
|
||||||
daysListRef.reverse().forEach((dayRefString) => {
|
daysListRef.reverse().forEach((dayRefString) => {
|
||||||
|
|
||||||
let tasksOfTheDay = '';
|
let tasksOfTheDay = '';
|
||||||
|
|
||||||
stats.tasksByDay[dayRefString].forEach((dayObj) => {
|
stats.tasksByDay[dayRefString].forEach((dayObj) => {
|
||||||
let graphicKeyword = '✅'
|
let graphicKeyword = '✅';
|
||||||
if ('DONE' !== dayObj.todoKeyword) {
|
if ('DONE' !== dayObj.todoKeyword) {
|
||||||
graphicKeyword = dayObj.todoKeyword;
|
graphicKeyword = dayObj.todoKeyword;
|
||||||
}
|
}
|
||||||
|
@ -173,78 +231,77 @@ function writeHtmlOutput() {
|
||||||
let tagDisplay = '';
|
let tagDisplay = '';
|
||||||
// console.log('dayObj.tags', dayObj.tags)
|
// console.log('dayObj.tags', dayObj.tags)
|
||||||
if (dayObj.tags && dayObj.tags.length) {
|
if (dayObj.tags && dayObj.tags.length) {
|
||||||
tagDisplay = ` <p class="archived-tags tag is-light is-primary">
|
tagDisplay = ` <p class='archived-tags tag is-light is-primary'>
|
||||||
${dayObj.tags}
|
${dayObj.tags}
|
||||||
</p>
|
</p>
|
||||||
`
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
tasksOfTheDay += ` <li>
|
tasksOfTheDay += ` <li>
|
||||||
<h2>
|
<h2>
|
||||||
<span class="keyword"> ${graphicKeyword}</span>
|
<span class='keyword'> ${graphicKeyword}</span>
|
||||||
<span class="title"> ${dayObj.title} </span>
|
<span class='title'> ${dayObj.title} </span>
|
||||||
</h2>
|
</h2>
|
||||||
${tagDisplay}
|
${tagDisplay}
|
||||||
</li>`
|
</li>`;
|
||||||
})
|
});
|
||||||
htmlOut += `
|
htmlOut += `
|
||||||
<div class="box">
|
<div class='box'>
|
||||||
|
|
||||||
<h1 class="title is-1">
|
<h1 class='title is-1'>
|
||||||
<span class="day-ref">
|
<span class='day-ref'>
|
||||||
${dayRefString}
|
${dayRefString}
|
||||||
</span>
|
</span>
|
||||||
<span class="counter pull-right tag is-success is-light">
|
<span class='counter pull-right tag is-success is-light'>
|
||||||
${stats.tasksByDay[dayRefString].length}
|
${stats.tasksByDay[dayRefString].length}
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div class="day-detail">
|
<div class='day-detail'>
|
||||||
<ul>
|
<ul>
|
||||||
${tasksOfTheDay}
|
${tasksOfTheDay}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div> `
|
</div> `;
|
||||||
})
|
});
|
||||||
htmlOut += `
|
htmlOut += `
|
||||||
<div class="box">
|
<div class='box'>
|
||||||
<h1 class="title is-1">
|
<h1 class='title is-1'>
|
||||||
|
|
||||||
Tadam, c'est tout!
|
Tadam, c'est tout!
|
||||||
</h1>
|
</h1>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
Source: <a href="https://forge.chapril.org/tykayn/org-report-stats">org-report-stats</a>
|
Source: <a href='https://forge.chapril.org/tykayn/org-report-stats'>org-report-stats</a>
|
||||||
<br>
|
<br>
|
||||||
Contactez-moi: <a href="https://www.cipherbliss.com/contact">par un de ces moyens</a>
|
Contactez-moi: <a href='https://www.cipherbliss.com/contact'>par un de ces moyens</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`
|
`;
|
||||||
|
|
||||||
fs.writeFile('output/output.json', JSON.stringify(stats), function (err, data) {
|
fs.writeFile('output/output.json', JSON.stringify(stats), function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return console.log(err);
|
return console.log(err);
|
||||||
}
|
}
|
||||||
console.log('wrote output json', data)
|
console.log('wrote output json', data);
|
||||||
})
|
});
|
||||||
fs.writeFile('output/output_' + outputFileName + '.html', htmlOut, function (err, data) {
|
fs.writeFile('output/output_' + outputFileName + '.html', htmlOut, function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return console.log(err);
|
return console.log(err);
|
||||||
}
|
}
|
||||||
console.log('wrote output html ' + outputFileName, data)
|
console.log('wrote output html ' + outputFileName, data);
|
||||||
|
|
||||||
})
|
});
|
||||||
if (enableFilterByTag) {
|
if (enableFilterByTag) {
|
||||||
console.log('excluded tasks by tag filter ', countExcluded)
|
console.log('excluded tasks by tag filter ', countExcluded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function sortObj(obj) {
|
function sortObj(obj) {
|
||||||
return Object.keys(obj).sort().reduce(function (result, key) {
|
return Object.keys(obj).sort().reduce(function (result, key) {
|
||||||
result[key] = obj[key];
|
result[key] = obj[key];
|
||||||
|
|
Loading…
Reference in New Issue