var express = require('express'); var fs = require('fs'); var _ = require('lodash'); var parseString = require("xml2js").parseString; var router = express.Router(); let convertFiles = true; // let convertFiles = false; let computeDataOnExtract = true; let jsonAllData = { tasks : {}, stats : {}, projects: {}, tags : {}, } /* GET home page. */ /** * obtenir la liste de tags que l'on a entré */ router.get('/', async function (req, res, next) { if (convertFiles) { convertOneXmlToJson('gtg_tasks', res) convertOneXmlToJson('tags', res) convertOneXmlToJson('projects', res) } else { console.log('================== conversion de fichiers désactivée dans index.js ================== ') } // récupérer le contenu des json jsonAllData.tags = require('../sources/tags_gtg.json') jsonAllData.tasks = require('../sources/gtg_tasks_gtg.json') if (computeDataOnExtract) { jsonAllData = computeData(jsonAllData) computeDataOnExtract = false; } else { console.log('================== calcul de stats désactivé dans index.js ================== ') } exportToMarkdown(res) console.log('json files read') res.render('index', { title: "Conversion de GTG tâches", json : jsonAllData, markdown : markdownExportData, getPercent, computeBgColorOnProportionOfOpenTasks, getPercentOfOpenTasks }) }); async function readfileJson(fileToOpen) { fs.readFile(`sources/${fileToOpen}`, "utf-8", function (err, data) { if (err) console.log(err); console.log('ok ', fileToOpen) return JSON.parse(data) }); } function computeData(jsonAllData) { // trouver le nombre de tâches ayant un tag en particulier // et rajouter ce nombre à chaque tag, dans countTasks : N // let tagCountTasks = Object.create(jsonAllData.tags); jsonAllData.stats = { tasksCount : jsonAllData.tasks.project.task.length, tasksClosed : 0, tasksOpen : 0, maxTasksCountPerTag: 0, listOpen : [], listOpenWeekly : [], listOpenMonthly : [], listClosed : [], listClosedWeekly : [], listDevWeeklyClosed : [], listClosedMonthly : [], } let now = new Date(); for (let t of jsonAllData.tasks.project.task) { // console.log('t', t) let tags = t["$"].tags.split(',') // count open and closed tasks let dateOfTask = new Date() if (t['$'].status == 'Active') { jsonAllData.stats.listOpen.push(t) let addeddate = new Date(t.addeddate) let daysDiff = getNumberOfDaysDiffTwoDates(addeddate, now); if (daysDiff <= 7) { jsonAllData.stats.listOpenWeekly.push(t) } else if (daysDiff >= 7 & daysDiff <= 31) { jsonAllData.stats.listOpenMonthly.push(t) } } else if (t['$'].status == 'Done') { jsonAllData.stats.listClosed.push(t) let donedate = new Date(t.donedate) let daysDiff = getNumberOfDaysDiffTwoDates(donedate, now); if (daysDiff <= 7) { jsonAllData.stats.listClosedWeekly.push(t) // tâches uniquement de dev if((/\b(dev|sysadmin|écriture|edu|fediverse)\b/g).test(t['$'].tags) ){ jsonAllData.stats.listDevWeeklyClosed.push(t) } } else if (daysDiff >= 7 & daysDiff <= 31) { jsonAllData.stats.listClosedMonthly.push(t) } } for (let tag of tags) { // console.log('tag', tag) jsonAllData.tags.tagstore.tag.map(elem => { // console.log('elem', elem) if (elem['$'].name == tag) { if (!elem.tasks) { elem.tasks = 0 } if (!elem.tasksListById) { elem.tasksListById = [] } if (!elem.tasksListByTitle) { elem.tasksListByTitle = [] } if (!elem.tasksListIsActiveByTitle) { elem.tasksListIsActiveByTitle = [] } if (!elem.tasksListIsDoneByTitle) { elem.tasksListIsDoneByTitle = [] } elem.tasks++ elem.tasksListById.push(t['$'].id) elem.tasksListByTitle.push(t.title) if (t['$'].status == "Active") { elem.tasksListIsActiveByTitle.push(t.title) } if (t['$'].status == "Done") { elem.tasksListIsDoneByTitle.push(t.title) } } if (elem.tasks > jsonAllData.stats.maxTasksCountPerTag) { jsonAllData.stats.maxTasksCountPerTag = elem.tasks } }) } } // sort tags by name return jsonAllData } const oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds function getNumberOfDaysDiffTwoDates(firstDate, secondDate) { return Math.round(Math.abs((firstDate - secondDate) / oneDay)); } function convertOneXmlToJson(fileToOpen, res) { fs.readFile(`sources/${fileToOpen}.xml`, "utf-8", function (err, data) { if (err) console.log(err); const results = transformToJson(data, fileToOpen, res) console.log('fichier converti en json', fileToOpen) }); } function getPercentOfOpenTasks(someCount) { return Math.round(100 * someCount / jsonAllData.stats.tasksOpen) } function getPercent(someCount, total) { return Math.round(100 * someCount / total) } function computeBgColorOnProportionOfOpenTasks(someProportionNumber) { let result = ''; if (someProportionNumber >= 95) { result = 'proportion-over-95' } else if (someProportionNumber >= 90) { result = 'proportion-over-90' } else if (someProportionNumber >= 80) { result = 'proportion-over-80' } else if (someProportionNumber >= 65) { result = 'proportion-over-65' } else if (someProportionNumber >= 50) { result = 'proportion-over-50' } else if (someProportionNumber >= 40) { result = 'proportion-over-40' } else if (someProportionNumber >= 25) { result = 'proportion-over-25' } else if (someProportionNumber >= 15) { result = 'proportion-over-15' } return result; } let datenow = new Date(); let markdownExportData = '' function exportToMarkdown(res) { markdownExportData = `# Export de Tâches GTG \n date: ` + datenow.toLocaleString() // fichier de rapport des tâches fermées durant les 7 derniers jours markdownExportData += `\n# Rapport hebdomadaire de dev `; markdownExportData += `\n## ${jsonAllData.stats.listDevWeeklyClosed.length} ont été fermées `; jsonAllData.stats.listDevWeeklyClosed.map(elem => { markdownExportData += `\n * ${elem.title}`; }) markdownExportData += `\n `; markdownExportData += `\n---`; markdownExportData += `\n `; markdownExportData += `\n# Rapport des tâches durant les 7 derniers jours `; markdownExportData += `\n `; markdownExportData += `\n## ${jsonAllData.stats.listClosedWeekly.length} ont été fermées `; markdownExportData += `\n `; jsonAllData.stats.listClosedWeekly.map(elem => { markdownExportData += `\n * ${elem.title}`; }) markdownExportData += `\n## ${jsonAllData.stats.listOpenWeekly.length} ont été ouvertes `; markdownExportData += `\n `; jsonAllData.stats.listOpenWeekly.map(elem => { markdownExportData += `\n * ${elem.title}`; }) markdownExportData += `\n--- `; // fichier de rapport des tâches fermées durant les 31 derniers jours markdownExportData += `\n# Rapport des autres tâches durant le mois `; markdownExportData += `\n `; markdownExportData += `\n## ${jsonAllData.stats.listClosedMonthly.length} ont été fermées `; markdownExportData += `\n `; jsonAllData.stats.listClosedMonthly.map(elem => { markdownExportData += `\n * ${elem.title}`; }) markdownExportData += `\n## ${jsonAllData.stats.listOpenMonthly.length} ont été ouvertes `; markdownExportData += `\n `; jsonAllData.stats.listOpenMonthly.map(elem => { markdownExportData += `\n * ${elem.title}`; }) markdownExportData += `\n--- `; // stats de fermeture des tâches markdownExportData += `\n# Stats de fermeture des tâches `; markdownExportData += `\n `; markdownExportData += `\n--- `; markdownExportData += `\n `; markdownExportData += `\n# Export de toutes les ${jsonAllData.stats.listOpen.length} tâches ouvertes GTG \n `; markdownExportData += `\n `; // jsonAllData.stats.listOpen.map(elem => { // dataTagsMd += `\n## ${elem.title} `; // dataTagsMd += `\n statut : ${elem['$'].status} `; // dataTagsMd += `\n créé le : ${elem.addeddate} `; // dataTagsMd += `\n modifié le : ${elem.modified} `; // dataTagsMd += `\n prévu pour : ${elem.duedate | ''} `; // dataTagsMd += `\n ${elem.content} `; // }) markdownExportData += `\n--- `; markdownExportData += `\n `; markdownExportData += `\n# Export de toutes les ${jsonAllData.stats.listClosed.length} tâches fermées GTG \n `; markdownExportData += `\n `; // // jsonAllData.stats.listClosed.map(elem=>{ // dataTagsMd += `\n * ${elem.title} `; // }) markdownExportData += `\n `; markdownExportData += `\n# Export de Tags GTG \n `; markdownExportData += `\n `; markdownExportData += `\n `; let sortedTagsByTitle = _.sortBy(jsonAllData.tags.tagstore.tag, [(o) => { o["$"].name }]) sortedTagsByTitle.map(elem => { markdownExportData += `\n * ${elem['$'].name} , ${elem.tasks | 0}`; }) markdownExportData += `\n `; markdownExportData += `\n rapport généré avec gtg2nodejs par tykayn - contact@cipherbliss.com `; // write file to disk fs.writeFile(`output/export_hebdo.md`, markdownExportData, `utf8`, (err) => { if (err) { console.log(`Error writing file: ${err}`); res.send(err) } else { console.log(`File \`output/export_tags.md\` is written successfully!`); } }); } function transformToJson(xml, fileToOpen, res) { return parseString(xml, function (err, result) { if (err) console.log(err); // console.dir(JSON.stringify(result)); console.log('Done'); // write file to disk fs.writeFile(`sources/${fileToOpen}_gtg.json`, JSON.stringify(result, null, 4), 'utf8', (err) => { if (err) { console.log(`Error writing file: ${err}`); // return JSON.stringify(result) res.send(err) } else { console.log(`File \`sources/${fileToOpen}_gtg.json\` is written successfully!`); } }); }); } module.exports = router;