Sindbad~EG File Manager

Current Path : /usr/home/beeson/MathXpert/logs/
Upload File :
Current File : /usr/home/beeson/MathXpert/logs/process_logs.php

<?php
/**
 * process_logs.php
 *
 * This script reads EngineLog.csv and userlog.csv,
 * correlates them by sessionID (if the timestamps are within one hour),
 * and updates a SQLite database (userlog.db) with valid user access entries.
 * The database table (UserLogs) stores:
 *   - timestamp (set to the first contact time),
 *   - ip_address,
 *   - first_use (the earliest user log time),
 *   - last_active (the latest engine log time within one hour),
 *   - and geolocation fields (country, region, city, isp) that initially are 'Pending'.
 *
 * Geolocation is performed using the ip-api.com service.
 *
 * Any errors are appended to process_logs.log.
 */

date_default_timezone_set('UTC');

// Log file location
$log_file = 'process_logs.log';
function logError($msg) {
    global $log_file;
    file_put_contents($log_file, date('Y-m-d H:i:s') . " - " . $msg . "\n", FILE_APPEND);
}

// Function to geolocate an IP using ip-api.com
function geolocate_ip($ip) {
    $url = "http://ip-api.com/json/" . urlencode($ip) . "?fields=status,country,regionName,city,isp";
    $response = @file_get_contents($url);
    if ($response === false) {
        logError("Failed to get geolocation data for IP: $ip");
        return array("Pending", "Pending", "Pending", "Pending");
    }
    $data = json_decode($response, true);
    if ($data && isset($data['status']) && $data['status'] == 'success') {
        return array($data['country'], $data['regionName'], $data['city'], $data['isp']);
    } else {
        logError("Geolocation API error for IP: $ip");
        return array("Pending", "Pending", "Pending", "Pending");
    }
}

// Connect to the SQLite database
try {
    $db = new PDO('sqlite:userlog.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    logError("DB Connection failed: " . $e->getMessage());
    exit;
}

// Create UserLogs table if it doesn't exist
$table_sql = "CREATE TABLE IF NOT EXISTS UserLogs (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    timestamp TEXT NOT NULL,
    ip_address TEXT NOT NULL,
    country TEXT DEFAULT 'Pending',
    region TEXT DEFAULT 'Pending',
    city TEXT DEFAULT 'Pending',
    isp TEXT DEFAULT 'Pending',
    first_use TEXT,
    last_active TEXT
)";
try {
    $db->exec($table_sql);
} catch (PDOException $e) {
    logError("Table creation failed: " . $e->getMessage());
    exit;
}

// 1. Read EngineLog.csv and index engine timestamps by sessionID
$engineLogs = array();
$engineFile = 'EngineLog.csv';
if (!file_exists($engineFile)) {
    logError("EngineLog.csv not found.");
    exit;
}
if (($handle = fopen($engineFile, "r")) !== false) {
    while (($data = fgetcsv($handle)) !== false) {
        // Expecting: date, time, sessionID
        if (count($data) < 3) continue;
        $date   = trim($data[0]);
        $time   = trim($data[1]);
        $sessID = trim($data[2]);
        $dt_str = $date . ' ' . $time;
        $engineTime = strtotime($dt_str);
        if ($engineTime === false) continue;
        if (!isset($engineLogs[$sessID])) {
            $engineLogs[$sessID] = array();
        }
        $engineLogs[$sessID][] = $engineTime;
    }
    fclose($handle);
} else {
    logError("Failed to open EngineLog.csv");
    exit;
}

// 2. Process userlog.csv and correlate with engine log entries
$userFile = 'userlog.csv';
if (!file_exists($userFile)) {
    logError("userlog.csv not found.");
    exit;
}
if (($handle = fopen($userFile, "r")) !== false) {
    while (($data = fgetcsv($handle)) !== false) {
        // Expecting: date, time, sessionID, ip_address
        if (count($data) < 4) continue;
        $date   = trim($data[0]);
        $time   = trim($data[1]);
        $sessID = trim($data[2]);
        $ip     = trim($data[3]);
        $user_dt_str = $date . ' ' . $time;
        $userTime = strtotime($user_dt_str);
        if ($userTime === false) continue;

        // Only process if the sessionID exists in engine logs
        if (!isset($engineLogs[$sessID])) continue;

        // Look for an engine log timestamp within 1 hour (3600 seconds) of the user log time.
        $validEngineTime = null;
        foreach ($engineLogs[$sessID] as $engineTime) {
            if (abs($engineTime - $userTime) <= 3600) {
                // Use the latest engine time among those that qualify
                if ($validEngineTime === null || $engineTime > $validEngineTime) {
                    $validEngineTime = $engineTime;
                }
            }
        }
        if ($validEngineTime === null) continue;  // No valid engine log found; skip as likely bot activity.

        // Determine first_use (earliest user contact) and last_active (latest engine call)
        $firstUseStr  = date("Y-m-d H:i:s", $userTime);
        $lastActiveStr = date("Y-m-d H:i:s", $validEngineTime);

        // Check if there's already an entry for this IP address
        try {
            $stmt = $db->prepare("SELECT id, first_use, last_active FROM UserLogs WHERE ip_address = ?");
            $stmt->execute([$ip]);
            $existing = $stmt->fetch(PDO::FETCH_ASSOC);
        } catch (PDOException $e) {
            logError("DB Select failed for IP $ip: " . $e->getMessage());
            continue;
        }

        if ($existing) {
            // Merge with existing record: update first_use (earlier) and last_active (later)
            $existingFirst = strtotime($existing['first_use']);
            $existingLast  = strtotime($existing['last_active']);
            $newFirst = ($existingFirst === false) ? $userTime : min($existingFirst, $userTime);
            $newLast  = ($existingLast === false)  ? $validEngineTime : max($existingLast, $validEngineTime);
            $mergedFirstStr  = date("Y-m-d H:i:s", $newFirst);
            $mergedLastStr   = date("Y-m-d H:i:s", $newLast);

            try {
                $updateStmt = $db->prepare("UPDATE UserLogs SET first_use = ?, last_active = ? WHERE id = ?");
                $updateStmt->execute([$mergedFirstStr, $mergedLastStr, $existing['id']]);
            } catch (PDOException $e) {
                logError("DB Update failed for IP $ip: " . $e->getMessage());
                continue;
            }
        } else {
            // Insert a new record for this valid user access
            try {
                $insertStmt = $db->prepare("INSERT INTO UserLogs (timestamp, ip_address, first_use, last_active) VALUES (?, ?, ?, ?)");
                $insertStmt->execute([$firstUseStr, $ip, $firstUseStr, $lastActiveStr]);
            } catch (PDOException $e) {
                logError("DB Insert failed for IP $ip: " . $e->getMessage());
                continue;
            }
        }
    }
    fclose($handle);
} else {
    logError("Failed to open userlog.csv");
    exit;
}

// 3. Geolocate entries still marked as 'Pending'
try {
    $pendingStmt = $db->query("SELECT id, ip_address FROM UserLogs WHERE country = 'Pending'");
    $pendingRows = $pendingStmt->fetchAll(PDO::FETCH_ASSOC);
    foreach ($pendingRows as $row) {
        $ip = $row['ip_address'];
        list($country, $region, $city, $isp) = geolocate_ip($ip);
        try {
            $updateGeoStmt = $db->prepare("UPDATE UserLogs SET country = ?, region = ?, city = ?, isp = ? WHERE id = ?");
            $updateGeoStmt->execute([$country, $region, $city, $isp, $row['id']]);
        } catch (PDOException $e) {
            logError("Geolocation update failed for IP $ip: " . $e->getMessage());
            continue;
        }
    }
} catch (PDOException $e) {
    logError("Geolocation pending query failed: " . $e->getMessage());
}

echo "Process completed.\n";
?>

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists