This commit is contained in:
Eric Chen 2019-08-30 11:09:45 +08:00
Родитель 8442169af5
Коммит 86c3827e2d
12 изменённых файлов: 229 добавлений и 121 удалений

Просмотреть файл

Просмотреть файл

@ -97,18 +97,12 @@ function encodeHTML(value) {
function deleteDigitalTwinFiles() {
const fileIds = this.type.value === INTERFACE ? this.selectedInterfaces.value : this.selectedCapabilityModels.value;
command("azure-digital-twins.deleteModel", fileIds, this.type.value, refreshDigitalTwinFileList.bind(this));
command("azure-digital-twins.deleteModels", this.publicRepository, fileIds, refreshDigitalTwinFileList.bind(this));
}
function editDigitalTwinFiles() {
const fileIds = this.type.value === INTERFACE ? this.selectedInterfaces.value : this.selectedCapabilityModels.value;
command(
"azure-digital-twins.downloadModel",
fileIds,
this.type.value,
this.publicRepository,
refreshDigitalTwinFileList.bind(this)
);
command("azure-digital-twins.downloadModels", this.publicRepository, fileIds, refreshDigitalTwinFileList.bind(this));
}
function createDigitalTwinFile() {
@ -136,7 +130,7 @@ function getNextPageDigitalTwinFiles(fileType) {
}
loadingDigitalTwinFiles.value = true;
command(commandName, this.searchKeywords, this.publicRepository, 50, nextToken.value, res => {
command(commandName, this.publicRepository, this.searchKeywords, 50, nextToken.value, res => {
Vue.set(fileList, VALUE, fileList.value.concat(res.result.results));
Vue.set(nextToken, VALUE, res.result.continuationToken);
Vue.set(loadingDigitalTwinFiles, VALUE, false);

Просмотреть файл

@ -8,7 +8,7 @@ export class ColorizedChannel {
const message: string = error
? subject.charAt(0).toLowerCase() + subject.slice(1)
: subject.charAt(0).toUpperCase() + subject.slice(1);
return error ? `Fail to ${message}. Error ${error.message}` : `${message} successfully`;
return error ? `Fail to ${message}. Error: ${error.message}` : `${message} successfully`;
}
private static buildTag(name: string | undefined): string {

Просмотреть файл

@ -1,20 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
export class Command {
public static readonly CREATE_INTERFACE = new Command("azure-digital-twins.createInterface", "Create Interface");
public static readonly CREATE_CAPABILITY_MODEL = new Command(
"azure-digital-twins.createCapabilityModel",
"Create Capability Model",
);
public static readonly OPEN_REPOSITORY = new Command("azure-digital-twins.openRepository", "Open Model Repository");
public static readonly SIGN_OUT_REPOSITORY = new Command(
"azure-digital-twins.signOutRepository",
"Sign out Model Repository",
);
public static readonly SUBMIT_FILES = new Command(
"azure-digital-twins.submitFiles",
"Submit Files to Model Repository",
);
private constructor(public readonly id: string, public readonly description: string) {}
export enum Command {
CreateInterface = "azure-digital-twins.createInterface",
CreateCapabilityModel = "azure-digital-twins.createCapabilityModeel",
OpenRepository = "azure-digital-twins.openRepository",
SignOutRepository = "azure-digital-twins.signOutRepository",
SearchInterface = "azure-digital-twins.searchInterface",
SearchCapabilityModel = "azure-digital-twins.searchCapabilityModel",
SubmitFiles = "azure-digital-twins.submitFiles",
DeleteModels = "azure-digital-twins.deleteModels",
DownloadModels = "azure-digital-twins.downloadModels",
}

Просмотреть файл

@ -5,6 +5,9 @@ export class Constants {
public static readonly EXTENSION_NAME = "azure-digital-twins";
public static readonly CHANNEL_NAME = "IoT Plug and Play";
public static readonly UTF8 = "utf8";
public static readonly JSON_SPACE = 2;
public static readonly NOT_FOUND_CODE = 404;
public static readonly DEFAULT_PAGE_SIZE = 50;
public static readonly RESOURCE_FOLDER = "resources";
public static readonly TEMPLATE_FOLDER = "templates";
public static readonly SAMPLE_FILENAME = "sample";
@ -13,7 +16,14 @@ export class Constants {
public static readonly MODEL_REPOSITORY_COMPONENT = "Model Repository";
public static readonly MODEL_REPOSITORY_CONNECTION_KEY = "ModelRepositoryConnectionKey";
public static readonly MODEL_REPOSITORY_API_VERSION = "2019-07-01-Preview";
public static readonly PUBLIC_REPOSITORY_URL = "publicRepositoryUrl";
public static readonly URL_PROTOCAL_REGEX = new RegExp("^[a-zA-Z]+://");
public static readonly HTTPS_PROTOCAL = "https://";
public static readonly MODEL_NAME_REGEX = new RegExp("^[a-zA-Z_][a-zA-Z0-9_]*$");
public static readonly MODEL_NAME_REGEX_DESCRIPTION = "alphanumeric and underscore, not start with number";
public static readonly DIGITAL_TWIN_ID_PLACEHOLDER = "{DigitalTwinIdentifier}";
public static readonly SCHEMA_ID_KEY = "@id";
public static readonly SCHEMA_TYPE_KEY = "@type";
public static readonly SCHEMA_CONTEXT_KEY = "@context";
public static readonly EXTENSION_ACTIVATED_MSG = "extensionActivated";
public static readonly NOT_EMPTY_MSG = "could not be empty";
@ -21,19 +31,11 @@ export class Constants {
"Company repository connection string is not found. Please sign out and sign in with a valid connection string";
public static readonly PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG = "Public repository url is not found";
public static readonly CONNECTION_STRING_INVALID_FORMAT_MSG = "Invalid connection string format";
public static readonly MODEL_TYPE_INVALID_MSG = "Invalid model type";
public static readonly NSAT_SURVEY_URL = "https://aka.ms/vscode-azure-digital-twins-survey";
public static readonly WEB_VIEW_PATH = "assets/modelRepository";
public static readonly COMPANY_REPOSITORY_PAGE = "index.html";
public static readonly PUBLIC_REPOSITORY_PAGE = "index.html?public";
public static readonly MODEL_NAME_REGEX = new RegExp("^[a-zA-Z_][a-zA-Z0-9_]*$");
public static readonly MODEL_NAME_REGEX_DESCRIPTION = "alphanumeric and underscore, not start with number";
public static readonly DIGITAL_TWIN_ID_PLACEHOLDER = "{DigitalTwinIdentifier}";
public static readonly URL_PROTOCAL_REGEX = new RegExp("^[a-zA-Z]+://");
public static readonly HTTPS_PROTOCAL = "https://";
public static readonly NOT_FOUND_CODE = 404;
public static readonly SCHEMA_ID_KEY = "@id";
public static readonly SCHEMA_TYPE_KEY = "@type";
public static readonly SCHEMA_CONTEXT_KEY = "@context";
public static readonly PUBLIC_REPOSITORY_URL = "publicRepositoryUrl";
}

Просмотреть файл

@ -4,6 +4,7 @@
import * as fs from "fs-extra";
import * as path from "path";
import { DeviceModelManager, ModelType } from "../deviceModel/deviceModelManager";
import { ModelFileInfo } from "../modelRepository/modelRepositoryManager";
import { Constants } from "./constants";
export class Utility {
@ -15,7 +16,7 @@ export class Utility {
const template: string = await fs.readFile(templatePath, Constants.UTF8);
const content: string = Utility.replaceAll(template, replacement);
const jsonContent = JSON.parse(content);
await fs.writeFile(filePath, JSON.stringify(jsonContent, null, 2), { encoding: Constants.UTF8 });
await fs.writeJson(filePath, jsonContent, { spaces: Constants.JSON_SPACE, encoding: Constants.UTF8 });
}
public static replaceAll(str: string, replacement: Map<string, string>, caseInsensitive: boolean = false): string {
@ -62,11 +63,7 @@ export class Utility {
const replacement = new Map<string, string>();
replacement.set(":", "_");
const modelName: string = Utility.replaceAll(modelId, replacement);
// TODO:(erichen): check if @type works
const type: ModelType = DeviceModelManager.convertToModelType(content[Constants.SCHEMA_TYPE_KEY]);
if (!type) {
throw new Error("Invalid model type");
}
let candidate: string = DeviceModelManager.generateModelFilename(modelName, type);
let counter: number = 0;
@ -78,7 +75,19 @@ export class Utility {
candidate = DeviceModelManager.generateModelFilename(`${modelName}_${counter}`, type);
}
await fs.writeFile(path.join(folder, candidate), JSON.stringify(content, null, 2), { encoding: Constants.UTF8 });
await fs.writeJson(path.join(folder, candidate), content, {
spaces: Constants.JSON_SPACE,
encoding: Constants.UTF8,
});
}
public static async listModelFiles(folder: string): Promise<string[]> {
const fileInfos: string[] = [];
const files: string[] = await fs.readdir(folder);
for (const file of files) {
fileInfos.push(file);
}
return fileInfos;
}
private constructor() {}

Просмотреть файл

@ -17,7 +17,11 @@ export enum ModelType {
export class DeviceModelManager {
public static convertToModelType(name: string): ModelType {
return ModelType[name as keyof typeof ModelType];
const type: ModelType = ModelType[name as keyof typeof ModelType];
if (!type) {
throw new Error(Constants.MODEL_TYPE_INVALID_MSG);
}
return type;
}
public static generateModelId(name: string): string {
@ -33,26 +37,29 @@ export class DeviceModelManager {
return DeviceModelManager.generateModelFilename(Constants.SAMPLE_FILENAME, type);
}
constructor(private readonly context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel) {}
private readonly component: string;
constructor(private readonly context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel) {
this.component = Constants.DEVICE_MODEL_COMPONENT;
}
public async createModel(type: ModelType): Promise<void> {
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
const name: string = await UI.inputModelName(UIConstants.INPUT_MODEL_NAME_LABEL, type, folder);
const subject = `Create ${type} ${name} in folder ${folder}`;
this.outputChannel.start(subject, Constants.DEVICE_MODEL_COMPONENT);
this.outputChannel.start(subject, this.component);
let filePath: string;
try {
filePath = await this.doCreateModel(type, folder, name);
} catch (error) {
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.DEVICE_MODEL_COMPONENT);
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
}
await UI.openAndShowTextDocument(filePath);
const message: string = ColorizedChannel.generateMessage(subject);
UI.showNotification(MessageType.Info, message);
this.outputChannel.end(message, Constants.DEVICE_MODEL_COMPONENT);
this.outputChannel.end(message, this.component);
}
private async doCreateModel(type: ModelType, folder: string, name: string): Promise<string> {

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT license.
import * as vscode from "vscode";
import { BadRequestError } from "./common/badRequestError";
import { ColorizedChannel } from "./common/colorizedChannel";
import { Command } from "./common/command";
import { Constants } from "./common/constants";
@ -11,6 +10,7 @@ import { ProcessError } from "./common/processError";
import { TelemetryClient, TelemetryContext } from "./common/telemetryClient";
import { UserCancelledError } from "./common/userCancelledError";
import { DeviceModelManager, ModelType } from "./deviceModel/deviceModelManager";
import { SearchResult } from "./modelRepository/modelRepositoryInterface";
import { ModelRepositoryManager } from "./modelRepository/modelRepositoryManager";
import { MessageType, UI } from "./views/ui";
@ -29,8 +29,8 @@ export function activate(context: vscode.ExtensionContext) {
outputChannel,
nsat,
true,
Command.CREATE_INTERFACE,
(): Promise<void> => {
Command.CreateInterface,
async (): Promise<void> => {
return deviceModelManager.createModel(ModelType.Interface);
},
);
@ -41,11 +41,117 @@ export function activate(context: vscode.ExtensionContext) {
outputChannel,
nsat,
true,
Command.CREATE_CAPABILITY_MODEL,
(): Promise<void> => {
Command.CreateCapabilityModel,
async (): Promise<void> => {
return deviceModelManager.createModel(ModelType.CapabilityModel);
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
true,
Command.OpenRepository,
async (): Promise<void> => {
return modelRepositoryManager.signIn();
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
true,
Command.SignOutRepository,
async (): Promise<void> => {
return modelRepositoryManager.signOut();
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
true,
Command.SubmitFiles,
async (): Promise<void> => {
return modelRepositoryManager.submitModels();
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
false,
Command.DeleteModels,
async (publicRepository: boolean, modelIds: string[]): Promise<void> => {
return modelRepositoryManager.deleteModels(publicRepository, modelIds);
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
false,
Command.DownloadModels,
async (publicRepository: boolean, modelIds: string[]): Promise<void> => {
return modelRepositoryManager.downloadModels(publicRepository, modelIds);
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
false,
Command.SearchInterface,
async (
publicRepository: boolean,
keyword?: string,
pageSize?: number,
continuationToken?: string,
): Promise<SearchResult> => {
return modelRepositoryManager.searchModel(
ModelType.Interface,
publicRepository,
keyword,
pageSize,
continuationToken,
);
},
);
initCommand(
context,
telemetryClient,
outputChannel,
nsat,
false,
Command.SearchCapabilityModel,
async (
publicRepository: boolean,
keyword?: string,
pageSize?: number,
continuationToken?: string,
): Promise<SearchResult> => {
return modelRepositoryManager.searchModel(
ModelType.CapabilityModel,
publicRepository,
keyword,
pageSize,
continuationToken,
);
},
);
}
export function deactivate() {}
@ -60,11 +166,9 @@ function initCommand(
callback: (...args: any[]) => Promise<any>,
): void {
context.subscriptions.push(
vscode.commands.registerCommand(command.id, async (...args: any[]) => {
vscode.commands.registerCommand(command, async (...args: any[]) => {
const telemetryContext: TelemetryContext = telemetryClient.createContext();
telemetryClient.sendEvent(`${command.id}.start`);
outputChannel.show();
outputChannel.start(`Trigger command ${command.description}`);
telemetryClient.sendEvent(`${command}.start`);
try {
return await callback(...args);
@ -83,8 +187,8 @@ function initCommand(
}
} finally {
telemetryClient.closeContext(telemetryContext);
telemetryClient.sendEvent(`${command.id}.end`, telemetryContext);
outputChannel.end(`Complete command ${command.description}`);
telemetryClient.sendEvent(`${command}.end`, telemetryContext);
outputChannel.show();
if (enableSurvey) {
nsat.takeSurvey(context);
}

Просмотреть файл

@ -63,7 +63,7 @@ export class ModelRepositoryClient {
return new Promise<SearchResult>((resolve, reject) => {
request(options)
.then((response) => {
const result = response as SearchResult;
const result = response.body as SearchResult;
return resolve(result);
})
.catch((err) => {

Просмотреть файл

@ -7,7 +7,6 @@ import { Constants } from "../common/constants";
const PROPERTY_SEPARATOR = ";";
const KEY_VALUE_SEPARATOR = "=";
const PROPERTY_COUNT = 4;
const KEY_VALUE_COUNT = 2;
const HOSTNAME_PROPERTY = "HostName";
const REPOSITORY_ID_PROPERTY = "RepositoryId";
const SHARED_ACCESS_KEY_NAME_PROPERTY = "SharedAccessKeyName";
@ -32,11 +31,16 @@ export class ModelRepositoryConnection {
throw new Error(Constants.CONNECTION_STRING_INVALID_FORMAT_MSG);
}
for (const property of properties) {
const fields: string[] = property.split(KEY_VALUE_SEPARATOR);
if (fields.length !== KEY_VALUE_COUNT) {
const index: number = property.indexOf(KEY_VALUE_SEPARATOR);
if (index <= 0) {
throw new Error(Constants.CONNECTION_STRING_INVALID_FORMAT_MSG);
}
map[fields[0]] = fields[1];
const name: string = property.substring(0, index);
const value: string = property.substring(index + 1);
if (!name || !value) {
throw new Error(Constants.CONNECTION_STRING_INVALID_FORMAT_MSG);
}
map[name] = value;
}
return new ModelRepositoryConnection(

Просмотреть файл

@ -25,7 +25,7 @@ export interface DigitalTwinModelBase {
publisherId: string;
publisherName: string;
createdOn: string;
lastUpdated: string;
updatedOn: string;
}
export interface SearchOptions {

Просмотреть файл

@ -10,7 +10,7 @@ import { Constants } from "../common/constants";
import { CredentialStore } from "../common/credentialStore";
import { ProcessError } from "../common/processError";
import { Utility } from "../common/utility";
import { DeviceModelManager, ModelType } from "../deviceModel/deviceModelManager";
import { ModelType } from "../deviceModel/deviceModelManager";
import { MessageType, UI } from "../views/ui";
import { UIConstants } from "../views/uiConstants";
import { ModelRepositoryClient } from "./modelRepositoryClient";
@ -36,8 +36,17 @@ export interface ModelFileInfo {
}
export class ModelRepositoryManager {
private static async buildRepositoryInfo(isCompany: boolean): Promise<RepositoryInfo> {
if (isCompany) {
private static async buildRepositoryInfo(publicRepository: boolean): Promise<RepositoryInfo> {
if (publicRepository) {
const url: string | undefined = Configuration.getProperty<string>(Constants.PUBLIC_REPOSITORY_URL);
if (!url) {
throw new Error(Constants.PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG);
}
return {
hostname: Utility.enforceHttps(url),
apiVersion: Constants.MODEL_REPOSITORY_API_VERSION,
};
} else {
const connectionString: string | null = await CredentialStore.get(Constants.MODEL_REPOSITORY_CONNECTION_KEY);
if (!connectionString) {
throw new Error(Constants.CONNECTION_STRING_NOT_FOUND_MSG);
@ -49,21 +58,12 @@ export class ModelRepositoryManager {
repositoryId: connection.repositoryId,
accessToken: connection.generateAccessToken(),
};
} else {
const url: string | undefined = Configuration.getProperty<string>(Constants.PUBLIC_REPOSITORY_URL);
if (!url) {
throw new Error(Constants.PUBLIC_REPOSITORY_URL_NOT_FOUND_MSG);
}
return {
hostname: Utility.enforceHttps(url),
apiVersion: Constants.MODEL_REPOSITORY_API_VERSION,
};
}
}
private static async setupConnection(connectionString: string, isNew: boolean): Promise<void> {
private static async setupConnection(connectionString: string, newConnection: boolean): Promise<void> {
const connection: ModelRepositoryConnection = ModelRepositoryConnection.parse(connectionString);
if (isNew) {
if (newConnection) {
ModelRepositoryConnection.validate(connection);
}
@ -74,8 +74,8 @@ export class ModelRepositoryManager {
accessToken: connection.generateAccessToken(),
};
// test connection by searching interface
ModelRepositoryClient.searchModel(repoInfo, ModelType.Interface, "", 1, null);
if (isNew) {
await ModelRepositoryClient.searchModel(repoInfo, ModelType.Interface, "", 1, null);
if (newConnection) {
await CredentialStore.set(Constants.MODEL_REPOSITORY_CONNECTION_KEY, connectionString);
}
}
@ -87,8 +87,10 @@ export class ModelRepositoryManager {
}
private readonly express: VSCExpress;
private readonly component: string;
constructor(context: vscode.ExtensionContext, private readonly outputChannel: ColorizedChannel, filePath: string) {
this.express = new VSCExpress(context, filePath);
this.component = Constants.MODEL_REPOSITORY_COMPONENT;
}
public async signIn(): Promise<void> {
@ -96,7 +98,7 @@ export class ModelRepositoryManager {
const selected: vscode.QuickPickItem = await UI.showQuickPick(UIConstants.SELECT_REPOSITORY_LABEL, items);
const subject = `Connect to ${selected.label}`;
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.start(subject, this.component);
if (selected.label === RepositoryType.Company) {
let isNew: boolean = false;
@ -107,15 +109,15 @@ export class ModelRepositoryManager {
}
try {
ModelRepositoryManager.setupConnection(connectionString, isNew);
await ModelRepositoryManager.setupConnection(connectionString, isNew);
} catch (error) {
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
}
}
const message: string = ColorizedChannel.generateMessage(subject);
UI.showNotification(MessageType.Info, message);
this.outputChannel.end(message, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.end(message, this.component);
// open web view
const uri =
@ -128,7 +130,7 @@ export class ModelRepositoryManager {
public async signOut(): Promise<void> {
const subject = "Sign out company repository";
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.start(subject, this.component);
const success: boolean = await CredentialStore.delete(Constants.MODEL_REPOSITORY_CONNECTION_KEY);
@ -136,77 +138,75 @@ export class ModelRepositoryManager {
if (success) {
UI.showNotification(MessageType.Info, message);
}
this.outputChannel.end(message, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.end(message, this.component);
if (this.express) {
this.express.close(Constants.COMPANY_REPOSITORY_PAGE);
}
}
public async submitFiles(): Promise<void> {
public async submitModels(): Promise<void> {
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
// const fileInfos: ModelFileInfo[] = await Utility.listModelFiles();
const fileInfos: string[] = await Utility.listModelFiles(folder);
vscode.window.showInformationMessage(`${fileInfos}`);
}
public async searchModel(
modelType: string,
isCompany: boolean,
type: ModelType,
publicRepository: boolean,
keyword: string = "",
pageSize: number = 20,
pageSize: number = Constants.DEFAULT_PAGE_SIZE,
continuationToken: string | null = null,
): Promise<SearchResult> {
const type: ModelType = DeviceModelManager.convertToModelType(modelType);
if (!type) {
throw new BadRequestError("unrecognized modelType");
}
if (pageSize <= 0) {
throw new BadRequestError("pageSize should be greater than 0");
}
const subject = `Search ${type} by keyword "${keyword}" from ${
isCompany ? RepositoryType.Company : RepositoryType.Public
publicRepository ? RepositoryType.Public : RepositoryType.Company
}`;
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.start(subject, this.component);
let result: SearchResult;
try {
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(isCompany);
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(publicRepository);
result = await ModelRepositoryClient.searchModel(repoInfo, type, keyword, pageSize, continuationToken);
} catch (error) {
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
}
const message = ColorizedChannel.generateMessage(subject);
this.outputChannel.end(message, Constants.DEVICE_MODEL_COMPONENT);
this.outputChannel.end(message, this.component);
return result;
}
public async deleteModels(isCompany: boolean, modelIds: string[]): Promise<void> {
if (!isCompany) {
public async deleteModels(publicRepository: boolean, modelIds: string[]): Promise<void> {
if (publicRepository) {
throw new BadRequestError(`${RepositoryType.Public} not support delete operation`);
}
ModelRepositoryManager.validateModelIds(modelIds);
try {
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(isCompany);
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(publicRepository);
await this.doDeleteLoopSilently(repoInfo, modelIds);
} catch (error) {
const subject = `Delete models from ${RepositoryType.Company}`;
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
}
}
public async downloadModels(isCompany: boolean, modelIds: string[]): Promise<void> {
public async downloadModels(publicRepository: boolean, modelIds: string[]): Promise<void> {
ModelRepositoryManager.validateModelIds(modelIds);
const folder: string = await UI.selectRootFolder(UIConstants.SELECT_ROOT_FOLDER_LABEL);
try {
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(isCompany);
const repoInfo: RepositoryInfo = await ModelRepositoryManager.buildRepositoryInfo(publicRepository);
await this.doDownloadLoopSilently([repoInfo], modelIds, folder);
} catch (error) {
const subject = `Download models from ${isCompany ? RepositoryType.Company : RepositoryType.Public}`;
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), Constants.MODEL_REPOSITORY_COMPONENT);
const subject = `Download models from ${publicRepository ? RepositoryType.Public : RepositoryType.Company}`;
throw new ProcessError(ColorizedChannel.generateMessage(subject, error), this.component);
}
}
@ -218,19 +218,16 @@ export class ModelRepositoryManager {
// download interface files
}
private async doDownloadLoopSilently(repoInfos: RepositoryInfo[], modelIds: string[], folder: string) {
private async doDownloadLoopSilently(repoInfos: RepositoryInfo[], modelIds: string[], folder: string): Promise<void> {
for (const modelId of modelIds) {
const subject = `Download model by id ${modelId}`;
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.start(subject, this.component);
try {
await this.doDownloadModel(repoInfos, modelId, folder);
this.outputChannel.end(ColorizedChannel.generateMessage(subject), Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.end(ColorizedChannel.generateMessage(subject), this.component);
} catch (error) {
this.outputChannel.error(
ColorizedChannel.generateMessage(subject, error),
Constants.MODEL_REPOSITORY_COMPONENT,
);
this.outputChannel.error(ColorizedChannel.generateMessage(subject, error), this.component);
}
}
}
@ -258,16 +255,13 @@ export class ModelRepositoryManager {
private async doDeleteLoopSilently(repoInfo: RepositoryInfo, modelIds: string[]): Promise<void> {
for (const modelId of modelIds) {
const subject = `Delete model by id ${modelId}`;
this.outputChannel.start(subject, Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.start(subject, this.component);
try {
await ModelRepositoryClient.deleteModel(repoInfo, modelId);
this.outputChannel.end(ColorizedChannel.generateMessage(subject), Constants.MODEL_REPOSITORY_COMPONENT);
this.outputChannel.end(ColorizedChannel.generateMessage(subject), this.component);
} catch (error) {
this.outputChannel.error(
ColorizedChannel.generateMessage(subject, error),
Constants.MODEL_REPOSITORY_COMPONENT,
);
this.outputChannel.error(ColorizedChannel.generateMessage(subject, error), this.component);
}
}
}