2021-02-27 10:26:37 +01:00
var express = require ( 'express' ) ;
2021-03-01 18:02:04 +01:00
var fs = require ( 'fs' ) ;
2021-03-02 11:57:31 +01:00
var _ = require ( 'lodash' ) ;
2021-03-01 18:02:04 +01:00
var parseString = require ( "xml2js" ) . parseString ;
2021-02-27 10:26:37 +01:00
var router = express . Router ( ) ;
2021-03-03 16:55:41 +01:00
let searchTagsForHebdoReport = /\b(dev|sysadmin|écriture|edu|fediverse|april|chapril)\b/g ;
2021-03-02 12:26:19 +01:00
let convertFiles = true ;
// let convertFiles = false;
2021-03-02 10:12:15 +01:00
let computeDataOnExtract = true ;
2021-03-03 16:34:29 +01:00
// let computeDataOnExtract = false;
2021-03-01 18:14:47 +01:00
2021-03-02 09:23:33 +01:00
let jsonAllData = {
2021-09-10 14:54:04 +02:00
all : { } ,
tasks : { } ,
stats : { } ,
projects : { } ,
tags : { } ,
2021-09-10 15:14:55 +02:00
weeklyDevReport : ''
2021-03-01 18:02:04 +01:00
}
2021-02-27 10:26:37 +01:00
/* GET home page. */
2021-03-01 18:02:04 +01:00
/ * *
2021-09-10 14:54:04 +02:00
* convertir le fichier XML et
* obtenir la liste de tags que l ' on a entré dans GTG
2021-03-01 18:02:04 +01:00
* /
2021-03-03 16:34:29 +01:00
router . get ( '/xml' , async function ( req , res , next ) {
2021-03-01 18:14:47 +01:00
2021-09-10 14:54:04 +02:00
console . log ( ' ### lecture de sources/gtg_data.xml' ) ;
fs . stat ( 'sources/gtg_data.xml' , function ( err , stat ) {
if ( err == null ) {
console . log ( 'File sources/gtg_data.xml exists' ) ;
} else if ( err . code === 'ENOENT' ) {
// file does not exist
res . send ( 'le fichier sources/gtg_data.xml est introuvable. Impossible d en extraire des infos. Importez d abord les fichiers de données xml de Getting Things Gnome dans le dossier sources' )
} else {
console . log ( 'Some other error: ' , err . code ) ;
}
} ) ;
convertOneXmlToJson ( 'gtg_data' , res )
console . log ( 'success conversion xml' )
res . render ( 'layout' , {
title : 'Conversion en Json' ,
message : 'ok fichier converti'
} )
// res.redirect('/')
2021-03-03 16:34:29 +01:00
} )
2021-09-10 14:54:04 +02:00
/ * *
* voir le compte rendu des tâches
* /
2021-03-03 16:34:29 +01:00
router . get ( '/' , async function ( req , res , next ) {
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
console . log ( " ### récupérer le contenu des json sources/gtg_data_gtg.json" )
jsonAllData . all = require ( '../sources/gtg_data_gtg.json' )
if ( ! jsonAllData . all . gtgData ) {
res . redirect ( '/xml' )
}
if ( computeDataOnExtract ) {
jsonAllData = computeData ( jsonAllData )
computeDataOnExtract = false ;
} else {
console . log ( '================== calcul de stats désactivé dans index.js ================== ' )
}
exportToMarkdown ( res )
2021-09-10 15:41:27 +02:00
exportToOrgmode ( res )
2021-09-10 14:54:04 +02:00
console . log ( 'json files read' )
res . render ( 'index' , {
title : "Conversion de GTG tâches" ,
json : jsonAllData ,
markdown : markdownExportData ,
getPercent ,
computeBgColorOnProportionOfOpenTasks ,
getPercentOfOpenTasks
} )
2021-03-02 09:23:33 +01:00
} ) ;
2021-03-02 10:57:26 +01:00
async function readfileJson ( fileToOpen ) {
2021-09-10 14:54:04 +02:00
fs . readFile ( ` sources/ ${ fileToOpen } ` , "utf-8" , function ( err , data ) {
if ( err ) console . log ( err ) ;
console . log ( 'ok ' , fileToOpen )
return JSON . parse ( data )
} ) ;
2021-03-02 09:23:33 +01:00
}
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
function computeData ( jsonConvertedData ) {
let gtgData = jsonConvertedData . all . gtgData
console . log ( '================== calcul des tâches depuis le fichier json ================== ' )
console . log ( 'gtgData : ' ) ;
console . log ( gtgData ) ;
// trouver le nombre de tâches ayant un tag en particulier
// et rajouter ce nombre à chaque tag, dans countTasks : N
2021-09-10 15:02:40 +02:00
let counterOfTasks = gtgData . tasklist [ 0 ] . task
2021-09-10 14:54:04 +02:00
// compter les tâches
// console.log('counterOfTasks',counterOfTasks);
2021-09-10 15:02:40 +02:00
jsonAllData . all = gtgData
2021-09-10 14:54:04 +02:00
jsonAllData . stats = {
2021-09-10 15:41:27 +02:00
tasksCount : counterOfTasks . length ,
2021-09-10 15:02:40 +02:00
// tasksCount: 0,
2021-09-10 14:54:04 +02:00
tasksClosed : 0 ,
tasksOpen : 0 ,
maxTasksCountPerTag : 0 ,
listTags : [ ] ,
2021-09-10 15:41:27 +02:00
tagByKey : { } ,
2021-09-10 16:27:07 +02:00
taskByKey : { } ,
2021-09-10 15:41:27 +02:00
listAll : [ ] ,
2021-09-10 14:54:04 +02:00
listOpen : [ ] ,
listOpenWeekly : [ ] ,
listOpenMonthly : [ ] ,
listClosed : [ ] ,
listClosedWeekly : [ ] ,
2021-09-10 15:14:55 +02:00
tasksListIsDismissByTitle : [ ] ,
2021-09-10 14:54:04 +02:00
listDevWeeklyClosed : [ ] ,
listDevWeeklyOpen : [ ] ,
listClosedMonthly : [ ] ,
2021-03-02 11:57:31 +01:00
}
2021-09-10 14:54:04 +02:00
let now = new Date ( ) ;
jsonAllData . stats . listTags = gtgData . taglist [ 0 ] . tag
console . log ( 'tasks' , gtgData . tasklist [ 0 ] . task ) ;
2021-09-10 15:41:27 +02:00
for ( let tagItem of jsonAllData . stats . listTags ) {
jsonAllData . stats . tagByKey [ tagItem [ "$" ] . id ] = tagItem [ "$" ]
}
2021-09-10 14:54:04 +02:00
for ( let taskItem of gtgData . tasklist [ 0 ] . task ) {
2021-09-10 16:27:07 +02:00
jsonAllData . stats . taskByKey [ taskItem [ "$" ] . id ] = taskItem
2021-09-10 14:54:04 +02:00
// count open and closed tasks
let now = new Date ( )
2021-09-10 15:41:27 +02:00
jsonAllData . stats . listAll . push ( taskItem )
2021-09-10 14:54:04 +02:00
if ( taskItem [ '$' ] . status == 'Active' ) {
jsonAllData . stats . listOpen . push ( taskItem )
let addeddate = new Date ( taskItem . addeddate )
let daysDiff = getNumberOfDaysDiffTwoDates ( addeddate , now ) ;
if ( daysDiff <= 7 ) {
jsonAllData . stats . listOpenWeekly . push ( taskItem )
// listDevWeeklyOpen
// tâches uniquement de dev
if ( ( searchTagsForHebdoReport ) . test ( taskItem [ '$' ] . tags )
) {
jsonAllData . stats . listDevWeeklyOpen . push ( taskItem )
}
} else if ( daysDiff >= 7 & daysDiff <= 31 ) {
jsonAllData . stats . listOpenMonthly . push ( taskItem )
}
} else if ( taskItem [ '$' ] . status == 'Done' ) {
jsonAllData . stats . listClosed . push ( taskItem )
let donedate = new Date ( taskItem . donedate )
let daysDiff = getNumberOfDaysDiffTwoDates ( donedate , now ) ;
if ( daysDiff <= 7 ) {
jsonAllData . stats . listClosedWeekly . push ( taskItem )
// tâches uniquement de dev
if ( ( searchTagsForHebdoReport ) . test ( taskItem [ '$' ] . tags )
) {
jsonAllData . stats . listDevWeeklyClosed . push ( taskItem )
}
} else if ( daysDiff >= 7 & daysDiff <= 31 ) {
jsonAllData . stats . listClosedMonthly . push ( taskItem )
}
2021-03-02 11:57:31 +01:00
2021-03-02 09:53:16 +01:00
}
2021-03-02 11:10:53 +01:00
2021-09-10 14:54:04 +02:00
for ( let tag of jsonAllData . stats . listTags ) {
// console.log('tag', tag)
2021-09-10 15:14:55 +02:00
jsonAllData . stats . listTags . 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 ( taskItem [ '$' ] . id )
elem . tasksListByTitle . push ( taskItem . title )
if ( taskItem [ '$' ] . status == "Active" ) {
elem . tasksListIsActiveByTitle . push ( taskItem . title )
}
if ( taskItem [ '$' ] . status == "Done" ) {
elem . tasksListIsDoneByTitle . push ( taskItem . title )
}
if ( taskItem [ '$' ] . status == "Dismiss" ) {
elem . tasksListIsDismissByTitle . push ( taskItem . title )
}
}
if ( elem . tasks > jsonAllData . stats . maxTasksCountPerTag ) {
jsonAllData . stats . maxTasksCountPerTag = elem . tasks
}
} )
2021-09-10 14:54:04 +02:00
}
2021-03-02 09:53:16 +01:00
}
2021-09-10 14:54:04 +02:00
// sort tags by name
2021-03-02 11:57:31 +01:00
2021-09-10 15:02:40 +02:00
console . log ( 'stats' , jsonAllData ) ;
return jsonAllData
2021-03-01 18:02:04 +01:00
2021-03-02 09:23:33 +01:00
}
2021-03-02 10:57:26 +01:00
2021-03-02 12:09:05 +01:00
const oneDay = 24 * 60 * 60 * 1000 ; // hours*minutes*seconds*milliseconds
function getNumberOfDaysDiffTwoDates ( firstDate , secondDate ) {
2021-09-10 14:54:04 +02:00
return Math . round ( Math . abs ( ( firstDate - secondDate ) / oneDay ) ) ;
2021-03-02 12:09:05 +01:00
}
2021-03-02 10:57:26 +01:00
function convertOneXmlToJson ( fileToOpen , res ) {
2021-09-10 14:54:04 +02:00
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' , res )
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
} ) ;
2021-03-01 18:02:04 +01:00
}
2021-03-02 10:57:26 +01:00
function getPercentOfOpenTasks ( someCount ) {
2021-09-10 14:54:04 +02:00
return Math . round ( 100 * someCount / jsonAllData . stats . tasksOpen )
2021-03-02 10:57:26 +01:00
}
function getPercent ( someCount , total ) {
2021-09-10 14:54:04 +02:00
return Math . round ( 100 * someCount / total )
2021-03-02 10:57:26 +01:00
}
function computeBgColorOnProportionOfOpenTasks ( someProportionNumber ) {
2021-09-10 14:54:04 +02:00
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 ;
2021-03-02 10:57:26 +01:00
}
2021-09-10 14:54:04 +02:00
2021-03-02 12:26:19 +01:00
let datenow = new Date ( ) ;
2021-03-03 16:19:11 +01:00
let markdownExportData = ''
2021-09-10 15:14:55 +02:00
let dataTagsMd = ''
2021-09-10 14:54:04 +02:00
2021-03-02 11:10:53 +01:00
2021-09-10 15:14:55 +02:00
function exportToMarkdown ( res ) {
let weeklyDevReport = ''
2021-09-10 14:54:04 +02:00
console . log ( 'jsonAllData.stats' , jsonAllData . stats ) ;
markdownExportData = ` # Export de Tâches GTG \n date: ` + datenow . toLocaleString ( )
2021-09-10 15:14:55 +02:00
// fichier de rapport des tâches fermées durant les 7 derniers jours
weeklyDevReport = ` \n # Rapport hebdomadaire de dev ` ;
weeklyDevReport += ` \n ## 1/ Actions passées ou en cours
\ n `
weeklyDevReport += ` \r \n ## ${ jsonAllData . stats . listDevWeeklyClosed . length } ont été fermées
\ n _ _ _ ` ;
jsonAllData . stats . listDevWeeklyClosed . map ( elem => {
weeklyDevReport += ` \n | ${ elem [ '$' ] . tags } | ${ elem . title } | ` ;
} )
weeklyDevReport += `
\ n _ _ _
\ n
\ n # # 2 / Actions à venir
\ n `
weeklyDevReport += ` \r \n ## ${ jsonAllData . stats . listDevWeeklyOpen . length } ont été ouvertes
\ n _ _ _ ` ;
jsonAllData . stats . listDevWeeklyOpen . map ( elem => {
// weeklyDevReport += `\n| ${elem['$'].tags} | ${elem.title}|`;
weeklyDevReport += ` \n | ${ elem . title } | ` ;
} )
weeklyDevReport += `
\ n _ _ _
\ n
\ n # # 3 / Points de blocage / points en retard corrigés cette semaine
\ n
\ n # # 4 / Points de blocage existants / points en retard à traiter
\ n
\ n # # 5 / Points forts de la semaine
\ n
\ n # # 6 / Points de vigilance de la semaine
\ n
\ n # # 7 / Points forts de la réunion
\ n
\ n # # 8 / Points de vigilance de la réunion ` ;
markdownExportData += ` \n ${ weeklyDevReport } ` ;
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 => {
2021-09-10 15:41:27 +02:00
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 } ` ;
2021-09-10 15:14:55 +02:00
} )
markdownExportData += ` \n --- ` ;
markdownExportData += ` \n ` ;
markdownExportData += ` \n # Export de toutes les ${ jsonAllData . stats . listClosed . length } tâches fermées GTG \n ` ;
markdownExportData += ` \n ` ;
2021-09-10 15:41:27 +02:00
jsonAllData . stats . listClosed . map ( elem => {
dataTagsMd += ` \n * ${ elem . title } ` ;
2021-09-10 15:14:55 +02:00
} )
markdownExportData += ` \n ` ;
markdownExportData += ` \n # Export de Tags GTG \n ` ;
markdownExportData += ` \n ` ;
markdownExportData += ` \n ` ;
let sortedTagsByTitle = _ . sortBy ( jsonAllData . stats . listTags , [ ( 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 ` ;
jsonAllData . weeklyDevReport = weeklyDevReport ;
2021-09-10 14:54:04 +02:00
// write file to disk
fs . writeFile ( ` output/export_hebdo.md ` , markdownExportData , ` utf8 ` , ( err ) => {
2021-03-02 12:26:19 +01:00
2021-09-10 14:54:04 +02:00
if ( err ) {
console . log ( ` Error writing file: ${ err } ` ) ;
res . send ( err )
} else {
console . log ( ` File \` output/export_tags.md \` is written successfully! ` ) ;
2021-03-02 11:10:53 +01:00
2021-09-10 14:54:04 +02:00
}
2021-03-02 11:10:53 +01:00
2021-09-10 14:54:04 +02:00
} ) ;
2021-03-02 10:57:26 +01:00
2021-03-02 10:12:15 +01:00
}
2021-03-02 10:57:26 +01:00
2021-09-10 15:41:27 +02:00
function exportToOrgmode ( res ) {
let orgmodeContent = ` # Tâches exportées
` ;
2021-09-10 16:27:07 +02:00
jsonAllData . stats . listAll . map ( taskItem => {
orgmodeContent += ` \n * ` ;
if ( taskItem . $ . status === 'Active' ) {
orgmodeContent += ` TODO ` ;
2021-09-10 15:41:27 +02:00
}
2021-09-10 16:27:07 +02:00
if ( taskItem . $ . status === 'Done' ) {
2021-09-10 15:41:27 +02:00
orgmodeContent += ` DONE ` ;
}
2021-09-10 16:27:07 +02:00
if ( taskItem . $ . status === 'Dismiss' ) {
2021-09-10 15:41:27 +02:00
orgmodeContent += ` CANCELED ` ;
}
2021-09-10 16:27:07 +02:00
orgmodeContent += ` ${ taskItem . title } ` ;
2021-09-10 15:41:27 +02:00
2021-09-10 16:27:07 +02:00
if ( taskItem . tags [ 0 ] ) {
orgmodeContent += ` ` ;
taskItem . tags [ 0 ] . tag . map ( tag => {
2021-09-10 15:41:27 +02:00
// console.log('tag', tag);
// console.log('jsonAllData.stats.tagByKey[tag]', jsonAllData.stats.tagByKey[tag]);
if ( tag ) {
orgmodeContent += ` : ${ jsonAllData . stats . tagByKey [ tag ] . name } : ` ;
// orgmodeContent += `:${tag}: `;
}
} )
}
2021-09-10 16:27:07 +02:00
if ( taskItem . $ . dates ) {
console . log ( 'elem.$.dates' , taskItem . $ . dates ) ;
orgmodeContent += ` \n ` ;
if ( taskItem . $ . dates [ 0 ] . added ) {
orgmodeContent += ` CREATED ${ taskItem . title } ` ;
}
}
if ( taskItem . content ) {
orgmodeContent += ` \n ` ;
taskItem . content . map ( content => {
orgmodeContent += ` \n ${ content } ` ;
} )
orgmodeContent += ` \n ______ ` ;
}
if (
// typeof elem.subtasks[0] === typeof Object &&
taskItem . subtasks [ 0 ] . sub . length ) {
let listSubTasks = taskItem . subtasks [ 0 ] . sub
orgmodeContent += ` \n ` ;
listSubTasks . map ( subtaskid => {
let subTask = jsonAllData . stats . taskByKey [ subtaskid ]
console . log ( 'subTask' , subTask ) ;
orgmodeContent += ` \n * ` ;
if ( taskItem . $ . status === 'Active' ) {
orgmodeContent += ` TODO ` ;
}
if ( taskItem . $ . status === 'Done' ) {
orgmodeContent += ` DONE ` ;
}
if ( taskItem . $ . status === 'Dismiss' ) {
orgmodeContent += ` CANCELED ` ;
}
orgmodeContent += ` => ${ subTask . title } ` ;
} )
}
2021-09-10 15:41:27 +02:00
} )
// write file to disk
fs . writeFile ( ` output/export_tasks.org ` , orgmodeContent , ` utf8 ` , ( err ) => {
if ( err ) {
console . log ( ` Error writing file: ${ err } ` ) ;
res . send ( err )
} else {
console . log ( ` File \` output/export_tasks.org \` is written successfully! ` ) ;
}
} ) ;
}
2021-09-10 14:54:04 +02:00
/ * *
* transformToJson
* @ param xml
* @ param fileToOpen
* @ param res
* @ returns { * }
* /
2021-03-02 10:57:26 +01:00
function transformToJson ( xml , fileToOpen , res ) {
2021-09-10 14:54:04 +02:00
return parseString ( xml , function ( err , result ) {
if ( err ) console . log ( err ) ;
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
// console.dir(JSON.stringify(result));
console . log ( 'Done' ) ;
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
// write file to disk
fs . writeFile ( ` output/ ${ fileToOpen } _gtg.json ` , JSON . stringify ( result , null , 4 ) , 'utf8' , ( err ) => {
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
if ( err ) {
console . log ( ` Error writing file: ${ err } ` ) ;
// return JSON.stringify(result)
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
res . send ( err )
} else {
console . log ( ` ### File \` output/ ${ fileToOpen } _gtg.json \` is written successfully! ` ) ;
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
}
2021-03-01 18:02:04 +01:00
2021-09-10 14:54:04 +02:00
} ) ;
2021-03-01 18:02:04 +01:00
} ) ;
}
2021-02-27 10:26:37 +01:00
module . exports = router ;