Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 12/03/2014, à 22:02

Slaan

Upload automatique fichier sur serveur FTP

Bonjour à tous.

Je vous expose mon projet :
Je souhaite créer une tache récurrente qui upload automatiquement n'importe quel fichier sur un ou deux serveurs FTP des qu'il se trouve dans un dossier et, une fois l'upload terminé, efface ce dit fichier.
J'ai pas mal farfouillé a droite à gauche, je ne suis pas un pro du batch mais j'apprends vite, il me faudrait créer quelque chose de ce style :

#/bin/bash
if [[ $(ls home/jo/tomove/*) ]]
then
gftp login:mdp@upload.server1.com "put -E home/jo/tomove/*  ; exit"
gftp login:mdp@upload.server2.com "put -E home/jo/tomove/*  ; exit"
rm -rf home/jo/tomove/*
fi
exit 0

Ensuite, je colle ce .sh dans une tache cron pour l’exécuter toute les heures, par exemple.

Alors, j'ai plusieurs questions,
D'une part, ça vous semble bon ? smile
Ensuite, j'ai peur que si l'upload foire, cela efface tout de même les fichiers. Y a t'il moyen de contrôler le succès de l'upload ?

Merci pour votre aide !

Slaan.

Hors ligne

#2 Le 13/03/2014, à 00:00

Slaan

Re : Upload automatique fichier sur serveur FTP

Au temps pour moi, ce script devrait mieux marcher :

#/bin/bash
FTPU="user" # ftp login name
FTPP="passwd" # ftp password
FTPS="ftp.server.com" # remote ftp server
FTPF="/" # remote ftp server directory for $FTPU & $FTPP
LOCALD="home/jo/tomove/*"
ncftpput -m -u $FTPU -p $FTPP $FTPS  $FTPF $LOCALD
rm -rf home/jo/tomove/*

Par contre, toujours le même questionnement concernant la suppression aprés upload smile

Merci !

Hors ligne

#3 Le 13/03/2014, à 08:54

k3c

Re : Upload automatique fichier sur serveur FTP

Tu peux t'inspirer de ce script qui utilise pyinotify.

Tu le lances au démarrage de ton PC, et c'est tout.
Tu remplaces la commande de conversion de vidéos par ton ftp, et tu mets le bon répertoire à surveiller.

http://forum.ubuntu-fr.org/viewtopic.php?pid=9218931


Archlinux sur Xiaomi Air 13

Hors ligne

#4 Le 13/03/2014, à 19:41

Slaan

Re : Upload automatique fichier sur serveur FTP

Hello,

Super, merci pour ton exemple, je crois que c'est ce qu'il me fallait effectivement.
Donc, si j'ai bien compris, je dois creer un script de cette trempe la :

# Example: daemonize pyinotify's notifier.
# Requires Python >= 2.5
import functools
import sys
import pyinotify
import subprocess

class Counter(object):
    """
    Simple counter.
    """
    def __init__(self):
        self.count = 0
    def plusone(self):
        self.count += 1

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CLOSE_WRITE(self, event):
        print "Close_write:", event.pathname
        fichier = event.pathname
        if fichier[-4:].lower() == '.mp4':
            process = subprocess.call(['ncftpput', '-m', '-u LOGIN', '-p PASS', 'ftp.server.com' '/', fichier,/])
def on_loop(notifier, counter):
    """
    Dummy function called after each event loop, this method only
    ensures the child process eventually exits (after 5 iterations).
    """
    sys.stdout.write("Loop %d\n" % counter.count)
    counter.plusone()

handler = EventHandler()
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, handler)
wm.add_watch('/home/jo/testftp/', pyinotify.IN_CLOSE_WRITE)
on_loop_func = functools.partial(on_loop, counter=Counter())
try:
    notifier.loop(daemonize=True, callback=on_loop_func,
                 pid_file='/tmp/pyinotify.pid', stdout='/tmp/stdout.txt')
except pyinotify.NotifierError, err:
    print >> sys.stderr, err

Sachant que la syntaxe de ncftp est :

ncftpput -m -u LOGIN -p PASSW FTP.SERVER.COM  FTPPATH LOCALPATH

Je doute sur la syntaxe du coup de mon :

process = subprocess.call(['ncftpput', '-m', '-u LOGIN', '-p PASS', 'ftp.server.com' '/', fichier,/])

Merci pour ton aide smile

Hors ligne

#5 Le 13/03/2014, à 20:06

k3c

Re : Upload automatique fichier sur serveur FTP

Faut que tu vires la ligne

if fichier[-4:].lower() == '.mp4':

(à moins que tous les fichiers que tu copies par ftp aient une extension mp4)

sinon ça a l'air OK.

Reste à voir comment tu sais que le ftp s'est bien passé, et que tu peux donc détruire les fichiers.


Archlinux sur Xiaomi Air 13

Hors ligne

#6 Le 13/03/2014, à 21:57

Slaan

Re : Upload automatique fichier sur serveur FTP

Cool.
Et imaginons que je veuille choisir plusieurs extensions de fichier, style .mp4, .avi et .mkv, es ce bien le caractère " | " que je dois utiliser ? comme ceci  :

if fichier[-4:].lower() == '.mp4|.avi|.mkv':

Imaginons aussi que l'envoie ftp se passe bien dans tout les cas, si je rajoute une ligne de ce style juste après cette dernière, ça n'effacera que le fichier précédemment envoyé ?

process = subprocess.call(['rm', fichier])

Merci pour ton aide, c'est assez enthousiasmant de découvrir de nouveaux outils smile

Dernière modification par Slaan (Le 13/03/2014, à 21:59)

Hors ligne

#7 Le 14/03/2014, à 07:04

k3c

Re : Upload automatique fichier sur serveur FTP

Non je ferai

if '.mp4' in fichier or '.mkv' in fichier or '.avi' in fichier:

ou même, plus précis

fichier.endswith('.mp4')...

si fichier contient
a.mp4
alors
fichier.endswith('.mp4')
renvoie True

Dernière modification par k3c (Le 14/03/2014, à 12:01)


Archlinux sur Xiaomi Air 13

Hors ligne

#8 Le 16/03/2014, à 13:40

Slaan

Re : Upload automatique fichier sur serveur FTP

Yop !

Okay, je vois smile
Alors, j'ai planché sur une solution à deux scripts.
L'un nommé "serversftp.py" qui liste les serveurs et qui réalise l'action d'envoyer les fichiers avec un peu d'info sur le déroulement des opérations, et avec la commande "os.remove(DATAFILE)" pour la suppressoin du fichier a la fin de l'upload.

Le second pour le daemon et la surveillance du dossier, inspiré donc de tes conseils.

Le premier :

 
# -*- coding: utf-8 -*-
 
import sys
import os
from ftplib import FTP
 
SERVERS = ['server1', 'server2']
LOGINS = ['log1', 'log2']
PSWDS = ['secret1', 'secret2']
DATAFILE = sys.argv[1] #le chemin/nom du fichier lorsqu'il est appellé par un autre process 
FILENAME = os.path.basename(DATAFILE) #le nom seul
 
def upload():
    print 'Connection to %s' % nom
    try:
        ftp = FTP(nom)
        ftp.login(LOGINS[index], PSWDS[index])
    except Exception as why:
        print 'login error: {0}'.format(why)
        sys.exit()
 
 
    print 'Read file %s' % DATAFILE
    with open(DATAFILE, "rb") as objf:
        print 'Upload file %s to server' % FILENAME
        try:
            ftp.storbinary('STOR ' + FILENAME, objf)
        except Exception as why:
            print 'upload failed: {0}'.format(why)
        else:
            print 'File uploaded, close ftp.'
        ftp.quit()
 
if __name__ == '__main__':
    # on boucle sur les noms de serveur
    for index, nom in SERVERS:
        upload(FILENAME, nom, LOGINS[index], PSWDS[index])
    os.remove(DATAFILE)

J'ai par contre une erreur sur la boucle. J'ai du me planter quelque part hmm

Traceback (most recent call last):
  File "scriptFTPpy.py", line 37, in <module>
    for index, nom in SERVERS:
ValueError: too many values to unpack

Et le second script, inspiré du tien et de tes conseils du coup :

 
# Example: daemonize pyinotify's notifier.
# Requires Python >= 2.5
import functools
import sys
import pyinotify
import subprocess
 
class Counter(object):
    """
    Simple counter.
    """
    def __init__(self):
        self.count = 0
    def plusone(self):
        self.count += 1
 
class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CLOSE_WRITE(self, event):
        print "Close_write:", event.pathname
        fichier = event.pathname
        if '.mp4' in fichier or '.mkv' in fichier or '.avi' in fichier:
            process = subprocess.call(['python', '/home/jo/serversftp.py', fichier])
def on_loop(notifier, counter):
    """
    Dummy function called after each event loop, this method only
    ensures the child process eventually exits (after 5 iterations).
    """
    sys.stdout.write("Loop %d\n" % counter.count)
    counter.plusone()
 
handler = EventHandler()
wm = pyinotify.WatchManager()
notifier = pyinotify.Notifier(wm, handler)
wm.add_watch('/home/jo/fichier_to_move_on_ftp/', pyinotify.IN_CLOSE_WRITE)
on_loop_func = functools.partial(on_loop, counter=Counter())

try:
    notifier.loop(daemonize=True, callback=on_loop_func,
                 pid_file='/tmp/pyinotify.pid', stdout='/tmp/stdout.txt')
except pyinotify.NotifierError, err:
    print >> sys.stderr, err

ça vous semble bon comme démarche et comme code ?
Merci !

Dernière modification par Slaan (Le 16/03/2014, à 13:48)

Hors ligne

#9 Le 16/03/2014, à 14:34

k3c

Re : Upload automatique fichier sur serveur FTP

tu ne peux pas faire

for index, nom in SERVERS:

vu que

SERVERS = ['server1', 'server2']

Archlinux sur Xiaomi Air 13

Hors ligne

#10 Le 16/03/2014, à 20:53

Slaan

Re : Upload automatique fichier sur serveur FTP

Ah oui.
ça collera ptet plus avec ça ?

for index, nom in enumerate(SERVERS):

Hors ligne

#11 Le 16/03/2014, à 21:27

Slaan

Re : Upload automatique fichier sur serveur FTP

Super ! ça fonctionne nickel apriori avec :

import sys
import os
from ftplib import FTP
 
SERVERS = ['ftp0.server1.com', 'upload.server2.com']
LOGINS = ['log1', 'log2']
PSWDS = ['secret1', 'secret2']
DATAFILE = sys.argv[1] #le chemin/nom du fichier lorsqu'il est appellé par un autre process 
FILENAME = os.path.basename(DATAFILE) #le nom seul
 
def upload():
    print 'Connection to %s' % SERVERS[index]
    try:
        ftp = FTP(SERVERS[index])
        [url=ftp://ftp.login]ftp.login[/url](LOGINS[index], PSWDS[index])
    except Exception as why:
        print 'login error: {0}'.format(why)
        sys.exit()
 
 
    print 'Read file %s' % DATAFILE
    with open(DATAFILE, "rb") as objf:
        print 'Upload file %s to server' % FILENAME
        try:
            [url=ftp://ftp.storbinary]ftp.storbinary[/url]('STOR ' + FILENAME, objf)
        except Exception as why:
            print 'upload failed: {0}'.format(why)
        else:
            print 'File uploaded, close ftp.'
        [url=ftp://ftp.quit]ftp.quit[/url]()
 
if __name__ == '__main__':
    # on boucle sur les noms de serveur
    for index, nom in enumerate(SERVERS):
        upload()
    os.remove(DATAFILE)

avec pour résultat un très joli et très explicite :

Connection to ftp0.serveur1.com
Read file fichier_to_move_on_ftp/fichier.mp4
Upload file fichier.mp4 to server
File uploaded, close ftp.
Connection to upload.serveur2.com
Read file fichier_to_move_on_ftp/fichier.mp4
Upload file fichier.mp4 to server
File uploaded, close ftp.

Et le fichier n'existe plus en local.
Allez hop, maintenant je m'attaque au daemon.

Sais tu s'il est possible de monitorer le daemon ? Lorsqu'il tourne, il est transparent non ? Y a til un moyen de savoir quand et comment il lance le batch lorsqu'il detecte un fichier avec "watchdir" ?

Dernière modification par Slaan (Le 16/03/2014, à 21:28)

Hors ligne

#12 Le 16/03/2014, à 21:32

k3c

Re : Upload automatique fichier sur serveur FTP

>>>Y a til un moyen de savoir quand et comment il lance le batch lorsqu'il detecte un fichier avec "watchdir"

Non, c'est la manière dont fonctionne inotify (et pyinotify s'appuie sur inotify), quand une mise à jour est effectuée dans le système de fichiers, inotify le sait immédiatement


Archlinux sur Xiaomi Air 13

Hors ligne