Altre pratiche funzioni agguinte, ed anche un po' di configurazione

Leonardo [2010-06-14 16:34]
Altre pratiche funzioni agguinte, ed anche un po' di configurazione
Filename
mlmanager.py
diff --git a/mlmanager.py b/mlmanager.py
index f4e0102..0e3ed85 100644
--- a/mlmanager.py
+++ b/mlmanager.py
@@ -8,21 +8,62 @@
 #
 # Leonardo Robol <leo@robol.it>

-__author__ = "Leonardo Robol <leo@robol.it>"
+#
+# 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 <mldonkey@%s>" % 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 <leo@robol.it>"
+
+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 "<Download '%s'>" % 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)
ViewGit