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

Unlock and lock product upon rename #560

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
39 changes: 29 additions & 10 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,9 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) {
// file does not exist, so we can rename the product.
fs.rename(PRODUCT_PATH, NEW_PATH, async (err) => {
if (err) {
res.status(500).send({ status: 'Internal Server Error' });
res.status(500).send({
status: 'Internal Server Error'
});
logger('WARNING', 'Error occured while renaming a Storylines product.' + err);
return;
} else {
Expand All @@ -390,7 +392,10 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) {
fs.rmSync(NEW_PATH + `/${oldId}_fr.json`);

// Delete and then re-initialize the Git repo to remove previous history.
fs.rmSync(NEW_PATH + `/.git`, { recursive: true, force: true });
fs.rmSync(NEW_PATH + `/.git`, {
recursive: true,
force: true
});
const git = simpleGit(NEW_PATH);
await git.init();

Expand All @@ -402,7 +407,9 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) {
const configPath = NEW_PATH + `/ramp-config/`;
fs.readdir(configPath, (err, files) => {
if (err) {
res.status(500).send({ status: 'Internal Server Error' });
res.status(500).send({
status: 'Internal Server Error'
});
logger('WARNING', 'Error occured while changing map names.' + err);
return;
}
Expand All @@ -422,7 +429,9 @@ app.route(ROUTE_PREFIX + '/rename').post(function (req, res) {
}
});
} else {
res.status(500).send({ status: 'Internal Server Error' });
res.status(500).send({
status: 'Internal Server Error'
});
logger('WARNING', 'Error occured while renaming a Storylines product.', error);
return;
}
Expand Down Expand Up @@ -536,9 +545,9 @@ async function commitToRepo(path, username, initial) {
versionNumber = Number(versionNumber) + 1;
}
// Commit the files for this storyline to its repo.
await git
.add('./*')
.commit(`Add product version ${versionNumber} on ${date} at ${time}`, { '--author': `"${username} <>"` });
await git.add('./*').commit(`Add product version ${versionNumber} on ${date} at ${time}`, {
'--author': `"${username} <>"`
});
const log = await git.log();
const commitsAfter = log.total;
return commitsAfter > commitsBefore;
Expand Down Expand Up @@ -617,7 +626,12 @@ wss.on('connection', (ws) => {
const { uuid, lock } = message;

if (!uuid) {
ws.send(JSON.stringify({ status: 'fail', message: 'UUID not provided.' }));
ws.send(
JSON.stringify({
status: 'fail',
message: 'UUID not provided.'
})
);
}
logger('INFO', `${msg}`);
// User wants to lock storyline since they are about to load/edit it.
Expand All @@ -627,7 +641,12 @@ wss.on('connection', (ws) => {
// Someone else is currently accessing this storyline, do not allow the user to lock!
if (currentLock && ws.uuid !== uuid) {
logger('INFO', `A client failed to lock the storyline ${uuid}.`);
ws.send(JSON.stringify({ status: 'fail', message: 'Another user has locked this storyline.' }));
ws.send(
JSON.stringify({
status: 'fail',
message: 'Another user has locked this storyline.'
})
);
}
// Lock the storyline for this user. No-one else can access it until the user is done with it.
// Send the secret key back to the client so that they can now get/save the storyline by passing in the
Expand Down Expand Up @@ -660,7 +679,7 @@ wss.on('connection', (ws) => {
logger('INFO', `A client successfully unlocked the storyline ${uuid}.`);
delete lockedUuids[uuid];
delete ws.uuid;
ws.send(JSON.stringify({ status: 'success' }));
//ws.send(JSON.stringify({ status: "success" }));

broadcastToClients({
type: 'unlock',
Expand Down
116 changes: 65 additions & 51 deletions src/components/metadata-editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1265,64 +1265,78 @@ export default class MetadataEditorV extends Vue {
const convertedFrench = JSON.stringify(frenchConfig, null, 4);

// First, hit the Express server `rename` endpoint to perform the `rename` syscall on the file system.
await axios
.post(this.apiUrl + `/rename`, {
user: this.user,
previousUuid: prevUuid,
newUuid: this.changeUuid,
configs: { en: convertedEnglish, fr: convertedFrench }
})
.then(async (res: AxiosResponse) => {
// Once the server has processed the renaming, update the UUID in the database if not in dev mode.
if (import.meta.env.VITE_APP_NET_API_URL !== undefined) {
await axios.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/update', {
uuid: prevUuid,
changeUuid: this.changeUuid
});
}
// Before doing so, we lock the new uuid, to ensure it is not already locked or does not already exist
this.lockStore.unlockStoryline(); // Unlock storyline using old UUID
this.lockStore
.lockStoryline(this.changeUuid)
.then(async () => {
await axios
.post(this.apiUrl + `/rename`, {
user: this.user,
previousUuid: prevUuid,
newUuid: this.changeUuid,
configs: { en: convertedEnglish, fr: convertedFrench }
})
.then(async (res: AxiosResponse) => {
// Once the server has processed the renaming, update the UUID in the database if not in dev mode.
if (import.meta.env.VITE_APP_NET_API_URL) {
await axios.post(import.meta.env.VITE_APP_NET_API_URL + '/api/version/update', {
uuid: prevUuid,
changeUuid: this.changeUuid
});
}

// After the server and database have been updated, re-build configFileStructure,
// save the new config files to the server and fetch the new Git history.
if (this.configFileStructure?.zip) {
// Remove the current configuration files from the ZIP folder.
this.configFileStructure?.zip.remove(enFile.name);
this.configFileStructure?.zip.remove(frFile.name);

// Re-add the configuration files to the ZIP with the new UUID.
this.configFileStructure?.zip.file(`${this.changeUuid}_en.json`, convertedEnglish);
this.configFileStructure?.zip.file(`${this.changeUuid}_fr.json`, convertedFrench);

// Iterate through the RAMP configuration files and rename them using the new UUID.
const configPromises: Promise<void>[] = [];
this.configFileStructure?.zip.folder('ramp-config/')?.forEach((relativePath, file) => {
configPromises.push(this.renameMapConfig(file.name, prevUuid));
});
// After the server and database have been updated, re-build configFileStructure,
// save the new config files to the server and fetch the new Git history.
if (this.configFileStructure?.zip) {
// Remove the current configuration files from the ZIP folder.
this.configFileStructure?.zip.remove(enFile.name);
this.configFileStructure?.zip.remove(frFile.name);

// Re-add the configuration files to the ZIP with the new UUID.
this.configFileStructure?.zip.file(`${this.changeUuid}_en.json`, convertedEnglish);
this.configFileStructure?.zip.file(`${this.changeUuid}_fr.json`, convertedFrench);

// Wait for map configuration files to be renamed.
await Promise.all(configPromises);
// Iterate through the RAMP configuration files and rename them using the new UUID.
const configPromises: Promise<void>[] = [];
this.configFileStructure?.zip.folder('ramp-config/')?.forEach((relativePath, file) => {
configPromises.push(this.renameMapConfig(file.name, prevUuid));
});

this.uuid = this.changeUuid;
// Wait for map configuration files to be renamed.
await Promise.all(configPromises);

// Reset source counts.
this.sourceCounts = {};
this.uuid = this.changeUuid;

this.configFileStructureHelper(this.configFileStructure.zip).then(() => {
this.fetchHistory();
this.renameMode = this.processingRename = false;
// Reset source counts.
this.sourceCounts = {};

this.configFileStructureHelper(this.configFileStructure.zip).then(() => {
this.fetchHistory();
this.renameMode = this.processingRename = false;
});
}
})
.catch((err) => {
/** If the server returns a 500 error for whatever reason (most likely due to file in use),
* roll back the UUID to the previous value and display an error message.
*/
if (err.status === 500) {
Message.error(this.$t('editor.warning.renameFailed'));
this.uuid = prevUuid;
this.processingRename = false;
console.log(this.configFileStructure);
return;
}
});
}
})
.catch((err) => {
/** If the server returns a 500 error for whatever reason (most likely due to file in use),
* roll back the UUID to the previous value and display an error message.
*/
if (err.status === 500) {
Message.error(this.$t('editor.warning.renameFailed'));
this.uuid = prevUuid;
this.processingRename = false;
console.log(this.configFileStructure);
return;
}
.catch(() => {
Message.error(this.$t('editor.warning.renameFailed'));
this.uuid = prevUuid;
this.processingRename = false;
console.log(this.configFileStructure);
this.lockStore.lockStoryline(this.uuid); // Lock original uuid again, since we previously unlocked it
return;
});
}
}
Expand Down
Loading