PHP Classes

File: scripts/import_nodelist.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   scripts/import_nodelist.php   Download  
File: scripts/import_nodelist.php
Role: Example script
Content type: text/plain
Description: Example script
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 12,501 bytes
 

Contents

Class file image Download
#!/usr/bin/env php <?php /** * Command-line nodelist import script for binkterm-php * Usage: php import_nodelist.php <nodelist_file> [--force] */ require_once __DIR__ . '/../vendor/autoload.php'; use BinktermPHP\Database; use BinktermPHP\Nodelist\NodelistManager; function initializeLogging() { $logDir = __DIR__ . '/../data/logs'; if (!is_dir($logDir)) { mkdir($logDir, 0755, true); } //$logFile = $logDir . '/nodelist_import_' . date('Y-m-d') . '.log'; $logFile = $logDir . '/nodelist_import.log'; return $logFile; } function writeLog($message, $logFile = null) { static $defaultLogFile = null; if ($defaultLogFile === null) { $defaultLogFile = initializeLogging(); } $logFile = $logFile ?: $defaultLogFile; $timestamp = date('Y-m-d H:i:s'); $logEntry = "[$timestamp] $message\n"; // Write to log file file_put_contents($logFile, $logEntry, FILE_APPEND | LOCK_EX); // Also echo to console echo $message . "\n"; } function printUsage() { echo "Usage: php import_nodelist.php <nodelist_file> <domain> [--force]\n"; echo "\nSupported formats:\n"; echo " - Plain text: NODELIST.xxx\n"; echo " - ZIP: NODELIST.Zxx (requires zip extension)\n"; echo " - ARC: NODELIST.Axx (requires external arc command)\n"; echo " - ARJ: NODELIST.Jxx (requires external arj command)\n"; echo " - LZH: NODELIST.Lxx (requires external lha command)\n"; echo " - RAR: NODELIST.Rxx (requires external rar command)\n"; echo "\nOptions:\n"; echo " --force Skip confirmation prompts\n"; echo " --help Show this help message\n"; echo "\nExamples:\n"; echo " php import_nodelist.php NODELIST.001 fidonet \n"; echo " php import_nodelist.php NODELIST.Z150 fidonet --force\n"; echo " php import_nodelist.php NODELIST.A365 fidonet\n"; } function detectArchiveType($filename) { $ext = strtoupper(pathinfo($filename, PATHINFO_EXTENSION)); if (preg_match('/^Z(\d+)$/', $ext, $matches)) { return 'ZIP'; } elseif (preg_match('/^A(\d+)$/', $ext, $matches)) { return 'ARC'; } elseif (preg_match('/^J(\d+)$/', $ext, $matches)) { return 'ARJ'; } elseif (preg_match('/^L(\d+)$/', $ext, $matches)) { return 'LZH'; } elseif (preg_match('/^R(\d+)$/', $ext, $matches)) { return 'RAR'; } return 'PLAIN'; } function extractArchive($archiveFile, $type, $tempDir) { $extractedFile = null; switch ($type) { case 'ZIP': if (!extension_loaded('zip')) { throw new Exception("ZIP extension not available"); } $zip = new ZipArchive; if ($zip->open($archiveFile) === TRUE) { // Look for nodelist file inside zip for ($i = 0; $i < $zip->numFiles; $i++) { $filename = $zip->getNameIndex($i); if (preg_match('/nodelist/i', $filename) || preg_match('/\.(\d{3})$/', $filename)) { $extractedFile = $tempDir . DIRECTORY_SEPARATOR . basename($filename); $zip->extractTo($tempDir, $filename); if (basename($filename) !== basename($extractedFile)) { rename($tempDir . DIRECTORY_SEPARATOR . $filename, $extractedFile); } break; } } $zip->close(); } else { throw new Exception("Could not open ZIP file"); } break; case 'ARC': $extractedFile = $tempDir . DIRECTORY_SEPARATOR . 'NODELIST.TXT'; $cmd = "arc e \"$archiveFile\" \"$tempDir\""; exec($cmd, $output, $returnCode); if ($returnCode !== 0) { throw new Exception("ARC extraction failed. Make sure 'arc' command is available."); } // Find the extracted nodelist file $files = glob($tempDir . DIRECTORY_SEPARATOR . '*'); foreach ($files as $file) { if (is_file($file) && (preg_match('/nodelist/i', basename($file)) || preg_match('/\.(\d{3})$/', basename($file)))) { $extractedFile = $file; break; } } break; case 'ARJ': $extractedFile = $tempDir . DIRECTORY_SEPARATOR . 'NODELIST.TXT'; $cmd = "arj e \"$archiveFile\" \"$tempDir\""; exec($cmd, $output, $returnCode); if ($returnCode !== 0) { throw new Exception("ARJ extraction failed. Make sure 'arj' command is available."); } // Find the extracted nodelist file $files = glob($tempDir . DIRECTORY_SEPARATOR . '*'); foreach ($files as $file) { if (is_file($file) && (preg_match('/nodelist/i', basename($file)) || preg_match('/\.(\d{3})$/', basename($file)))) { $extractedFile = $file; break; } } break; case 'LZH': $extractedFile = $tempDir . DIRECTORY_SEPARATOR . 'NODELIST.TXT'; $cmd = "lha ew=\"$tempDir\" \"$archiveFile\""; exec($cmd, $output, $returnCode); if ($returnCode !== 0) { throw new Exception("LZH extraction failed. Make sure 'lha' command is available."); } // Find the extracted nodelist file $files = glob($tempDir . DIRECTORY_SEPARATOR . '*'); foreach ($files as $file) { if (is_file($file) && (preg_match('/nodelist/i', basename($file)) || preg_match('/\.(\d{3})$/', basename($file)))) { $extractedFile = $file; break; } } break; case 'RAR': $extractedFile = $tempDir . DIRECTORY_SEPARATOR . 'NODELIST.TXT'; $cmd = "rar e \"$archiveFile\" \"$tempDir\""; exec($cmd, $output, $returnCode); if ($returnCode !== 0) { throw new Exception("RAR extraction failed. Make sure 'rar' command is available."); } // Find the extracted nodelist file $files = glob($tempDir . DIRECTORY_SEPARATOR . '*'); foreach ($files as $file) { if (is_file($file) && (preg_match('/nodelist/i', basename($file)) || preg_match('/\.(\d{3})$/', basename($file)))) { $extractedFile = $file; break; } } break; default: return $archiveFile; // Plain text file } if (!$extractedFile || !file_exists($extractedFile)) { throw new Exception("Could not find nodelist file in archive"); } return $extractedFile; } function cleanupTempFiles($tempDir) { if (is_dir($tempDir)) { $files = glob($tempDir . DIRECTORY_SEPARATOR . '*'); foreach ($files as $file) { if (is_file($file)) { unlink($file); } } rmdir($tempDir); } } function main($argc, $argv) { if ($argc < 2 || in_array('--help', $argv)) { printUsage(); exit(0); } $nodelistFile = $argv[1]; $domain = $argv[2] ?? ''; if(!$domain) { echo "You must specify the network domain, eg: fidonet, fsxnet, testnet, etc\n"; exit(1); } $force = in_array('--force', $argv); if (!file_exists($nodelistFile)) { echo "Error: Nodelist file not found: {$nodelistFile}\n"; exit(1); } if (!is_readable($nodelistFile)) { echo "Error: Cannot read nodelist file: {$nodelistFile}\n"; exit(1); } writeLog("BinkTerm-PHP Nodelist Importer"); writeLog("=============================="); writeLog("File: {$nodelistFile}"); writeLog("Size: " . number_format(filesize($nodelistFile)) . " bytes"); // Detect archive type and extract if needed $archiveType = detectArchiveType($nodelistFile); $actualNodelistFile = $nodelistFile; $tempDir = null; if ($archiveType !== 'PLAIN') { writeLog("Format: {$archiveType} archive"); writeLog("Extracting archive..."); $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'nodelist_' . uniqid(); mkdir($tempDir); try { $actualNodelistFile = extractArchive($nodelistFile, $archiveType, $tempDir); writeLog("Extracted to: " . basename($actualNodelistFile)); writeLog("Extracted size: " . number_format(filesize($actualNodelistFile)) . " bytes"); } catch (Exception $e) { cleanupTempFiles($tempDir); writeLog("Error: " . $e->getMessage()); exit(1); } } else { writeLog("Format: Plain text"); } writeLog(""); try { $nodelistManager = new NodelistManager(); // Check for existing nodelist $activeNodelist = $nodelistManager->getActiveNodelist(); if ($activeNodelist && !$force) { writeLog("Warning: An active nodelist already exists:"); writeLog(" File: {$activeNodelist['filename']}"); writeLog(" Date: {$activeNodelist['release_date']}"); writeLog(" Nodes: " . number_format($activeNodelist['total_nodes'])); writeLog(""); writeLog("This will archive the current nodelist and import the new one."); echo "Continue? (y/N): "; $response = trim(fgets(STDIN)); if (strtolower($response) !== 'y' && strtolower($response) !== 'yes') { writeLog("Import cancelled by user."); exit(0); } writeLog("User confirmed import continuation."); writeLog(""); } writeLog("Starting import..."); $startTime = microtime(true); $result = $nodelistManager->importNodelist($actualNodelistFile,$domain, true); $endTime = microtime(true); $duration = round($endTime - $startTime, 2); writeLog("Import completed successfully!"); writeLog(""); writeLog("Import Results:"); writeLog("=============="); writeLog(" Filename: {$result['filename']}"); writeLog(" Total nodes processed: " . number_format($result['total_nodes'])); writeLog(" Successfully inserted: " . number_format($result['inserted_nodes'])); writeLog(" Failed/skipped: " . number_format($result['total_nodes'] - $result['inserted_nodes'])); writeLog(" Duration: {$duration} seconds"); writeLog(" Processing rate: " . number_format($result['total_nodes'] / max($duration, 0.001), 0) . " nodes/sec"); writeLog(""); // Show detailed statistics $stats = $nodelistManager->getNodelistStats(); writeLog("Nodelist Statistics:"); writeLog("==================="); writeLog(" Total nodes: " . number_format($stats['total_nodes'])); writeLog(" Zones: " . $stats['total_zones']); writeLog(" Networks: " . $stats['total_nets']); writeLog(" Point systems: " . number_format($stats['point_nodes'])); writeLog(" Special nodes: " . number_format($stats['special_nodes']) . " (PVT, HOLD, DOWN, etc.)"); writeLog(" Regular nodes: " . number_format($stats['total_nodes'] - $stats['point_nodes'] - $stats['special_nodes'])); // Calculate success rate $successRate = ($result['inserted_nodes'] / max($result['total_nodes'], 1)) * 100; writeLog(""); writeLog("Import Summary:"); writeLog("=============="); writeLog(" Success rate: " . number_format($successRate, 1) . "%"); writeLog(" Import completed at: " . date('Y-m-d H:i:s')); } catch (Exception $e) { writeLog("Error: " . $e->getMessage()); if ($tempDir) { cleanupTempFiles($tempDir); } exit(1); } finally { // Clean up temporary files if ($tempDir) { writeLog("Cleaning up temporary files..."); cleanupTempFiles($tempDir); } } } // Run the script main($argc, $argv);