forked from sheepzh/time-tracker-4-browser
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocessor.ts
More file actions
89 lines (75 loc) · 2.85 KB
/
Copy pathprocessor.ts
File metadata and controls
89 lines (75 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { getVersion } from "@api/chrome/runtime"
import db from "@db/stat-database"
import { cvtOption2Locale } from "@i18n"
import { cvtDateRange2Str, formatTimeYMD, MILL_PER_DAY, MILL_PER_WEEK } from "@util/time"
import optionHolder from "../components/option-holder"
import BrowserNotifier from "./browser/notifier"
import CallbackNotifier from "./callback/notifier"
import type { NotificationData, NotificationRequest, Notifier } from "./types"
const DATE_RANGE_CALCULATORS: Record<NotificationRequest['cycle'], (now: number) => Date | [Date, Date]> = {
daily: now => new Date(now - MILL_PER_DAY),
weekly: now => [new Date(now - MILL_PER_WEEK), new Date(now - MILL_PER_DAY)],
}
class Processor {
private notifiers: {
[method in tt4b.notification.Method]: Notifier
}
constructor() {
this.notifiers = {
browser: new BrowserNotifier(),
callback: new CallbackNotifier(),
}
}
async doSend(): Promise<string | undefined> {
const option = await optionHolder.get()
const {
notificationCycle: cycle, notificationMethod: method,
notificationEndpoint: endpoint, notificationAuthToken: authToken,
} = option
if (cycle === 'none') return undefined
const notifier = this.notifiers[method]
const req: NotificationRequest = { cycle, method, endpoint, authToken }
const data = await this.buildData(req)
try {
return await notifier.send(req, data)
} catch (e) {
console.error("Error to send notification", e)
return e instanceof Error ? e.message : String(e)
}
}
private async buildData(req: NotificationRequest): Promise<NotificationData> {
const now = Date.now()
const date = DATE_RANGE_CALCULATORS[req.cycle](now)
// Query rows
const rows = await db.select({ date: cvtDateRange2Str(date) })
// Calculate summary
let totalFocus = 0
let totalVisit = 0
const uniqueHosts = new Set<string>()
rows.forEach(row => {
totalFocus += row.focus
totalVisit += row.time
uniqueHosts.add(row.host)
})
const option = await optionHolder.get()
const locale = cvtOption2Locale(option.locale)
const [dateStart, dateEnd] = Array.isArray(date) ? date : [date, date]
return {
cycle: req.cycle,
meta: {
locale,
version: getVersion(),
ts: Date.now(),
},
summary: {
focus: totalFocus,
visit: totalVisit,
siteCount: uniqueHosts.size,
dateStart: formatTimeYMD(dateStart),
dateEnd: formatTimeYMD(dateEnd),
},
row: rows,
}
}
}
export default new Processor()