|
| 1 | +const |
| 2 | + blessed = require('blessed'), |
| 3 | + fs = require('fs'), |
| 4 | + contrib = require('blessed-contrib'), |
| 5 | + present = require('./presenter'), |
| 6 | + pkg = require('../../../package.json'), |
| 7 | + xml2js = require('xml2js'), |
| 8 | + say = require('../../sayings/threads.json'), |
| 9 | + ts = Date.now(), |
| 10 | + date_ob = new Date(ts), |
| 11 | + date = date_ob.getDate(), |
| 12 | + month = date_ob.getMonth() + 1, |
| 13 | + year = date_ob.getFullYear(), |
| 14 | + currentdate = month + "/" + date + "/" + year, |
| 15 | + space = ' ', |
| 16 | + br = '\n', |
| 17 | + header = '`COVID19-TRACKER-CLI (v'+pkg.version+')`', |
| 18 | + tagline = '*A curl-based command line tracker for Novel Coronavirus or COVID-19 pandemic.*', |
| 19 | + source = 'Source: https://www.worldometers.info/coronavirus/', |
| 20 | + repo = 'Code: https://github.com/warengonzaga/covid19-tracker-cli', |
| 21 | + bmcurl = 'warengonza.ga/coffee4dev', |
| 22 | + twitterhandle = '@warengonzaga', |
| 23 | + twitterhashtag = '#covid19trackercli', |
| 24 | + gcashNum = '+639176462753', |
| 25 | + ansiBMC = '`(Buy Me A Coffee)` '+bmcurl, |
| 26 | + ansiTwitter = twitterhandle+space+twitterhashtag, |
| 27 | + ansiGCash = '(GCash) '+gcashNum, |
| 28 | + XMLTemplate = '/template.xml'; |
| 29 | + |
| 30 | +let cachedTemplate = null |
| 31 | + |
| 32 | +// random sayings |
| 33 | +const randomSay = () => { |
| 34 | + let random = Math.floor(Math.random() * say.length); |
| 35 | + return say[random]; |
| 36 | +}; |
| 37 | + |
| 38 | +const patchBlessed = () => { |
| 39 | + blessed.Program.prototype.listem = function() {} |
| 40 | + process.on = function() {} |
| 41 | +}; |
| 42 | + |
| 43 | +patchBlessed(); |
| 44 | + |
| 45 | + |
| 46 | +exports.historyCountryTracker = (req, res, n, c, tC, d, tD, r, a, cl, cPOM, u, h, chartType, countryInfo) => { |
| 47 | + const name = n, cases = c, todayCases = tC, |
| 48 | + deaths = d, todayDeaths = tD, recovered = r, |
| 49 | + active = a, critical = cl, casesPerOneMillion = cPOM, |
| 50 | + mortalityPercentage = (d/c)*100, recoveredPercentage = (r/c)*100, |
| 51 | + asof = new Date(u), |
| 52 | + dates = Object.keys(h.timeline[chartType]), |
| 53 | + from = dates[0], |
| 54 | + to = dates[dates.length - 1], |
| 55 | + parser = new xml2js.Parser(), |
| 56 | + builder = new xml2js.Builder(), |
| 57 | + tableFooter = randomSay(), |
| 58 | + defaultfooter = ansiBMC+ansiTwitter+br+br, |
| 59 | + specialfooter = ansiGCash+br+ansiBMC+ansiTwitter+br+br; |
| 60 | + |
| 61 | + const parseXML = (data) => { |
| 62 | + parser.parseString(data, function (err, result) { |
| 63 | + |
| 64 | + const casesDataTable = |
| 65 | + '\n' + |
| 66 | + ` ,${cases},${deaths},${recovered},${active},${casesPerOneMillion}\n` + |
| 67 | + ' ,Today Cases,Today Deaths,Critical,Mortality %,Recovery %\n' + |
| 68 | + ` ,${todayCases},${todayDeaths},${critical},${mortalityPercentage},${recoveredPercentage}\n`; |
| 69 | + |
| 70 | + // header |
| 71 | + result.document.page[0].item[0].markdown[0].markdown[0] = header+br+tagline |
| 72 | + |
| 73 | + // map |
| 74 | + result.document.page[0].item[1].map[0].markers[0].m[0].$ = { |
| 75 | + lat: countryInfo.lat, |
| 76 | + lon: countryInfo.long, |
| 77 | + char: '\u24E7'+` ${name}`, |
| 78 | + color: 'magenta', |
| 79 | + }; |
| 80 | + |
| 81 | + // Doughnut/donut |
| 82 | + result.document.page[0].item[4].donut[0].data[0].m[0].$={ |
| 83 | + color: 'red', |
| 84 | + percent: parseFloat(mortalityPercentage).toFixed(2), |
| 85 | + label: 'Mortality', |
| 86 | + }; |
| 87 | + |
| 88 | + result.document.page[0].item[4].donut[0].data[0].m[1].$={ |
| 89 | + color: 'green', |
| 90 | + percent: parseFloat(recoveredPercentage).toFixed(2), |
| 91 | + label: 'Recovery', |
| 92 | + }; |
| 93 | + |
| 94 | + // bar graph |
| 95 | + result.document.page[0].item[3].bar[0].$['data-data'] = `${cases},${deaths},${recovered},${active}`; |
| 96 | + |
| 97 | + // line graph |
| 98 | + result.document.page[0].item[5].line[0].label = `Cases from ${from} to ${to}` |
| 99 | + result.document.page[0].item[5].line[0].data[0].m[0].$ = { |
| 100 | + title: 'Cases', |
| 101 | + 'style-line': 'blue', |
| 102 | + x:Object.keys(h.timeline.cases).join(','), |
| 103 | + y:Object.values(h.timeline.cases).join(','), |
| 104 | + }; |
| 105 | + |
| 106 | + result.document.page[0].item[5].line[0].data[0].m[1].$ = { |
| 107 | + title: 'Deaths', |
| 108 | + 'style-line': 'red', |
| 109 | + x:Object.keys(h.timeline.deaths).join(','), |
| 110 | + y:Object.values(h.timeline.deaths).join(','), |
| 111 | + }; |
| 112 | + |
| 113 | + result.document.page[0].item[5].line[0].data[0].m[2].$ = { |
| 114 | + title: 'Recovered', |
| 115 | + 'style-line': 'green', |
| 116 | + x:Object.keys(h.timeline.recovered).join(','), |
| 117 | + y:Object.values(h.timeline.recovered).join(','), |
| 118 | + }; |
| 119 | + |
| 120 | + // Historical data table |
| 121 | + result.document.page[0].item[2].table[0].label = 'Historical data as of '+asof.toLocaleString()+' [Date:'+currentdate+']' |
| 122 | + result.document.page[0].item[2].table[0]['data-data'][0] = casesDataTable; |
| 123 | + |
| 124 | + // footer |
| 125 | + result.document.page[0].item[6].markdown[0].markdown[0] = (n.toLowerCase() == 'philippines') ? tableFooter+br+specialfooter+br+source+br+repo : tableFooter+br+defaultfooter+br+source+br+repo; |
| 126 | + |
| 127 | + present(req, res, builder.buildObject(result), function(err) { |
| 128 | + if (err) console.log(new Error().stack); |
| 129 | + if (err) return contrib.serverError(req, res, err); |
| 130 | + }); |
| 131 | + |
| 132 | + }); |
| 133 | + } |
| 134 | + |
| 135 | + const readXML = () => { |
| 136 | + fs.readFile(__dirname + XMLTemplate, (err, data) => { |
| 137 | + cachedTemplate = data |
| 138 | + parseXML(data) |
| 139 | + }); |
| 140 | + } |
| 141 | + |
| 142 | + // read XML template from file or cache |
| 143 | + if(!cachedTemplate) return readXML () |
| 144 | + |
| 145 | + try { |
| 146 | + return parseXML(new Buffer.from(cachedTemplate.toString())) |
| 147 | + } catch (e) { |
| 148 | + return readXML () |
| 149 | + } |
| 150 | + |
| 151 | + |
| 152 | +}; |
0 commit comments