oshkoshbagoshh icon

Untitled

oshkoshbagoshh | PRO | 07/03/24 06:34:00 PM UTC | 0 ⭐ | 1128 👁️ | Never ⏰ | [Scripts, Shell, BASH, folders]
Bash |

5.67 KB

|

Source Code

|

0 👍

/

0 👎

#!/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