# ================================
# lib/passive_queue/web.rb
# ================================
require 'erb'
require 'json'
module PassiveQueue
class Web
def call(env)
request = Rack::Request.new(env)
case request.path_info
when '/'
dashboard_response
when '/api/stats'
api_stats_response
when '/api/zen'
api_zen_response
when '/favicon.ico'
favicon_response
when '/logo.svg'
logo_response
when '/logo-dark.svg'
logo_dark_response
else
not_found_response
end
end
private
def dashboard_response
html = dashboard_html
[200, {'Content-Type' => 'text/html'}, [html]]
end
def api_stats_response
stats = {
jobs_queued: rand(9999..99999),
jobs_processed: 0,
jobs_failed: 0,
jobs_succeeded: "∞",
uptime: "#{rand(1..999)} days of perfect inactivity",
memory_usage: "0 MB",
cpu_usage: "0%",
queue_names: ["default", "mailers", "active_storage", "imports", "exports"].sample(rand(2..5)),
processing_time: "0ms",
success_rate: "100%",
zen_level: ["Transcendent", "Enlightened", "Peaceful", "Serene"].sample
}
[200, {'Content-Type' => 'application/json'}, [stats.to_json]]
end
def api_zen_response
quote = PassiveQueue.zen_quotes.sample
[200, {'Content-Type' => 'application/json'}, [{quote: quote}.to_json]]
end
def css_response
css = dashboard_css
[200, {'Content-Type' => 'text/css'}, [css]]
end
def logo_response
svg = logo_svg
[200, {'Content-Type' => 'image/svg+xml'}, [svg]]
end
def logo_dark_response
svg = logo_svg_dark
[200, {'Content-Type' => 'image/svg+xml'}, [svg]]
end
def favicon_response
# Return empty response for favicon
[200, {'Content-Type' => 'image/x-icon'}, ['']]
end
def not_found_response
[404, {'Content-Type' => 'text/html'}, ['<h1>404 - Page Not Found (Just Like Our Jobs)</h1>']]
end
def logo_svg
logo_path = File.join(File.dirname(__FILE__), '..', '..', 'html', 'logo.svg')
File.read(logo_path)
end
def logo_svg_dark
logo_path = File.join(File.dirname(__FILE__), '..', '..', 'html', 'logo-dark.svg')
File.read(logo_path)
end
def dashboard_html
<<~HTML
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Passive Queue Dashboard - The Art of Non-Execution</title>
<link rel="icon" href="/passive_queue/logo.svg" type="image/svg+xml">
<script>
(function() {
// Get saved theme or default to auto
const savedTheme = localStorage.getItem('theme');
const themeToApply = savedTheme !== null ? savedTheme : 'auto';
function getSystemTheme() {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
let actualTheme;
if (themeToApply === 'auto') {
actualTheme = getSystemTheme();
} else {
actualTheme = themeToApply;
}
// Apply theme immediately to prevent flash
document.documentElement.setAttribute('data-theme', actualTheme);
// Store current preference for later use
window.currentThemePreference = themeToApply;
})();
</script>
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css" />
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
body { font-family: 'Inter', sans-serif; }
/* Light mode gradients and shadows (default) */
.zen-gradient {
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
}
.peaceful-shadow {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}
/* Dark mode variations */
[data-theme="dark"] .zen-gradient {
background: linear-gradient(135deg, #1f2937 0%, #111827 100%);
}
[data-theme="dark"] .peaceful-shadow {
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}
/* Animations remain the same */
.loading-dots::after {
content: '';
animation: dots 2s infinite;
}
@keyframes dots {
0%, 20% { content: '.'; }
40% { content: '..'; }
60% { content: '...'; }
80%, 100% { content: ''; }
}
.float { animation: float 6s ease-in-out infinite; }
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
.pulse-zen { animation: pulse-zen 3s ease-in-out infinite; }
@keyframes pulse-zen {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
/* Theme toggle button styles */
.theme-toggle {
display: none;
width: 48px;
height: 24px;
background: var(--fallback-b2,oklch(var(--b2)));
border-radius: 12px;
border: 2px solid var(--fallback-bc,oklch(var(--bc)/0.2));
cursor: pointer;
position: relative;
transition: all 0.3s ease;
}
.theme-toggle::before {
content: '';
position: absolute;
top: 50%;
left: 2px;
transform: translateY(-50%);
font-size: 14px;
transition: all 0.3s ease;
}
[data-theme="dark"] .theme-toggle::before {
content: '';
left: 22px;
}
.theme-toggle::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
background: var(--fallback-bc,oklch(var(--bc)));
border-radius: 50%;
transition: all 0.3s ease;
}
[data-theme="dark"] .theme-toggle::after {
transform: translateX(20px);
}
</style>
</head>
<body class="zen-gradient min-h-screen">
<!-- Navigation -->
<div class="navbar bg-base-100/80 backdrop-blur-sm peaceful-shadow">
<div class="navbar-start">
<a class="btn btn-ghost text-xl font-light">
<!-- Light mode logo -->
<img src="/passive_queue/logo.svg" alt="Passive Queue Logo"
class="w-7 h-7 mr-2 logo-light">
<!-- Dark mode logo -->
<img src="/passive_queue/logo-dark.svg" alt="Passive Queue Logo"
class="w-7 h-7 mr-2 hidden logo-dark">
Passive Queue Dashboard
</a>
</div>
<div class="navbar-center">
<div class="badge badge-success badge-lg">
<span class="loading loading-ring loading-xs mr-1"></span>
Non-Processing
</div>
</div>
<div class="navbar-end">
<!-- Theme Toggle -->
<div class="flex items-center gap-2 mr-4">
<button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle theme"></button>
<div class="dropdown dropdown-end z-[100]">
<div tabindex="0" role="button" class="btn btn-ghost btn-sm">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path>
</svg>
</div>
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52 z-50 z-[100]">
<li><a onclick="setTheme('light')">☀️ Light Mode</a></li>
<li><a onclick="setTheme('dark')">🌙 Dark Mode</a></li>
<li><a onclick="setTheme('auto')">🔄 Auto (System)</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- Main Dashboard -->
<div class="container mx-auto px-4 py-8">
<!-- Hero Stats -->
<div class="stats stats-vertical lg:stats-horizontal shadow w-full mb-8 bg-base-100 peaceful-shadow">
<div class="stat">
<div class="stat-figure text-primary">
<div class="text-3xl float">📊</div>
</div>
<div class="stat-title">Jobs Queued</div>
<div class="stat-value text-primary" id="jobs-queued">∞</div>
<div class="stat-desc">All waiting peacefully</div>
</div>
<div class="stat">
<div class="stat-figure text-secondary">
<div class="text-3xl pulse-zen">✨</div>
</div>
<div class="stat-title">Jobs Processed</div>
<div class="stat-value text-secondary" id="jobs-processed">0</div>
<div class="stat-desc">Perfect execution rate</div>
</div>
<div class="stat">
<div class="stat-figure text-accent">
<div class="text-3xl">⏱️</div>
</div>
<div class="stat-title">Avg Processing Time</div>
<div class="stat-value text-accent" id="processing-time">0ms</div>
<div class="stat-desc">Blazing fast non-execution</div>
</div>
<div class="stat">
<div class="stat-figure text-success">
<div class="text-3xl">🎯</div>
</div>
<div class="stat-title">Success Rate</div>
<div class="stat-value text-success" id="success-rate">100%</div>
<div class="stat-desc">At doing nothing</div>
</div>
</div>
<div class="grid lg:grid-cols-2 gap-8 mb-8">
<!-- Queue Status -->
<div class="card bg-base-100 peaceful-shadow">
<div class="card-body">
<h2 class="card-title">
<span class="text-2xl mr-2">📋</span>
Queue Status
</h2>
<div class="space-y-4">
<div class="flex justify-between items-center">
<span class="font-medium">Active Queues</span>
<div class="badge badge-info" id="active-queues">5</div>
</div>
<div class="space-y-2" id="queue-list">
<!-- Queues will be populated by JavaScript -->
</div>
</div>
<div class="card-actions justify-end mt-4">
<button class="btn btn-sm btn-outline" onclick="refreshQueues()">
<span class="loading loading-spinner loading-xs mr-1 hidden" id="refresh-spinner"></span>
Refresh
</button>
</div>
</div>
</div>
<!-- System Status -->
<div class="card bg-base-100 peaceful-shadow">
<div class="card-body">
<h2 class="card-title">
<span class="text-2xl mr-2">💻</span>
System Status
</h2>
<div class="space-y-4">
<div class="flex justify-between items-center">
<span>Memory Usage</span>
<div class="text-right">
<div class="text-sm font-mono" id="memory-usage">0 MB</div>
<progress class="progress progress-success w-24" value="0" max="100"></progress>
</div>
</div>
<div class="flex justify-between items-center">
<span>CPU Usage</span>
<div class="text-right">
<div class="text-sm font-mono" id="cpu-usage">0%</div>
<progress class="progress progress-success w-24" value="0" max="100"></progress>
</div>
</div>
<div class="flex justify-between items-center">
<span>Uptime</span>
<div class="text-sm font-mono" id="uptime">∞ days</div>
</div>
<div class="flex justify-between items-center">
<span>Zen Level</span>
<div class="badge badge-primary" id="zen-level">Transcendent</div>
</div>
</div>
</div>
</div>
</div>
<!-- Zen Quotes Section -->
<div class="card bg-base-100 peaceful-shadow mb-8">
<div class="card-body text-center">
<h2 class="card-title justify-center">
<span class="text-2xl mr-2">🧘♂️</span>
Daily Zen
</h2>
<div class="max-w-2xl mx-auto">
<blockquote class="text-lg italic text-base-content/80 mb-4" id="zen-quote">
"Loading wisdom..."
</blockquote>
<button class="btn btn-primary btn-sm" onclick="getNewZenQuote()">
New Wisdom
</button>
</div>
</div>
</div>
<!-- Recent Non-Activity -->
<div class="card bg-base-100 peaceful-shadow">
<div class="card-body">
<h2 class="card-title">
<span class="text-2xl mr-2">📝</span>
Recent Non-Activity
</h2>
<div class="overflow-x-auto">
<table class="table table-zebra">
<thead>
<tr>
<th>Job ID</th>
<th>Queue</th>
<th>Class</th>
<th>Status</th>
<th>Non-Executed At</th>
</tr>
</thead>
<tbody id="recent-jobs">
<!-- Jobs will be populated by JavaScript -->
</tbody>
</table>
</div>
<div class="text-center mt-4">
<div class="text-sm text-base-content/60">
All jobs are successfully not being processed 🎯
</div>
</div>
</div>
</div>
</div>
<!-- JavaScript -->
<script>
function updateLogos() {
// Check the actual applied theme instead of system preference
const currentTheme = document.documentElement.getAttribute('data-theme');
const lightLogos = document.querySelectorAll('.logo-light');
const darkLogos = document.querySelectorAll('.logo-dark');
if (currentTheme === 'dark') {
lightLogos.forEach(logo => logo.classList.add('hidden'));
darkLogos.forEach(logo => logo.classList.remove('hidden'));
} else {
lightLogos.forEach(logo => logo.classList.remove('hidden'));
darkLogos.forEach(logo => logo.classList.add('hidden'));
}
}
// Theme management system
let currentThemePreference = 'auto'; // Track current preference
function getSystemTheme() {
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
}
function applyTheme(theme) {
currentThemePreference = theme;
if (theme === 'auto') {
const systemTheme = getSystemTheme();
document.documentElement.setAttribute('data-theme', systemTheme);
return systemTheme;
} else {
document.documentElement.setAttribute('data-theme', theme);
return theme;
}
}
function setTheme(theme) {
localStorage.setItem('theme', theme);
applyTheme(theme);
updateLogos();
}
function toggleTheme() {
const themes = ['light', 'dark', 'auto'];
const currentIndex = themes.indexOf(currentThemePreference);
const nextTheme = themes[(currentIndex + 1) % themes.length];
setTheme(nextTheme);
}
function initTheme() {
// Get saved theme or default to auto
const savedTheme = localStorage.getItem('theme');
const themeToApply = savedTheme !== null ? savedTheme : 'auto';
applyTheme(themeToApply);
// Listen for system theme changes
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
if (currentThemePreference === 'auto') {
applyTheme('auto');
updateLogos();
}
});
updateLogos();
}
async function loadStats() {
try {
const response = await fetch('/passive_queue/api/stats');
const stats = await response.json();
document.getElementById('jobs-queued').textContent = stats.jobs_queued.toLocaleString();
document.getElementById('jobs-processed').textContent = stats.jobs_processed;
document.getElementById('processing-time').textContent = stats.processing_time;
document.getElementById('success-rate').textContent = stats.success_rate;
document.getElementById('memory-usage').textContent = stats.memory_usage;
document.getElementById('cpu-usage').textContent = stats.cpu_usage;
document.getElementById('uptime').textContent = stats.uptime;
document.getElementById('zen-level').textContent = stats.zen_level;
// Update queue list
const queueList = document.getElementById('queue-list');
queueList.innerHTML = stats.queue_names.map(queue =>
`<div class="flex justify-between items-center">
<span class="text-sm">${queue}</span>
<div class="badge badge-ghost badge-sm">0 processing</div>
</div>`
).join('');
document.getElementById('active-queues').textContent = stats.queue_names.length;
} catch (error) {
console.error('Failed to load stats:', error);
}
}
async function getNewZenQuote() {
try {
const response = await fetch('/passive_queue/api/zen');
const data = await response.json();
document.getElementById('zen-quote').textContent = data.quote;
} catch (error) {
console.error('Failed to load zen quote:', error);
}
}
function refreshQueues() {
const spinner = document.getElementById('refresh-spinner');
spinner.classList.remove('hidden');
setTimeout(() => {
loadStats();
spinner.classList.add('hidden');
}, 1000);
}
function generateRecentJobs() {
const jobClasses = ['UserMailer', 'DataProcessor', 'ImageResizer', 'ReportGenerator', 'BackupJob'];
const queues = ['default', 'mailers', 'critical', 'background'];
const tbody = document.getElementById('recent-jobs');
const jobs = Array.from({length: 10}, (_, i) => {
const jobId = `passive-${Date.now() + i}`;
const queue = queues[Math.floor(Math.random() * queues.length)];
const jobClass = jobClasses[Math.floor(Math.random() * jobClasses.length)];
const time = new Date(Date.now() - Math.random() * 3600000);
return `
<tr>
<td><code class="text-xs">${jobId}</code></td>
<td><span class="badge badge-outline badge-xs">${queue}</span></td>
<td>${jobClass}</td>
<td><div class="badge badge-success badge-xs">Not Processed</div></td>
<td class="text-xs">${time.toLocaleString()}</td>
</tr>
`;
});
tbody.innerHTML = jobs.join('');
}
// Initialize dashboard
document.addEventListener('DOMContentLoaded', function() {
initTheme();
loadStats();
getNewZenQuote();
generateRecentJobs();
// Auto-refresh every 30 seconds
setInterval(loadStats, 30000);
// Change zen quote every 2 minutes
setInterval(getNewZenQuote, 120000);
});
// Run theme init immediately to prevent flash
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTheme);
} else {
initTheme();
}
// Easter egg: Add some zen to the console
console.log('🧘 Welcome to the Passive Queue Dashboard');
console.log('💭 Remember: The best job is the one never executed');
console.log('✨ Achievement unlocked: 100% success rate at doing nothing');
</script>
</body>
</html>
HTML
end
end
end
# ================================
# lib/passive_queue/engine.rb
# ================================
module PassiveQueue
class Engine
def self.call(env)
# Strip the mount path to get relative path
path_info = env['PATH_INFO']
script_name = env['SCRIPT_NAME']
# Create new env with adjusted paths for the Web app
web_env = env.dup
web_env['PATH_INFO'] = path_info
web_env['SCRIPT_NAME'] = script_name
Web.new.call(web_env)
end
end
end
# ================================
# Usage in Rails routes.rb:
# ================================
# Rails.application.routes.draw do
# mount PassiveQueue::Engine => '/passive_queue'
# end