Dateien hochladen mit Python

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo zusammen,

    ich möchte mit Python meine Videodateien die Motion erstellt auf meinen Webspace hochladen. Bisher habe ich das mit "wput" gemacht. Leider läd er die Dateien nicht mehr vollständig hoch. Er bleibt immer bei ca 99 % stehen.

    Hat jemand eine Idee wie man es mit zb. Python machen kann? Ich vermute ich muss dann Motion bebringen wie ich dann dieses Pythonscript starte.

    Vielen Dank im voraus,
    Gruß
    Plan_C

  • Hat jemand eine Idee wie man es mit zb. Python machen kann? Ich vermute ich muss dann Motion bebringen wie ich dann dieses Pythonscript starte.

    Eigentlich nicht. Wenn ich mich richtig erinnere hast du in deiner Konfigurastionsdatei on_movie_end eingetragen und dahinter steht der auszuführende Befehl, oder?
    Es würde also reichen einfach python mit der Scriptdatei aufzurufen... Oder du erstellst ein bash Script in welchem dann das python Script (und ggf weitere Befehle) ausgeführt werden, aber das wäre i.d.R. überflüssig :)

    Also angenommen du erstellst ein Python Script /home/pi/FTPupload.py , dann machst du das ausführbar (chmod +x /home/pi/FTPupload.py), setzt oben einen Shebang (#!/usr/bin/python) und trägst in deine motion Config nur noch folgendes ein:

    Code
    on_movie_end /home/pi/FTPupload.py %f


    Das %f bewirkt dass das Aufgenommende Videofile (inkl. absolutem path) an das Script übergeben wird...
    Ggf. muss es auch so eingetragen werden:

    Code
    on_movie_end "/home/pi/FTPupload.py %f"

    Oder nicht bei "on_movie_end" sondern "on_event_end":

    Code
    on_event_end /home/pi/FTPupload.py %f


    Soweit schon mal zur Vorbereitung.

    Was man aber auch noch bräuchte wäre die Übergabe der Videodatei zu beachten. Das kann man mit sys.argv[1] abrufen :)

    Versuch es mal mit folgendem Script:


    Alternativ:

    Code
    apt-get install python-ftputil

    ACHTUNG! python-ftputil ist eine zu alte Version! Das Module unbedingt über pip installieren!!

    Beachten sollte man aber auch das obiger Code nur mit python v2.x funktioniert und folglich nur mit ftputil v2.8.. Wer das aktuellste ftputil (zZt. v3.2) nutzen will muss zwangsläufig python v3.x nutzen da ftputil3.2 kein python2 mehr unterstützt!


    //EDIT: 2 sichtliche Fehler im Script behoben :blush:

    //EDIT2: total_size hatte ich auch vergessen :blush:

    //EDIT3: Kleinere Optimierungen bzw Fehlerbehandlungen vorgenommen, altes Script hier in den Spoiler und neues Script nach oben verschoben - und auch ein Problem bei der Installation in diesem Beitrag korregiert (siehe Beitrag#6)

    "alte version 0.1"


    [code=php]
    #!/usr/bin/python
    # -*- coding: utf-8 -*-

    import time, sys, os
    import re #regular expressions
    import ftputil

    #ftputil docu: http://ftputil.sschwarzer.net/trac/wiki/Documentation

    ##----- CONFIG - START ----------------------------------------

    ftpHost = "192.168.0.11"
    ftpUser = 'pi'
    ftpPass = 'raspberry'
    ftpRemoteDir = '/'

    ##----- CONFIG - END ------------------------------------------


    if len(sys.argv) < 2:
    print("Usage: %s <file>" % sys.argv[0])
    sys.exit(1)

    localFile = sys.argv[1]
    total_size = float(os.path.getsize(localFile))/1024 #kB
    received_size = 0

    def logError(message):
    try:
    sys.stderr.write(message + "\n")
    except UnicodeEncodeError:
    sys.stderr.write(message.encode("utf8") + "\n")

    def onError(err):
    print err

    def connectFtp():
    global connected
    connected = True
    try:
    ftp = ftputil.FTPHost(ftpHost, ftpUser, ftpPass)
    except OSError, e:
    print >> sys.stderr, 'Got error: "%s"' % e
    connected = False
    if connected:
    return ftp

    def progress(chunk):
    global received_size
    received_size += len(chunk)
    print("Uploading Progress: {} kB / {} kB".format(float(received_size)/1024, total_size))

    if __name__ == '__main__':
    try:
    ftp = connectFtp()
    if not connected:
    print >> sys.stderr, 'Cant connect to remote! Exiting Script'
    sys.exit(1)
    #remove all whitespace characters (space, tab, newline, and so on)
    remotePath = ftpRemoteDir.rstrip('/')
    #pattern = re.compile(r'\s+')
    #remotePath = re.sub(pattern, '', remotePath)
    remoteFile = remotePath+"/"+localFile
    #change to remote dir
    try:
    ftp.chdir(remotePath)
    except OSError, e:
    logError("Remote Directory {} doesnt Exists!".format(remotePath))
    raise
    #upload file
    try:
    ftp.upload(localFile, remoteFile, callback=progress)
    except Exception:
    print("Upload failed!")
    raise
    except Exception, e:
    print "Error: %s occurred" % (e)
    except ftputil.error.PermanentError, e:
    logError("Permanent Error occurred: %s") % (e)
    finally:
    ftp.close()
    ftp.close()
    [/php]

  • ..Er hat mir gestern Abend im IRC eine Nachricht hinterlassen:

    Zitat

    [22:51:15] (Plan_C): Nachdem eine Bewegung erkannt wurde, erscheint im Terminal Fenster (da wo motion gestartet wurde) "Usage: /home/pi/motion/FTPupload.py <file>"
    [22:51:22] (Plan_C): Aber es wird keine Datei hochgeladen
    [22:52:10] (Plan_C): habe unter "Config" dein pythonscript bearbeitet. Bei "ftpremotedir" habe ich /html/c eingegeben, damit die Videodatei unter html/c auf meinem Webspace hochgeladen wird
    [22:52:17] (Plan_C): Dort kommt aber nichts an :(

    Versuch es mal mit folgendem Eintrag in der motion.conf:

    Code
    on_movie_end "/home/pi/motion/FTPupload.py %f"

    (also den vorhandenen Eintrag so abändern)

    Ansonsten einfach erst mal das Script manuell testen, wirst ja irgendeine größere Datei rumliegen haben oder? ;)

  • Hi

    Versuche gerade einen einfachen Upload von Raspi zu Raspi zu machen.
    Habe das Script von meigrafd benutzt und bekomme jedoch folgenede
    Meldung:
    Error: upload() got an unexpected keyword argument 'callback' occurred
    Was mache ich falsch?

  • Mach bitte folgende Schritte:

    Code
    apt-get remove --purge python-ftputil
    apt-get install python-pip
    pip install ftputil

    Dann funktioniert das auch.

    Offensichtlich ist das über apt-get erhältliche Paket noch zu alt. Das callback Argument wurde erst vor kurzem implementiert und ist erst mit Version 3.2 verwendbar. Über apt-get kriegt man aber eine sehr alte Version 2.4

    ..ich passe den Beitrag#2 auch mal an damit dieses Problem nicht mehr auftritt - sorry, Fehler meinerseits!

  • Habe alles so hin bekommen.
    Kämpfe jetzt aber mit einem anderen Problem schon seit Stunden.
    Got error: "[Errno 111] Connection refused
    Die Angaben stimmen alle und der Host 'lebt'.

    Was kann das jetzt sein?

    Danke für deine Mühe.

  • Naja kannst du dich denn mit den selben Daten manuell über FTP anmelden? Wenn das auch nicht geht läge es schon mal nicht am python Script ;)

    Code
    apt-get install ftp
    
    
    ftp 192.168.0.11

    Auf der anderen Seite muss halt ein FTP-Server laufen, und erwartet wird auch das dieser auf Port 21 erreichbar ist - ansonsten kann man den Port aber auch mit angeben:
    [code=php]ftp = ftputil.FTPHost(ftpHost, ftpUser, ftpPass, port=21)[/php]

    &quot;v0.21 - mit ftpPort Angabe&quot;

    [code=php]#!/usr/bin/python
    # -*- coding: utf-8 -*-
    #
    # v0.21 by meigrafd
    #
    # requires ftputil >= v3.2
    #
    # apt-get install python-pip && pip install ftputil
    #
    #ftputil docu: http://ftputil.sschwarzer.net/trac/wiki/Documentation

    import time, sys, os
    import ftputil

    ##----- CONFIG - START ----------------------------------------

    ftpHost = '192.168.0.11'
    ftpPort = 21
    ftpUser = 'pi'
    ftpPass = 'raspberry'
    ftpRemoteDir = '/'

    ##----- CONFIG - END ------------------------------------------


    def logError(message):
    try:
    sys.stderr.write(message + "\n")
    except UnicodeEncodeError:
    sys.stderr.write(message.encode("utf8") + "\n")

    def connectFtp():
    connected = True
    ftp = None
    try:
    ftp = ftputil.FTPHost(ftpHost, ftpUser, ftpPass, port=ftpPort)
    except OSError, e:
    print >> sys.stderr, 'Got error: "%s"' % e
    connected = False
    return ftp, connected

    def progress(chunk):
    global received_size
    received_size += len(chunk)
    print("Uploading Progress: {} kB / {} kB".format(float(received_size)/1024, total_size))

    if __name__ == '__main__':
    if len(sys.argv) < 2:
    print("Usage: %s <file>" % sys.argv[0])
    sys.exit(1)
    localFile = sys.argv[1]
    ftp = None
    received_size = 0
    try:
    total_size = float(os.path.getsize(localFile))/1024 #kB
    ftp, connected = connectFtp()
    if not connected:
    print >> sys.stderr, 'Cant connect to remote! Exiting Script'
    sys.exit(1)
    #remove all whitespace characters (space, tab, newline, and so on)
    remotePath = ftpRemoteDir.rstrip('/')
    remoteFile = remotePath+"/"+localFile
    #change to remote dir
    try:
    ftp.chdir(remotePath)
    except OSError, e:
    logError("Remote Directory {} doesnt Exists!".format(remotePath))
    raise
    #upload file
    try:
    ftp.upload(localFile, remoteFile, callback=progress)
    except Exception:
    logError("Upload failed!")
    raise
    except Exception, e:
    logError("Error: %s" % (e))
    except ftputil.error.PermanentError, e:
    logError("Permanent Error occurred: %s") % (e)
    except (KeyboardInterrupt, SystemExit):
    print("\nSchliesse Programm..\n")
    finally:
    if ftp:
    ftp.close()
    [/php]

  • Werde mal ein frisches Image auflegen, da stimmt was nicht.
    Gestern hat ein einfaches Script noch funktioniert - jedoch ohne jegliche Fehlerbehandlung - das geht jetzt auch nicht mehr.
    Melde mich mich dann wieder.
    Danke bis dahin.....

  • Deshalb gleich ein neues Image installieren ist i.d.R. übertrieben. Da ich aber nicht weiß was du als FTP-Server verwendest, kann ich nur allgemein Tips geben:

    - Prüfen ob der FTP-Server läuft oder auf welchem Port: netstat -tulpen
    - Paket vollständig deinstallieren: apt-get remove --purge PAKET
    -- Und anschließend neu installieren.

  • Keine Ahnung warum ich das nicht schnell hin bekommen habe.
    Nachdem ich proftpd installiert hatte, lief dein
    Script auf Anhieb.

    Besten Dank meigrafd

Jetzt mitmachen!

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