Skip to content

Commit

Permalink
[no-issue] fix semrush redirects i18n json files (#1468)
Browse files Browse the repository at this point in the history
* wip: rgx with #

* fix: 1282 processedCount update links 30x

* wip: adjust to scan src/i18n with simple quote

* fix: adjust 30x link url

* chore: disable continue console.log

* fix: async correction to process file i18n

* fix: replace 30x links to the 200
  • Loading branch information
robsongajunior authored Jan 25, 2025
1 parent 8a3fe28 commit cb4b377
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 144 deletions.
191 changes: 101 additions & 90 deletions backend/semrush-replace-url/index.i18n.js
Original file line number Diff line number Diff line change
@@ -1,110 +1,121 @@
import { parse } from 'csv-parse'
import fs from 'fs'
import { createReadStream } from 'fs'
import path from 'path'
import { parse } from 'csv-parse';
import { promises as fs } from 'fs';
import { createReadStream } from 'fs';
import path from 'path';

let counterFoundLinks = 0
let PATH = {
csv: './www.azion.com_permanent_redirects_20241225.csv',
i18n: `${process.env.OLDPWD}/src/i18n`
}
const wwwazioncom = 'https://www.azion.com'
let counterFoundLinks = 0;
const PATH = {
csv: './www.azion.com_permanent_redirects_20241225.csv',
i18n: `${process.env.OLDPWD}/src/i18n`
};
const wwwazioncom = 'https://www.azion.com';
const removeLangFromUrl = (url) => url.replace('/pt-br', '').replace('/en', '');
const removeHostFromUrl = (url) => url.replace(wwwazioncom, '');
const removeHostAndLangFromUrl = (url) => removeLangFromUrl(removeHostFromUrl(url));
const isFromRoot = (url) => url === wwwazioncom;

async function loadRedirects() {
const redirects = []
const parser = createReadStream(PATH.csv).pipe(
parse({
columns: true,
skip_empty_lines: true,
})
)

for await (const record of parser) {
redirects.push({
page: record.page,
initialUrl: record.initial_url,
destinationUrl: record.destination_url,
statusCode: record.status,
discovered: record.discovered
})
}
const redirects = [];
const parser = createReadStream(PATH.csv).pipe(
parse({
columns: true,
skip_empty_lines: true,
})
);

return redirects
try {
for await (const record of parser) {
redirects.push({
page: record.page,
initialUrl: record.initial_url,
destinationUrl: record.destination_url,
statusCode: record.status,
discovered: record.discovered
});
}
return redirects;
} catch (error) {
throw new Error(`Error loading redirects: ${error.message}`);
}
}

async function processFile(filePath, redirects) {
fs.readFile(filePath, async (err, content) => {
if(err) {
console.error(err)
return
}
try {
const content = await fs.readFile(filePath, 'utf-8');
let newContent = content;
let fileModified = false;

const utf8Content = Buffer.from(content).toString('utf-8')
for (const item of redirects) {
const url30x = isFromRoot(item.initialUrl) ? wwwazioncom : removeHostAndLangFromUrl(item.initialUrl);
const url200 = removeHostAndLangFromUrl(item.destinationUrl);
const isRoot = isFromRoot(url30x);
const rgx = new RegExp(`'${url30x}'`, 'g');
const contentMatch = newContent.match(rgx);

for (const item of redirects) {
const url30x = item.initialUrl === wwwazioncom ? wwwazioncom : item.initialUrl.replace(wwwazioncom, '')
const url200 = item.destinationUrl.replace(wwwazioncom, '')
const isRoot = url30x === wwwazioncom
const rgx = new RegExp(`${url30x}`, 'g')
const contentMatch = utf8Content.match(rgx)
if (!contentMatch) continue;

if(!contentMatch) {
// console.log(`NOT MATCH `, `${rgx} : ${url30x}`)
continue
} else {
console.log(`MATCH`, `${rgx} : ${url30x}`)
}
counterFoundLinks++
counterFoundLinks++;
fileModified = true;

console.log(`{
isRoot: ${isRoot},
file: ${filePath},
rgx: ${rgx},
url30x: ${url30x},
url200: ${url200},
contentMatch: ${contentMatch},
contentMatchCount: ${contentMatch.length},
processedCount: ${counterFoundLinks}
}`)
console.log({
isRoot,
file: filePath,
rgx: rgx.toString(),
url30x,
url200,
contentMatchCount: contentMatch.length,
processedCount: counterFoundLinks
});

const newContent = utf8Content.replace(isRoot ? /'https\:\/\/www\.azion\.com\/'/ : rgx, `'${url200}'`)
await fs.writeFile(filePath, newContent, async (err) => {
if(err) throw err
console.log(`[OK] ${filePath} updated`)
})
}
})
}
newContent = newContent.replace(
isRoot ? /'https\:\/\/www\.azion\.com\/'/ : rgx,
`'${url200}'`
);
}

function processDirectory(directory, redirects) {
fs.readdir(directory, { withFileTypes: true }, (err, entries) => {
if (err) {
console.error('[ERROR] directory can not be readed:', err)
return
}
if (fileModified) {
await fs.writeFile(filePath, newContent);
console.log(`[OK] ${filePath} updated`);
}
} catch (error) {
console.error(`[ERROR] Processing file ${filePath}:`, error);
}
}

for (const entry of entries) {
const fullPath = path.join(directory, entry.name)
async function processDirectory(directory, redirects) {
try {
const entries = await fs.readdir(directory, { withFileTypes: true });
const processingPromises = entries.map(async (entry) => {
const fullPath = path.join(directory, entry.name);

if (entry.isDirectory()) {
return processDirectory(fullPath, redirects);
} else if (entry.isFile()) {
return processFile(fullPath, redirects);
} else {
console.warn(`[WARN] ${fullPath} is not a file or directory`);
}
});

if(entry.isDirectory()) {
processDirectory(fullPath, redirects)
} else if (entry.isFile()) {
processFile(fullPath, redirects)
} else {
console.error(`[ERROR] ${fullPath} is not a file or directory`)
}
}
})
await Promise.all(processingPromises);
} catch (error) {
console.error(`[ERROR] Processing directory ${directory}:`, error);
}
}

async function main() {
try {
const redirects = await loadRedirects()
processDirectory(PATH.i18n, redirects)
} catch (error) {
console.error('[ERROR] ', error)
process.exit(1)
}
try {
console.log('[INFO] Loading redirects...');
const redirects = await loadRedirects();
console.log(`[INFO] Loaded ${redirects.length} redirects`);

console.log('[INFO] Starting directory processing...');
await processDirectory(PATH.i18n, redirects);
console.log(`[INFO] Processing complete. Found and replaced ${counterFoundLinks} links`);
} catch (error) {
console.error('[ERROR] Fatal error:', error);
process.exit(1);
}
}

main()
main();
4 changes: 2 additions & 2 deletions src/i18n/en/graphqlMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
{ text: 'Features',header: true, anchor: true, type: 'learn', slug: '/documentation/devtools/graphql-api/features/', key: 'features' },

{ text: 'Fields', header: true, key: 'fields', type: 'learn', items: [
{ text: 'Real-Time Events GQL', slug: '/documentation/products/graphql-api/features/events-fields/', key: 'fields/Events' },
{ text: 'Real-Time Metrics GQL', slug: '/documentation/products/graphql-api/features/metrics-fields/', key: 'fields/Metrics' },
{ text: 'Real-Time Events GQL', slug: '/documentation/devtools/graphql-api/features/gql-real-time-events-fields/', key: 'fields/Events' },
{ text: 'Real-Time Metrics GQL', slug: '/documentation/devtools/graphql-api/features/gql-real-time-metrics-fields/', key: 'fields/Metrics' },
{ text: 'Billing GQL', slug: '/documentation/devtools/graphql-api/features/gql-billing-fields/', key: 'fields/Billing' },
{ text: 'Accounting GQL', slug: '/documentation/devtools/graphql-api/features/gql-accounting-fields/', key: 'fields/Accounting' },
]
Expand Down
16 changes: 8 additions & 8 deletions src/i18n/en/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default [
{
text: 'Developer tools', header: true, type: 'learn', key: 'developerTools', hasLabel: 'menu.addResources', items: [
{ text: 'API', header: true, anchor: true, type: 'learn', key: 'devtools/api', slug: '/documentation/products/overview-azion-api/' },
{ text: 'CLI', header: true, anchor: true, type: 'learn', key: 'devtools/cli', slug: '/documentation/products/cli/' },
{ text: 'CLI', header: true, anchor: true, type: 'learn', key: 'devtools/cli', slug: '/documentation/products/azion-cli/overview/' },
{ text: 'API GraphQL Playground', header: true, anchor: true, type: 'learn', slug: '/documentation/products/devtools/graphql-playground/', key: 'devtools/graphQLplayground' },
{ text: 'SDK', header: true, anchor: true, type: 'learn', slug: '/documentation/devtools/sdk/go/', key: 'devtools/sdk' },
{ text: 'Terraform', header: true, anchor: true, type: 'learn', slug: '/documentation/products/terraform-provider/', key: 'devtools/terraform' },
Expand All @@ -74,13 +74,13 @@ export default [
text: 'Build', header: true, type: 'learn', key: 'buildRef', hasLabel: 'menu.reference', items: [
{ text: 'Edge Application', header: true, anchor: true, type: 'learn', key: 'reference/edgeApplication', slug: '/documentation/products/build/edge-application/' },
{ text: 'Application Accelerator', header: true, anchor: true, type: 'learn', key: 'reference/applicationAcceleration', slug: '/documentation/products/build/edge-application/application-accelerator/' },
{ text: 'Edge Cache', header: true, anchor: true, type: 'learn', key: 'reference/edgeCaching', slug: '/documentation/products/build/edge-application/edge-caching/' },
{ text: 'Edge Cache', header: true, anchor: true, type: 'learn', key: 'reference/edgeCaching', slug: '/documentation/products/build/edge-application/edge-cache/' },
{ text: 'Edge Functions', header: true, anchor: true, type: 'learn', key: 'reference/edge Functions', slug: '/documentation/products/build/edge-application/edge-functions/' },
{ text: 'Image Processor', header: true, anchor: true, type: 'learn', key: 'reference/imageProcessor', slug: '/documentation/products/build/edge-application/image-processor/' },
{ text: 'Load Balancer', header: true, anchor: true, type: 'learn', key: 'reference/loadBalancer', slug: '/documentation/products/build/edge-application/load-balancer/' },
{ text: 'Tiered Cache', header: true, anchor: true, type: 'learn', key: 'reference/l2Caching', slug: '/documentation/products/edge-application/l2-caching/' },
{ text: 'Main Settings', header: true, anchor: true, type: 'learn', key: 'reference/mainSettings', slug: '/documentation/products/edge-application/build/main-settings/' },
{ text: 'Cache Settings', header: true, anchor: true, type: 'learn', key: 'reference/cacheSettings', slug: '/documentation/products/edge-application/cache-settings/' },
{ text: 'Tiered Cache', header: true, anchor: true, type: 'learn', key: 'reference/l2Caching', slug: '/documentation/products/build/edge-application/tiered-cache/' },
{ text: 'Main Settings', header: true, anchor: true, type: 'learn', key: 'reference/mainSettings', slug: '/documentation/products/build/edge-application/main-settings/' },
{ text: 'Cache Settings', header: true, anchor: true, type: 'learn', key: 'reference/cacheSettings', slug: '/documentation/products/build/edge-application/cache-settings/' },
{ text: 'Edge Functions Instances', header: true, anchor: true, type: 'learn', key: 'reference/edgeFunctionsInstancesApplication', slug: '/documentation/products/build/edge-application/edge-functions-instances/' },
{ text: 'Device Groups', header: true, anchor: true, type: 'learn', key: 'reference/deviceGroups', slug: '/documentation/products/build/edge-application/device-groups/' },
{ text: 'Error Responses', header: true, anchor: true, type: 'learn', key: 'reference/errorResponses', slug: '/documentation/products/build/edge-application/error-responses/' },
Expand All @@ -104,7 +104,7 @@ export default [
{ text: 'Network Layer Protection', header: true, anchor: true, type: 'learn', key: 'reference/networkLayerProtection', slug: '/documentation/products/secure/edge-firewall/network-layer-protection/' },
{ text: 'Network Lists', header: true, anchor: true, type: 'learn', key: 'reference/networkLists', slug: '/documentation/products/secure/edge-firewall/network-layer-protection/network-lists/' },
{ text: 'Web Application Firewall', header: true, anchor: true, type: 'learn', key: 'reference/webApplicationFirewall', slug: '/documentation/products/secure/edge-firewall/web-application-firewall/' },
{ text: 'WAF Rule Sets', header: true, anchor: true, type: 'learn', key: 'reference/wafRuleSets', slug: '/documentation/products/secure/edge-firewall/web-application-firewall/rules-engine/' },
{ text: 'WAF Rule Sets', header: true, anchor: true, type: 'learn', key: 'reference/wafRuleSets', slug: '/documentation/products/secure/edge-firewall/web-application-firewall/rules-set/' },
{ text: 'WAF Custom Allowed Rules', header: true, anchor: true, type: 'learn', key: 'reference/wafCustomAllowedRules', slug: '/documentation/products/secure/edge-firewall/web-application-firewall/custom-allowed-rules/' },
{ text: 'Edge Functions', header: true, anchor: true, type: 'learn', key: 'reference/edgeFunctionsFirewall', slug: '/documentation/products/secure/edge-firewall/edge-functions/' },
{ text: 'Edge Functions Instances', header: true, anchor: true, type: 'learn', key: 'reference/edgeFunctionsInstancesFirewall', slug: '/documentation/products/secure/edge-firewall/edge-functions-instances/' },
Expand All @@ -129,14 +129,14 @@ export default [
{ text: 'Edge Pulse', header: true, anchor: true, type: 'learn', key: 'reference/edgePulse', slug: '/documentation/products/observe/edge-pulse/' },
{ text: 'Real-Time Events', header: true, anchor: true, type: 'learn', key: 'reference/realTimeEvents', slug: '/documentation/products/observe/real-time-events/' },
{ text: 'Real-Time Metrics', header: true, anchor: true, type: 'learn', key: 'reference/realTimeMetrics', slug: '/documentation/products/observe/real-time-metrics/' },
{ text: 'Historical Real-Time Metrics', header: true, anchor: true, type: 'learn', key: 'reference/historicalRealTimeMetrics', slug: '/documentation/products/historical-real-time-metrics/' },
{ text: 'Historical Real-Time Metrics', header: true, anchor: true, type: 'learn', key: 'reference/historicalRealTimeMetrics', slug: '/documentation/products/observe/historical-real-time-metrics/' },

]
},
{
text: 'Marketplace', header: true, type: 'learn', key: 'mktpRef', items: [
{ text: 'Marketplace', header: true, anchor: true, type: 'learn', key: 'mktp', slug: '/documentation/products/marketplace/' },
{ text: 'Permissions', header: true, anchor: true, type: 'learn', key: 'mktp/permissions', slug: '/documentation/products/guides/permissions-marketplace/' },
{ text: 'Permissions', header: true, anchor: true, type: 'learn', key: 'mktp/permissions', slug: '/documentation/products/marketplace/permissions-marketplace/' },
{ text: 'Marketplace Seller Guide', header: true, anchor: true, type: 'learn', key: 'mktp/sellerGuide', slug: '/documentation/products/marketplace/marketplace-seller-guide/' },
]
},
Expand Down
4 changes: 2 additions & 2 deletions src/i18n/pt-br/graphqlMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
{ text: 'Recursos', header: true, anchor: true, type: 'learn', slug: '/documentacao/produtos/graphql-api-recursos', key: 'features' },

{ text: 'Campos', header: true, key: 'fields', type: 'learn', items: [
{ text: 'Real-Time Events GQL', slug: '/documentacao/produtos/graphql-api/recursos/campos-events/', key: 'fields/Events' },
{ text: 'Real-Time Metrics GQL', slug: '/documentacao/produtos/graphql-api/recursos/campos-metrics/', key: 'fields/Metrics' },
{ text: 'Real-Time Events GQL', slug: '/documentacao/devtools/graphql-api/recursos/campos-gql-real-time-events/', key: 'fields/Events' },
{ text: 'Real-Time Metrics GQL', slug: '/documentacao/devtools/graphql-api/recursos/campos-gql-real-time-metrics/', key: 'fields/Metrics' },
{ text: 'Billing GQL', slug: '/documentacao/devtools/graphql-api/recursos/campos-gql-billing/', key: 'fields/Billing' },
{ text: 'Accounting GQL', slug: '/documentacao/devtools/graphql-api/recursos/campos-gql-accounting/', key: 'fields/Accounting' },
]
Expand Down
Loading

0 comments on commit cb4b377

Please sign in to comment.