Skip to content

Commit

Permalink
create shared assets folder
Browse files Browse the repository at this point in the history
  • Loading branch information
IshavSohal committed Nov 26, 2024
1 parent d0bda58 commit 27ea45a
Show file tree
Hide file tree
Showing 9 changed files with 503 additions and 100 deletions.
93 changes: 48 additions & 45 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ const responseMessages = [];
require('dotenv').config();

// CONFIGURATION
PORT = process.env.port ? process.env.port : 6040; // the Express server will run on this port.
UPLOAD_PATH =
const PORT = process.env.port ? process.env.port : 6040; // the Express server will run on this port.
const UPLOAD_PATH =
process.env.SERVER_CURR_ENV && process.env.SERVER_CURR_ENV !== '#{CURR_ENV}#'
? process.env.SERVER_UPLOAD_PATH
: './files'; // files uploaded from the app will be uploaded to this folder (deleted after processing)
TARGET_PATH =
const TARGET_PATH =
process.env.SERVER_CURR_ENV && process.env.SERVER_CURR_ENV !== '#{CURR_ENV}#'
? process.env.SERVER_TARGET_PATH
: './public'; // ZIP files in the UPLOAD_PATH folder will be extracted here.
LOG_PATH =
const LOG_PATH =
process.env.SERVER_CURR_ENV && process.env.SERVER_CURR_ENV !== '#{CURR_ENV}#'
? process.env.SERVER_LOG_PATH
: './logfile.txt'; // the path to the logfile
ROUTE_PREFIX =
const ROUTE_PREFIX =
process.env.SERVER_CURR_ENV && process.env.SERVER_CURR_ENV !== '#{CURR_ENV}#'
? '/Storylines-Editor-STB-Server'
: '';
Expand All @@ -45,7 +45,7 @@ app.use(cors());
// POST requests made to /upload will be handled here.
app.route(ROUTE_PREFIX + '/upload').post(function (req, res, next) {
// TODO: Putting this on the header isn't great. The body has the zipped folder. And usernames in the URL doesn't look great either. Maybe improve this somehow.
const user = req.headers.user
const user = req.headers.user;
if (!user) {
// Send back error if the user uploading the storyline was not provided.
responseMessages.push({
Expand Down Expand Up @@ -80,6 +80,7 @@ app.route(ROUTE_PREFIX + '/upload').post(function (req, res, next) {
res.status(500).send({ status: 'Internal Server Error' });
return;
}
logger('INFO', file.data.originalFilename);

const fileName = `${TARGET_PATH}/${file.data.originalFilename.split('.zip')[0]}`;
const secureFilename = `${UPLOAD_PATH}/${file.data.newFilename}`;
Expand Down Expand Up @@ -123,10 +124,9 @@ app.route(ROUTE_PREFIX + '/upload').post(function (req, res, next) {
// Initialize a new git repo if this is a new storyline.
// Otherwise, simply create a new commit with the zipped folder.
if (!newStorylines) {
await commitToRepo(fileName, user, false)
}
else {
await initGitRepo(fileName, user)
await commitToRepo(fileName, user, false);
} else {
await initGitRepo(fileName, user);
}
// Finally, delete the uploaded zip file.
safeRM(secureFilename, UPLOAD_PATH);
Expand All @@ -143,10 +143,10 @@ app.route(ROUTE_PREFIX + '/upload').post(function (req, res, next) {
// GET requests made to /retrieve/ID/commitHash will be handled here.
// Calling this with commitHash as "latest" simply fetches the product as normal.
app.route(ROUTE_PREFIX + '/retrieve/:id/:hash').get(function (req, res, next) {
// This user is only needed for backwards compatibility.
// This user is only needed for backwards compatibility.
// If we have an existing storylines product that is not a git repo, we need to initialize a git repo
// and make an initial commit for it, but we need the user for the commit.
const user = req.headers.user
const user = req.headers.user;
if (!user) {
// Send back error if the user uploading the storyline was not provided.
responseMessages.push({
Expand All @@ -161,35 +161,38 @@ app.route(ROUTE_PREFIX + '/retrieve/:id/:hash').get(function (req, res, next) {
var archive = archiver('zip');
const PRODUCT_PATH = `${TARGET_PATH}/${req.params.id}`;
const uploadLocation = `${UPLOAD_PATH}/${req.params.id}-outgoing.zip`;
const commitHash = req.params.hash
const commitHash = req.params.hash;

// Check if the product exists.
if (
fs.access(PRODUCT_PATH, async (error) => {
if (!error) {
// Backwards compatibility. If the existing product is not a git repo i.e. it existed before git version control,
// we make a git repo for it before returning the version history. Otherwise, the code below will explode.
await initGitRepo(PRODUCT_PATH, user)
await initGitRepo(PRODUCT_PATH, user);
const git = simpleGit(PRODUCT_PATH);
// Get the current branch. We do it this way instead of assuming its "main" in case someone has it set to master.
const branches = await git.branchLocal()
const currBranch = branches.current
const branches = await git.branchLocal();
const currBranch = branches.current;
if (commitHash !== 'latest') {
// If the user does not ask for the latest commit, we checkout a new branch at the point of the requested commit,
// If the user does not ask for the latest commit, we checkout a new branch at the point of the requested commit,
// and then proceed with getting the zipped folder below.
try {
// First, we check if the requested commit exists.
// NOTE: When calling from frontend, the catch block should never run.
const commitExists = await git.catFile(['-t', commitHash]);
if (commitExists !== 'commit\n') {
throw new Error()
throw new Error();
}
} catch (error) {
responseMessages.push({
type: 'INFO',
message: `Access attempt to version ${commitHash} of product ${req.params.id} failed, does not exist.`
});
logger('INFO', `Access attempt to version ${commitHash} of product ${req.params.id} failed, does not exist.`);
logger(
'INFO',
`Access attempt to version ${commitHash} of product ${req.params.id} failed, does not exist.`
);
res.status(404).send({ status: 'Not Found' });
return;
}
Expand Down Expand Up @@ -219,10 +222,9 @@ app.route(ROUTE_PREFIX + '/retrieve/:id/:hash').get(function (req, res, next) {
// Since the user has not asked for the latest commit, we need to clean up.
// Go back to the main branch and delete the newly created branch.
await git.checkout(currBranch);
await git.deleteLocalBranch(`version-${commitHash}`)
await git.deleteLocalBranch(`version-${commitHash}`);
}
});

});

// Write the product data to the ZIP file.
Expand All @@ -235,7 +237,6 @@ app.route(ROUTE_PREFIX + '/retrieve/:id/:hash').get(function (req, res, next) {

responseMessages.push({ type: 'INFO', message: `Successfully loaded product ${req.params.id}` });
logger('INFO', `Successfully loaded product ${req.params.id}`);

} else {
responseMessages.push({
type: 'INFO',
Expand Down Expand Up @@ -291,10 +292,10 @@ app.route(ROUTE_PREFIX + '/retrieve/:id/:lang').get(function (req, res) {
});

app.route(ROUTE_PREFIX + '/history/:id').get(function (req, res, next) {
// This user is only needed for backwards compatibility.
// This user is only needed for backwards compatibility.
// If we have an existing storylines product that is not a git repo, we need to initialize a git repo
// and make an initial commit for it, but we need the user for the commit.
const user = req.headers.user
const user = req.headers.user;
if (!user) {
// Send back error if the user uploading the storyline was not provided.
responseMessages.push({
Expand All @@ -316,21 +317,21 @@ app.route(ROUTE_PREFIX + '/history/:id').get(function (req, res, next) {
});
logger('INFO', `Access attempt to versions of ${req.params.id} failed, does not exist.`);
res.status(404).send({ status: 'Not Found' });
}
else {
} else {
// Backwards compatibility. If the existing product is not a git repo i.e. it existed before git version control,
// we make a git repo for it before returning the version history. Otherwise, the code below will explode.
await initGitRepo(PRODUCT_PATH, user)
await initGitRepo(PRODUCT_PATH, user);
// Get version history for this product via git log command
const git = simpleGit(PRODUCT_PATH);
const log = await git.log()
const log = await git.log();
// TODO: Remove the 10 version limit once pagination is implemented
const history = log.all.slice(0, 10).map((commit) => ({hash: commit.hash, created: commit.date, storylineUUID: req.params.id}))
res.json(history)
const history = log.all
.slice(0, 10)
.map((commit) => ({ hash: commit.hash, created: commit.date, storylineUUID: req.params.id }));
res.json(history);
}
})

})
});
});

// GET reuests made to /retrieveMessages will recieve all the responseMessages currently queued.
app.route(ROUTE_PREFIX + '/retrieveMessages').get(function (req, res) {
Expand All @@ -341,7 +342,7 @@ app.route(ROUTE_PREFIX + '/retrieveMessages').get(function (req, res) {
/*
* Initializes a git repo at the requested path, if one does not already exist.
* Creates an initial commit with any currently existing files in the directory.
*
*
* @param {string} path the path of the git repo
* @param {string} username the name of the user initializing the repo
*/
Expand All @@ -357,16 +358,16 @@ async function initGitRepo(path, username) {
// Product directory is in a git repo but not top-level, we are working locally.
repoExists = false;
}
} catch(error) {
} catch (error) {
// Product directory is not a git repo nor is it within a git repo.
repoExists = false;
}

if (!repoExists) {
// Repo does not exist for the storyline product.
// Repo does not exist for the storyline product.
// Initialize a git repo and add an initial commit with all existing files.
await git.init()
await commitToRepo(path, username, true)
await git.init();
await commitToRepo(path, username, true);
}
}

Expand All @@ -378,20 +379,22 @@ async function initGitRepo(path, username) {
* @param {boolean} initial specifies whether this is the initial commit
*/
async function commitToRepo(path, username, initial) {
const date = moment().format('YYYY-MM-DD')
const time = moment().format('hh:mm:ss a')
const date = moment().format('YYYY-MM-DD');
const time = moment().format('hh:mm:ss a');
// Initialize git
const git = simpleGit(path);
let versionNumber = 1
let versionNumber = 1;
if (!initial) {
// Compute version number for storyline if this is not the initial commit.
const log = await git.log()
const lastMessage = log.latest.message
versionNumber = lastMessage.split(' ')[3]
const log = await git.log();
const lastMessage = log.latest.message;
versionNumber = lastMessage.split(' ')[3];
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} <>"` });
}

/*
Expand Down
4 changes: 4 additions & 0 deletions src/components/dynamic-editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@
:centerSlide="centerSlide"
:dynamicSelected="dynamicSelected"
@slide-edit="$emit('slide-edit')"
@shared-asset="(assetName: string) => {
console.log('emitting shared-asset event from dynamic editor');
$emit('shared-asset', assetName);
}"
></component>
</div>
</div>
Expand Down
60 changes: 59 additions & 1 deletion src/components/editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
:slideIndex="slideIndex"
:isLast="slideIndex === slides.length - 1"
:uid="uuid"
@shared-asset="onSharedAsset"
@slide-change="selectSlide"
@slide-edit="onSlidesEdited"
@custom-slide-updated="updateCustomSlide"
Expand Down Expand Up @@ -335,8 +336,8 @@ import {
ConfigFileStructure,
HelpSection,
MetadataContent,
Slide,
MultiLanguageSlide,
Slide,
SourceCounts,
StoryRampConfig,
TextPanel
Expand Down Expand Up @@ -404,7 +405,64 @@ export default class EditorV extends Vue {
@Watch('slides', { deep: true })
onSlidesEdited(): void {
console.log('editor - slide edit event emitted');
this.$emit('save-status', true);
}
// move asset from opposite lang's assets folder to shared assets folder
onSharedAsset(assetName: string): void {
console.log('editor - asset to be moved to shared asset folder');
console.log(assetName);
// access config of opposite lang
const oppositeLang = this.configLang === 'en' ? 'fr' : 'en';
const oppositeConfig = this.configs[oppositeLang];
console.log('opposite langs config (before)');
console.log(JSON.parse(JSON.stringify(oppositeConfig)));
console.log('opposite langs slides (before)');
console.log(JSON.parse(JSON.stringify(oppositeConfig?.slides)));
const sharedAssetHelper = (panel) => {
switch (panel.type) {
case 'slideshow':
panel.items.forEach((item) => sharedAssetHelper(item));
break;
case 'dynamic':
panel.children.forEach((child) => sharedAssetHelper(child.panel));
break;
case 'image':
case 'video':
if (panel.src) {
let assetSrc = panel.src.split('/');
const assetFolder = assetSrc[2];
if (panel.src.includes(assetName) && assetFolder === oppositeLang) {
console.log('need to change to shared');
assetSrc[2] = 'shared';
panel.src = assetSrc.join('/');
}
}
break;
}
};
oppositeConfig?.slides.forEach((slide) => {
console.log('current slide');
console.log(JSON.parse(JSON.stringify(slide)));
slide.panel.forEach((panel) => {
console.log('current panel');
console.log(JSON.parse(JSON.stringify(panel)));
sharedAssetHelper(panel);
});
});
console.log('opposite langs config (after)');
console.log(JSON.parse(JSON.stringify(oppositeConfig)));
console.log('opposite langs slides (after)');
console.log(JSON.parse(JSON.stringify(oppositeConfig?.slides)));
this.$emit('save-status', true);
console.log(' ');
}
@Watch('metadata', { deep: true })
Expand Down
1 change: 1 addition & 0 deletions src/components/helpers/custom-editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export default class CustomEditorV extends Vue {
}
saveChanges(): void {
console.log('customeditor.vue - saving changes after opening advanced editor ');
this.$emit('config-edited', this.updatedConfig);
this.edited = false;
Expand Down
Loading

0 comments on commit 27ea45a

Please sign in to comment.