Skip to content

Commit 454c96d

Browse files
committed
refactoring and working on dependency checks
1 parent 46fc1ed commit 454c96d

File tree

5 files changed

+141
-28
lines changed

5 files changed

+141
-28
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import { inject, injectable } from 'inversify';
7+
import { QuickPickItem, QuickPickOptions } from 'vscode';
8+
import { ICommandNameArgumentTypeMapping } from '../../common/application/commands';
9+
import { IApplicationShell, ICommandManager } from '../../common/application/types';
10+
import { IDisposable } from '../../common/types';
11+
import { Commands } from '../constants';
12+
import { INotebookEditorProvider } from '../types';
13+
import { ExportFormat, ExportManager, IExportManager } from './exportManager';
14+
15+
interface IExportQuickPickItem extends QuickPickItem {
16+
handler(): void;
17+
}
18+
19+
@injectable()
20+
export class ExportCommands implements IDisposable {
21+
private readonly disposables: IDisposable[] = [];
22+
constructor(
23+
@inject(ICommandManager) private readonly commandManager: ICommandManager,
24+
@inject(IExportManager) private exportManager: ExportManager,
25+
@inject(INotebookEditorProvider) private notebookEditorProvider: INotebookEditorProvider,
26+
@inject(IApplicationShell) private readonly applicationShell: IApplicationShell
27+
) {}
28+
public register() {
29+
this.registerCommand(Commands.ExportAsPythonScript, () => this.export(ExportFormat.python));
30+
this.registerCommand(Commands.ExportToHTML, () => this.export(ExportFormat.html));
31+
this.registerCommand(Commands.ExportToPDF, () => this.export(ExportFormat.pdf));
32+
this.registerCommand(Commands.Export, this.export);
33+
}
34+
35+
public dispose() {
36+
this.disposables.forEach((d) => d.dispose());
37+
}
38+
39+
private registerCommand<
40+
E extends keyof ICommandNameArgumentTypeMapping,
41+
U extends ICommandNameArgumentTypeMapping[E]
42+
// tslint:disable-next-line: no-any
43+
>(command: E, callback: (...args: U) => any) {
44+
const disposable = this.commandManager.registerCommand(command, callback, this);
45+
this.disposables.push(disposable);
46+
}
47+
48+
private async export(exportMethod?: ExportFormat) {
49+
// get notebook provider
50+
const activeEditor = this.notebookEditorProvider.activeEditor;
51+
if (!activeEditor) {
52+
throw Error('No active editor found.');
53+
}
54+
55+
if (exportMethod) {
56+
await this.exportManager.export(exportMethod, activeEditor);
57+
} else {
58+
// if no method was provided display quick pick menu
59+
const pickedItem = await this.showExportQuickPickMenu().then((item) => item);
60+
if (pickedItem !== undefined) {
61+
pickedItem.handler();
62+
}
63+
}
64+
}
65+
66+
private getExportQuickPickItems(): IExportQuickPickItem[] {
67+
return [
68+
{
69+
label: 'Python Script',
70+
picked: true,
71+
handler: () => this.commandManager.executeCommand(Commands.ExportAsPythonScript)
72+
}
73+
//{ label: 'HTML', picked: false, handler: () => this.commandManager.executeCommand(Commands.ExportToHTML) },
74+
//{ label: 'PDF', picked: false, handler: () => this.commandManager.executeCommand(Commands.ExportToPDF) }
75+
];
76+
}
77+
78+
private async showExportQuickPickMenu(): Promise<IExportQuickPickItem | undefined> {
79+
const items = this.getExportQuickPickItems();
80+
81+
const options: QuickPickOptions = {
82+
ignoreFocusOut: false,
83+
matchOnDescription: true,
84+
matchOnDetail: true,
85+
placeHolder: 'Export As...'
86+
};
87+
88+
return this.applicationShell.showQuickPick(items, options);
89+
}
90+
}

src/client/datascience/export/exportManager.ts

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export class ExportManager implements IExportManager {
9292
return tempFile;
9393
}
9494

95-
private getFileSaveLocation(): Uri {
95+
private getLastFileSaveLocation(): Uri {
9696
const filePath = this.workspaceStorage.get(
9797
ExportNotebookSettings.lastSaveLocation,
9898
this.defaultExportSaveLocation
@@ -126,7 +126,7 @@ export class ExportManager implements IExportManager {
126126
}
127127

128128
const options: SaveDialogOptions = {
129-
defaultUri: this.getFileSaveLocation(),
129+
defaultUri: this.getLastFileSaveLocation(),
130130
saveLabel: '',
131131
filters: fileExtensions
132132
};
@@ -139,31 +139,6 @@ export class ExportManager implements IExportManager {
139139
}
140140
}
141141

142-
@injectable()
143-
export class ExportManagerDependencyChecker implements IExportManager {
144-
constructor(@inject(ExportManager) private readonly manager: IExportManager) {}
145-
146-
public async export(format: ExportFormat, activeEditor: INotebookEditor): Promise<Uri | undefined> {
147-
// CHekc dependnecies.. etc.
148-
149-
// if not ok return.
150-
// Else export.
151-
return this.manager.export(format, activeEditor);
152-
}
153-
}
154-
155-
@injectable()
156-
export class ExportManagerFileOpener implements IExportManager {
157-
constructor(@inject(ExportManagerDependencyChecker) private readonly manager: IExportManager) {}
158-
159-
public async export(format: ExportFormat, activeEditor: INotebookEditor): Promise<Uri | undefined> {
160-
const uri = await this.manager.export(format, activeEditor);
161-
162-
// open the file.
163-
return uri;
164-
}
165-
}
166-
// make new command registry, move stuff from old
167142
// continue with decorater pattern - READ
168143
// ts mockito - READ
169144
// do depenedncy checking using code seen before
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { inject, injectable } from 'inversify';
2+
import { Uri } from 'vscode';
3+
import * as localize from '../../common/utils/localize';
4+
import { IJupyterExecution, IJupyterInterpreterDependencyManager, INotebookEditor } from '../types';
5+
import { ExportFormat, ExportManager, IExportManager } from './exportManager';
6+
7+
@injectable()
8+
export class ExportManagerDependencyChecker implements IExportManager {
9+
constructor(
10+
@inject(ExportManager) private readonly manager: IExportManager,
11+
@inject(IJupyterExecution) private jupyterExecution: IJupyterExecution,
12+
@inject(IJupyterInterpreterDependencyManager)
13+
private readonly dependencyManager: IJupyterInterpreterDependencyManager
14+
) {}
15+
16+
public async export(format: ExportFormat, activeEditor: INotebookEditor): Promise<Uri | undefined> {
17+
// Before we try the import, see if we don't support it, if we don't give a chance to install dependencies
18+
if (!(await this.jupyterExecution.isImportSupported())) {
19+
await this.dependencyManager.installMissingDependencies();
20+
}
21+
22+
if (await this.jupyterExecution.isImportSupported()) {
23+
return this.manager.export(format, activeEditor);
24+
} else {
25+
throw new Error(localize.DataScience.jupyterNbConvertNotSupported());
26+
}
27+
}
28+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { inject, injectable } from 'inversify';
2+
import { Uri } from 'vscode';
3+
import { INotebookEditor } from '../types';
4+
import { ExportFormat, IExportManager } from './exportManager';
5+
import { ExportManagerDependencyChecker } from './exportManagerDependencyChecker';
6+
7+
@injectable()
8+
export class ExportManagerFileOpener implements IExportManager {
9+
constructor(@inject(ExportManagerDependencyChecker) private readonly manager: IExportManager) {}
10+
11+
public async export(format: ExportFormat, activeEditor: INotebookEditor): Promise<Uri | undefined> {
12+
const uri = await this.manager.export(format, activeEditor);
13+
14+
// open the file.
15+
return uri;
16+
}
17+
}

src/client/datascience/serviceRegistry.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ import { CodeWatcher } from './editor-integration/codewatcher';
3434
import { Decorator } from './editor-integration/decorator';
3535
import { HoverProvider } from './editor-integration/hoverProvider';
3636
import { DataScienceErrorHandler } from './errorHandler/errorHandler';
37-
import { ExportFormat, ExportManager, ExportManagerDependencyChecker, IExport, IExportManager } from './export/exportManager';
37+
import { ExportCommands } from './export/exportCommands';
38+
import { ExportFormat, ExportManager, IExport, IExportManager } from './export/exportManager';
39+
import { ExportManagerDependencyChecker } from './export/exportManagerDependencyChecker';
3840
import { ExportToHTML } from './export/exportToHTML';
3941
import { ExportToPDF } from './export/exportToPDF';
4042
import { ExportToPython } from './export/exportToPython';
@@ -273,6 +275,7 @@ export function registerTypes(serviceManager: IServiceManager) {
273275
serviceManager.addSingleton<IExport>(IExport, ExportToPDF, ExportFormat.pdf);
274276
serviceManager.addSingleton<IExport>(IExport, ExportToHTML, ExportFormat.html);
275277
serviceManager.addSingleton<IExport>(IExport, ExportToPython, ExportFormat.python);
278+
serviceManager.addSingleton<ExportCommands>(ExportCommands, ExportCommands);
276279

277280
registerGatherTypes(serviceManager);
278281
registerNotebookTypes(serviceManager);

0 commit comments

Comments
 (0)