2
0
mirror of https://github.com/frappe/books.git synced 2024-11-08 14:50:56 +00:00

fix: simplify telemetry code, send platform

This commit is contained in:
18alantom 2022-07-18 16:43:56 +05:30
parent 12654539c3
commit c88908de9a
10 changed files with 91 additions and 197 deletions

View File

@ -13,7 +13,7 @@ import { TelemetryManager } from './telemetry/telemetry';
import {
DEFAULT_CURRENCY,
DEFAULT_DISPLAY_PRECISION,
DEFAULT_INTERNAL_PRECISION,
DEFAULT_INTERNAL_PRECISION
} from './utils/consts';
import * as errors from './utils/errors';
import { format } from './utils/format';
@ -226,6 +226,10 @@ export class Fyo {
skipTelemetryLogging: false,
appVersion: '',
platform: '',
language: '',
instanceId: '',
deviceId: '',
openCount: -1,
};
}

View File

@ -1,101 +0,0 @@
import { Fyo } from 'fyo';
import { ConfigFile, ConfigKeys } from 'fyo/core/types';
import { DEFAULT_COUNTRY_CODE } from 'fyo/utils/consts';
import { ModelNameEnum } from 'models/types';
import { getRandomString } from 'utils';
import { UniqueId } from './types';
export function getCountry(fyo: Fyo): string {
return (
(fyo.singles.SystemSettings?.countryCode as string) ?? DEFAULT_COUNTRY_CODE
);
}
export function getLanguage(fyo: Fyo): string {
return fyo.config.get('language') as string;
}
export function getDeviceId(fyo: Fyo): UniqueId {
let deviceId = fyo.config.get(ConfigKeys.DeviceId) as string | undefined;
if (deviceId === undefined) {
deviceId = getRandomString();
fyo.config.set(ConfigKeys.DeviceId, deviceId);
}
return deviceId;
}
export async function getInstanceId(fyo: Fyo): Promise<UniqueId> {
const instanceId = (await fyo.getValue(
ModelNameEnum.SystemSettings,
'instanceId'
)) as string;
const companyName = (await fyo.getValue(
ModelNameEnum.AccountingSettings,
'companyName'
)) as string;
const dbPath = fyo.db.dbPath!;
const files = (fyo.config.get(ConfigKeys.Files) ?? []) as ConfigFile[];
let file = files.find((f) => f.id === instanceId);
if (file === undefined) {
file = addNewConfigFile(companyName, dbPath, instanceId, files, fyo);
}
if (!file.id) {
setIdOnConfigFile(instanceId, companyName, dbPath, files, fyo);
}
return instanceId;
}
export function addNewConfigFile(
companyName: string,
dbPath: string,
instanceId: string,
files: ConfigFile[],
fyo: Fyo
): ConfigFile {
const newFile: ConfigFile = {
companyName,
dbPath,
id: instanceId,
openCount: 0,
};
files.push(newFile);
fyo.config.set(ConfigKeys.Files, files);
return newFile;
}
export async function getVersion(fyo: Fyo) {
const version = (await fyo.getValue(
ModelNameEnum.SystemSettings,
'version'
)) as string | undefined;
if (version) {
return version;
}
return fyo.store.appVersion;
}
function setIdOnConfigFile(
instanceId: string,
companyName: string,
dbPath: string,
files: ConfigFile[],
fyo: Fyo
) {
for (const file of files) {
if (file.companyName !== companyName || file.dbPath !== dbPath) {
continue;
}
file.id = instanceId;
}
fyo.config.set(ConfigKeys.Files, files);
}

View File

@ -1,14 +1,6 @@
import { Fyo } from 'fyo';
import { cloneDeep } from 'lodash';
import { DateTime } from 'luxon';
import {
getCountry,
getDeviceId,
getInstanceId,
getLanguage,
getVersion,
} from './helpers';
import { Noun, Platform, Telemetry, Verb } from './types';
import { ConfigKeys } from 'fyo/core/types';
import { Noun, Telemetry, Verb } from './types';
/**
* # Telemetry
@ -19,11 +11,11 @@ import { Noun, Platform, Telemetry, Verb } from './types';
* Used to initialize state. It should be called before any logging and after an
* instance has loaded.
* It is called on three events:
* 1. When Desk is opened, i.e. when the usage starts, this also sends a started
* log.
* 2. On visibility change if not started, eg: when user minimizeds Books and
* 1. When Desk is opened, i.e. when the usage starts, this also sends a
* Opened instance log.
* 2. On visibility change if not started, eg: when user minimizes Books and
* then comes back later.
* 3. When `log` is called, but telemetry wasn't initialized.
* 3. When `log` is called, but telemetry isn't initialized.
*
* ## `log`
* Used to log activity.
@ -39,17 +31,12 @@ export class TelemetryManager {
#url: string = '';
#token: string = '';
#started = false;
#telemetryObject: Partial<Telemetry> = {};
fyo: Fyo;
constructor(fyo: Fyo) {
this.fyo = fyo;
}
set platform(value: Platform) {
this.#telemetryObject.platform ||= value;
}
get hasCreds() {
return !!this.#url && !!this.#token;
}
@ -58,18 +45,11 @@ export class TelemetryManager {
return this.#started;
}
get telemetryObject(): Readonly<Partial<Telemetry>> {
return cloneDeep(this.#telemetryObject);
}
async start(openCount?: number) {
await this.#init();
async start(isOpened?: boolean) {
this.#started = true;
await this.#setCreds();
if (typeof openCount === 'number') {
this.#telemetryObject.openCount = openCount;
if (isOpened) {
this.log(Verb.Opened, 'instance');
} else {
this.log(Verb.Resumed, 'instance');
@ -83,7 +63,6 @@ export class TelemetryManager {
this.log(Verb.Closed, 'instance');
this.#started = false;
this.#clear();
}
log(verb: Verb, noun: Noun, more?: Record<string, unknown>) {
@ -96,7 +75,6 @@ export class TelemetryManager {
}
async logOpened() {
await this.#init();
await this.#setCreds();
this.#sendBeacon(Verb.Opened, 'app');
}
@ -125,46 +103,29 @@ export class TelemetryManager {
this.#token = tokenString;
}
async #init() {
this.#telemetryObject.language ??= getLanguage(this.fyo);
this.#telemetryObject.deviceId ||= getDeviceId(this.fyo);
this.#telemetryObject.version = this.fyo.store.appVersion;
if (this.fyo.db.dbPath) {
this.#telemetryObject.country ||= getCountry(this.fyo);
this.#telemetryObject.instanceId ||= await getInstanceId(this.fyo);
this.#telemetryObject.version = await getVersion(this.fyo);
} else {
this.#telemetryObject.country ||= '';
this.#telemetryObject.instanceId ||= '';
}
}
#getTelemtryData(
verb: Verb,
noun: Noun,
more?: Record<string, unknown>
): Telemetry {
const countryCode = this.fyo.singles.SystemSettings?.countryCode as
| string
| undefined;
return {
country: this.#telemetryObject.country!,
language: this.#telemetryObject.language!,
deviceId: this.#telemetryObject.deviceId!,
instanceId: this.#telemetryObject.instanceId!,
version: this.#telemetryObject.version!,
openCount: this.#telemetryObject.openCount!,
timestamp: DateTime.now().toMillis().toString(),
country: countryCode ?? '',
language: this.fyo.store.language,
deviceId:
this.fyo.store.deviceId ||
(this.fyo.config.get(ConfigKeys.DeviceId) as string),
instanceId: this.fyo.store.instanceId,
version: this.fyo.store.appVersion,
openCount: this.fyo.store.openCount,
timestamp: new Date().toISOString().replace('T', ' ').slice(0, -1),
platform: this.fyo.store.platform,
verb,
noun,
more,
};
}
#clear() {
delete this.#telemetryObject.country;
delete this.#telemetryObject.language;
delete this.#telemetryObject.deviceId;
delete this.#telemetryObject.instanceId;
delete this.#telemetryObject.version;
delete this.#telemetryObject.openCount;
}
}

View File

@ -2,8 +2,6 @@ export type AppVersion = string;
export type UniqueId = string;
export type Timestamp = string;
export type Platform = 'Windows' | 'Mac' | 'Linux';
export enum Verb {
Created = 'created',
Deleted = 'deleted',
@ -21,7 +19,7 @@ export type Noun = string;
export interface Telemetry {
deviceId: UniqueId;
instanceId: UniqueId;
platform?: Platform;
platform?: string;
country: string;
language: string;
version: AppVersion;
@ -29,5 +27,5 @@ export interface Telemetry {
openCount: number;
verb: Verb;
noun: Noun;
more?: Record<string, unknown>
more?: Record<string, unknown>;
}

View File

@ -38,7 +38,6 @@
<script>
import { ConfigKeys } from 'fyo/core/types';
import { ModelNameEnum } from 'models/types';
import { incrementOpenCount } from 'src/utils/misc';
import { computed } from 'vue';
import WindowsTitleBar from './components/WindowsTitleBar.vue';
import { handleErrorWithDialog } from './errorHandling';
@ -94,8 +93,7 @@ export default {
async setDesk(filePath) {
this.activeScreen = 'Desk';
await this.setDeskRoute();
const openCount = await incrementOpenCount(filePath);
await fyo.telemetry.start(openCount);
await fyo.telemetry.start(true);
await checkForUpdates(false);
this.dbPath = filePath;
this.companyName = await fyo.getValue(

View File

@ -1,4 +1,5 @@
import { Fyo } from 'fyo';
import { ConfigFile, ConfigKeys } from 'fyo/core/types';
import { getRegionalModels, models } from 'models';
import { ModelNameEnum } from 'models/types';
import { getRandomString, getValueMapFromList } from 'utils';
@ -32,7 +33,9 @@ export async function initializeInstance(
await setSingles(fyo);
await setCreds(fyo);
await setVersion(fyo);
setDeviceId(fyo);
await setInstanceId(fyo);
await incrementOpenCount(fyo);
await setCurrencySymbols(fyo);
}
@ -63,11 +66,25 @@ async function setVersion(fyo: Fyo) {
}
}
function setDeviceId(fyo: Fyo) {
let deviceId = fyo.config.get(ConfigKeys.DeviceId) as string | undefined;
if (deviceId === undefined) {
deviceId = getRandomString();
fyo.config.set(ConfigKeys.DeviceId, deviceId);
}
fyo.store.deviceId = deviceId;
}
async function setInstanceId(fyo: Fyo) {
const systemSettings = await fyo.doc.getDoc(ModelNameEnum.SystemSettings);
if (!systemSettings.instanceId) {
await systemSettings.setAndSync('instanceId', getRandomString());
}
fyo.store.instanceId = (await fyo.getValue(
ModelNameEnum.SystemSettings,
'instanceId'
)) as string;
}
async function setCurrencySymbols(fyo: Fyo) {
@ -81,3 +98,26 @@ async function setCurrencySymbols(fyo: Fyo) {
'symbol'
) as Record<string, string | undefined>;
}
export async function incrementOpenCount(fyo: Fyo) {
const instanceId = (await fyo.getValue(
ModelNameEnum.SystemSettings,
'instanceId'
)) as string;
let openCount = 0;
const files = (fyo.config.get(ConfigKeys.Files) ?? []) as ConfigFile[];
for (const file of files) {
if (file.id !== instanceId) {
continue;
}
file.openCount ??= 0;
file.openCount += 1;
openCount = file.openCount;
break;
}
fyo.config.set(ConfigKeys.Files, files);
fyo.store.openCount = openCount;
}

View File

@ -95,12 +95,7 @@
{{ file.companyName }}
</p>
<div
class="
text-sm text-gray-600
flex
justify-between
overflow-x-auto
"
class="text-sm text-gray-600 flex justify-between overflow-x-auto"
>
<p class="whitespace-nowrap mr-2">
{{ formatDate(file.modified) }}
@ -180,13 +175,13 @@ import { setupDummyInstance } from 'dummy';
import { ipcRenderer } from 'electron';
import { t } from 'fyo';
import { ConfigKeys } from 'fyo/core/types';
import { addNewConfigFile } from 'fyo/telemetry/helpers';
import { DateTime } from 'luxon';
import LanguageSelector from 'src/components/Controls/LanguageSelector.vue';
import FeatherIcon from 'src/components/FeatherIcon.vue';
import Loading from 'src/components/Loading.vue';
import { fyo } from 'src/initFyo';
import { deleteDb, getSavePath } from 'src/utils/ipcCalls';
import { addNewConfigFile } from 'src/utils/misc';
import { showMessageDialog } from 'src/utils/ui';
import { IPC_ACTIONS } from 'utils/messages';

View File

@ -19,6 +19,7 @@ import { setLanguageMap } from './utils/language';
if (language) {
await setLanguageMap(language);
}
fyo.store.language = language || 'English';
ipcRenderer.send = getErrorHandled(ipcRenderer.send);
ipcRenderer.invoke = getErrorHandled(ipcRenderer.invoke);
@ -61,7 +62,6 @@ import { setLanguageMap } from './utils/language';
},
});
fyo.telemetry.platform = platformName;
await fyo.telemetry.logOpened();
app.mount('body');
})();

View File

@ -27,6 +27,7 @@ export default async function setupInstance(
const { companyName, country, bankName, chartOfAccounts } =
setupWizardOptions;
fyo.store.skipTelemetryLogging = true;
await initializeDatabase(dbPath, country, fyo);
await updateSystemSettings(setupWizardOptions, fyo);
await updateAccountingSettings(setupWizardOptions, fyo);
@ -39,6 +40,7 @@ export default async function setupInstance(
await createDefaultNumberSeries(fyo);
await completeSetup(companyName, fyo);
fyo.store.skipTelemetryLogging = false;
}
async function createDefaultEntries(fyo: Fyo) {

View File

@ -1,3 +1,4 @@
import { Fyo } from 'fyo';
import { ConfigFile, ConfigKeys } from 'fyo/core/types';
import { DateTime } from 'luxon';
import { SetupWizard } from 'models/baseModels/SetupWizard/SetupWizard';
@ -57,27 +58,23 @@ export async function getSetupWizardDoc() {
);
}
export async function incrementOpenCount(dbPath: string) {
const companyName = (await fyo.getValue(
ModelNameEnum.AccountingSettings,
'companyName'
)) as string;
let openCount = 0;
const files = fyo.config.get(ConfigKeys.Files) as ConfigFile[];
for (const file of files) {
if (file.companyName !== companyName || file.dbPath !== dbPath) {
continue;
}
file.openCount ??= 0;
file.openCount += 1;
openCount = file.openCount;
break;
}
export function addNewConfigFile(
companyName: string,
dbPath: string,
instanceId: string,
files: ConfigFile[],
fyo: Fyo
): ConfigFile {
const newFile: ConfigFile = {
companyName,
dbPath,
id: instanceId,
openCount: 0,
};
files.push(newFile);
fyo.config.set(ConfigKeys.Files, files);
return openCount;
return newFile;
}
export const docsPathMap: Record<string, string | undefined> = {