#1 Le 12/03/2014, à 21: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 ?
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 12/03/2014, à 23: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
Merci !
Hors ligne
#3 Le 13/03/2014, à 07: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.
Debian 12 sur Thinkpad reconditionné
Hors ligne
#4 Le 13/03/2014, à 18: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
Hors ligne
#5 Le 13/03/2014, à 19: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.
Debian 12 sur Thinkpad reconditionné
Hors ligne
#6 Le 13/03/2014, à 20: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
Dernière modification par Slaan (Le 13/03/2014, à 20:59)
Hors ligne
#7 Le 14/03/2014, à 06: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, à 11:01)
Debian 12 sur Thinkpad reconditionné
Hors ligne
#8 Le 16/03/2014, à 12:40
- Slaan
Re : Upload automatique fichier sur serveur FTP
Yop !
Okay, je vois
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
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, à 12:48)
Hors ligne
#9 Le 16/03/2014, à 13:34
- k3c
Re : Upload automatique fichier sur serveur FTP
tu ne peux pas faire
for index, nom in SERVERS:
vu que
SERVERS = ['server1', 'server2']
Debian 12 sur Thinkpad reconditionné
Hors ligne
#10 Le 16/03/2014, à 19: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, à 20: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, à 20:28)
Hors ligne
#12 Le 16/03/2014, à 20: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
Debian 12 sur Thinkpad reconditionné
Hors ligne