Web Interface Datei hochladen (Cherrypy)

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Ich versuche gerade verzweifelt einen einfachen Upload für ein kleines Web-Interface hinzukriegen, aber alles was ich versuche klappt nicht.
    Leider kenne ich mich in HTML/Javascript nicht so gut aus um zu beurteilen ob es nun daran liegt, oder an den cherrypy Server dahinter.

    Ich will halt einfach nur eine einzelne Date hochladen, ohne das die Seite wechselt. Meldung das der Upload fertig ist mache ich dann mit einem einfachen alert, das reicht für meinen Fall vollkommen aus. Ich will halt nur nicht das die Seite irgendwie wechselt.

    Im HTML Body hab ich dies:

    Code
    <div>
        <label>Upload Sound:</label>
        <input id="pathSound" style="width: 80%" type="file" accept=".mp3"/><br>
        <button id="uploadSound">Upload</button>
    </div>

    Im Header im Script Tag dies:

    Und im Python Code dies:

    Code
    @cherrypy.expose
    def uploadSound(self,  cardID='', myFile=None):
        print 'uploadSound : ',  cardID
        print 'uploadSound : ',  myFile
        return ''

    Leider wird die Python Funktion nie aufgerufen. Alle bisherigen Funktionen funktionieren, also ist es prinzipiell schon richtig eingerichtet, halt nur nicht für den Upload. Sende aber bisher auch nur String zwischen Server und Webseite hin und her, vielleicht liegt es ja daran, das es hier Biärdaten einer Datei sind oder so...

    Hat jemand schon Erfahrung mit cherrypy und kann mir da einen Tip geben?

    Habe mich für cherrypy entschieden, weil es bisher am einfachsten erscheint, aber falls jemand da ein Codebeispiel für ein anderes Web-Framework hat, was vergleichbar einfach zu benutzen ist hab ich auch kein Problem ein anderes Framework zu benutzen, will halt einfach das es funktioniert.

  • Das ist so ziemlich das einzige Beispiel was man zu einem Upload findet.
    Leider Funktioniert es nicht so, da dies Beispiel mit einer alten Version con cherrypy gemacht wurde, außerdem benutzt das ja ein submit, was dann die angezeigte Seite wechselt, was genau das ist, was ich eben nicht will.

  • Muss es denn unbedingt CherryPy sein?

    Ich kann dir meine upload.php bereitstellen, vielleicht hilft dir das:

    [code=php]
    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <style>
    body {
    background-color:#0f1113;
    }
    .tab {
    letter-spacing: 0px;
    font-family: verdana, arial, helvetica, verdana, tahoma, sans-serif;
    font-size: 13px;
    text-align: left;
    color: #c8c8c8;
    font-weight: normal;
    }
    .tabred {
    letter-spacing: 0px;
    font-family: verdana, arial, helvetica, verdana, tahoma, sans-serif;
    font-size: 13px;
    text-align: left;
    color: firebrick;
    font-weight: bold;
    }
    .tabgreen {
    letter-spacing: 0px;
    font-family: verdana, arial, helvetica, verdana, tahoma, sans-serif;
    font-size: 13px;
    text-align: left;
    color: limegreen;
    font-weight: bold;
    }
    </style>
    </head>
    <body>
    <?php

    # CONFIG - START

    // Upload to which Directory?
    $TMPdir="/tmp/upload";

    # CONFIG - END

    error_reporting(E_ALL);
    ini_set("upload_max_filesize", "100M");
    ini_set('track_errors', 1);
    ini_set('display_errors', 1);
    ini_set('log_errors', 1);

    $s=" ";
    $_SELF=$_SERVER['PHP_SELF'];
    $UploadedFile = isset($_FILES["uploadfile"]) ? $_FILES["uploadfile"] : "";

    echo "<form enctype='multipart/form-data' action='".htmlspecialchars($_SELF)."' method='POST'>\n";
    echo "<b class='tab'>Datei:</b> <input name='uploadfile' type='file' size='50' maxlength='100000'>\n";
    echo "$s$s<input type='submit' value='Upload'><br/><br/>\n";
    echo "</form>\n";

    if (!empty($UploadedFile)){
    if (!is_dir("$TMPdir") AND !mkdir("$TMPdir",0777,true)) {
    echo "<b class='tabred'>Error creating temp dir $TMPdir</b><br/>\n";
    } else {
    $FileName = $UploadedFile['name'];
    $FileError = $UploadedFile['error'];
    #exec("rm -rf ".$TMPdir."/* 2>/dev/null",$output,$return_var);
    if (!move_uploaded_file($UploadedFile['tmp_name'],"$TMPdir/".$FileName."")) {
    echo "<b class='tabred'>Beim Upload trat ein Fehler auf, bitte noch mal probieren!</b> \n";
    if (isset($FileError) AND !empty($FileError)) { echo "<b class='tab'>".uploaderror($FileError)."</b>"; }
    echo "<br/>\n";
    } else {
    $FileSize = get_size($UploadedFile['size']);
    $FileType = $UploadedFile['type'];
    echo "<b class='tabgreen'>Die Datei</b> <b class='tab'>".$FileName." (".$FileSize.")</b>";
    echo "<b class='tabgreen'>wurde erfolgreich hochgeladen und befindet sich nun in</b> <b class='tab'>".$TMPdir."</b><br/>\n";
    }
    }
    }


    function get_size($size,$precision=2,$long_name=true,$real_size=true) {
    $base=$real_size?1024:1000;
    $pos=0;
    while ($size>$base) {
    $size/=$base;
    $pos++;
    }
    $prefix=get_size_prefix($pos);
    $size_name=$long_name?$prefix."bytes":$prefix[0].'B';
    return round($size,$precision).' '.ucfirst($size_name);
    }

    function get_size_prefix($pos) {
    switch ($pos) {
    case 00: return "";
    case 01: return "Kilo";
    case 02: return "Mega";
    case 03: return "Giga";
    case 04: return "Tera";
    case 05: return "Peta";
    case 06: return "Exa";
    case 07: return "Zetta";
    case 08: return "Yotta";
    case 09: return "Xenna";
    case 10: return "W-";
    case 11: return "Vendeka";
    case 12: return "u-";
    default: return "?-";
    }
    }

    # http://www.php.net/manual/en/features.file-upload.errors.php
    function uploaderror($returncode) {
    $msg="";
    switch ($returncode) {
    case 0:
    $msg = "";
    break;
    case 1:
    $msg = "The uploaded file exceeds the upload_max_filesize directive in php.ini.";
    break;
    case 2:
    $msg = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.";
    break;
    case 3:
    $msg = "The uploaded file was only partially uploaded.";
    break;
    case 4:
    $msg = "No file was uploaded.";
    break;
    case 6:
    $msg = "Missing a temporary folder.";
    break;
    case 7:
    $msg = "Failed to write file to disk.";
    break;
    case 8:
    $msg = "A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop";
    $msg.= " examining the list of loaded extensions with phpinfo() may help."
    break;
    default:
    $msg = "Unknown upload error";
    break;
    }
    return $msg;
    }

    ?>

    </body>
    </html>
    [/php]


    //EDIT: Achso gerade erst gesehen:


    Ich will halt nur nicht das die Seite irgendwie wechselt.

    Dann musst du wohl auf Javascript umsatteln..

  • Nein, muss kein cherrypy sein, habe ich nur benutzt, weil es mir am einfachsten erschien. Habe da halt schon ein paar Tage rein gesteckt, dies Framework jetzt zu lernen.
    Versuche das ganze gerade zu bottle zu konvertieren, ist aber teilweise wieder von 0 anfangen.

    Mir php kann ich da nichts anfangen, es soll ein Web-Interface zu einem laufenden python Programm sein, und am liebsten halt direkt mit einem embeded Web Server. Möchte nicht alles mögliche weitere (wie apache) installieren, sondern alles kompakt als ein Paket haben.

    Aber danke fürs Angebot ;)

  • Funktioniert gar nix.
    Also das Beispiel aus dem Tutorial der cherrypy Dokumentation funktioniert mit der neusten Version so nicht.

    Ich bin mir gerade auch nicht sicher ob der Javascript Teil so korrekt ist.
    Mit bottle hab ich jetzt alles andere soweit auch recht einfach hin gekriegt, hänge da aber auch wieder beim File Upload fest.

    Ist der Ajax-Request denn so überhaupt korrekt?
    Es kommt mir so vor, als wenn dort ein Fehler ist, und die Date so gar nicht übergeben werden kann.

    Mit bottle sieht die Funktion jetzt so aus:

    Code
    @route('/uploadSound', method='GET')
    def uploadSound(self):
        cardID = request.forms.get('cardID')
        myFile = request.forms.get('myFile')
        print 'uploadSound : ',  cardID
        print 'uploadSound : ',  myFile
        return ''


    Wird aber auch nie aufgerufen.
    Glaube da ist auch noch ein Fehler, weil die File ja nicht aus dem forms-Dictionary geholt werden muss, sondern aus dem file-Dictionary, aber wie stecke ich die da rein?

    So scheint es zu funktionieren:

    Javascript

    Python

    Code
    @route('/uploadSound', method='POST')
    def uploadSound():
        cardID = request.forms.get('cardID')
        myFile = request.files.get('myFile')
        print 'uploadSound : ',  cardID
        print 'uploadSound : ',  myFile
        return ''

    Zumindest kriege ich so ein erwartetes File Objekt im Parameter myFile. Das ganze jetzt an die richtige Stelle auf dem Server speichern muss ich noch erledigen. Aber zumindest scheint dies so jetzt zu funktionieren.

    Einmal editiert, zuletzt von RyuKajiya (5. Januar 2015 um 15:01)

  • Also in bottle funktioniert es wunderbar mit dem Code aus der Doku:


    Du musst bei dir get und post trennen.

    Edit:
    Hier mal ein min. Beispiel mit einem CherryPyServer

    app.py

    Template:
    upload.tpl

    Im Ordner, in welchem deine bottle App ist, machst du noch folgende Ordner "htdocs", "Uploads" und ganz wichtig "views" denn bottles Template-Engine sucht die Templates als erstes wenn nichts anderes angegeben ist im Ordner "views".

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!