Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/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 =
Advertisement
Add Comment
Please, Sign In to add comment