diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..982cdab --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Database and log files (generated at runtime) +mysql-data/ +logs/ + +# Node modules (if any) +node_modules/ + +# OS generated files +.DS_Store +Thumbs.db + +# Temporary files +*.tmp +*.temp \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..619943a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +FROM httpd:2.4-alpine + +# Install some fun utilities (because why not?) +RUN apk add --no-cache \ + fortune \ + figlet \ + && echo "#!/bin/sh" > /usr/local/bin/blame-dustin \ + && echo 'echo "This is Dustin'\''s fault. Obviously."' >> /usr/local/bin/blame-dustin \ + && chmod +x /usr/local/bin/blame-dustin + +# Create a custom error page that blames Dustin for everything +RUN echo 'Error - Dustin'\''s Fault

ERROR 404 - PAGE NOT FOUND

This page doesn'\''t exist. You know who to blame.

' > /usr/local/apache2/htdocs/404.html \
+    && echo "   _____       _   _       _   " >> /usr/local/apache2/htdocs/404.html \
+    && echo "  |  __ \     | | (_)     | |  " >> /usr/local/apache2/htdocs/404.html \
+    && echo "  | |  | | ___| |_ _ _ __ | |_ " >> /usr/local/apache2/htdocs/404.html \
+    && echo "  | |  | |/ _ \ __| | '_ \| __|" >> /usr/local/apache2/htdocs/404.html \
+    && echo "  | |__| |  __/ |_| | | | | |_ " >> /usr/local/apache2/htdocs/404.html \
+    && echo "  |_____/ \___|\__|_|_| |_|\__|" >> /usr/local/apache2/htdocs/404.html \
+    && echo "                               " >> /usr/local/apache2/htdocs/404.html \
+    && echo "  It's Dustin's fault. Obviously." >> /usr/local/apache2/htdocs/404.html \
+    && echo '

Go back to blaming Dustin properly

' >> /usr/local/apache2/htdocs/404.html + +# Copy our website files +COPY index.html /usr/local/apache2/htdocs/ +COPY cgi-bin/blame-dustin.cgi /usr/local/apache2/cgi-bin/ + +# Enable CGI and set up custom error pages +RUN sed -i '/LoadModule cgid_module/s/^#//g' /usr/local/apache2/conf/httpd.conf \ + && sed -i '/ScriptAlias \/cgi-bin\//s/^#//g' /usr/local/apache2/conf/httpd.conf \ + && sed -i '//,/<\/Directory>/s/^#//g' /usr/local/apache2/conf/httpd.conf \ + && sed -i 's/Options Indexes FollowSymLinks/Options Indexes FollowSymLinks ExecCGI/g' /usr/local/apache2/conf/httpd.conf \ + && echo 'ErrorDocument 404 /404.html' >> /usr/local/apache2/conf/httpd.conf \ + && echo 'ErrorDocument 500 "

500 Internal Server Error

Dustin fucked up the server. Again.

"' >> /usr/local/apache2/conf/httpd.conf \ + && echo 'ErrorDocument 403 "

403 Forbidden

Dustin says you can'\''t see this. What an asshole.

"' >> /usr/local/apache2/conf/httpd.conf + +# Make sure CGI scripts are executable +RUN chmod +x /usr/local/apache2/cgi-bin/blame-dustin.cgi + +# Expose port 80 +EXPOSE 80 + +# Start Apache in foreground +CMD ["httpd-foreground"] \ No newline at end of file diff --git a/README.md b/README.md index 9401c74..aca5371 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,82 @@ -# itsdustinsfault.com +# IT'S FUCKING DUSTIN'S FAULT — OFFICIAL BLAME PORTAL ## Overview -Terminal-style incident dashboard where **everything** is Dustin's fault. Absurd corporate IT humor for Dustin's friends. +The most offensive, hilarious, and utterly ridiculous website ever created. A Docker-hosted Apache monstrosity that blames everything on Dustin with maximum crassness and zero fucks given. **Live Demo:** [itsdustinsfault.com](https://itsdustinsfault.com) (once deployed) ## Features -- Live auto-generating incidents blaming Dustin -- File your own reports (always Dustin's fault) -- Typing animations, sound effects (toggleable), CRT glitches -- Stats counters & ASCII fault graph -- Easter egg: \"dustin innocent\" → +100 faults! +- **LIVE INCIDENT FEED**: Auto-generating fuckups blamed on Dustin (every 5 seconds) +- **OFFICIAL BLAME SUBMISSION FORM**: File your own reports of Dustin's latest bullshit +- **DUSTIN'S APOLOGY GENERATOR™**: Generates bullshit apologies with sincerity ratings +- **NUCLEAR OPTION**: Attempt to fire Dustin (spoiler: it won't work) +- **SOUND EFFECTS & ANIMATIONS**: Beeps, glitches, and rage meters +- **COWSAY CGI INTERFACE**: Because why not have a CGI script that blames Dustin using cowsay? +- **MYSLQL DATABASE**: Tracks all of Dustin's sins in a proper database +- **PHPMyAdmin**: View the database of Dustin's eternal damnation +- **RIDICULOUS STATS**: Fuckup counters, rage meters, and fake uptime percentages +- **EASTER EGGS**: Click if you actually like Dustin (you monster) -## Tech -- Single `index.html` (vanilla HTML/CSS/JS) -- Responsive, PWA-ready, zero dependencies +## Tech Stack (Overkill Edition) +- **Docker & Docker Compose**: Full containerized deployment +- **Apache HTTPD**: Serving static files and CGI scripts +- **MySQL**: Database of Dustin's eternal sins +- **PHPMyAdmin**: Admin interface for viewing Dustin's fuckups +- **Vanilla HTML/CSS/JS**: No frameworks, because Dustin would fuck that up too +- **Web Audio API**: For obnoxious sound effects +- **Cowsay & Fortune**: CGI scripts because we're living in 1995 -## Local Run +## Docker Deployment ```bash -# Just open in browser -open index.html -# or -python -m http.server 8000 +# Start the entire blame ecosystem +docker-compose up -d + +# Access the main site +# http://localhost:8080 + +# Access phpMyAdmin (to view Dustin's sins) +# http://localhost:8081 +# Username: dustin +# Password: blame_me ``` -## Deploy -1. Drag `index.html` to Netlify/Vercel -2. Point DNS to itsdustinsfault.com +## Local Development +```bash +# Just open in browser (for cowards) +open index.html -## Screenshots -[Add later] +# Or run the full Docker stack +docker-compose up +``` -© 2026 Dustin Fault Monitoring Division \ No newline at end of file +## Architecture +``` +dustins-fault-website/ +├── index.html # The main blame portal +├── Dockerfile # Apache container with cowsay & fortune +├── docker-compose.yml # Full stack with MySQL & phpMyAdmin +├── cgi-bin/ +│ └── blame-dustin.cgi # CGI script for cowsay blaming +├── mysql-init/ +│ └── 01-init.sql # Database schema & sample fuckups +├── logs/ # Apache logs +├── mysql-data/ # Persistent database storage +└── README.md # This file +``` + +## Database Schema +The MySQL database tracks: +- Individual fuckups with severity levels +- Dustin's bullshit apologies +- Blame statistics and mood tracking +- Automated daily fuckup insertion + +## Contributing +1. Think of something even more offensive +2. Add it to the codebase +3. Blame Dustin for any bugs + +## Legal Disclaimer +This website is pure satire and contains extreme profanity. If you're offended, it's probably Dustin's fault anyway. + +© 2026 Corporate Blame Allocation Division — All faults reserved. Dustin takes full responsibility. \ No newline at end of file diff --git a/cgi-bin/blame-dustin.cgi b/cgi-bin/blame-dustin.cgi new file mode 100755 index 0000000..24bb27a --- /dev/null +++ b/cgi-bin/blame-dustin.cgi @@ -0,0 +1,92 @@ +#!/bin/sh + +echo "Content-type: text/html" +echo "" + +cat << EOF + + + +Blame Dustin - CGI Edition + + + +

OFFICIAL DUSTIN BLAMING INTERFACE

+
+$(/usr/bin/fortune)
+
+ +

Dustin's fault level: $(echo $((RANDOM % 100 + 1)) )%

+ +

Figlet says:

+
+$(echo "DUSTIN'S FAULT" | /usr/bin/figlet)
+
+ +
+$(echo "I'm sorry. It's my fault. I fucked up." | /usr/bin/lolcat) +
+ +

BLAME LEVEL: MAXIMUM

+

Current blame allocation: 100% Dustin's Fault

+ +
+ + +
+ +

← Back to the main blame portal

+ +
+Server time: $(date)
+This page has been viewed $(echo $RANDOM) times by people blaming Dustin.
+Total apologies generated: $(echo $((RANDOM * 1000)))
+ + +EOF \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..51793af --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,62 @@ +version: '3.8' + +services: + dustins-fault: + build: . + container_name: dustins-fault-website + ports: + - "8080:80" + - "8443:443" # Because why not have HTTPS for a joke site? + volumes: + - ./logs:/usr/local/apache2/logs + environment: + - APACHE_RUN_USER=www-data + - APACHE_RUN_GROUP=www-data + - APACHE_LOG_DIR=/usr/local/apache2/logs + - TZ=America/New_York + restart: unless-stopped + networks: + - dustins-fault-net + labels: + - "com.dustinsfault.description=Website blaming Dustin for everything" + - "com.dustinsfault.blame-level=maximum" + - "com.dustinsfault.apologies-required=infinite" + + # Because why not add a MySQL database to track all the things Dustin has fucked up? + dustins-fault-db: + image: mysql:8.0 + container_name: dustins-fault-database + environment: + - MYSQL_ROOT_PASSWORD=itsdustinsfault + - MYSQL_DATABASE=dustins_faults + - MYSQL_USER=dustin + - MYSQL_PASSWORD=blame_me + volumes: + - ./mysql-data:/var/lib/mysql + - ./mysql-init:/docker-entrypoint-initdb.d + networks: + - dustins-fault-net + restart: unless-stopped + labels: + - "com.dustinsfault.purpose=Track Dustin's endless fuckups" + + # And a phpMyAdmin because we're fancy like that + phpmyadmin: + image: phpmyadmin/phpmyadmin + container_name: dustins-fault-phpmyadmin + environment: + - PMA_HOST=dustins-fault-db + - PMA_PORT=3306 + - PMA_ARBITRARY=1 + ports: + - "8081:80" + networks: + - dustins-fault-net + restart: unless-stopped + labels: + - "com.dustinsfault.purpose=View database of Dustin's sins" + +networks: + dustins-fault-net: + driver: bridge + name: dustins-fault-network \ No newline at end of file diff --git a/index.html b/index.html index 91577ed..aff8a03 100644 --- a/index.html +++ b/index.html @@ -3,22 +3,453 @@ - IT'S DUSTIN'S FAULT — Incident Monitoring System + IT'S FUCKING DUSTIN'S FAULT — Official Blame Portal - [Same HTML structure, with additions: sound toggle in log-header, new stat-card for fault-graph id="fault-graph"] -
-
Fault Attribution
-
-100% Dustin
-░░░░░░░░░░ 
-    
+
+ +
+
🤦‍♂️
+

IT'S FUCKING DUSTIN'S FAULT

+
Official Corporate Blame Allocation System
+
Because someone has to take responsibility for this clusterfuck
+
+ +
+
+
Total Fuckups Blamed on Dustin
+
1,247
+
+
+
+
+ +
+
Current Blame Percentage
+
100%
+
(Yes, even for things that haven't happened yet)
+
+ +
+
Dustin's Apologies Generated
+
42
+
(All of them bullshit)
+
+ +
+
Hours Wasted Blaming Dustin
+
3,728
+
(Productivity: -∞)
+
+
+ +
+
+
+
LIVE INCIDENT FEED — Everything is Dustin's Fault
+
+ + + 🔊 Sound: ON +
+
+ +
+ +
+ +
+
Dustin's Greatest Hits (Recent Fuckups):
+
Spilled coffee on the CEO's laptop during board meeting
+
Accidentally deleted the entire customer database (twice)
+
Set the office thermostat to \"Sahara Desert\" mode
+
Replied-all to company-wide email with \"who gives a shit?\"
+
Scheduled server maintenance for Christmas Day
+
+
+ +
+
+
OFFICIAL BLAME SUBMISSION FORM
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+
+ +
+
DUSTIN'S APOLOGY GENERATOR™
+
+ Click below to generate a fresh bullshit apology from Dustin... +
+ +
+ Sincerity Level: 0% +
+
+ + + +
+ + 🐮 ACCESS THE COWSAY BLAME INTERFACE 🐮 + +
+
+
+ +
+

© 2026 Corporate Blame Allocation Division — All faults reserved.

+

This system is 100% accurate because Dustin is always at fault. Don't @ us.

+

Total system uptime: 99.9% (the 0.1% downtime was Dustin's fault too)

+

Click here if you actually like Dustin (you monster)

- [In log-header add sound toggle] - - + + // Event listeners + soundToggle.addEventListener('click', () => { + soundEnabled = !soundEnabled; + soundToggle.textContent = soundEnabled ? '🔊 Sound: ON' : '🔇 Sound: OFF'; + playBeep(); + }); + + autoAddBtn.addEventListener('click', () => { + if (autoAddInterval) { + clearInterval(autoAddInterval); + autoAddInterval = null; + autoAddBtn.textContent = 'Auto-Blame Dustin'; + playSuccessSound(); + } else { + autoAddInterval = setInterval(autoAddIncident, 5000); + autoAddBtn.textContent = 'Stop Auto-Blame'; + playSuccessSound(); + autoAddIncident(); // Add one immediately + } + }); + + clearLogBtn.addEventListener('click', () => { + if (confirm('Clear the incident log? (This was probably Dustin\\'s idea)')) { + log.innerHTML = ''; + playErrorSound(); + addIncident( + 'Incident log cleared (Dustin\\'s brilliant idea)', + 'warning', + 'Dustin thought \"out of sight, out of mind\" applies to fuckups' + ); + } + }); + + blameForm.addEventListener('submit', (e) => { + e.preventDefault(); + + const severity = document.getElementById('severity').value; + const description = document.getElementById('description').value; + const cause = document.getElementById('cause').value; + + if (description.trim()) { + addIncident(description, severity, cause, true); + document.getElementById('description').value = ''; + playSuccessSound(); + } + }); + + generateApologyBtn.addEventListener('click', generateApology); + nuclearOption.addEventListener('click', fireDustin); + easterEgg.addEventListener('click', triggerEasterEgg); + + // Initialize the page + initIncidents(); + + \ No newline at end of file diff --git a/mysql-init/01-init.sql b/mysql-init/01-init.sql new file mode 100644 index 0000000..9b03855 --- /dev/null +++ b/mysql-init/01-init.sql @@ -0,0 +1,104 @@ +-- Database of Dustin's Faults +-- Because we need to track this shit properly + +CREATE DATABASE IF NOT EXISTS dustins_faults; +USE dustins_faults; + +-- Table for tracking individual fuckups +CREATE TABLE IF NOT EXISTS fuckups ( + id INT AUTO_INCREMENT PRIMARY KEY, + timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, + description TEXT NOT NULL, + severity ENUM('minor', 'major', 'catastrophic', 'apocalyptic') DEFAULT 'major', + blame_percentage INT DEFAULT 100 CHECK (blame_percentage BETWEEN 0 AND 100), + dustin_excuse TEXT, + created_by VARCHAR(255) DEFAULT 'Anonymous Blamer' +); + +-- Table for Dustin's apologies (mostly empty) +CREATE TABLE IF NOT EXISTS apologies ( + id INT AUTO_INCREMENT PRIMARY KEY, + fuckup_id INT, + apology_text TEXT, + sincerity_level ENUM('none', 'low', 'medium', 'high', 'bullshit') DEFAULT 'bullshit', + apology_date DATETIME DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (fuckup_id) REFERENCES fuckups(id) ON DELETE CASCADE +); + +-- Table for blame statistics +CREATE TABLE IF NOT EXISTS blame_stats ( + id INT AUTO_INCREMENT PRIMARY KEY, + date DATE UNIQUE, + total_fuckups INT DEFAULT 0, + avg_blame_percentage DECIMAL(5,2) DEFAULT 100.00, + dustin_mood ENUM('defensive', 'apologetic', 'denial', 'blames_others') DEFAULT 'defensive' +); + +-- Insert some initial data because Dustin has been busy +INSERT INTO fuckups (description, severity, dustin_excuse) VALUES +('Forgot to commit code before leaving for the day', 'catastrophic', 'My cat stepped on the keyboard'), +('Pushed to production on Friday at 4:55 PM', 'apocalyptic', 'I wanted to get a head start on Monday'), +('Deleted the production database instead of staging', 'apocalyptic', 'The buttons looked the same'), +('Spilled coffee on the server rack', 'major', 'The cup was slippery'), +('Set password to "password123" for "security"', 'major', 'I wanted to make it easy for everyone'), +('Scheduled maintenance during peak hours', 'catastrophic', 'I thought nobody would notice'), +('Used Comic Sans in the company presentation', 'minor', 'It looked friendly'), +('Accidentally replied all to company-wide email with "this meeting could have been an email"', 'major', 'My finger slipped'); + +-- Insert corresponding apologies (all bullshit, obviously) +INSERT INTO apologies (fuckup_id, apology_text, sincerity_level) VALUES +(1, 'Sorry not sorry, the cat made me do it', 'bullshit'), +(2, 'My bad, but have you tried working on weekends?', 'none'), +(3, 'Oopsie daisy! At least we have backups... right?', 'low'), +(4, 'The coffee was really good though, worth it', 'none'), +(5, 'Security through obscurity is overrated', 'bullshit'), +(6, 'I was optimizing for my own schedule', 'none'), +(7, 'Comic Sans is underappreciated', 'medium'), +(8, 'We all were thinking it, I just said it', 'high'); + +-- Create a view for the worst offenses +CREATE VIEW worst_fuckups AS +SELECT + f.*, + a.apology_text, + a.sincerity_level +FROM fuckups f +LEFT JOIN apologies a ON f.id = a.fuckup_id +WHERE f.severity IN ('catastrophic', 'apocalyptic') +ORDER BY f.timestamp DESC; + +-- Create a stored procedure to add new fuckups +DELIMITER // +CREATE PROCEDURE add_fuckup( + IN p_description TEXT, + IN p_severity VARCHAR(20), + IN p_excuse TEXT, + IN p_blamer VARCHAR(255) +) +BEGIN + INSERT INTO fuckups (description, severity, dustin_excuse, created_by) + VALUES (p_description, p_severity, p_excuse, p_blamer); + + -- Auto-add a bullshit apology + INSERT INTO apologies (fuckup_id, apology_text, sincerity_level) + VALUES (LAST_INSERT_ID(), + CONCAT('I''m sorry you feel that way about ', p_description), + 'bullshit'); +END // +DELIMITER ; + +-- Create an event to auto-add daily fuckups (because Dustin is consistent) +DELIMITER // +CREATE EVENT daily_dustin_fuckup +ON SCHEDULE EVERY 1 DAY +STARTS CURRENT_TIMESTAMP +DO +BEGIN + CALL add_fuckup( + CONCAT('Daily fuckup #', FLOOR(RAND() * 1000)), + ELT(FLOOR(RAND() * 4) + 1, 'minor', 'major', 'catastrophic', 'apocalyptic'), + ELT(FLOOR(RAND() * 5) + 1, 'It was Tuesday', 'The stars were misaligned', 'I was hungry', 'My horoscope said so', 'Aliens'), + 'Auto-Blame-Bot 3000' + ); +END // +DELIMITER ; \ No newline at end of file