mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
incr: flatten locale
- simplify telemetry calls - add platform
This commit is contained in:
parent
88f44692d6
commit
3d4275ef34
@ -84,6 +84,7 @@ export default {
|
|||||||
TelemetryModal,
|
TelemetryModal,
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
telemetry.platform = this.platform;
|
||||||
const lastSelectedFilePath = config.get('lastSelectedFilePath', null);
|
const lastSelectedFilePath = config.get('lastSelectedFilePath', null);
|
||||||
const { connectionSuccess, reason } = await connectToLocalDatabase(
|
const { connectionSuccess, reason } = await connectToLocalDatabase(
|
||||||
lastSelectedFilePath
|
lastSelectedFilePath
|
||||||
@ -132,7 +133,7 @@ export default {
|
|||||||
},
|
},
|
||||||
changeDbFile() {
|
changeDbFile() {
|
||||||
config.set('lastSelectedFilePath', null);
|
config.set('lastSelectedFilePath', null);
|
||||||
telemetry.stop()
|
telemetry.stop();
|
||||||
purgeCache(true);
|
purgeCache(true);
|
||||||
this.activeScreen = 'DatabaseSelector';
|
this.activeScreen = 'DatabaseSelector';
|
||||||
},
|
},
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
import { ipcRenderer } from 'electron';
|
|
||||||
import SQLiteDatabase from 'frappe/backends/sqlite';
|
import SQLiteDatabase from 'frappe/backends/sqlite';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import models from '../models';
|
import models from '../models';
|
||||||
import regionalModelUpdates from '../models/regionalModelUpdates';
|
import regionalModelUpdates from '../models/regionalModelUpdates';
|
||||||
import postStart, { setCurrencySymbols } from '../server/postStart';
|
import postStart, { setCurrencySymbols } from '../server/postStart';
|
||||||
import { DB_CONN_FAILURE, IPC_ACTIONS } from './messages';
|
import { DB_CONN_FAILURE } from './messages';
|
||||||
import runMigrate from './migrate';
|
import runMigrate from './migrate';
|
||||||
import { getId } from './telemetry/helpers';
|
import { getId } from './telemetry/helpers';
|
||||||
import telemetry from './telemetry/telemetry';
|
import telemetry from './telemetry/telemetry';
|
||||||
@ -97,10 +96,7 @@ export async function connectToLocalDatabase(filePath) {
|
|||||||
|
|
||||||
// second init with currency, normal usage
|
// second init with currency, normal usage
|
||||||
await callInitializeMoneyMaker();
|
await callInitializeMoneyMaker();
|
||||||
const creds = await ipcRenderer.invoke(IPC_ACTIONS.GET_CREDS);
|
await telemetry.start();
|
||||||
telemetry.setCreds(creds?.telemetryUrl ?? '', creds?.tokenString ?? '');
|
|
||||||
telemetry.start();
|
|
||||||
await telemetry.setCount();
|
|
||||||
|
|
||||||
if (frappe.store.isDevelopment) {
|
if (frappe.store.isDevelopment) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -154,7 +154,12 @@ function registerIpcRendererListeners() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('visibilitychange', function () {
|
document.addEventListener('visibilitychange', function () {
|
||||||
if (document.visibilityState !== 'hidden') {
|
const { visibilityState } = document;
|
||||||
|
if (visibilityState === 'visible' && !telemetry.started) {
|
||||||
|
telemetry.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visibilityState !== 'hidden') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import config, { ConfigFile, ConfigKeys } from '@/config';
|
import config, { ConfigFile, ConfigKeys } from '@/config';
|
||||||
|
import { IPC_ACTIONS } from '@/messages';
|
||||||
|
import { ipcRenderer } from 'electron';
|
||||||
import { DoctypeName } from '../../models/types';
|
import { DoctypeName } from '../../models/types';
|
||||||
import { Count, Locale, UniqueId } from './types';
|
import { Count, UniqueId } from './types';
|
||||||
|
|
||||||
export function getId(): string {
|
export function getId(): string {
|
||||||
let id: string = '';
|
let id: string = '';
|
||||||
@ -12,12 +14,13 @@ export function getId(): string {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getLocale(): Locale {
|
export function getCountry(): string {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const country: string = frappe.AccountingSettings?.country ?? '';
|
return frappe.AccountingSettings?.country ?? '';
|
||||||
const language: string = config.get('language') as string;
|
}
|
||||||
|
|
||||||
return { country, language };
|
export function getLanguage(): string {
|
||||||
|
return config.get('language') as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCounts(): Promise<Count> {
|
export async function getCounts(): Promise<Count> {
|
||||||
@ -122,3 +125,10 @@ function setInstanceId(companyName: string, files: ConfigFile[]): UniqueId {
|
|||||||
config.set(ConfigKeys.Files, files);
|
config.set(ConfigKeys.Files, files);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getCreds() {
|
||||||
|
const creds = await ipcRenderer.invoke(IPC_ACTIONS.GET_CREDS);
|
||||||
|
const url: string = creds?.telemetryUrl ?? '';
|
||||||
|
const token: string = creds?.tokenString ?? '';
|
||||||
|
return { url, token };
|
||||||
|
}
|
||||||
|
@ -1,8 +1,48 @@
|
|||||||
import config, { ConfigKeys, TelemetrySetting } from '@/config';
|
import config, { ConfigKeys, TelemetrySetting } from '@/config';
|
||||||
import frappe from 'frappe';
|
import frappe from 'frappe';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { getCounts, getDeviceId, getInstanceId, getLocale } from './helpers';
|
import {
|
||||||
import { Noun, NounEnum, Telemetry, Verb } from './types';
|
getCountry,
|
||||||
|
getCounts,
|
||||||
|
getCreds,
|
||||||
|
getDeviceId,
|
||||||
|
getInstanceId,
|
||||||
|
getLanguage,
|
||||||
|
} from './helpers';
|
||||||
|
import { Noun, NounEnum, Platform, Telemetry, Verb } from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* # Telemetry
|
||||||
|
*
|
||||||
|
* ## `start`
|
||||||
|
* Used to initialize state. It should be called before interaction.
|
||||||
|
* It is called on three events:
|
||||||
|
* 1. On db initialization which happens everytime a db is loaded or changed.
|
||||||
|
* 2. On visibility change if not started, eg: when user minimizeds Books and
|
||||||
|
* then comes back later.
|
||||||
|
* 3. When `log` is called if not initialized.
|
||||||
|
*
|
||||||
|
* ## `log`
|
||||||
|
* Used to make entries in the `timeline` which happens only if telmetry
|
||||||
|
* is set to 'Allow Telemetry`
|
||||||
|
*
|
||||||
|
* ## `error`
|
||||||
|
* Called in errorHandling.ts and maintains a count of errors that were
|
||||||
|
* thrown during usage.
|
||||||
|
*
|
||||||
|
* ## `stop`
|
||||||
|
* This is to be called when a session is being stopped. It's called on two events
|
||||||
|
* 1. When the db is being changed.
|
||||||
|
* 2. When the visiblity has changed which happens when either the app is being shut or
|
||||||
|
* the app is hidden.
|
||||||
|
*
|
||||||
|
* This function can't be async as it's called when visibility changes to 'hidden'
|
||||||
|
* at which point async doesn't seem to work and hence count is captured on `start()`
|
||||||
|
*
|
||||||
|
* ## `finalLogAndStop`
|
||||||
|
* Called when telemetry is set to "Don't Log Anything" so as to indicate cessation of
|
||||||
|
* telemetry and not app usage.
|
||||||
|
*/
|
||||||
|
|
||||||
class TelemetryManager {
|
class TelemetryManager {
|
||||||
#url: string = '';
|
#url: string = '';
|
||||||
@ -10,32 +50,42 @@ class TelemetryManager {
|
|||||||
#started = false;
|
#started = false;
|
||||||
#telemetryObject: Partial<Telemetry> = {};
|
#telemetryObject: Partial<Telemetry> = {};
|
||||||
|
|
||||||
start() {
|
set platform(value: Platform) {
|
||||||
this.#telemetryObject.locale = getLocale();
|
this.#telemetryObject.platform ||= value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasCreds() {
|
||||||
|
return !!this.#url && !!this.#token;
|
||||||
|
}
|
||||||
|
|
||||||
|
get started() {
|
||||||
|
return this.#started;
|
||||||
|
}
|
||||||
|
|
||||||
|
get telemetryObject(): Readonly<Partial<Telemetry>> {
|
||||||
|
return cloneDeep(this.#telemetryObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
this.#telemetryObject.country ||= getCountry();
|
||||||
|
this.#telemetryObject.language ??= getLanguage();
|
||||||
this.#telemetryObject.deviceId ||= getDeviceId();
|
this.#telemetryObject.deviceId ||= getDeviceId();
|
||||||
this.#telemetryObject.instanceId ||= getInstanceId();
|
this.#telemetryObject.instanceId ||= getInstanceId();
|
||||||
this.#telemetryObject.openTime ||= new Date().valueOf();
|
this.#telemetryObject.openTime ||= new Date().valueOf();
|
||||||
this.#telemetryObject.timeline ??= [];
|
this.#telemetryObject.timeline ??= [];
|
||||||
this.#telemetryObject.errors ??= {};
|
this.#telemetryObject.errors ??= {};
|
||||||
|
this.#telemetryObject.counts ??= {};
|
||||||
this.#started = true;
|
this.#started = true;
|
||||||
|
|
||||||
|
await this.#postStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
getCanLog(): boolean {
|
async log(verb: Verb, noun: Noun, more?: Record<string, unknown>) {
|
||||||
const telemetrySetting = config.get(ConfigKeys.Telemetry) as string;
|
|
||||||
return telemetrySetting === TelemetrySetting.allow;
|
|
||||||
}
|
|
||||||
|
|
||||||
setCreds(url: string, token: string) {
|
|
||||||
this.#url ||= url;
|
|
||||||
this.#token ||= token;
|
|
||||||
}
|
|
||||||
|
|
||||||
log(verb: Verb, noun: Noun, more?: Record<string, unknown>) {
|
|
||||||
if (!this.#started) {
|
if (!this.#started) {
|
||||||
this.start();
|
await this.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.getCanLog()) {
|
if (!this.#getCanLog()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,32 +106,23 @@ class TelemetryManager {
|
|||||||
this.#telemetryObject.errors[name] += 1;
|
this.#telemetryObject.errors[name] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setCount() {
|
|
||||||
this.#telemetryObject.counts = this.getCanLog() ? await getCounts() : {};
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
// Will set ids if not set.
|
this.#started = false;
|
||||||
this.start();
|
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
this.#telemetryObject.version = frappe.store.appVersion ?? '';
|
this.#telemetryObject.version = frappe.store.appVersion ?? '';
|
||||||
this.#telemetryObject.closeTime = new Date().valueOf();
|
this.#telemetryObject.closeTime = new Date().valueOf();
|
||||||
|
|
||||||
const telemetryObject = this.#telemetryObject;
|
const data = JSON.stringify({
|
||||||
|
token: this.#token,
|
||||||
|
telemetryData: this.#telemetryObject,
|
||||||
|
});
|
||||||
|
|
||||||
this.#started = false;
|
this.#clear();
|
||||||
this.#telemetryObject = {};
|
|
||||||
|
|
||||||
if (config.get(ConfigKeys.Telemetry) === TelemetrySetting.dontLogAnything) {
|
if (config.get(ConfigKeys.Telemetry) === TelemetrySetting.dontLogAnything) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = JSON.stringify({
|
|
||||||
token: this.#token,
|
|
||||||
telemetryData: telemetryObject,
|
|
||||||
});
|
|
||||||
|
|
||||||
navigator.sendBeacon(this.#url, data);
|
navigator.sendBeacon(this.#url, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,8 +131,43 @@ class TelemetryManager {
|
|||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
get telemetryObject(): Readonly<Partial<Telemetry>> {
|
async #postStart() {
|
||||||
return cloneDeep(this.#telemetryObject);
|
await this.#setCount();
|
||||||
|
await this.#setCreds();
|
||||||
|
}
|
||||||
|
|
||||||
|
async #setCount() {
|
||||||
|
if (!this.#getCanLog()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#telemetryObject.counts = await getCounts();
|
||||||
|
}
|
||||||
|
|
||||||
|
async #setCreds() {
|
||||||
|
if (this.hasCreds) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { url, token } = await getCreds();
|
||||||
|
this.#url = url;
|
||||||
|
this.#token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
#getCanLog(): boolean {
|
||||||
|
const telemetrySetting = config.get(ConfigKeys.Telemetry) as string;
|
||||||
|
return telemetrySetting === TelemetrySetting.allow;
|
||||||
|
}
|
||||||
|
|
||||||
|
#clear() {
|
||||||
|
// Delete only what varies
|
||||||
|
delete this.#telemetryObject.openTime;
|
||||||
|
delete this.#telemetryObject.closeTime;
|
||||||
|
delete this.#telemetryObject.errors;
|
||||||
|
delete this.#telemetryObject.counts;
|
||||||
|
delete this.#telemetryObject.timeline;
|
||||||
|
delete this.#telemetryObject.instanceId;
|
||||||
|
delete this.#telemetryObject.country;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,11 +11,6 @@ export interface InteractionEvent {
|
|||||||
more?: Record<string, unknown>;
|
more?: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Locale {
|
|
||||||
country: string;
|
|
||||||
language: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Count = Partial<{
|
export type Count = Partial<{
|
||||||
[key in DoctypeName]: number;
|
[key in DoctypeName]: number;
|
||||||
}>;
|
}>;
|
||||||
@ -30,7 +25,8 @@ export interface Telemetry {
|
|||||||
timeline?: InteractionEvent[];
|
timeline?: InteractionEvent[];
|
||||||
counts?: Count;
|
counts?: Count;
|
||||||
errors: Record<string, number>;
|
errors: Record<string, number>;
|
||||||
locale: Locale;
|
country: string;
|
||||||
|
language: string;
|
||||||
version: AppVersion;
|
version: AppVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user