mirror of
https://github.com/frappe/books.git
synced 2024-11-08 23:00:56 +00:00
fix: simplify telemetry code, send platform
This commit is contained in:
parent
12654539c3
commit
c88908de9a
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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>;
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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';
|
||||
|
||||
|
@ -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');
|
||||
})();
|
||||
|
@ -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) {
|
||||
|
@ -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> = {
|
||||
|
Loading…
Reference in New Issue
Block a user