From d7854fd719fc1a31a0c568e90f704f4738cbae58 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 14 Jun 2010 18:34:21 +0200 Subject: [PATCH] Altre pratiche funzioni agguinte, ed anche un po' di configurazione --- mlmanager.py | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 17 deletions(-) diff --git a/mlmanager.py b/mlmanager.py index f4e0102..0e3ed85 100644 --- a/mlmanager.py +++ b/mlmanager.py @@ -8,21 +8,62 @@ # # Leonardo Robol -__author__ = "Leonardo Robol " +# +# START OF CONFIGURATION SECTION +# + +# The fully qualified (or not fully qualified - it really doesn't matter) +# domain that the server is part of. +local_domain = "robol.it" + +# This is the mail address that will be set as sender for all +# the emails generated by the script. +from_addr = "mldonkey " % local_domain -import os, sys, socket, shutil, subprocess, time +# Mail server that the script will use to deliver emails. It must be properly +# configured to relay mail from the domain selected. +mail_server = "localhost" -# Set file extensions to match. -video_extensions = ['avi', 'mpeg', 'mpg', 'mkv', 'm2v', 'divx', 'xvid'] -audio_extensions = ['mp3,' 'ogg', 'wav', 'flac', 'aac' ] -text_extensions = ['pdf', 'doc', 'odt', 'ods', 'odp', 'ppt', 'rtf', - 'pps', 'xls' , 'txt' ] +# Users that should be notified when an error occurs in the script. You +# can use the wildcard "owner" to match the owner of the file downladed. +# This is generally true for every email function in mlmanager +error_recipients = [ "owner" ] + +# Number of times that rsync should try to transfer the file before +# giving up. +rsync_tries = 5 + +# Set file extensions to match. You can add extensions in every category +video_extensions = ['avi', 'mpeg', 'mpg', 'mkv', 'm2v', 'divx', 'xvid'] +audio_extensions = ['mp3,' 'ogg', 'wav', 'flac', 'aac' ] +text_extensions = ['pdf', 'doc', 'odt', 'ods', 'odp', 'ppt', 'rtf', + 'pps', 'xls' , 'txt' ] cdimage_extensions = [ 'iso', 'nrg' ] +archive_extensions = [ 'rar', 'zip', '7z', 'tar.gz', 'tar.bz2', 'lzo' ] + + +# +# END OF CONFIGURATION +# +# +# START OF CODE +# + +__author__ = "Leonardo Robol " + +import os, sys, socket, shutil, subprocess, time, smtplib +from email.mime.text import MIMEText class FileType(): """ This class represent the type of a file, i.e you can check if it is a video, a text, an image... + It can be: + - video + - audio + - text + - archive + - other """ def __init__(self, filename): @@ -44,6 +85,8 @@ class FileType(): self._type = "text" elif len(filter(self._test_extension, cdimage_extensions)) > 0: self._type = "cdimage" + elif len(filter(self._test_extension, archive_extensions)) > 0: + self._type = "archive" else: self._type = "other" @@ -59,6 +102,9 @@ class FileType(): def is_cdimage(self): return (self._type == "cdimage") + def is_archive(self): + return (self._type == "archive") + def __str__(self): return self._type @@ -101,6 +147,8 @@ class Download(): self._owner = os.getenv("FILE_OWNER") self._incoming = os.getenv("INCOMING") + self._user_email = os.getenv("USER_EMAIL") + # The file is not yet committed. You will need to commit it # before trying to move it. self._committed = False @@ -114,6 +162,7 @@ class Download(): self._type = FileType(self._filename) + def __repr__(self): return "" % self._filename @@ -131,6 +180,7 @@ class Download(): self._committed = True + def send_command(self, command_list): """You can send a command, or a list of command to the daemon. Note that the every call to this @@ -145,7 +195,7 @@ class Download(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("localhost", 4000)) except Exception, e: - raise RuntimeError("Unable to connect to mldonkey daemon: %s" % e) + self.notify_error("Unable to connect to mldonkey daemon: %s" % e) # Costruct the command line command_line = "\n".join(command_list) @@ -177,6 +227,19 @@ class Download(): # Update _dest_path self._dest_path = destination_folder + filename + def copy(self, destination, track = False): + """ + Copy the file to another destination. Destination could be a folder + to move the file in, or a complete path. The script will keep track + only of the original file, i.e. if you call move() it will move the + original file; if this is not what you want, move() the file to the + right location and then copy() it around.""" + + if not self._committed: + self.commit() + shutil.copy(self._dest_path, destination) + + def rsync(self, remote_destination): """Rsync the file to the remote destination. There must be an ssh key in the remote server otherwise nothing will happen. The script will @@ -188,32 +251,69 @@ class Download(): # Initialize internal counter of the times we have tried to move the file self._rsync_counter = 0 s = subprocess.Popen("rsync --partial -az --compress-level=9 \"%s\" \"%s\"" % (self._dest_path, - remote_destination), - shell = True, stderr = subprocess.PIPE, stdout = subprocess.PIPE) + remote_destination), + shell = True, stderr = subprocess.PIPE, stdout = subprocess.PIPE) ret_code = s.wait () - # If we fail call this funtion recursively to retry...wait for 5 seconds and the go (it could + # If we fail call this funtion recursively to retry...wait for 60 seconds and then go (it could # be only a network problem) if ret_code != 0: self._rsync_counter += 1 - if self._rsync_counter < 5: - time.sleep (5) + if self._rsync_counter < rsync_tries: + time.sleep (60) self.rsync(remote_destination) else: self.notify_error("Rsync transfer of file %s failed more than 5 times, aborting" % self._filename) def notify_error(self, message): """Notify error via email""" - pass + self._send_mail (error_recipients, "[mlmanager] An error occurred", + message) - def notify_email(self, recipients, message): + def notify_email(self, recipients, subject, message): """Notify something to some people via email""" - pass + self._send_email (recipients, subject, message) + + def _send_email(self, recipients, subject, message): + """Low level function to send an e-mail.""" + + msg = MIMEText(message) + msg.set_charset ("utf-8") + msg['From'] = from_addr + + # If recipients is a string make it a list + if isinstance(recipients, str): + recipients = [ recipients ] + + # Add user email if requested + if "owner" in recipients: + recipients.remove("owner") + recipients.append(self._user_email) + + msg['To'] = ", ".join(to_addr) + msg['Subject'] = subject + + # Obtain message data + data = msg.as_string () + + # Open a connection to the SMTP server + try: + s = smtplib.SMTP( host = mail_server ) + s.sendmail (from_addr, to_addr, data) + s.quit () + except Exception, e: + raise RuntimeError("Error while notifying you of an error: %s" % e) + + def is_in_group(self, group): + """Return True if file is part of the selected group, + False otherwise""" + return (self._group == group) + def get_type(self): """ Return the type of the selected file, it could be - Video, Audio, Image or Other, if none matches. + video, audio, image, cdimage, archive or other, if none matches. """ return str(self._type) -- 2.1.4