Untitled
oshkoshbagoshh |
PRO |
07/03/24 06:34:00 PM UTC |
0 ⭐ |
1128 👁️ |
Never ⏰ |
[Scripts, Shell, BASH, folders]
#!/bin/bash
# Create project directories
mkdir -p project-root/{config,src/{models,services,utils,controllers},assets,data,scripts}
# Create .env file
cat <<EOL > project-root/.env
# MongoDB configuration
MONGODB_URI=mongodb://localhost:27017/seo_data
# PostgreSQL configuration
PGUSER=yourusername
PGHOST=localhost
PGDATABASE=yourdatabase
PGPASSWORD=yourpassword
PGPORT=5432
# Path to Client folder One Drive
CLIENT_ONEDRIVE_PATH=/path/to/onedrive/folder
EOL
# Create config/db.js
cat <<EOL > project-root/config/db.js
import { Client } from 'pg';
import mongoose from 'mongoose';
import dotenv from 'dotenv';
dotenv.config();
// MongoDB Configuration
mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB connected'))
.catch(err => console.error('MongoDB connection error:', err));
// PostgreSQL Configuration
const pgClient = new Client({
user: process.env.PGUSER,
host: process.env.PGHOST,
database: process.env.PGDATABASE,
password: process.env.PGPASSWORD,
port: process.env.PGPORT,
});
pgClient.connect()
.then(() => console.log('PostgreSQL connected'))
.catch(err => console.error('PostgreSQL connection error:', err));
export { mongoose, pgClient };
EOL
# Create config/puppeteer.js
cat <<EOL > project-root/config/puppeteer.js
import puppeteer from 'puppeteer';
const launchOptions = {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
};
export const getBrowserInstance = async () => {
const browser = await puppeteer.launch(launchOptions);
return browser;
};
EOL
# Create src/models/SeoData.js
cat <<EOL > project-root/src/models/SeoData.js
import mongoose from 'mongoose';
const seoSchema = new mongoose.Schema({
url: String,
title: String,
seoScore: Number,
colors: [String],
colorAccessibility: Boolean,
isWP: Boolean,
wpThemeDeveloper: String,
wpPlugins: [String],
imgAltDescriptions: [String],
});
const SeoData = mongoose.model("SeoData", seoSchema);
export default SeoData;
EOL
# Create src/services/scrapeService.js
cat <<EOL > project-root/src/services/scrapeService.js
import puppeteer from 'puppeteer';
import fs from 'fs';
import path from 'path';
import { saveToMongoDB, saveToPostgres } from './dbService';
import { calculateSeoScore } from './seoScore';
import { checkColorAccessibility } from '../utils/helpers';
import { getBrowserInstance } from '../../config/puppeteer';
import dotenv from 'dotenv';
dotenv.config();
async function scrapeSite(site) {
const browser = await getBrowserInstance();
const page = await browser.newPage();
try {
await page.goto(site.url, { waitUntil: 'networkidle2' });
// Take a PDF of the site
const pdfPath = path.join('assets', \`\${site.url.replace(/https?:\\/\\//, '').replace(/\\//g, '_')}.pdf\`);
await page.pdf({ path: pdfPath, format: 'A4' });
// Extract data from the site
const data = await page.evaluate(() => {
const title = document.title;
const colors = Array.from(new Set(Array.from(document.querySelectorAll('*')).map(el => getComputedStyle(el).color)));
const isWP = !!document.querySelector('meta[name="generator"][content*="WordPress"]');
const wpThemeDeveloper = isWP ? document.querySelector('meta[name="generator"]').content : null;
const wpPlugins = isWP ? Array.from(document.querySelectorAll('[class*="plugin"]')).map(el => el.className) : [];
const imgAltDescriptions = Array.from(document.querySelectorAll('img')).map(img => img.alt);
const ariaUsage = !!document.querySelector('[role]') || !!document.querySelector('[aria-*]');
const brokenLinks = Array.from(document.querySelectorAll('a')).filter(a => !a.href || a.href === '#').length;
return {
title,
colors,
isWP,
wpThemeDeveloper,
wpPlugins,
imgAltDescriptions,
ariaUsage,
brokenLinks
};
});
// Calculate SEO score
data.seoScore = calculateSeoScore(data);
data.url = site.url;
// Save data to MongoDB and PostgreSQL
await saveToMongoDB(data);
await saveToPostgres(data);
console.log(\`Scraped and saved data for \${site.url}\`);
} catch (error) {
console.error(\`Error scraping \${site.url}: \`, error);
} finally {
await browser.close();
}
}
export { scrapeSite };
EOL
# Create src/services/seoScore.js
cat <<EOL > project-root/src/services/seoScore.js
const weights = {
bestPractices: 0.15,
mobile: 0.10,
analyticsAndMonitoring: 0.10,
performance: 0.15,
usability: 0.10,
semantics: 0.10,
seo: 0.20,
codeQuality: 0.05,
accessibility: 0.10,
security: 0.05,
socialMediaAndStructuredData: 0.05,
};
const maxScore = {
required: {
bestPractices: 4,
mobile: 4,
analyticsAndMonitoring: 2,
performance: 3,
usability: 5,
semantics: 2,
seo: 4,
codeQuality: 5,
accessibility: 3,
security: 2,
socialMediaAndStructuredData: 0, // No required tasks
},
optional: {
usability: 2,
security: 3,
socialMediaAndStructuredData: 4,
andFinally: 1,
}
};
function calculateSeoScore(data) {
let totalScore = 0;
// Calculate required scores
Object.keys(weights).forEach(category => {
if (data[category] && data[category].required) {
const completedTasks = data[category].required.filter(task => task.completed).length;
totalScore += (completedTasks / maxScore.required[category]) * weights[category];
}
if (data[category] && data[category].optional) {
const completedTasks =
Comments