Skip to content

Commit

Permalink
Merge pull request #91 from danbilokha/improve-charts
Browse files Browse the repository at this point in the history
Improve charts partially resolves #80
  • Loading branch information
Proladge committed Apr 22, 2020
2 parents 650fca3 + f137559 commit 27f32b6
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 20 deletions.
54 changes: 47 additions & 7 deletions server/src/bots/telegram/botResponse/trendResponse.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { getCovidTrends } from '../../../services/api/api-chart';
import { addDays, Now } from '../../../utils/dateUtils';
import { CountrySituationInfo } from '../../../models/covid19.models';
import { Transform } from '../../../services/domain/chart';
import {
Transform,
enrichWithTitle,
enrichWithType,
} from '../../../services/domain/chart';
import { catchAsyncError } from '../../../utils/catchError';
import { getRequestedCountry } from '../../../services/domain/countries';
import { logger } from '../../../utils/logger';
import { CallBackQueryHandlerWithCommandArgument } from '../models';
import * as TelegramBot from 'node-telegram-bot-api';
import { Frequency } from './../../../models/constants';

export const trendsByCountryResponse: CallBackQueryHandlerWithCommandArgument = async (
bot: TelegramBot,
message: TelegramBot.Message,
chatId: number,
requestedCountry?: string | undefined
requestedCountry?: string | undefined,
requestedFrequency?: Frequency | undefined
): Promise<TelegramBot.Message> => {
const ferequency = requestedFrequency || Frequency.Weekly;

const [err, [foundCountry, foundSituation]] = await catchAsyncError(
getRequestedCountry(requestedCountry)
);
Expand All @@ -25,12 +33,44 @@ export const trendsByCountryResponse: CallBackQueryHandlerWithCommandArgument =

return bot.sendMessage(chatId, err.message);
}
const lastWeekSituation = foundSituation.filter(
(c: CountrySituationInfo) => {

let startDate: Date;
let hasFilter = true;
switch (ferequency) {
case Frequency.Weekly:
startDate = addDays(Now, -7);
break;
case Frequency.Monthly:
startDate = addDays(Now, -30);
break;
case Frequency.WholePeriod:
hasFilter = false;
break;
}

let periodSituation = foundSituation;
if (hasFilter) {
periodSituation = periodSituation.filter((c: CountrySituationInfo) => {
const date = new Date(c.date);
return date < Now && date > addDays(Now, -7);
}
return date < Now && date > startDate;
});
}

const frequencyName =
ferequency === Frequency.WholePeriod
? 'Whole period'
: capitalize(ferequency);

let model = enrichWithTitle(
Transform(periodSituation),
`${frequencyName} trends for ${capitalize(requestedCountry)}`
);
if (ferequency === Frequency.Weekly) {
model = enrichWithType(model, 'barStacked');
}

return bot.sendPhoto(chatId, getCovidTrends(Transform(lastWeekSituation)));
return bot.sendPhoto(chatId, getCovidTrends(model));
};

const capitalize = (input: string): string =>
input.charAt(0).toUpperCase() + input.substring(1).toLowerCase();
6 changes: 5 additions & 1 deletion server/src/bots/telegram/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
} from './botResponse/subscribeResponse';
import { SubscriptionType } from '../../models/subscription.models';
import { MessageHandlerRegistry } from './services/registry/messageHandlerRegistry';
import { withTwoArgumentsAfterCommand } from './services/registry/withTwoArgumentsAfterCommand';
import { subscriptionNotifierHandler } from './services/subscriptionNotifierManager';
import { unsubscribeStrategyResponse } from './botResponse/unsubscribeResponse';
import { trendsByCountryResponse } from './botResponse/trendResponse';
Expand Down Expand Up @@ -110,7 +111,10 @@ export function runTelegramBot(
],
unsubscribeStrategyResponse
)
.registerMessageHandler([UserRegExps.Trends], trendsByCountryResponse);
.registerMessageHandler(
[UserRegExps.Trends],
withTwoArgumentsAfterCommand(trendsByCountryResponse)
);

// Message handler for feature Countries / Country
for (const continent of Object.keys(Continents)) {
Expand Down
19 changes: 15 additions & 4 deletions server/src/bots/telegram/services/keyboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
CustomSubscriptions,
UserMessages,
UserRegExps,
Frequency,
} from '../../../models/constants';
import { InlineKeyboard, ReplyKeyboard } from 'node-telegram-keyboard-wrapper';
import { UNSUBSCRIPTIONS_ROW_ITEMS_NUMBER } from '../models';
Expand Down Expand Up @@ -33,10 +34,20 @@ export const getAfterCountryResponseInlineKeyboard = (
ik.addRow({
text: `${CustomSubscriptions.SubscribeMeOn} ${country}`,
callback_data: `${UserRegExps.Subscribe} ${country}`,
}).addRow({
text: 'Show weekly chart',
callback_data: `${UserRegExps.Trends} ${country}`,
});
}).addRow(
{
text: 'Show weekly chart',
callback_data: `${UserRegExps.Trends} ${country}`,
},
{
text: 'Show monthly chart',
callback_data: `${UserRegExps.Trends} ${country} ${Frequency.Monthly}`,
},
{
text: 'Show whole period chart',
callback_data: `${UserRegExps.Trends} ${country} ${Frequency.WholePeriod}`,
}
);

return ik.build();
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { CallBackQueryHandlerWithCommandArgument } from '../../models';
import * as TelegramBot from 'node-telegram-bot-api';
import { LogCategory } from '../../../../models/constants';
import { logger } from '../../../../utils/logger';
import { noResponse } from '../../botResponse/noResponse';

export const withTwoArgumentsAfterCommand = (
handlerFn: CallBackQueryHandlerWithCommandArgument
): CallBackQueryHandlerWithCommandArgument => {
return (
bot: TelegramBot,
message: TelegramBot.Message,
chatId: number,
ikCbData?: string
): Promise<TelegramBot.Message> => {
try {
const [arg1, arg2] = splitArgument(ikCbData);

return handlerFn.call(
this,
bot,
message,
chatId,
(arg1 && arg1.toLowerCase()) || ikCbData,
arg2 && arg2.toLowerCase()
);
} catch (err) {
logger.error(
`Error happend inside withTwoArgumentsAfterCommand() for ${chatId} with message: ${message.text} and ikCbData: ${ikCbData}`,
err,
LogCategory.Command,
chatId
);

return noResponse(this.bot, message, chatId);
}
};
};

const splitArgsRegexp = new RegExp(
'(?<firstArg>[^ ]+)[\\s.,;]+(?<secondArg>[^ ]+)'
);
function splitArgument(argument: string): [string, string] {
const match = splitArgsRegexp.exec(argument);
if (!match) {
return [undefined, undefined];
}

/* tslint:disable:no-string-literal */
return [match.groups['firstArg'], match.groups['secondArg']];
}
4 changes: 3 additions & 1 deletion server/src/models/chart.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ export type DataSet = {
label: string;
data: Array<number>;
fill: boolean;
borderColor: string;
backgroundColor?: string;
borderColor?: string;
};

type ChartData = {
Expand All @@ -13,4 +14,5 @@ type ChartData = {
export type ChartModel = {
type: string;
data: ChartData;
options: any;
};
8 changes: 7 additions & 1 deletion server/src/models/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ export enum Continents {
Other = 'Other',
}

export enum Frequency {
Weekly = 'weekly',
Monthly = 'monthly',
WholePeriod = 'wholeperiod',
}

export enum Status {
Confirmed = 'confirmed',
Confirmed = 'active',
Deaths = 'deaths',
Recovered = 'recovered',
}
Expand Down
60 changes: 55 additions & 5 deletions server/src/services/domain/chart.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Status } from '../../models/constants';
import { ChartModel } from '../../models/chart.models';
import { CountrySituationInfo } from '../../models/covid19.models';

import { Status } from '../../models/constants';
export const Transform = (situations: CountrySituationInfo[]): ChartModel => {
const days = situations.map((x) => x.date);
return {
Expand All @@ -13,21 +12,72 @@ export const Transform = (situations: CountrySituationInfo[]): ChartModel => {
label: Status.Confirmed,
data: situations.map((x) => x.confirmed),
fill: false,
borderColor: 'blue',
borderColor: 'rgb(230, 165, 96)',
backgroundColor: 'rgb(230, 165, 96)',
},
{
label: Status.Deaths,
data: situations.map((x) => x.deaths),
fill: false,
borderColor: 'red',
borderColor: 'rgb(222, 66, 91)',
backgroundColor: 'rgb(222, 66, 91)',
},
{
label: Status.Recovered,
data: situations.map((x) => x.recovered),
fill: false,
borderColor: 'green',
borderColor: 'rgb(62, 148, 107)',
backgroundColor: 'rgb(62, 148, 107)',
},
],
},
options: {},
};
};

export const enrichWithTitle = (
model: ChartModel,
title: string
): ChartModel => {
return {
...model,
options: {
...model.options,
title: {
display: true,
text: title,
fontColor: 'dark',
fontFamily: 'Helvetica',
fontSize: 28,
},
},
};
};

export const enrichWithType = (model: ChartModel, type: string): ChartModel => {
if (type === 'barStacked') {
return {
...model,
type: 'bar',
options: {
...model.options,
scales: {
xAxes: [
{
stacked: true,
},
],
yAxes: [
{
stacked: true,
},
],
},
},
};
}
return {
...model,
type,
};
};
2 changes: 1 addition & 1 deletion server/src/utils/dateUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const addDays = (date: string | Date, days: number) => {
export const addDays = (date: string | Date, days: number): Date => {
const result = new Date(date);
result.setDate(result.getDate() + days);
return result;
Expand Down

0 comments on commit 27f32b6

Please sign in to comment.