oshkoshbagoshh

Untitled

Jul 3rd, 2024
1,198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 5.67 KB | Source Code | 0 0
  1. #!/bin/bash
  2.  
  3. # Create project directories
  4. mkdir -p project-root/{config,src/{models,services,utils,controllers},assets,data,scripts}
  5.  
  6. # Create .env file
  7. cat <<EOL > project-root/.env
  8. # MongoDB configuration
  9. MONGODB_URI=mongodb://localhost:27017/seo_data
  10.  
  11. # PostgreSQL configuration
  12. PGUSER=yourusername
  13. PGHOST=localhost
  14. PGDATABASE=yourdatabase
  15. PGPASSWORD=yourpassword
  16. PGPORT=5432
  17.  
  18. # Path to Client folder One Drive
  19. CLIENT_ONEDRIVE_PATH=/path/to/onedrive/folder
  20. EOL
  21.  
  22. # Create config/db.js
  23. cat <<EOL > project-root/config/db.js
  24. import { Client } from 'pg';
  25. import mongoose from 'mongoose';
  26. import dotenv from 'dotenv';
  27.  
  28. dotenv.config();
  29.  
  30. // MongoDB Configuration
  31. mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
  32.   .then(() => console.log('MongoDB connected'))
  33.   .catch(err => console.error('MongoDB connection error:', err));
  34.  
  35. // PostgreSQL Configuration
  36. const pgClient = new Client({
  37.   user: process.env.PGUSER,
  38.   host: process.env.PGHOST,
  39.   database: process.env.PGDATABASE,
  40.   password: process.env.PGPASSWORD,
  41.   port: process.env.PGPORT,
  42. });
  43.  
  44. pgClient.connect()
  45.   .then(() => console.log('PostgreSQL connected'))
  46.   .catch(err => console.error('PostgreSQL connection error:', err));
  47.  
  48. export { mongoose, pgClient };
  49. EOL
  50.  
  51. # Create config/puppeteer.js
  52. cat <<EOL > project-root/config/puppeteer.js
  53. import puppeteer from 'puppeteer';
  54.  
  55. const launchOptions = {
  56.   headless: true,
  57.   args: ['--no-sandbox', '--disable-setuid-sandbox'],
  58. };
  59.  
  60. export const getBrowserInstance = async () => {
  61.   const browser = await puppeteer.launch(launchOptions);
  62.   return browser;
  63. };
  64. EOL
  65.  
  66. # Create src/models/SeoData.js
  67. cat <<EOL > project-root/src/models/SeoData.js
  68. import mongoose from 'mongoose';
  69.  
  70. const seoSchema = new mongoose.Schema({
  71.   url: String,
  72.   title: String,
  73.   seoScore: Number,
  74.   colors: [String],
  75.   colorAccessibility: Boolean,
  76.   isWP: Boolean,
  77.   wpThemeDeveloper: String,
  78.   wpPlugins: [String],
  79.   imgAltDescriptions: [String],
  80. });
  81.  
  82. const SeoData = mongoose.model("SeoData", seoSchema);
  83.  
  84. export default SeoData;
  85. EOL
  86.  
  87. # Create src/services/scrapeService.js
  88. cat <<EOL > project-root/src/services/scrapeService.js
  89. import puppeteer from 'puppeteer';
  90. import fs from 'fs';
  91. import path from 'path';
  92. import { saveToMongoDB, saveToPostgres } from './dbService';
  93. import { calculateSeoScore } from './seoScore';
  94. import { checkColorAccessibility } from '../utils/helpers';
  95. import { getBrowserInstance } from '../../config/puppeteer';
  96. import dotenv from 'dotenv';
  97.  
  98. dotenv.config();
  99.  
  100. async function scrapeSite(site) {
  101.   const browser = await getBrowserInstance();
  102.   const page = await browser.newPage();
  103.  
  104.   try {
  105.     await page.goto(site.url, { waitUntil: 'networkidle2' });
  106.    
  107.     // Take a PDF of the site
  108.     const pdfPath = path.join('assets', \`\${site.url.replace(/https?:\\/\\//, '').replace(/\\//g, '_')}.pdf\`);
  109.     await page.pdf({ path: pdfPath, format: 'A4' });
  110.    
  111.     // Extract data from the site
  112.     const data = await page.evaluate(() => {
  113.       const title = document.title;
  114.       const colors = Array.from(new Set(Array.from(document.querySelectorAll('*')).map(el => getComputedStyle(el).color)));
  115.       const isWP = !!document.querySelector('meta[name="generator"][content*="WordPress"]');
  116.       const wpThemeDeveloper = isWP ? document.querySelector('meta[name="generator"]').content : null;
  117.       const wpPlugins = isWP ? Array.from(document.querySelectorAll('[class*="plugin"]')).map(el => el.className) : [];
  118.       const imgAltDescriptions = Array.from(document.querySelectorAll('img')).map(img => img.alt);
  119.       const ariaUsage = !!document.querySelector('[role]') || !!document.querySelector('[aria-*]');
  120.       const brokenLinks = Array.from(document.querySelectorAll('a')).filter(a => !a.href || a.href === '#').length;
  121.  
  122.       return {
  123.         title,
  124.         colors,
  125.         isWP,
  126.         wpThemeDeveloper,
  127.         wpPlugins,
  128.         imgAltDescriptions,
  129.         ariaUsage,
  130.         brokenLinks
  131.       };
  132.     });
  133.  
  134.     // Calculate SEO score
  135.     data.seoScore = calculateSeoScore(data);
  136.     data.url = site.url;
  137.  
  138.     // Save data to MongoDB and PostgreSQL
  139.     await saveToMongoDB(data);
  140.     await saveToPostgres(data);
  141.  
  142.     console.log(\`Scraped and saved data for \${site.url}\`);
  143.   } catch (error) {
  144.     console.error(\`Error scraping \${site.url}: \`, error);
  145.   } finally {
  146.     await browser.close();
  147.   }
  148. }
  149.  
  150. export { scrapeSite };
  151. EOL
  152.  
  153. # Create src/services/seoScore.js
  154. cat <<EOL > project-root/src/services/seoScore.js
  155. const weights = {
  156.   bestPractices: 0.15,
  157.   mobile: 0.10,
  158.   analyticsAndMonitoring: 0.10,
  159.   performance: 0.15,
  160.   usability: 0.10,
  161.   semantics: 0.10,
  162.   seo: 0.20,
  163.   codeQuality: 0.05,
  164.   accessibility: 0.10,
  165.   security: 0.05,
  166.   socialMediaAndStructuredData: 0.05,
  167. };
  168.  
  169. const maxScore = {
  170.   required: {
  171.     bestPractices: 4,
  172.     mobile: 4,
  173.     analyticsAndMonitoring: 2,
  174.     performance: 3,
  175.     usability: 5,
  176.     semantics: 2,
  177.     seo: 4,
  178.     codeQuality: 5,
  179.     accessibility: 3,
  180.     security: 2,
  181.     socialMediaAndStructuredData: 0, // No required tasks
  182.   },
  183.   optional: {
  184.     usability: 2,
  185.     security: 3,
  186.     socialMediaAndStructuredData: 4,
  187.     andFinally: 1,
  188.   }
  189. };
  190.  
  191. function calculateSeoScore(data) {
  192.   let totalScore = 0;
  193.  
  194.   // Calculate required scores
  195.   Object.keys(weights).forEach(category => {
  196.     if (data[category] && data[category].required) {
  197.       const completedTasks = data[category].required.filter(task => task.completed).length;
  198.       totalScore += (completedTasks / maxScore.required[category]) * weights[category];
  199.     }
  200.    
  201.     if (data[category] && data[category].optional) {
  202.       const completedTasks =
  203.  
  204.  
Advertisement
Add Comment
Please, Sign In to add comment