Download Manager

Anwendungen für Webseiten. Künstliche Intelligenz verwenden.
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Download Manager

Ungelesener Beitrag von Volker »

Huhu :D

Hier noch ein kleiner Block der es ermöglicht schnell und einfach Downloads anzubieten.
Mit Zähler und automatischer Größen Anzeige.

Wie immer mit Doppelklick :D
https://www.niederastroth.de/dlmanager/

So werde ich in Zukunft den Download meiner Blöcke und Scripte gestalten :D
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Moin,

dieser Download-Manager gefällt mir sehr gut, insbesondere wird sich die Suchfunktion bewähren. Den kann man sehr gut gebrauchen.
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Wenn der optimiert ist kommt der auch als Download. Allerdings werden die Dateien auch da über ein Formular hochgeladen ;) Aber hast Du ja bestimmt schon gesehen ;)
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Ja - aber das macht ja nur der Admin - dann kann ja eigentlich sowieso nix passieren.
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Der neuste Eintrag steht immer oben links. Ich werde dann oben noch eine Einteilung per Hand schreiben.
Header Blöcke, Artikel Blöcke, Blöcke mit PHP API usw. Oder ? das würde doch reichen denke ich. Jeweils mit Link zum Demo Block. Ich hab das jetzt im 4er Grid so will ich auch lassen. 6 Wäre zu klein und auch die Bilder.Oder ich mach 3 aber dann wird richtig lang. Oder ich mach ein Dropdown ...ich weiß noch nicht :D
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

So wird der Umbau nun sein. Hier schonmal der Anfang der Sektion Cards, Menüs und Button ;)

https://www.niederastroth.de/DL1.html

Ich denke das ist dann übersichtlich. Kommen dann noch Header als Sektion und Blöcke mit PHP Script als Sektion.
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Ja - das sieht gut und sicher auch übersichtlich aus.

Ich frage mich nur ernsthaft - wie lange. Eine Lösung als scrollbare Tabelle wäre da schlussendlich wahrscheinlich übersichtlicher und zukunftssicherer.

Am Handy wird das sehr bald (ist es jetzt schon) verdammt lang :eek:

Jetzt sagts Du sicherlich gleich: "Am Handy nutzt man das ja nicht als Download" - schon, aber man sitzt am Fernseher und guckt nebenbei eben genau am Handy und sucht dort vielleicht eher mal als am Laptop. Aber eben nicht bei einem 10 Meter langen Kachel-Bandwurm :eek:
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Moin Tommy

auch dafür hab ich eine Lösung - dachte mir ja das Handy wieder Thema wird ;)

https://www.niederastroth.de/dlmanager/

Schau, so siehts dann aus :cool:
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Lösung - echt - Hilfeeee :D

Download-Kacheln am Handy - das geht gar nicht.jpg
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Naja ich arbeite noch daran :-)
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

So Tommy fertig :D

Schau mal so besser ?

https://www.niederastroth.de/dlmanager/
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Jepp - so sieht es Klasse aus - das ist die perfekte Lösung :)
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Dann kommt der auch so zum Download, damit die Handy Freaks zufrieden sind :D

Ist eigentlich so fertig oder gibts noch was zu ändern Tommy ?
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Für mich sieht das so fertig aus. Auch der Administrator-Bereich.

Nun konnte ich das Teil ja selbst noch nicht wirklich ausprobieren, weil es ja noch kein Download gibt (oder habe ich den verpasst?)
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Ne hast nix verpasst,

hier für Dich exclusiv zum testen und mir dann sagen was noch faul ist ;) : https://www.niederastroth.de/dl-manager.mbrext

API:

Code: Alles auswählen

<?php
/**
 * Bento Download & Admin API - REPARIERTE VERSION (Original-Dateinamen & Bild-Fix)
 * Erstellt eine SQLite-Datenbank für Extensions, verwaltet Uploads,
 * Bildvorschauen, Live-Demos, Download-Zähler und Datumsstempel.
 */

header('Content-Type: application/json; charset=utf-8');

// Konfiguration
$dbFile = 'bento_downloads.sqlite';
$uploadDir = 'uploads/';
$adminPassword = 'volker04'; // 🔒 Hier dein echtes Passwort eintragen!

// Zeitzone für korrekte deutsche Uhrzeiten setzen
date_default_timezone_set('Europe/Berlin');

ini_set('display_errors', 0);
error_reporting(E_ALL);

try {
    $db = new PDO("sqlite:" . $dbFile);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

    $db->exec("CREATE TABLE IF NOT EXISTS bento_documents (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT NOT NULL,
        filename TEXT NOT NULL,
        filesize TEXT,
        filetype TEXT,
        preview_img TEXT,
        demo_url TEXT,
        downloads INTEGER DEFAULT 0,
        created_at TEXT
    )");

    $stmt = $db->query("PRAGMA table_info(bento_documents)");
    $columns = $stmt->fetchAll();
    $hasCreatedAt = false;
    foreach ($columns as $col) {
        if ($col['name'] === 'created_at') {
            $hasCreatedAt = true;
            break;
        }
    }
    if (!$hasCreatedAt) {
        $db->exec("ALTER TABLE bento_documents ADD COLUMN created_at TEXT");
    }

} catch (PDOException $e) {
    echo json_encode(array('success' => false, 'error' => 'Datenbank-Fehler: ' . $e->getMessage()));
    exit;
}

function formatBytes($bytes, $precision = 2) {
    $units = array('B', 'KB', 'MB', 'GB');
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
    $bytes /= pow(1024, $pow);
    return round($bytes, $precision) . ' ' . $units[$pow];
}

$inputData = json_decode(file_get_contents('php://input'), true) ?? array();
$action = $_POST['action'] ?? $inputData['action'] ?? '';
$passwordInput = $_POST['password'] ?? $inputData['password'] ?? '';

// ==========================================
// ROUTE 1: GET - Öffentliche Liste der Downloads laden
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'GET' && !isset($_GET['adminCheck']) && !isset($_GET['file_id'])) {
    try {
        $stmt = $db->query("SELECT id, title, filesize, filetype, preview_img, demo_url, downloads, created_at FROM bento_documents ORDER BY id DESC");
        $docs = $stmt->fetchAll();
        echo json_encode(array('success' => true, 'docs' => $docs));
        exit;
    } catch (PDOException $e) {
        echo json_encode(array('success' => false, 'error' => $e->getMessage()));
        exit;
    }
}

// ==========================================
// ROUTE 2: GET - Datei herunterladen & Zähler erhöhen
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['file_id'])) {
    $fileId = intval($_GET['file_id']);
    
    try {
        $stmt = $db->prepare("SELECT * FROM bento_documents WHERE id = :id");
        $stmt->execute(array(':id' => $fileId));
        $doc = $stmt->fetch();

        if ($doc) {
            $filePath = $uploadDir . $doc['filename'];
            
            if (file_exists($filePath)) {
                $update = $db->prepare("UPDATE bento_documents SET downloads = downloads + 1 WHERE id = :id");
                $update->execute(array(':id' => $fileId));

                header('Content-Description: File Transfer');
                header('Content-Type: application/octet-stream');
                header('Content-Disposition: attachment; filename="' . basename($doc['filename']) . '"');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . filesize($filePath));
                readfile($filePath);
                exit;
            } else {
                echo "Datei nicht auf dem Server gefunden.";
                exit;
            }
        }
    } catch (PDOException $e) {
        echo "Download-Fehler.";
        exit;
    }
}

// ==========================================
// ROUTE 3: GET - Admin-Liste laden (Passwortgeschützt)
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['adminCheck'])) {
    if ($_GET['adminCheck'] !== $adminPassword) {
        echo json_encode(array('success' => false, 'error' => 'Nicht autorisiert.'));
        exit;
    }
    
    $stmt = $db->query("SELECT * FROM bento_documents ORDER BY id DESC");
    $docs = $stmt->fetchAll();
    echo json_encode(array('success' => true, 'docs' => $docs));
    exit;
}

// ==========================================
// ROUTE 4: POST - Admin Aktionen verarbeiten
// ==========================================
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    
    if ($action === 'checkLogin') {
        if ($passwordInput === $adminPassword) {
            echo json_encode(array('success' => true));
        } else {
            echo json_encode(array('success' => false, 'error' => 'Falsches Passwort'));
        }
        exit;
    }

    if ($passwordInput !== $adminPassword) {
        echo json_encode(array('success' => false, 'error' => 'Ungültiges Passwort!'));
        exit;
    }

    // Eintrag löschen
    if ($action === 'deleteFile') {
        $id = intval($inputData['id'] ?? 0);
        
        $stmt = $db->prepare("SELECT filename, preview_img FROM bento_documents WHERE id = :id");
        $stmt->execute(array(':id' => $id));
        $doc = $stmt->fetch();

        if ($doc) {
            if (!empty($doc['filename']) && file_exists($uploadDir . $doc['filename'])) {
                @unlink($uploadDir . $doc['filename']);
            }
            if (!empty($doc['preview_img']) && file_exists($uploadDir . $doc['preview_img'])) {
                @unlink($uploadDir . $doc['preview_img']);
            }

            $del = $db->prepare("DELETE FROM bento_documents WHERE id = :id");
            $del->execute(array(':id' => $id));

            echo json_encode(array('success' => true, 'message' => 'Erfolgreich gelöscht!'));
        } else {
            echo json_encode(array('success' => false, 'error' => 'Eintrag nicht gefunden.'));
        }
        exit;
    }

    // Bearbeiten / Titel aktualisieren
    if ($action === 'updateTitle') {
        $id = intval($_POST['id'] ?? 0);
        $newTitle = trim($_POST['title'] ?? '');
        $newDemoUrl = trim($_POST['demo_url'] ?? '');

        if (empty($newTitle)) {
            echo json_encode(array('success' => false, 'error' => 'Titel darf nicht leer sein!'));
            exit;
        }

        $previewFilename = null;
        if (isset($_FILES['new_preview']) && $_FILES['new_preview']['error'] === UPLOAD_ERR_OK) {
            $stmtImg = $db->prepare("SELECT preview_img FROM bento_documents WHERE id = :id");
            $stmtImg->execute(array(':id' => $id));
            $oldDoc = $stmtImg->fetch();
            if ($oldDoc && !empty($oldDoc['preview_img']) && file_exists($uploadDir . $oldDoc['preview_img'])) {
                @unlink($uploadDir . $oldDoc['preview_img']);
            }

            $pExt = strtolower(pathinfo($_FILES['new_preview']['name'], PATHINFO_EXTENSION));
            // Sicherer, sauberer Vorschaubild-Name
            $previewFilename = 'thumb_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $pExt;
            // 🔥 FEHLER BEHOBEN: Hier stand fälschlicherweise move_uploaded_uploaded_file
            move_uploaded_file($_FILES['new_preview']['tmp_name'], $uploadDir . $previewFilename);
        }

        if ($previewFilename !== null) {
            $update = $db->prepare("UPDATE bento_documents SET title = :title, demo_url = :demo_url, preview_img = :preview_img WHERE id = :id");
            $update->execute(array(':title' => $newTitle, ':demo_url' => $newDemoUrl, ':preview_img' => $previewFilename, ':id' => $id));
        } else {
            $update = $db->prepare("UPDATE bento_documents SET title = :title, demo_url = :demo_url WHERE id = :id");
            $update->execute(array(':title' => $newTitle, ':demo_url' => $newDemoUrl, ':id' => $id));
        }

        echo json_encode(array('success' => true));
        exit;
    }

    // Statistik zurücksetzen
    if ($action === 'resetDownloads') {
        try {
            $db->exec("UPDATE bento_documents SET downloads = 0");
            echo json_encode(array('success' => true, 'message' => 'Alle Zähler wurden auf 0 zurückgesetzt!'));
        } catch (PDOException $e) {
            echo json_encode(array('success' => false, 'error' => $e->getMessage()));
        }
        exit;
    }

    // Brandneuer Upload
    if (isset($_FILES['file'])) {
        $title = trim($_POST['title'] ?? 'Unbenannte Extension');
        $demoUrl = trim($_POST['demo_url'] ?? '');

        if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
            echo json_encode(array('success' => false, 'error' => 'Fehler beim Datei-Upload.'));
            exit;
        }

        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }

        // 🔥 FIX 2: Original-Dateinamen behalten & säubern
        $origFilename = $_FILES['file']['name'];
        $ext = strtolower(pathinfo($origFilename, PATHINFO_EXTENSION));
        $pureName = pathinfo($origFilename, PATHINFO_FILENAME);
        
        // Ungültige Zeichen aus dem Namen entfernen für saubere URLs
        $cleanName = preg_replace('/[^A-Za-z0-9_\-]/', '_', $pureName);
        $newFilename = $cleanName . '.' . $ext;

        // Falls die Datei schon existiert, Nummer anhängen (z.B. block_1.mbrext)
        $counter = 1;
        while (file_exists($uploadDir . $newFilename)) {
            $newFilename = $cleanName . '_' . $counter . '.' . $ext;
            $counter++;
        }

        $sizeFormatted = formatBytes($_FILES['file']['size']);

        if (!move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $newFilename)) {
            echo json_encode(array('success' => false, 'error' => 'Datei konnte nicht gespeichert werden.'));
            exit;
        }

        // 🔥 FIX 1: Bildvorschau-Name stabilisieren
        $previewFilename = '';
        if (isset($_FILES['preview']) && $_FILES['preview']['error'] === UPLOAD_ERR_OK) {
            $pExt = strtolower(pathinfo($_FILES['preview']['name'], PATHINFO_EXTENSION));
            // Nutzt den sauberen Namen des Blocks auch für das Bild, damit der Pfad immer greift
            $previewFilename = 'thumb_' . $cleanName . '_' . time() . '.' . $pExt;
            move_uploaded_file($_FILES['preview']['tmp_name'], $uploadDir . $previewFilename);
        }

        try {
            $stmt = $db->prepare("INSERT INTO bento_documents (title, filename, filesize, filetype, preview_img, demo_url, created_at) VALUES (:title, :filename, :filesize, :filetype, :preview_img, :demo_url, :created_at)");
            $stmt->execute(array(
                ':title' => $title,
                ':filename' => $newFilename,
                ':filesize' => $sizeFormatted,
                ':filetype' => strtoupper($ext),
                ':preview_img' => $previewFilename,
                ':demo_url' => $demoUrl,
                ':created_at' => date('Y-m-d H:i:s')
            ));

            echo json_encode(array('success' => true, 'message' => 'Extension erfolgreich hochgeladen!'));
        } catch (PDOException $e) {
            echo json_encode(array('success' => false, 'error' => 'Datenbank-Eintrag fehlgeschlagen: ' . $e->getMessage()));
        }
        exit;
    }
}

echo json_encode(array('success' => false, 'error' => 'Ungültige Anfrage.'));
exit;
?>
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Ja - also das ist mal wieder so ein Volker-Genialismus Ei :D

https://www.mobirise-tutorials.com/AI-B ... nager.html

Großartig, Design und Technik.

> Du musst dazu schreiben wie die API-Datei heißen muss: download-api.php

> Ein "Zurück-Button" zur Download-Seite vom Admin-Bereich wäre schön

> Es sollte beim Suchen immer ein Fenster erscheinen, nicht jetzt die App einfach weg sein Es sollte also ein vielleicht 500 px hohes Fenster stehen bleiben mit dem Hinweis "Keine Fundstellen" oder so.


Frage:

Ich habe das Verzeichnis "uploads" gleich händisch angelegt oder macht das Programm das auch alleine?


Wenn Du fertig bist hätte ich das gerne für meine Tutorial-Seiten. Ich werde es aber w ahrscheinlich nur als zusätzliches Beispiel nutzen - obwohl - mal sehen, denn das ist echt ruichtig gut,

Chapeau - großartig :tu:
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

Hab ich schonmal angefangen :

https://www.niederastroth.de/dl2.html

https://www.niederastroth.de/DL1.html

So dachte ich mir das :D
Volker
Moderator
Moderator
Beiträge: 2620
Registriert: Sa 12. Dez 2020, 22:35

Re: Download Manager

Ungelesener Beitrag von Volker »

uploads ordner wird automatisch angelegt, kannst du aber auch den Namen ändern in der api

Code: Alles auswählen

$uploadDir = 'uploads/';
Weil ich hatte schon einen im Root :D

Auch DB Namen kannst frei anpassen

Naja - ich hatte da 3 Dicke Fehler im Script - Dank KI aber gelöst ;) Hab die Kommentare ja drin gelassen ;)

Aber war meine Idee :D Und ich lerne echt durch KI stündlich dazu das ist einfach nur Geil

Du kannst die API nennen wie du willst, muss dann nur im Javascript auch angepasst werden im Block.
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Also dann werde ich den Ordner wohl eher "downlaod" nennen und der API solltest Du einen festen Namen geben, sonst muss man das ja alles erklären. Ich habe die jetzt "download-api.php" genannt. So wird diese doich aber auch in der HTML vom Block angesprochen :confused:
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8661
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Download Manager

Ungelesener Beitrag von Tommy Herrmann »

Das man als Entwickler die KI verwendet wird ganz sicher sowieso zum Standard werden, alles andere macht sonst arbeitslos.

Das ist also vollkommen egal - zählen tut hier nur die Idee und am Ende die fertige App. Wer da was gemacht hat ist pupsegal.
Antworten

Wer ist online?

Mitglieder in diesem Forum: Volker und 4 Gäste