sábado, 23 de maio de 2026

thumbnail

Servidor caseiro com arbiam


 1. Atualizar o sistema

sudo apt update && sudo apt upgrade -y


2. Instalar Apache

sudo apt install apache2 -y sudo systemctl enable apache2 sudo systemctl start apache2


3. Instalar MariaDB

sudo apt install mariadb-server mariadb-client -y sudo systemctl enable mariadb sudo systemctl start mariadb

Segurança do MariaDB (muito recomendado):

sudo mysql_secure_installation

Responda as perguntas:

  • Set root password? → Y
  • Remove anonymous users? → Y
  • Disallow root login remotely? → Y (ou N se quiser acesso remoto)
  • Remove test database? → Y
  • Reload privilege tables? → Y

4. Instalar PHP

sudo apt install php libapache2-mod-php php-mysql php-curl php-gd php-mbstring php-xml php-zip php-soap php-intl -y

Depois reinicie o Apache:

sudo systemctl restart apache2


5. Instalar phpMyAdmin

sudo apt install phpmyadmin -y


6. Configurações finais

# Reiniciar serviços sudo systemctl restart apache2 sudo systemctl restart mariadb


7. Criar um arquivo php gerenciador

# Entrar no diretório web cd /var/www/html # Criar o arquivo (vazio primeiro) sudo touch filemanager.php # Abrir no nano para editar sudo nano filemanager.php


Dentro do Nano — Colar o Código

Quando o nano abrir (tela preta vazia):
  1. Baixe o arquivo que eu corrigi aqui:
  2. Abra no seu PC com qualquer editor de texto (Bloco de Notas, VS Code, etc.)
  3. Copie TODO o conteúdo (Ctrl+ACtrl+C)
  4. Volte no terminal SSH com o nano aberto
  5. Cole com Shift+Ctrl+V (ou botão direito → Colar no PuTTY)
  6. Salvar: Ctrl+OEnter
  7. Sair: Ctrl+X

Ajustar Permissões Depois

cd /var/www/html
sudo nano filemanager.php
# (colar código → Ctrl+O → Enter → Ctrl+X)

sudo chown www-data:www-data filemanager.php
sudo chmod 644 filemanager.php

8. código do filebrowser

<?php
/**
 * Simple File Manager - Gerenciador de Arquivos Web
 * Similar ao Tiny File Manager mas mais leve
 * Único arquivo PHP - basta copiar para o servidor
 */

// ==================== CONFIGURAÇÕES ====================
$use_auth = true; // true = exige login, false = acesso livre
$auth_users = array(
    'admin' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // senha: password
    'user'  => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'  // senha: password
);
$readonly_users = array('user'); // usuários que só podem visualizar

$root_path = $_SERVER['DOCUMENT_ROOT']; // pasta raiz a gerenciar
$root_url = ''; // URL relativa
$max_upload_size = 50 * 1024 * 1024; // 50MB
$show_hidden = false; // mostrar arquivos ocultos (começam com .)
$allowed_extensions = array(); // deixe vazio para permitir tudo, ou array('jpg','png','php')

// ==================== SESSÃO E AUTENTICAÇÃO ====================
if (!isset($_SESSION)) {
    session_start();
}

function is_logged_in() {
    global $use_auth;
    if (!$use_auth) return true;
    return isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true;
}

function is_readonly() {
    global $readonly_users;
    if (!is_logged_in()) return true;
    if (isset($_SESSION['username']) && in_array($_SESSION['username'], $readonly_users)) {
        return true;
    }
    return false;
}

function login($user, $pass) {
    global $auth_users;
    if (isset($auth_users[$user]) && password_verify($pass, $auth_users[$user])) {
        $_SESSION['logged_in'] = true;
        $_SESSION['username'] = $user;
        return true;
    }
    return false;
}

function logout() {
    unset($_SESSION['logged_in']);
    unset($_SESSION['username']);
    session_destroy();
}

// Processar login/logout
if (isset($_GET['logout'])) {
    logout();
    header('Location: ' . $_SERVER['PHP_SELF']);
    exit;
}

if (isset($_POST['login'])) {
    if (login($_POST['username'], $_POST['password'])) {
        header('Location: ' . $_SERVER['PHP_SELF']);
        exit;
    } else {
        $login_error = 'Usuário ou senha incorretos!';
    }
}

// ==================== FUNÇÕES UTILITÁRIAS ====================
function get_file_icon($ext) {
    $icons = array(
        'php' => '🐘', 'html' => '🌐', 'htm' => '🌐', 'css' => '🎨', 'js' => '⚡',
        'jpg' => '🖼️', 'jpeg' => '🖼️', 'png' => '🖼️', 'gif' => '🖼️', 'svg' => '🖼️',
        'pdf' => '📄', 'doc' => '📝', 'docx' => '📝', 'txt' => '📃', 'md' => '📃',
        'zip' => '📦', 'rar' => '📦', 'tar' => '📦', 'gz' => '📦',
        'mp3' => '🎵', 'mp4' => '🎬', 'avi' => '🎬', 'mkv' => '🎬',
        'sql' => '🗄️', 'json' => '📊', 'xml' => '📊', 'csv' => '📊',
        'folder' => '📁'
    );
    return isset($icons[$ext]) ? $icons[$ext] : '📄';
}

function format_size($size) {
    $units = array('B', 'KB', 'MB', 'GB', 'TB');
    $i = 0;
    while ($size >= 1024 && $i < count($units) - 1) {
        $size /= 1024;
        $i++;
    }
    return round($size, 2) . ' ' . $units[$i];
}

function get_mime_type($file) {
    if (function_exists('mime_content_type')) {
        return mime_content_type($file);
    }
    if (function_exists('finfo_open')) {
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime = finfo_file($finfo, $file);
        finfo_close($finfo);
        return $mime;
    }
    return 'application/octet-stream';
}

function is_text_file($file) {
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
    $text_exts = array('php','html','htm','css','js','txt','md','json','xml','sql','csv','ini','conf','log','htaccess','sh','py','rb','java','c','cpp','h','go','rs','ts','vue','jsx','tsx','yaml','yml','dockerfile','nginx','apache');
    return in_array($ext, $text_exts);
}

function is_image_file($file) {
    $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
    return in_array($ext, array('jpg','jpeg','png','gif','bmp','svg','webp','ico'));
}

function safe_path($path) {
    $path = str_replace('\\', '/', $path);
    $path = preg_replace('/\.\.\//', '', $path);
    $path = preg_replace('/\.\.\\\\/', '', $path);
    return $path;
}

// ==================== PROCESSAMENTO DE AÇÕES ====================
$current_path = isset($_GET['p']) ? safe_path($_GET['p']) : '';
$full_path = $root_path . '/' . $current_path;
$full_path = realpath($full_path) ?: $root_path;

// Verificar se está dentro do root_path
if (strpos($full_path, realpath($root_path)) !== 0) {
    $full_path = realpath($root_path);
    $current_path = '';
}

$action = isset($_GET['action']) ? $_GET['action'] : '';
$message = '';
$error = '';

// Upload de arquivo
if (isset($_FILES['upload']) && is_logged_in() && !is_readonly()) {
    $upload_file = $_FILES['upload'];
    if ($upload_file['error'] === UPLOAD_ERR_OK) {
        $target = $full_path . '/' . basename($upload_file['name']);
        if (move_uploaded_file($upload_file['tmp_name'], $target)) {
            $message = 'Arquivo enviado com sucesso!';
        } else {
            $error = 'Erro ao mover arquivo!';
        }
    } else {
        $error = 'Erro no upload: ' . $upload_file['error'];
    }
}

// Criar pasta
if (isset($_POST['new_folder']) && is_logged_in() && !is_readonly()) {
    $folder_name = safe_path($_POST['folder_name']);
    if ($folder_name && !file_exists($full_path . '/' . $folder_name)) {
        if (mkdir($full_path . '/' . $folder_name, 0755, true)) {
            $message = 'Pasta criada com sucesso!';
        } else {
            $error = 'Erro ao criar pasta!';
        }
    }
}

// Criar arquivo
if (isset($_POST['new_file']) && is_logged_in() && !is_readonly()) {
    $file_name = safe_path($_POST['file_name']);
    if ($file_name && !file_exists($full_path . '/' . $file_name)) {
        if (file_put_contents($full_path . '/' . $file_name, '') !== false) {
            $message = 'Arquivo criado com sucesso!';
        } else {
            $error = 'Erro ao criar arquivo!';
        }
    }
}

// Deletar
if ($action === 'delete' && isset($_GET['item']) && is_logged_in() && !is_readonly()) {
    $item = $full_path . '/' . basename($_GET['item']);
    if (is_dir($item)) {
        if (rmdir($item)) {
            $message = 'Pasta deletada!';
        } else {
            $error = 'Erro ao deletar pasta (deve estar vazia)!';
        }
    } else {
        if (unlink($item)) {
            $message = 'Arquivo deletado!';
        } else {
            $error = 'Erro ao deletar arquivo!';
        }
    }
}

// Renomear
if ($action === 'rename' && isset($_POST['old_name'], $_POST['new_name']) && is_logged_in() && !is_readonly()) {
    $old = $full_path . '/' . basename($_POST['old_name']);
    $new = $full_path . '/' . safe_path($_POST['new_name']);
    if (rename($old, $new)) {
        $message = 'Renomeado com sucesso!';
    } else {
        $error = 'Erro ao renomear!';
    }
}

// Copiar
if ($action === 'copy' && isset($_POST['source'], $_POST['dest']) && is_logged_in() && !is_readonly()) {
    $src = $full_path . '/' . basename($_POST['source']);
    $dst = $full_path . '/' . safe_path($_POST['dest']);
    if (copy($src, $dst)) {
        $message = 'Copiado com sucesso!';
    } else {
        $error = 'Erro ao copiar!';
    }
}

// Mover
if ($action === 'move' && isset($_POST['source'], $_POST['dest']) && is_logged_in() && !is_readonly()) {
    $src = $full_path . '/' . basename($_POST['source']);
    $dst = $full_path . '/' . safe_path($_POST['dest']);
    if (rename($src, $dst)) {
        $message = 'Movido com sucesso!';
    } else {
        $error = 'Erro ao mover!';
    }
}

// Salvar edição
if (isset($_POST['save_file']) && isset($_POST['file_path'], $_POST['content']) && is_logged_in() && !is_readonly()) {
    $file = safe_path($_POST['file_path']);
    $file_full = $root_path . '/' . $file;
    if (file_put_contents($file_full, $_POST['content']) !== false) {
        $message = 'Arquivo salvo com sucesso!';
    } else {
        $error = 'Erro ao salvar arquivo!';
    }
}

// Download
if ($action === 'download' && isset($_GET['item'])) {
    $file = $full_path . '/' . basename($_GET['item']);
    if (is_file($file)) {
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($file) . '"');
        header('Content-Length: ' . filesize($file));
        readfile($file);
        exit;
    }
}

// Visualizar
if ($action === 'view' && isset($_GET['item'])) {
    $file = $full_path . '/' . basename($_GET['item']);
    if (is_file($file)) {
        $mime = get_mime_type($file);
        header('Content-Type: ' . $mime);
        readfile($file);
        exit;
    }
}

// Editar
$edit_file = null;
$edit_content = '';
if ($action === 'edit' && isset($_GET['item']) && is_logged_in()) {
    $file = $full_path . '/' . basename($_GET['item']);
    if (is_file($file) && is_text_file($file)) {
        $edit_file = $current_path . '/' . basename($_GET['item']);
        $edit_content = file_get_contents($file);
    }
}

// ==================== LISTAR ARQUIVOS ====================
$items = array();
if (is_dir($full_path)) {
    $dh = opendir($full_path);
    while (($file = readdir($dh)) !== false) {
        if ($file === '.' || $file === '..') continue;
        if (!$show_hidden && $file[0] === '.') continue;

        $item_path = $full_path . '/' . $file;
        $is_dir = is_dir($item_path);
        $ext = $is_dir ? 'folder' : strtolower(pathinfo($file, PATHINFO_EXTENSION));

        if (!$is_dir && !empty($allowed_extensions) && !in_array($ext, $allowed_extensions)) {
            continue;
        }

        $items[] = array(
            'name' => $file,
            'is_dir' => $is_dir,
            'size' => $is_dir ? '-' : format_size(filesize($item_path)),
            'modified' => date('d/m/Y H:i', filemtime($item_path)),
            'perms' => substr(sprintf('%o', fileperms($item_path)), -4),
            'ext' => $ext,
            'icon' => get_file_icon($ext)
        );
    }
    closedir($dh);

    // Ordenar: pastas primeiro, depois arquivos
    usort($items, function($a, $b) {
        if ($a['is_dir'] !== $b['is_dir']) {
            return $a['is_dir'] ? -1 : 1;
        }
        return strcasecmp($a['name'], $b['name']);
    });
}

// Breadcrumb
$breadcrumbs = array();
if ($current_path) {
    $parts = explode('/', $current_path);
    $path_build = '';
    foreach ($parts as $part) {
        if ($part) {
            $path_build .= ($path_build ? '/' : '') . $part;
            $breadcrumbs[] = array('name' => $part, 'path' => $path_build);
        }
    }
}
?>
<!DOCTYPE html>
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Simple File Manager</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            background: #0f172a;
            color: #e2e8f0;
            min-height: 100vh;
        }
        .container { max-width: 1400px; margin: 0 auto; padding: 20px; }

        /* Header */
        .header {
            background: #1e293b;
            border-bottom: 1px solid #334155;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            flex-wrap: wrap;
            gap: 10px;
        }
        .header h1 { font-size: 1.5rem; color: #60a5fa; display: flex; align-items: center; gap: 10px; }
        .header-actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
        .user-info { color: #94a3b8; font-size: 0.9rem; }

        /* Buttons */
        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 0.9rem;
            transition: all 0.2s;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            gap: 6px;
        }
        .btn-primary { background: #3b82f6; color: white; }
        .btn-primary:hover { background: #2563eb; }
        .btn-success { background: #10b981; color: white; }
        .btn-success:hover { background: #059669; }
        .btn-danger { background: #ef4444; color: white; }
        .btn-danger:hover { background: #dc2626; }
        .btn-warning { background: #f59e0b; color: white; }
        .btn-warning:hover { background: #d97706; }
        .btn-secondary { background: #475569; color: white; }
        .btn-secondary:hover { background: #334155; }
        .btn-sm { padding: 5px 10px; font-size: 0.8rem; }

        /* Messages */
        .alert {
            padding: 12px 16px;
            border-radius: 6px;
            margin: 15px 0;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .alert-success { background: #064e3b; color: #6ee7b7; border: 1px solid #059669; }
        .alert-error { background: #450a0a; color: #fca5a5; border: 1px solid #dc2626; }

        /* Breadcrumb */
        .breadcrumb {
            background: #1e293b;
            padding: 10px 20px;
            border-bottom: 1px solid #334155;
            display: flex;
            align-items: center;
            gap: 8px;
            flex-wrap: wrap;
        }
        .breadcrumb a { color: #60a5fa; text-decoration: none; }
        .breadcrumb a:hover { text-decoration: underline; }
        .breadcrumb span { color: #64748b; }

        /* Toolbar */
        .toolbar {
            background: #1e293b;
            padding: 15px 20px;
            border-bottom: 1px solid #334155;
            display: flex;
            gap: 10px;
            flex-wrap: wrap;
            align-items: center;
        }
        .toolbar form { display: flex; gap: 10px; align-items: center; }
        .toolbar input[type="text"], .toolbar input[type="file"] {
            background: #0f172a;
            border: 1px solid #334155;
            color: #e2e8f0;
            padding: 8px 12px;
            border-radius: 6px;
            font-size: 0.9rem;
        }
        .toolbar input[type="text"]:focus {
            outline: none;
            border-color: #3b82f6;
        }

        /* File Table */
        .file-table {
            width: 100%;
            border-collapse: collapse;
            background: #1e293b;
            border-radius: 8px;
            overflow: hidden;
            margin-top: 0;
        }
        .file-table th {
            background: #0f172a;
            padding: 12px 16px;
            text-align: left;
            font-weight: 600;
            color: #94a3b8;
            border-bottom: 1px solid #334155;
            font-size: 0.85rem;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }
        .file-table td {
            padding: 12px 16px;
            border-bottom: 1px solid #334155;
            font-size: 0.9rem;
        }
        .file-table tr:hover { background: #252f47; }
        .file-table tr:last-child td { border-bottom: none; }

        .file-name {
            display: flex;
            align-items: center;
            gap: 10px;
            color: #e2e8f0;
            text-decoration: none;
        }
        .file-name:hover { color: #60a5fa; }
        .file-icon { font-size: 1.3rem; }

        .file-actions {
            display: flex;
            gap: 5px;
            flex-wrap: wrap;
        }

        .file-size { color: #94a3b8; font-family: monospace; }
        .file-date { color: #64748b; font-size: 0.85rem; }
        .file-perms { 
            color: #fbbf24; 
            font-family: monospace; 
            font-size: 0.8rem;
            background: #292524;
            padding: 2px 6px;
            border-radius: 4px;
        }

        /* Empty state */
        .empty-state {
            text-align: center;
            padding: 60px 20px;
            color: #64748b;
        }
        .empty-state-icon { font-size: 4rem; margin-bottom: 15px; }

        /* Login Form */
        .login-container {
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background: #0f172a;
        }
        .login-box {
            background: #1e293b;
            padding: 40px;
            border-radius: 12px;
            border: 1px solid #334155;
            width: 100%;
            max-width: 400px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }
        .login-box h2 { 
            text-align: center; 
            margin-bottom: 30px; 
            color: #60a5fa;
            font-size: 1.8rem;
        }
        .login-box .form-group { margin-bottom: 20px; }
        .login-box label { 
            display: block; 
            margin-bottom: 8px; 
            color: #94a3b8; 
            font-size: 0.9rem; 
        }
        .login-box input {
            width: 100%;
            padding: 12px;
            background: #0f172a;
            border: 1px solid #334155;
            color: #e2e8f0;
            border-radius: 6px;
            font-size: 1rem;
        }
        .login-box input:focus {
            outline: none;
            border-color: #3b82f6;
        }
        .login-box button {
            width: 100%;
            padding: 12px;
            margin-top: 10px;
        }
        .login-error {
            background: #450a0a;
            color: #fca5a5;
            padding: 10px;
            border-radius: 6px;
            margin-bottom: 20px;
            text-align: center;
            font-size: 0.9rem;
        }

        /* Editor */
        .editor-container {
            background: #1e293b;
            border-radius: 8px;
            overflow: hidden;
            margin-top: 15px;
        }
        .editor-header {
            background: #0f172a;
            padding: 12px 16px;
            border-bottom: 1px solid #334155;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .editor-header h3 { color: #60a5fa; font-size: 1rem; }
        .editor-form { padding: 0; }
        .editor-textarea {
            width: 100%;
            min-height: 500px;
            background: #0f172a;
            color: #e2e8f0;
            border: none;
            padding: 16px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 0.9rem;
            line-height: 1.6;
            resize: vertical;
            outline: none;
        }
        .editor-footer {
            background: #0f172a;
            padding: 12px 16px;
            border-top: 1px solid #334155;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        /* Modal */
        .modal-overlay {
            display: none;
            position: fixed;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(0,0,0,0.7);
            z-index: 1000;
            justify-content: center;
            align-items: center;
        }
        .modal-overlay.active { display: flex; }
        .modal {
            background: #1e293b;
            border-radius: 12px;
            border: 1px solid #334155;
            padding: 25px;
            width: 90%;
            max-width: 500px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.4);
        }
        .modal h3 { color: #60a5fa; margin-bottom: 20px; }
        .modal .form-group { margin-bottom: 15px; }
        .modal label { display: block; margin-bottom: 8px; color: #94a3b8; }
        .modal input {
            width: 100%;
            padding: 10px;
            background: #0f172a;
            border: 1px solid #334155;
            color: #e2e8f0;
            border-radius: 6px;
        }
        .modal-actions {
            display: flex;
            gap: 10px;
            justify-content: flex-end;
            margin-top: 20px;
        }

        /* Responsive */
        @media (max-width: 768px) {
            .header { flex-direction: column; text-align: center; }
            .toolbar { flex-direction: column; align-items: stretch; }
            .toolbar form { width: 100%; }
            .file-table th:nth-child(3),
            .file-table td:nth-child(3),
            .file-table th:nth-child(4),
            .file-table td:nth-child(4) { display: none; }
            .file-actions { flex-direction: column; }
            .btn { padding: 6px 10px; font-size: 0.8rem; }
        }

        /* Scrollbar */
        ::-webkit-scrollbar { width: 8px; height: 8px; }
        ::-webkit-scrollbar-track { background: #0f172a; }
        ::-webkit-scrollbar-thumb { background: #334155; border-radius: 4px; }
        ::-webkit-scrollbar-thumb:hover { background: #475569; }
    </style>
</head>
<body>

<?php if (!is_logged_in() && $use_auth): ?>
<!-- TELA DE LOGIN -->
<div class="login-container">
    <div class="login-box">
        <h2>📁 Simple File Manager</h2>
        <?php if (isset($login_error)): ?>
            <div class="login-error"><?php echo htmlspecialchars($login_error); ?></div>
        <?php endif; ?>
        <form method="POST">
            <div class="form-group">
                <label>Usuário</label>
                <input type="text" name="username" placeholder="admin" required autofocus>
            </div>
            <div class="form-group">
                <label>Senha</label>
                <input type="password" name="password" placeholder="password" required>
            </div>
            <button type="submit" name="login" class="btn btn-primary">Entrar</button>
        </form>
        <p style="text-align: center; margin-top: 20px; color: #64748b; font-size: 0.85rem;">
            Default: admin / password
        </p>
    </div>
</div>

<?php else: ?>
<!-- INTERFACE PRINCIPAL -->
<div class="header">
    <h1>📁 Simple File Manager</h1>
    <div class="header-actions">
        <?php if (is_logged_in()): ?>
            <span class="user-info">👤 <?php echo htmlspecialchars($_SESSION['username']); ?> 
                <?php if (is_readonly()): ?><span style="color: #f59e0b;">[Somente Leitura]</span><?php endif; ?>
            </span>
            <a href="?logout=1" class="btn btn-danger btn-sm">🚪 Sair</a>
        <?php endif; ?>
    </div>
</div>

<div class="breadcrumb">
    <a href="?">🏠 Home</a>
    <?php foreach ($breadcrumbs as $crumb): ?>
        <span>/</span>
        <a href="?p=<?php echo urlencode($crumb['path']); ?>"><?php echo htmlspecialchars($crumb['name']); ?></a>
    <?php endforeach; ?>
</div>

<?php if ($message): ?>
    <div class="container">
        <div class="alert alert-success">✅ <?php echo htmlspecialchars($message); ?></div>
    </div>
<?php endif; ?>
<?php if ($error): ?>
    <div class="container">
        <div class="alert alert-error">❌ <?php echo htmlspecialchars($error); ?></div>
    </div>
<?php endif; ?>

<?php if (!$edit_file): ?>
<!-- LISTAGEM DE ARQUIVOS -->
<div class="toolbar">
    <?php if (is_logged_in() && !is_readonly()): ?>
        <form method="POST" enctype="multipart/form-data">
            <input type="file" name="upload" required>
            <button type="submit" class="btn btn-success btn-sm">📤 Upload</button>
        </form>
        <button onclick="showModal('folderModal')" class="btn btn-primary btn-sm">📁 Nova Pasta</button>
        <button onclick="showModal('fileModal')" class="btn btn-primary btn-sm">📄 Novo Arquivo</button>
    <?php endif; ?>
    <span style="color: #64748b; margin-left: auto;">
        📍 <?php echo htmlspecialchars($current_path ?: 'Root'); ?> 
        (<?php echo count($items); ?> itens)
    </span>
</div>

<div class="container" style="padding-top: 0;">
    <?php if (empty($items)): ?>
        <div class="empty-state">
            <div class="empty-state-icon">📂</div>
            <p>Esta pasta está vazia</p>
        </div>
    <?php else: ?>
        <table class="file-table">
            <thead>
                <tr>
                    <th>Nome</th>
                    <th>Tamanho</th>
                    <th>Modificado</th>
                    <th>Permissões</th>
                    <th>Ações</th>
                </tr>
            </thead>
            <tbody>
                <?php if ($current_path): ?>
                <tr>
                    <td colspan="5">
                        <a href="?p=<?php echo urlencode(dirname($current_path) === '.' ? '' : dirname($current_path)); ?>" class="file-name">
                            <span class="file-icon">⬆️</span> ..
                        </a>
                    </td>
                </tr>
                <?php endif; ?>

                <?php foreach ($items as $item): ?>
                <tr>
                    <td>
                        <?php if ($item['is_dir']): ?>
                            <a href="?p=<?php echo urlencode(($current_path ? $current_path . '/' : '') . $item['name']); ?>" class="file-name">
                                <span class="file-icon"><?php echo $item['icon']; ?></span>
                                <?php echo htmlspecialchars($item['name']); ?>
                            </a>
                        <?php else: ?>
                            <span class="file-name">
                                <span class="file-icon"><?php echo $item['icon']; ?></span>
                                <?php echo htmlspecialchars($item['name']); ?>
                            </span>
                        <?php endif; ?>
                    </td>
                    <td class="file-size"><?php echo $item['size']; ?></td>
                    <td class="file-date"><?php echo $item['modified']; ?></td>
                    <td><span class="file-perms"><?php echo $item['perms']; ?></span></td>
                    <td>
                        <div class="file-actions">
                            <?php if (!$item['is_dir']): ?>
                                <a href="?action=download&p=<?php echo urlencode($current_path); ?>&item=<?php echo urlencode($item['name']); ?>" class="btn btn-secondary btn-sm" title="Download">⬇️</a>

                                <?php if (is_text_file($full_path . '/' . $item['name'])): ?>
                                    <a href="?action=edit&p=<?php echo urlencode($current_path); ?>&item=<?php echo urlencode($item['name']); ?>" class="btn btn-warning btn-sm" title="Editar">✏️</a>
                                <?php endif; ?>

                                <?php if (is_image_file($full_path . '/' . $item['name'])): ?>
                                    <a href="?action=view&p=<?php echo urlencode($current_path); ?>&item=<?php echo urlencode($item['name']); ?>" target="_blank" class="btn btn-secondary btn-sm" title="Visualizar">👁️</a>
                                <?php endif; ?>
                            <?php endif; ?>

                            <?php if (is_logged_in() && !is_readonly()): ?>
                                <button onclick="renameItem('<?php echo addslashes($item['name']); ?>')" class="btn btn-secondary btn-sm" title="Renomear">📝</button>
                                <button onclick="copyItem('<?php echo addslashes($item['name']); ?>')" class="btn btn-secondary btn-sm" title="Copiar">📋</button>
                                <a href="?action=delete&p=<?php echo urlencode($current_path); ?>&item=<?php echo urlencode($item['name']); ?>" 
                                   onclick="return confirm('Tem certeza que deseja deletar <?php echo addslashes($item['name']); ?>?')" 
                                   class="btn btn-danger btn-sm" title="Deletar">🗑️</a>
                            <?php endif; ?>
                        </div>
                    </td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    <?php endif; ?>
</div>

<?php else: ?>
<!-- EDITOR DE TEXTO -->
<div class="container">
    <div style="margin-bottom: 15px;">
        <a href="?p=<?php echo urlencode($current_path); ?>" class="btn btn-secondary btn-sm">⬅️ Voltar</a>
    </div>

    <div class="editor-container">
        <div class="editor-header">
            <h3>✏️ Editando: <?php echo htmlspecialchars(basename($edit_file)); ?></h3>
            <span style="color: #64748b; font-size: 0.85rem;"><?php echo htmlspecialchars($edit_file); ?></span>
        </div>
        <form method="POST" class="editor-form">
            <input type="hidden" name="file_path" value="<?php echo htmlspecialchars($edit_file); ?>">
            <textarea name="content" class="editor-textarea" spellcheck="false"><?php echo htmlspecialchars($edit_content); ?></textarea>
            <div class="editor-footer">
                <span style="color: #64748b; font-size: 0.85rem;">
                    <?php echo format_size(strlen($edit_content)); ?> | 
                    <?php echo substr_count($edit_content, "\n") + 1; ?> linhas
                </span>
                <div>
                    <?php if (!is_readonly()): ?>
                        <button type="submit" name="save_file" class="btn btn-success">💾 Salvar</button>
                    <?php endif; ?>
                </div>
            </div>
        </form>
    </div>
</div>
<?php endif; ?>

<!-- MODAIS -->
<div class="modal-overlay" id="folderModal">
    <div class="modal">
        <h3>📁 Criar Nova Pasta</h3>
        <form method="POST">
            <div class="form-group">
                <label>Nome da Pasta</label>
                <input type="text" name="folder_name" placeholder="minha-pasta" required autofocus>
            </div>
            <div class="modal-actions">
                <button type="button" onclick="hideModal('folderModal')" class="btn btn-secondary">Cancelar</button>
                <button type="submit" name="new_folder" class="btn btn-primary">Criar</button>
            </div>
        </form>
    </div>
</div>

<div class="modal-overlay" id="fileModal">
    <div class="modal">
        <h3>📄 Criar Novo Arquivo</h3>
        <form method="POST">
            <div class="form-group">
                <label>Nome do Arquivo</label>
                <input type="text" name="file_name" placeholder="arquivo.txt" required autofocus>
            </div>
            <div class="modal-actions">
                <button type="button" onclick="hideModal('fileModal')" class="btn btn-secondary">Cancelar</button>
                <button type="submit" name="new_file" class="btn btn-primary">Criar</button>
            </div>
        </form>
    </div>
</div>

<div class="modal-overlay" id="renameModal">
    <div class="modal">
        <h3>📝 Renomear</h3>
        <form method="POST" action="?action=rename&p=<?php echo urlencode($current_path); ?>">
            <input type="hidden" name="old_name" id="renameOld">
            <div class="form-group">
                <label>Novo Nome</label>
                <input type="text" name="new_name" id="renameNew" required autofocus>
            </div>
            <div class="modal-actions">
                <button type="button" onclick="hideModal('renameModal')" class="btn btn-secondary">Cancelar</button>
                <button type="submit" class="btn btn-primary">Renomear</button>
            </div>
        </form>
    </div>
</div>

<div class="modal-overlay" id="copyModal">
    <div class="modal">
        <h3>📋 Copiar/Mover</h3>
        <form method="POST" action="?action=copy&p=<?php echo urlencode($current_path); ?>">
            <input type="hidden" name="source" id="copySource">
            <div class="form-group">
                <label>Destino (nome ou caminho)</label>
                <input type="text" name="dest" id="copyDest" required autofocus>
            </div>
            <div class="modal-actions">
                <button type="button" onclick="hideModal('copyModal')" class="btn btn-secondary">Cancelar</button>
                <button type="submit" class="btn btn-primary">Copiar</button>
            </div>
        </form>
    </div>
</div>

<script>
function showModal(id) {
    document.getElementById(id).classList.add('active');
}
function hideModal(id) {
    document.getElementById(id).classList.remove('active');
}
function renameItem(name) {
    document.getElementById('renameOld').value = name;
    document.getElementById('renameNew').value = name;
    showModal('renameModal');
}
function copyItem(name) {
    document.getElementById('copySource').value = name;
    document.getElementById('copyDest').value = name;
    showModal('copyModal');
}

// Fechar modal ao clicar fora
document.querySelectorAll('.modal-overlay').forEach(function(modal) {
    modal.addEventListener('click', function(e) {
        if (e.target === this) hideModal(this.id);
    });
});

// Atalhos de teclado no editor
document.addEventListener('keydown', function(e) {
    if (e.ctrlKey && e.key === 's') {
        var saveBtn = document.querySelector('button[name="save_file"]');
        if (saveBtn) {
            e.preventDefault();
            saveBtn.click();
        }
    }
});
</script>

<?php endif; ?>

</body>
</html>

quarta-feira, 15 de maio de 2024

thumbnail

Nerd Miner: Desvendando os Segredos

 


Nerd Miner: Desvendando os Segredos da Mineração de Bitcoin em Miniatura

O Nerd Miner se destaca como um dispositivo inovador que democratiza o acesso à mineração de Bitcoin, abrindo as portas para entusiastas e curiosos por essa tecnologia. Seu tamanho compacto, baixo consumo de energia e interface amigável o tornam acessível para iniciantes, enquanto sua natureza educacional proporciona uma jornada de aprendizado empolgante sobre o fascinante mundo das criptomoedas.

Mergulhando no Universo Nerd Miner:

  • Mineração Simplificada: O Nerd Miner atua como um mini PC dedicado à mineração de Bitcoin, operando em loteria. Isso significa que, em vez de competir diretamente com grandes mineradores, ele busca por blocos órfãos, aumentando suas chances de obter recompensas em Bitcoin.
  • Consumo de Energia Insignificante: Um dos diferenciais do Nerd Miner é seu baixo consumo de energia, equivalente a cerca de 1 watt. Isso o torna ideal para quem busca uma opção sustentável e econômica para se aventurar na mineração.
  • Experiência Educacional: Mais do que apenas minerar, o Nerd Miner proporciona uma experiência educativa. Através de um tutorial intuitivo e materiais de apoio, você aprende os conceitos básicos da mineração de Bitcoin, desvendando os mistérios dessa tecnologia disruptiva.
  • Acessibilidade e Facilidade de Uso: O Nerd Miner se destaca por sua simplicidade. A configuração é rápida e descomplicada, exigindo apenas alguns passos básicos. Além disso, seu design compacto permite que ele seja instalado em qualquer lugar, ocupando pouco espaço.

Considerações Importantes:

  • Lucratividade: É crucial ter expectativas realistas. O Nerd Miner não garante lucros exorbitantes, pois a recompensa por bloco é variável e depende da sorte. No entanto, a experiência de aprendizado e a possibilidade de obter Bitcoin de forma divertida e educativa podem ser recompensadoras por si só.
  • Loteria de Blocos: A natureza lotérica da mineração com o Nerd Miner exige paciência e persistência. As chances de encontrar um bloco órfão podem ser baixas, mas a satisfação de desvendar um pode ser imensa.
  • Comunidade Vibrante: Uma comunidade ativa e engajada de entusiastas do Nerd Miner se encontra online, pronta para oferecer suporte, compartilhar conhecimentos e trocar experiências.

O Nerd Miner é mais do que apenas um dispositivo de mineração: é um portal para o universo das criptomoedas, um convite para aprender, explorar e se divertir. Se você busca uma experiência educacional única e a oportunidade de entrar em contato com o futuro do dinheiro, o Nerd Miner pode ser a chave para uma jornada empolgante e gratificante.





About

Pesquisar este blog

Tecnologia do Blogger.

Arquivo do blog