Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support default path environment variable #1652

Merged
merged 33 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d762cc4
save tmp code
liweitian Nov 5, 2019
fc70cee
save tmp code
liweitian Nov 6, 2019
14180f3
save current path in data.json
liweitian Nov 6, 2019
4c44b47
initialize default path according to OS
liweitian Nov 6, 2019
b206858
use default path if current path does not work
liweitian Nov 7, 2019
f258e89
fix bug about updating last accessed path
liweitian Nov 11, 2019
bb67fcb
create default folder
liweitian Nov 11, 2019
8faff5b
handle comments
liweitian Nov 14, 2019
9497928
handle comments
liweitian Nov 15, 2019
7499ffc
fix lint error
liweitian Nov 19, 2019
078ccd0
fix test case
liweitian Nov 19, 2019
2877231
fix test case
liweitian Nov 19, 2019
0d1e5ed
merge data.json and data.template.json and support defautlpath enviro…
liweitian Nov 21, 2019
5c4c890
resolve default path
liweitian Nov 22, 2019
5f08ab2
use warped path utility
liweitian Nov 22, 2019
bcb6a1a
remove console.log
liweitian Nov 22, 2019
865e790
fix bug
liweitian Nov 25, 2019
88aacb5
fix bug when user set default path as D: rather than D:/
liweitian Nov 25, 2019
96b8348
Merge branch 'master' into liweitian/updateDefaultFolder
liweitian Nov 25, 2019
626da44
add debug logger
a-b-r-o-w-n Nov 25, 2019
79ee214
add COMPOSER_BOTS_FOLDER to env settings
a-b-r-o-w-n Nov 25, 2019
efc69e1
resolve default path in settings
a-b-r-o-w-n Nov 25, 2019
0a12d21
log all settings in debug mode
a-b-r-o-w-n Nov 25, 2019
cc82449
use default path from settings
a-b-r-o-w-n Nov 25, 2019
45141d4
move setting default bots folder to settings
a-b-r-o-w-n Nov 25, 2019
ee6b925
run migrations on start up
a-b-r-o-w-n Nov 25, 2019
f474533
Merge branch 'master' into liweitian/updateDefaultFolder
a-b-r-o-w-n Nov 25, 2019
6a6a433
use TestBots directory for e2e tests
a-b-r-o-w-n Nov 25, 2019
a3327d5
create COMPOSER_BOTS_FOLDER if it doesn't exist
a-b-r-o-w-n Nov 25, 2019
4dd4493
use debug log when creating new bots
a-b-r-o-w-n Nov 25, 2019
9af88d2
Merge branch 'master' into liweitian/updateDefaultFolder
a-b-r-o-w-n Nov 26, 2019
e62b5cf
fix bugs
liweitian Nov 26, 2019
0d7b759
fix issue accessing defaultFolder from development settings
a-b-r-o-w-n Nov 26, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,18 @@ import path from 'path';
import { jsx } from '@emotion/core';
import { Fragment, useEffect, useState, useContext, useRef } from 'react';

import storage from '../../utils/storage';

import { FileSelector } from './FileSelector';
import { StoreContext } from './../../store';
import { FileTypes } from './../../constants';

const NEW_BOT_LOCATION_KEY = 'newBotLocation';

export function LocationSelectContent(props) {
const { state, actions } = useContext(StoreContext);
const { storages, focusedStorageFolder, storageFileLoadingStatus } = state;
const { onOpen, onChange, allowOpeningBot = true } = props;

const { fetchFolderItemsByPath } = actions;
const currentStorageIndex = useRef(0);
const [currentPath, setCurrentPath] = useState(storage.get(NEW_BOT_LOCATION_KEY, ''));
const [currentPath, setCurrentPath] = useState('');
const currentStorageId = storages[currentStorageIndex.current] ? storages[currentStorageIndex.current].id : 'default';

useEffect(() => {
Expand All @@ -39,6 +35,7 @@ export function LocationSelectContent(props) {
// const formatedPath = path.normalize(newPath.replace(/\\/g, '/'));
const formatedPath = path.normalize(newPath);
await fetchFolderItemsByPath(storageId, formatedPath);
await actions.updateCurrentPath(formatedPath);
setCurrentPath(formatedPath);
}
};
Expand All @@ -48,7 +45,7 @@ export function LocationSelectContent(props) {
let path = currentPath;
let id = '';
if (storages[index]) {
path = path || storages[index].path;
path = storages[index].path;
id = storages[index].id;
}
updateCurrentPath(path, id);
Expand All @@ -58,7 +55,6 @@ export function LocationSelectContent(props) {
if (onChange) {
onChange(currentPath);
}
storage.set(NEW_BOT_LOCATION_KEY, currentPath);
}, [currentPath]);

const onSelectionChanged = item => {
Expand Down
4 changes: 4 additions & 0 deletions Composer/packages/client/src/store/action/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,7 @@ export const fetchFolderItemsByPath: ActionCreator = async ({ dispatch }, id, pa
});
}
};

export const updateCurrentPath: ActionCreator = async ({ dispatch }, path) => {
await httpClient.put(`/storages/currentPath`, { path: path });
};
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jest.mock('../../src/store/store', () => {
name: 'This PC',
type: 'LocalDisk',
path: '.',
defaultPath: '.',
},
],
recentBotProjects: [] as any[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jest.mock('../../src/store/store', () => {
name: 'This PC',
type: 'LocalDisk',
path: '.',
defaultPath: '.',
},
];
return {
Expand Down
6 changes: 6 additions & 0 deletions Composer/packages/server/src/controllers/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ function createStorageConnection(req: Request, res: Response) {
res.status(200).json(StorageService.getStorageConnections());
}

function updateCurrentPath(req: Request, res: Response) {
StorageService.updateCurrentPath(req.body.path);
res.status(200).json('success');
}

async function getBlob(req: Request, res: Response) {
const storageId = req.params.storageId;
const reqpath = decodeURI(req.params.path);
Expand All @@ -34,4 +39,5 @@ export const StorageController = {
getStorageConnections,
createStorageConnection,
getBlob,
updateCurrentPath,
};
1 change: 1 addition & 0 deletions Composer/packages/server/src/router/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ router.post('/projects/opened/project/saveAs', ProjectController.saveProjectAs);
router.get('/projects/recent', ProjectController.getRecentProjects);

// storages
router.put('/storages/currentPath', StorageController.updateCurrentPath);
router.get('/storages', StorageController.getStorageConnections);
router.post('/storages', StorageController.createStorageConnection);
router.get('/storages/:storageId/blobs/:path(*)', StorageController.getBlob);
Expand Down
30 changes: 28 additions & 2 deletions Composer/packages/server/src/services/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class StorageService {

constructor() {
this.storageConnections = Store.get(this.STORE_KEY);
this.ensureDefaultBotFoldersExist();
}

public getStorageClient = (storageId: string): IFileStorage => {
Expand All @@ -39,11 +40,18 @@ class StorageService {
};

public getStorageConnections = (): StorageConnection[] => {
return this.storageConnections.map(s => {
const connections = this.storageConnections.map(s => {
const temp = Object.assign({}, s);
temp.path = Path.resolve(s.path); // resolve path if path is relative, and change it to unix pattern
// if the last accessed path exist
if (fs.existsSync(s.path)) {
temp.path = Path.resolve(s.path); // resolve path if path is relative, and change it to unix pattern
} else {
temp.path = Path.resolve(s.defaultPath);
}
return temp;
});
this.ensureDefaultBotFoldersExist();
return connections;
};

public checkBlob = async (storageId: string, filePath: string): Promise<boolean> => {
Expand Down Expand Up @@ -85,6 +93,17 @@ class StorageService {
}
};

public updateCurrentPath = (path: string) => {
this.storageConnections[0].path = path;
Store.set(this.STORE_KEY, this.storageConnections);
};

private ensureDefaultBotFoldersExist = () => {
this.storageConnections.forEach(s => {
this.createFolderRecurively(s.defaultPath);
});
};

private isBotFolder = (path: string) => {
// locate Main.dialog
const mainPath = Path.join(path, 'ComposerDialogs/Main', 'Main.dialog');
Expand Down Expand Up @@ -119,6 +138,13 @@ class StorageService {
const result = await Promise.all(children);
return result.filter(item => !!item);
};

private createFolderRecurively = (path: string) => {
if (!fs.existsSync(path)) {
this.createFolderRecurively(Path.dirname(path));
fs.mkdirSync(path);
}
};
}

const service = new StorageService();
Expand Down
22 changes: 20 additions & 2 deletions Composer/packages/server/src/store/data.template.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import path from 'path';
import os from 'os';
import fs from 'fs';

import { Path } from '../utility/path';

let defaultPath = process.env.DEFAULT_PATH;
if (defaultPath && defaultPath.endsWith(':')) {
defaultPath = defaultPath + '/';
}
if (!defaultPath) {
console.log(`The default path is set to ${Path.join(os.homedir(), 'Documents', 'Composer')}`);
defaultPath = Path.join(os.homedir(), 'Documents', 'Composer');
} else if (!fs.existsSync(defaultPath)) {
console.log(
`The default path ${defaultPath} does not exist. We set it to ${Path.join(os.homedir(), 'Documents', 'Composer')}`
);
defaultPath = Path.join(os.homedir(), 'Documents', 'Composer');
}
defaultPath = Path.resolve(defaultPath);
export default {
storageConnections: [
{
id: 'default',
name: 'This PC',
type: 'LocalDisk',
path: path.resolve(__dirname, '../../../../../MyBots'),
path: '', // this is used as last accessed path, if it is invalid, use defaultPath
defaultPath,
},
],
recentBotProjects: [],
Expand Down
16 changes: 14 additions & 2 deletions Composer/packages/server/src/store/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import fs from 'fs';
import path from 'path';

import set from 'lodash/set';
import get from 'lodash/get';

import localInitData from './data.template';
import abhInitData from './abh-template.json';

const isHostedInAzure = !!process.env.WEBSITE_NODE_DEFAULT_VERSION;
const dataStorePath =
isHostedInAzure && process.env.HOME
Expand All @@ -15,14 +17,24 @@ const dataStorePath =

const initData = isHostedInAzure ? abhInitData : localInitData;

// create data.json if not exits
// create data.json if not exist
if (!fs.existsSync(dataStorePath)) {
fs.writeFileSync(dataStorePath, JSON.stringify(initData, null, 2) + '\n');
if (isHostedInAzure) {
// for some very odd reason on Azure webapp, fs.readFileSync after writeFileSync doesn't
// always find the file, add one more io to kick the virtual file system
fs.appendFileSync(dataStorePath, ' ');
}
} else {
//merge data.json if exists
const userData = JSON.parse(fs.readFileSync(dataStorePath, 'utf-8'));
set(userData, 'storageConnections[0].defaultPath', get(initData, 'storageConnections[0].defaultPath', ''));
fs.writeFileSync(dataStorePath, JSON.stringify(userData, null, 2) + '\n');
if (isHostedInAzure) {
// for some very odd reason on Azure webapp, fs.readFileSync after writeFileSync doesn't
// always find the file, add one more io to kick the virtual file system
fs.appendFileSync(dataStorePath, ' ');
}
}

interface KVStore {
Expand Down