Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
110 changes: 58 additions & 52 deletions api/src/services/wordpress.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import axios from "axios";
import _ from "lodash";
//import _ from "lodash";
import { MIGRATION_DATA_CONFIG } from "../constants/index.js";
import jsdom from "jsdom";
import { htmlToJson } from "@contentstack/json-rte-serializer";
Expand Down Expand Up @@ -113,7 +113,7 @@ let blog_base_url = "";
//helper function to convert entries with content type
function mapContentTypeToEntry(contentType: any, data: any) {
return contentType?.fieldMapping?.reduce((acc: { [key: string]: any }, field: FieldMapping) => {
const fieldValue = data[field.uid];
const fieldValue = data?.[field?.uid];
let formattedValue;

switch (field?.contentstackFieldType) {
Expand All @@ -131,6 +131,9 @@ function mapContentTypeToEntry(contentType: any, data: any) {
default:
formattedValue = fieldValue;
}
if(field?.advanced?.multiple){
formattedValue = Array.isArray(formattedValue) ? formattedValue : [formattedValue];
}

acc[field.contentstackFieldUid] = formattedValue;
return acc;
Expand Down Expand Up @@ -366,7 +369,7 @@ async function saveAsset(assets: any, retryCount: number, affix: string, destina
await writeFileAsync(failedJSONFilePath, failedJSON, 4);

if (retryCount === 0) {
return saveAsset(assets, 1, affix, destinationStackId, projectId, baseSiteUrl);
return await saveAsset(assets, 1, affix, destinationStackId, projectId, baseSiteUrl);
} else {
const message = getLogMessage(
srcFunc,
Expand All @@ -384,15 +387,15 @@ async function getAsset(attachments: any[], affix: string, destinationStackId: s
const BATCH_SIZE = 5; // 5 promises at a time
const results = [];

for (let i = 0; i < attachments.length; i += BATCH_SIZE) {
const batch = attachments.slice(i, i + BATCH_SIZE);
for (let i = 0; i < attachments?.length; i += BATCH_SIZE) {
const batch = attachments?.slice(i, i + BATCH_SIZE);

const batchResults = await Promise.allSettled(
batch.map((data) => {
saveAsset(data, 0, affix, destinationStackId, projectId, baseSiteUrl)
batch?.map(async (data) => {
await saveAsset(data, 0, affix, destinationStackId, projectId, baseSiteUrl)
})
);
results.push(...batchResults);
results?.push(...batchResults);
}
await writeFileAsync(
path.join(assetsSave, MIGRATION_DATA_CONFIG.ASSETS_FILE_NAME),
Expand All @@ -419,7 +422,7 @@ async function getAllAssets(
const assets: Asset[] =
alldataParsed?.rss?.channel?.item ?? alldataParsed?.channel?.item;
// await writeFileAsync(path.join(assetsSave, MIGRATION_DATA_CONFIG.ASSETS_FILE_NAME), assets, 4);
if (!assets || assets.length === 0) {
if (!assets || assets?.length === 0) {
const message = getLogMessage(
"createAssetFolderFile",
`No assets found.`,
Expand All @@ -430,10 +433,10 @@ async function getAllAssets(
return;
}

const attachments = assets.filter(
const attachments = assets?.filter(
({ "wp:post_type": postType }) => postType === "attachment"
);
if (attachments.length > 0) {
if (attachments?.length > 0) {
await getAsset(attachments, affix, destinationStackId, projectId,baseSiteUrl);
}
return;
Expand Down Expand Up @@ -756,42 +759,45 @@ async function saveAuthors(authorDetails: any[], destinationStackId: string, pro
const srcFunc = "saveAuthors";
try {

const authordata = authorDetails.reduce(
async (acc: { [key: string]: any }, data) => {
const uid = `authors_${data["wp:author_id"] || data["wp:author_login"]
}`;

const title = data["wp:author_login"] || `Authors - ${data["wp:author_id"]}`;
const url = `/${title.toLowerCase().replace(/ /g, "_")}`;
const customId = idCorrector(uid);
const authordata: any = {
uid: uid,
title: data["wp:author_login"],
url: url,
email: data["wp:author_email"],
first_name: data["wp:author_first_name"],
last_name: data["wp:author_last_name"],
};
acc[customId] = {
...acc[customId],
uid: customId,
...mapContentTypeToEntry(contentType, authordata),
};
acc[customId].publish_details = [];
const authordata: { [key: string]: any } = {};

const message = getLogMessage(
srcFunc,
`Entry title ${data["wp:author_login"]} (authors) in the ${master_locale} locale has been successfully transformed.`,
{}
);

await customLogger(projectId, destinationStackId, 'info', message);
return acc;
},
{}
);
for (const data of authorDetails) {
const uid = `authors_${data["wp:author_id"] || data["wp:author_login"]}`;
const title = data["wp:author_login"] || `Authors - ${data["wp:author_id"]}`;
const url = `/${title.toLowerCase().replace(/ /g, "_")}`;
const customId = idCorrector(uid);

const authordataEntry: any = {
uid: uid,
title: data["wp:author_login"],
url: url,
email: data["wp:author_email"],
first_name: data["wp:author_first_name"],
last_name: data["wp:author_last_name"],
};

authordata[customId] = {
...authordata[customId],
uid: customId,
...mapContentTypeToEntry(contentType, authordataEntry),
};
authordata[customId].publish_details = [];

const message = getLogMessage(
srcFunc,
`Entry title ${data["wp:author_login"]} (authors) in the ${master_locale} locale has been successfully transformed.`,
{}
);

await customLogger(projectId, destinationStackId, 'info', message);
}
await writeFileAsync(authorsFilePath, authordata, 4);
await writeFileAsync(path.join(authorsFolderPath, "index.json"), {"1": `${master_locale}.json`}, 4);
await writeFileAsync(
path.join(authorsFolderPath, "index.json"),
{ "1": `${master_locale}.json` },
4
);

const message = getLogMessage(
srcFunc,
`${authorDetails.length} Authors exported successfully`,
Expand Down Expand Up @@ -1522,11 +1528,11 @@ async function getAllTerms(affix: string, packagePath: string, destinationStackI
const alldata: any = await fs.promises.readFile(packagePath, "utf8");
const alldataParsed = JSON.parse(alldata);
const terms =
alldataParsed?.rss?.channel["wp:term"] ||
alldataParsed?.channel["wp:term"] ||
alldataParsed?.rss?.channel?.["wp:term"] ||
alldataParsed?.channel?.["wp:term"] ||
"";

if (!terms || terms.length === 0) {
if (!terms || terms?.length === 0) {
const message = getLogMessage(
srcFunc,
`No terms found`,
Expand Down Expand Up @@ -1738,7 +1744,7 @@ function getParent(data: any,id: string) {

return catParent;
}
async function saveCategories(categoryDetails: any[], destinationStackId:string, projectId: string, contenttype:any, master_locale:stting) {
async function saveCategories(categoryDetails: any[], destinationStackId:string, projectId: string, contenttype:any, master_locale:string) {
const srcFunc = 'saveCategories';
try {
const categorydata = categoryDetails.reduce(
Expand Down Expand Up @@ -1922,7 +1928,7 @@ async function featuredImageMapping(postid: string, post: any, postdata: any) {
.filter(Boolean); // Filter out undefined matches

if (assetsDetails.length > 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assetsDetails?.length

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

postdata[postid]["featured_image"] = assetsDetails;
postdata[postid]["featured_image"] = assetsDetails[0];
}
return postdata;
} catch (error) {
Expand Down Expand Up @@ -2030,13 +2036,13 @@ async function processChunkData(
const base = blog_base_url.split("/").filter(Boolean);
const blogname = base[base.length - 1];
const url = data["link"].split(blogname)[1];
const title = data["title"] ?? `Posts - ${data["wp:post_id"]}`;
//const title = data["title"] ?? `Posts - ${data["wp:post_id"]}`;
const uid = `posts_${data["wp:post_id"]}`
const customId = idCorrector(uid)
postdata[customId] = {
title: data["title"] || `Posts - ${data["wp:post_id"]}`,
uid: customId,
url: "/"+title.toLowerCase().replace(/ /g, "_"),
url: url,
date: postDate,
full_description: jsonValue,
excerpt: data["excerpt:encoded"]
Expand Down
8 changes: 7 additions & 1 deletion ui/src/components/LegacyCms/Actions/LoadFileFormat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,14 @@ const LoadFileFormat = (props: LoadFileFormatProps) => {
};

const getFileExtension = (filePath: string): string => {
const normalizedPath = filePath.replace(/\\/g, "/")?.replace(/\/$/, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const normalizedPath = filePath?.replace(/\/g, "/")?.replace(//$/, "");

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// Use regex to extract the file extension
const match = normalizedPath.match(/\.([a-zA-Z0-9]+)$/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normalizedPath?.match

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

const ext = match ? match[1].toLowerCase() : "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const ext = match ? match?.[1]?.toLowerCase() : "";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


const fileName = filePath?.split('/')?.pop();
const ext = fileName?.split('.')?.pop();
//const ext = fileName?.split('.')?.pop();
const validExtensionRegex = /\.(pdf|zip|xml|json)$/i;
return ext && validExtensionRegex?.test(`.${ext}`) ? `${ext}` : '';
};
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => {
}
};
//await updateLegacyCMSData(selectedOrganisation.value, projectId, { legacy_cms: newSelectedCard?.cms_id });
dispatch(updateNewMigrationData(newMigrationDataObj));
//dispatch(updateNewMigrationData(newMigrationDataObj));
props?.handleStepChange(props?.currentStep);
}

Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/LegacyCms/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ const LegacyCMSComponent = forwardRef(({ legacyCMSData, isCompleted, handleOnAll
}

//Make Step 2 complete
if (!isEmptyString(selectedCmsData?.cms_id) && !isEmptyString(legacyCMSData?.affix)) {
if (!isEmptyString(selectedCmsData?.cms_id) && (!isEmptyString(legacyCMSData?.affix) || !isEmptyString(newMigrationData?.legacy_cms?.affix))) {
setInternalActiveStepIndex(1);
}

Expand Down
16 changes: 8 additions & 8 deletions upload-api/migration-sitecore/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/* eslint-disable @typescript-eslint/no-var-requires */

const contentTypes = require("./libs/contenttypes.js")
const contentTypes = require('./libs/contenttypes.js');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ExtractConfiguration = require("./libs/configuration.js")
const ExtractConfiguration = require('./libs/configuration.js');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const reference = require("./libs/reference.js")
const reference = require('./libs/reference.js');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ExtractFiles = require("./libs/convert.js")
const ExtractFiles = require('./libs/convert.js');
// eslint-disable-next-line @typescript-eslint/no-var-requires
const extractLocales = require("./libs/extractLocales.js")
const extractLocales = require('./libs/extractLocales.js');

module.exports = {
module.exports = {
contentTypes,
ExtractConfiguration,
reference,
ExtractFiles,
ExtractFiles,
extractLocales
}
};
43 changes: 21 additions & 22 deletions upload-api/migration-sitecore/libs/extractLocales.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,32 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require("fs");
const path = require("path");

const fs = require('fs');
const path = require('path');

const uniqueLanguages = new Set(); // Define uniqueLanguages globally or pass it as a parameter

const extractLocales = (dir) => {
const items = fs.readdirSync(dir, { withFileTypes: true });
const items = fs.readdirSync(dir, { withFileTypes: true });

for (const item of items) {
const fullPath = path.join(dir, item.name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

item?.name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


for (const item of items) {
const fullPath = path.join(dir, item.name);

if (item.isDirectory()) {
extractLocales(fullPath); // Proper recursion
} else if (item.isFile() && item.name === "data.json.json") {
try {
const rawData = fs.readFileSync(fullPath, "utf8");
const jsonData = JSON.parse(rawData);
const language = jsonData?.item?.$?.language;
if (item.isDirectory()) {
extractLocales(fullPath); // Proper recursion
} else if (item.isFile() && item.name === 'data.json.json') {
try {
const rawData = fs.readFileSync(fullPath, 'utf8');
const jsonData = JSON.parse(rawData);
const language = jsonData?.item?.$?.language;

if (language) {
uniqueLanguages.add(language);
}
} catch (error) {
console.error(`Error reading ${fullPath}:`, error.message);
}
if (language) {
uniqueLanguages.add(language);
}
} catch (error) {
console.error(`Error reading ${fullPath}:`, error.message);
}
}
return uniqueLanguages;
}
return uniqueLanguages;
};

module.exports = extractLocales;
module.exports = extractLocales;
Loading