Skip to content

Commit

Permalink
Merge branch 'master' into plugins_support
Browse files Browse the repository at this point in the history
Conflicts:
      application/client/src/app/service/actions.ts
      application/client/src/app/service/actions/index.ts
      application/holder/src/service/actions/index.ts
      application/platform/ipc/request/actions/index.ts
  • Loading branch information
AmmarAbouZor committed Feb 10, 2025
2 parents 833cf90 + 77602f2 commit 7991de9
Show file tree
Hide file tree
Showing 32 changed files with 454 additions and 935 deletions.
2 changes: 1 addition & 1 deletion application/client/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chipmunk",
"version": "3.15.3",
"version": "3.16.0",
"description": "Logs analyzer tool",
"author": "Dmitry Astafyev",
"scripts": {
Expand Down
5 changes: 5 additions & 0 deletions application/client/src/app/module/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ declare global {
interface Window {
electron: {
ipc: IPC;
webUtils: WebUtils;
};
}
}
Expand All @@ -18,3 +19,7 @@ export interface IPC {
unsubscribe: (channel: string, callback: (...args: any[]) => void) => void;
unsubscribeAll: (channel: string) => void;
}

export interface WebUtils {
getPathForFile(file: File): string;
}
48 changes: 48 additions & 0 deletions application/client/src/app/service/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,54 @@ export class Service extends Implementation {
},
),
);
this.register(
api
.transport()
.respondent(
this.getName(),
Requests.Actions.ExportSessionState.Request,
(
_request: Requests.Actions.ExportSessionState.Request,
): CancelablePromise<Requests.Actions.ExportSessionState.Response> => {
return new CancelablePromise((resolve, _reject) => {
new handlers.ExportSession.Action()
.apply()
.catch((err: Error) => {
this.log().error(
`Fail to call ExportSessionState action: ${err.message}`,
);
})
.finally(() => {
resolve(new Requests.Actions.Help.Response());
});
});
},
),
);
this.register(
api
.transport()
.respondent(
this.getName(),
Requests.Actions.ImportSessionState.Request,
(
_request: Requests.Actions.ImportSessionState.Request,
): CancelablePromise<Requests.Actions.ImportSessionState.Response> => {
return new CancelablePromise((resolve, _reject) => {
new handlers.ImportSession.Action()
.apply()
.catch((err: Error) => {
this.log().error(
`Fail to call ImportSessionState action: ${err.message}`,
);
})
.finally(() => {
resolve(new Requests.Actions.Help.Response());
});
});
},
),
);
this.register(
api
.transport()
Expand Down
42 changes: 42 additions & 0 deletions application/client/src/app/service/actions/export.session.state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Base } from './action';
import { session } from '@service/session';
import { bridge } from '@service/bridge';
import { Notification, notifications } from '@ui/service/notifications';

export const ACTION_UUID = 'export_session_state';

export class Action extends Base {
public group(): number {
return 4;
}
public uuid(): string {
return ACTION_UUID;
}

public caption(): string {
return 'Export Current Filters';
}

public async apply(): Promise<void> {
const active = session.active().session();
if (active === undefined) {
return;
}
const snap = active.snap().get();
const filename = await bridge.files().select.save('state', undefined);
if (filename === undefined) {
return Promise.resolve();
}
bridge
.files()
.write(filename, snap, true)
.catch((err: Error) => {
notifications.notify(
new Notification({
message: `Export failed with: ${err.message}`,
actions: [],
}),
);
});
}
}
48 changes: 48 additions & 0 deletions application/client/src/app/service/actions/import.session.state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Base } from './action';
import { session } from '@service/session';
import { bridge } from '@service/bridge';
import { Notification, notifications } from '@ui/service/notifications';

export const ACTION_UUID = 'import_session_state';

export class Action extends Base {
public group(): number {
return 4;
}
public uuid(): string {
return ACTION_UUID;
}

public caption(): string {
return 'Import Filters';
}

public async apply(): Promise<void> {
const active = session.active().session();
if (active === undefined) {
return;
}
const files = await bridge.files().select.any();
if (files.length !== 1) {
return Promise.resolve();
}
bridge
.files()
.read(files[0].filename)
.then((content: string) => {
const err = active.snap().load(content);
if (err instanceof Error) {
return Promise.reject(err);
}
return undefined;
})
.catch((err: Error) => {
notifications.notify(
new Notification({
message: `Import failed with: ${err.message}`,
actions: [],
}),
);
});
}
}
6 changes: 6 additions & 0 deletions application/client/src/app/service/actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import * as Updates from './updates';
import * as Settings from './settings';
import * as Exit from './exit';
import * as Help from './help';
import * as ExportSession from './export.session.state';
import * as ImportSession from './import.session.state';
import * as PluginsManager from './plugins_manager';
import * as StdoutPlugin from './stdout.plugin';

Expand Down Expand Up @@ -55,6 +57,8 @@ export * as Updates from './updates';
export * as Settings from './settings';
export * as Exit from './exit';
export * as Help from './help';
export * as ExportSession from './export.session.state';
export * as ImportSession from './import.session.state';
export * as PluginsManager from './plugins_manager';
export * as StdoutPlugin from './stdout.plugin';

Expand Down Expand Up @@ -87,6 +91,8 @@ export const all = [
[Settings.ACTION_UUID, Settings.Action],
[Help.ACTION_UUID, Help.Action],
[Exit.ACTION_UUID, Exit.Action],
[ExportSession.ACTION_UUID, ExportSession.Action],
[ImportSession.ACTION_UUID, ImportSession.Action],
[PluginsManager.ACTION_UUID, PluginsManager.Action],
[StdoutPlugin.ACTION_UUID, StdoutPlugin.Action],
];
Expand Down
14 changes: 13 additions & 1 deletion application/client/src/app/service/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class Service extends Implementation {
cp(src: string, dest: string): Promise<void>;
copy(files: string[], dest: string): Promise<void>;
read(filename: string): Promise<string>;
write(filename: string, content: string, overwrite: true): Promise<void>;
select: {
any(): Promise<File[]>;
dlt(): Promise<File[]>;
Expand Down Expand Up @@ -284,9 +285,20 @@ export class Service extends Implementation {
return Promise.resolve(response.text as string);
});
},
write: (filename: string, content: string, overwrite: true): Promise<void> => {
return Requests.IpcRequest.send<Requests.File.Write.Response>(
Requests.File.Write.Response,
new Requests.File.Write.Request({ filename, content, overwrite }),
).then((response) => {
if (response.error !== undefined) {
return Promise.reject(new Error(response.error));
}
return undefined;
});
},
select: {
any: (): Promise<File[]> => {
return request(undefined, `dlt,pcapng,txt,log,logs`);
return request(undefined);
},
dlt: (): Promise<File[]> => {
return request(FileType.Binary, 'dlt');
Expand Down
97 changes: 97 additions & 0 deletions application/client/src/app/service/session/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import { session } from '@service/session';
import { Highlights } from './dependencies/search/highlights';
import { TeamWork } from './dependencies/teamwork';
import { Cli } from './dependencies/cli';
import { FilterRequest } from './dependencies/search/filters/request';
import { ChartRequest } from './dependencies/search/charts/request';
import { DisabledRequest } from './dependencies/search/disabled/request';
import { StoredEntity } from './dependencies/search/store';
import { Notification, notifications } from '@ui/service/notifications';
import { error } from '@platform/log/utils';

import * as ids from '@schema/ids';
import * as Requests from '@platform/ipc/request';
Expand All @@ -31,6 +37,12 @@ import * as Types from '@platform/types/observe/types/index';

export { Stream };

interface Snap {
filters: string[];
charts: string[];
disabled: string[];
}

@SetupLogger()
export class Session extends Base {
public readonly storage: Storage = new Storage();
Expand Down Expand Up @@ -351,6 +363,91 @@ export class Session extends Base {
};
}

public snap(): {
get(): string;
load(json: string): Error | undefined;
} {
return {
get: (): string => {
const snap: Snap = {
filters: this.search
.store()
.filters()
.get()
.map((v) => v.json().to()),
disabled: this.search
.store()
.disabled()
.get()
.map((v) => v.json().to()),
charts: this.search
.store()
.charts()
.get()
.map((v) => v.json().to()),
};
return JSON.stringify(snap);
},
load: (json: string): Error | undefined => {
try {
const snap: Snap = JSON.parse(json);
if (snap.filters === undefined) {
throw new Error(`No filters list`);
}
if (snap.disabled === undefined) {
throw new Error(`No disabled list`);
}
if (snap.charts === undefined) {
throw new Error(`No charts list`);
}
const warnings: string[] = [];
const check = (v: FilterRequest | DisabledRequest | ChartRequest | Error) => {
if (!(v instanceof Error)) {
return true;
} else {
warnings.push(v.message);
return false;
}
};
const filters = snap.filters
.map((json) => FilterRequest.fromJson(json))
.filter((v) => check(v)) as FilterRequest[];
const charts = snap.charts
.map((json) => ChartRequest.fromJson(json))
.filter((v) => check(v)) as ChartRequest[];
const disabled = snap.disabled
.map((json) => DisabledRequest.fromJson(json))
.filter((v) => check(v)) as DisabledRequest[];
this.search
.store()
.filters()
.overwrite(filters as StoredEntity<FilterRequest>[]);
this.search
.store()
.charts()
.overwrite(charts as StoredEntity<ChartRequest>[]);
this.search
.store()
.disabled()
.overwrite(disabled as StoredEntity<DisabledRequest>[]);
if (warnings.length > 0) {
notifications.notify(
new Notification({
message: `Some filters/charts weren't imported: ${warnings.join(
'; ',
)}`,
actions: [],
}),
);
}
return undefined;
} catch (err) {
return new Error(`Fail to parse session snap file: ${error(err)}`);
}
},
};
}

public getTabAPI(): ITabAPI {
return this._tab;
}
Expand Down
11 changes: 4 additions & 7 deletions application/client/src/app/ui/env/directives/dragdrop.file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,11 @@ export class MatDragDropFileFeatureDirective implements OnDestroy {
if (event.dataTransfer === null || event.dataTransfer === undefined) {
return [];
}
const path = (entity: unknown): string => {
return typeof (entity as { [key: string]: string })['path'] === 'string'
? (entity as { [key: string]: string })['path']
: (entity as { [key: string]: string })['name'];
};
const files = (() => {
if (event.dataTransfer.files) {
return Array.from(event.dataTransfer.files).map((f) => path(f));
return Array.from(event.dataTransfer.files).map((f) =>
window.electron.webUtils.getPathForFile(f),
);
} else if (event.dataTransfer.items) {
return (
Array.from(event.dataTransfer.items)
Expand All @@ -56,7 +53,7 @@ export class MatDragDropFileFeatureDirective implements OnDestroy {
}
})
.filter((f) => f !== undefined) as File[]
).map((f) => path(f));
).map((f) => window.electron.webUtils.getPathForFile(f));
} else {
return [];
}
Expand Down
Loading

0 comments on commit 7991de9

Please sign in to comment.