#!/usr/bin/env python3 """ RinCoin Mining Pool Web Interface Provides web dashboard for pool statistics and miner management """ import json import sqlite3 from datetime import datetime, timedelta from http.server import HTTPServer, BaseHTTPRequestHandler import threading import time class PoolWebInterface: def __init__(self, pool_db, host='0.0.0.0', port=8080): self.pool_db = pool_db self.host = host self.port = port def get_pool_stats(self): """Get current pool statistics""" try: cursor = self.pool_db.cursor() # Total miners cursor.execute('SELECT COUNT(DISTINCT id) FROM miners') total_miners = cursor.fetchone()[0] # Active miners (last 10 minutes) cursor.execute(''' SELECT COUNT(DISTINCT m.id) FROM miners m JOIN shares s ON m.id = s.miner_id WHERE s.submitted > datetime('now', '-10 minutes') ''') active_miners = cursor.fetchone()[0] # Total shares (last 24 hours) cursor.execute(''' SELECT COUNT(*) FROM shares WHERE submitted > datetime('now', '-24 hours') ''') total_shares_24h = cursor.fetchone()[0] # Pool hashrate estimate cursor.execute(''' SELECT COUNT(*) FROM shares WHERE submitted > datetime('now', '-5 minutes') ''') recent_shares = cursor.fetchone()[0] hashrate = recent_shares * 12 # Rough estimate # Total blocks found cursor.execute('SELECT COUNT(*) FROM blocks') total_blocks = cursor.fetchone()[0] # Recent blocks cursor.execute(''' SELECT block_hash, height, reward, found_at FROM blocks ORDER BY found_at DESC LIMIT 10 ''') recent_blocks = cursor.fetchall() # Top miners cursor.execute(''' SELECT m.user, m.worker, COUNT(s.id) as shares, m.last_share FROM miners m JOIN shares s ON m.id = s.miner_id WHERE s.submitted > datetime('now', '-24 hours') GROUP BY m.id ORDER BY shares DESC LIMIT 10 ''') top_miners = cursor.fetchall() return { 'total_miners': total_miners, 'active_miners': active_miners, 'total_shares_24h': total_shares_24h, 'hashrate': hashrate, 'total_blocks': total_blocks, 'recent_blocks': recent_blocks, 'top_miners': top_miners } except Exception as e: print(f"Error getting pool stats: {e}") return {} def generate_html(self, stats): """Generate HTML dashboard""" html = f""" RinCoin Mining Pool

šŸŠā€ā™‚ļø RinCoin Mining Pool

Distribute block rewards among multiple miners

{stats.get('total_miners', 0)}
Total Miners
{stats.get('active_miners', 0)}
Active Miners
{stats.get('hashrate', 0):.2f}
Hashrate (H/s)
{stats.get('total_blocks', 0)}
Blocks Found

šŸ“Š Pool Statistics

24h Shares: {stats.get('total_shares_24h', 0):,}

Pool Fee: 1%

Connection String: stratum+tcp://YOUR_IP:3333

šŸ‘„ Top Miners (24h)

""" for miner in stats.get('top_miners', []): user, worker, shares, last_share = miner html += f""" """ html += """
User Worker Shares Last Share
{user} {worker} {shares:,} {last_share or 'Never'}

šŸ† Recent Blocks

""" for block in stats.get('recent_blocks', []): block_hash, height, reward, found_at = block html += f""" """ html += """
Height Hash Reward Found At
{height} {block_hash[:16]}... {reward:.8f} RIN {found_at}

šŸ”— Connect to Pool

Use any RinHash-compatible miner:

./cpuminer -a rinhash -o stratum+tcp://YOUR_IP:3333 -u username.workername -p x

Replace YOUR_IP with your server's public IP address

""" return html class PoolWebHandler(BaseHTTPRequestHandler): def __init__(self, *args, pool_interface=None, **kwargs): self.pool_interface = pool_interface super().__init__(*args, **kwargs) def do_GET(self): if self.path == '/': stats = self.pool_interface.get_pool_stats() html = self.pool_interface.generate_html(stats) self.send_response(200) self.send_header('Content-type', 'text/html') self.end_headers() self.wfile.write(html.encode('utf-8')) elif self.path == '/api/stats': stats = self.pool_interface.get_pool_stats() self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() self.wfile.write(json.dumps(stats).encode('utf-8')) else: self.send_response(404) self.end_headers() self.wfile.write(b'Not Found') def log_message(self, format, *args): # Suppress access logs pass def start_web_interface(pool_db, host='0.0.0.0', port=8080): """Start the web interface server""" interface = PoolWebInterface(pool_db, host, port) class Handler(PoolWebHandler): def __init__(self, *args, **kwargs): super().__init__(*args, pool_interface=interface, **kwargs) server = HTTPServer((host, port), Handler) print(f"🌐 Web interface running on http://{host}:{port}") print("Press Ctrl+C to stop") try: server.serve_forever() except KeyboardInterrupt: print("\nšŸ›‘ Shutting down web interface...") server.shutdown() if __name__ == "__main__": # This would be called from the main pool server print("Web interface module loaded")