CIS: ftp transfer API implemented
authorCalin-Andrei Burloiu <calin.burloiu@gmail.com>
Fri, 25 Nov 2011 16:08:23 +0000 (18:08 +0200)
committerCalin-Andrei Burloiu <calin.burloiu@gmail.com>
Fri, 25 Nov 2011 16:08:23 +0000 (18:08 +0200)
cis/api/api_exceptions.py [moved from cis/cis_exceptions.py with 87% similarity]
cis/api/avhandling.py
cis/api/base.py
cis/api/file_transfer.py [new file with mode: 0644]
cis/api/ftp_config.py [new file with mode: 0644]
cis/cisd.py
cis/config.py

similarity index 87%
rename from cis/cis_exceptions.py
rename to cis/api/api_exceptions.py
index 33c314f..fa03c33 100644 (file)
@@ -16,3 +16,6 @@ class TranscodingException(Exception):
 
 class ThumbExtractionException(Exception):
     pass
+
+class FileTransferException(Exception):
+    pass
index a64f7f2..8d04272 100644 (file)
@@ -7,7 +7,7 @@ videos and thumbnail extraction from videos using FFmpeg CLI program.
 """
 
 import base
-import cis_exceptions
+import api_exceptions
 import subprocess
 import re
 import os
@@ -90,7 +90,7 @@ class FFmpegTranscoder(base.BaseTranscoder):
 
         exit_code = p.wait()
         if exit_code > 0:
-            raise cis_exceptions.TranscodingException( \
+            raise api_exceptions.TranscodingException( \
                     'FFmpeg exited with code ' + str(exit_code) + '.')
 
         log.close()
@@ -131,14 +131,14 @@ class FFmpegThumbExtractor(base.BaseThumbExtractor):
 
         exit_code = p.wait()
         if exit_code > 0:
-            raise cis_exceptions.ThumbExtractionException( \
+            raise api_exceptions.ThumbExtractionException( \
                     'FFmpeg exited with code ' + str(exit_code) + '.')
 
         # FFmpeg bug: when no key frame is found from seek_pos to the
         # end of file an empty image file is created.
         if os.path.getsize(output_file) == 0L:
             os.unlink(output_file)
-            raise cis_exceptions.ThumbExtractionException( \
+            raise api_exceptions.ThumbExtractionException( \
                     'FFmpeg created an empty file.')
 
     def get_video_duration(self):
@@ -163,6 +163,6 @@ class FFmpegThumbExtractor(base.BaseThumbExtractor):
 
         exit_code = p.wait()
         if exit_code > 0:
-            raise cis_exceptions.ThumbExtractionException( \
+            raise api_exceptions.ThumbExtractionException( \
                     'FFmpeg exited with code ' + str(exit_code) + '.')
 
index 8ea2cd3..a57d96d 100644 (file)
@@ -4,7 +4,7 @@
 Base classes for the external programs API.
 """
 
-import cis_exceptions
+import api_exceptions
 import re
 import cis_util
 import random
@@ -131,7 +131,7 @@ class BaseTranscoder:
         """ Translates container API name into external program identifier."""
 
         if not self.containers.has_key(name) or self.containers[name] is None:
-            raise cis_exceptions.NotImplementedException("Container " + name)
+            raise api_exceptions.NotImplementedException("Container " + name)
 
         return self.containers[name]
 
@@ -152,7 +152,7 @@ class BaseTranscoder:
         """ Translates audio codec API name into external program identifier."""
 
         if not self.a_codecs.has_key(name) or self.a_codecs[name] is None:
-            raise cis_exceptions.NotImplementedException("Audio Codec " + name)
+            raise api_exceptions.NotImplementedException("Audio Codec " + name)
 
         return self.a_codecs[name]
 
@@ -160,7 +160,7 @@ class BaseTranscoder:
         """ Translates video codec API name into external program identifier."""
 
         if not self.v_codecs.has_key(name) or self.v_codecs[name] is None:
-            raise cis_exceptions.NotImplementedException("Video Codec " + name)
+            raise api_exceptions.NotImplementedException("Video Codec " + name)
 
         return self.v_codecs[name]
 
@@ -222,7 +222,7 @@ class BaseThumbExtractor:
             thumb_extracted = True
             try:
                 self.extract_thumb(seek_pos, resolution, index)
-            except cis_exceptions.ThumbExtractionException as e:
+            except api_exceptions.ThumbExtractionException as e:
                 thumb_extracted = False
 
             if thumb_extracted:
@@ -243,3 +243,47 @@ class BaseThumbExtractor:
         output_file_name = self.dest_path + self.name \
                 + '_t' + ("%02d" % index) + '.jpg'
         return output_file_name
+
+
+class BaseFileTransferer:
+    """
+    Ensures file transfer from the Web Server to the CIS (here).
+    
+    Several implementations can be done by extending this class for
+    file transfer protocol such as FTP, SCP, RSYNC, HTTP etc.
+    """
+    
+    local_path = ''
+    remote_path = ''
+    
+    def __init__(self, local_path='', remote_path=''):
+        """ Initialize by setting local and remote paths for file transfer. """
+        self.local_path = local_path
+        self.remote_path = remote_path
+
+    def __del__(self):
+        self.close()
+
+    def get(self, files):
+        """
+        Transfers files locally from the Web Server.
+
+        files: a list of file name strings
+        """
+        pass
+
+    def put(self, files):
+        """
+        Transfers files from the Web Server locally.
+
+        files: a list of file name strings
+        """
+        pass
+
+    def close(self):
+        """
+        This method should be called when the instance is no longer required.
+
+        Class's destructor calls this method.
+        """
+        pass
diff --git a/cis/api/file_transfer.py b/cis/api/file_transfer.py
new file mode 100644 (file)
index 0000000..5a6ff01
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+"""
+Classes that facilitate file transfer (between Web Server and CIS).
+
+They may extend BaseFileTransferer class.
+"""
+
+import sys
+from ftplib import FTP_TLS
+import base
+import ftp_config
+import socket
+import api_exceptions
+import os
+
+
+class FTPFileTransferer(base.BaseFileTransferer):
+    """
+    FTPS implementation for file transfering between Web Server and CIS.
+    """
+
+    ftp = None
+
+    def __init__(self, local_path='', remote_path=''):
+        base.BaseFileTransferer.__init__(self, local_path, remote_path)
+
+        self.ftp = FTP_TLS(ftp_config.FTP_HOST, ftp_config.FTP_USER,
+                ftp_config.FTP_PASSWD, ftp_config.FTP_ACCT)
+        self.ftp.set_pasv(True)
+
+    def get(self, files):
+        for crt_file in files:
+            crt_file = os.path.join(self.local_path, crt_file)
+            try:
+                file_local = open(crt_file, 'wb')
+            except IOError as e:
+                raise api_exceptions.FileTransferException( \
+                        "Could not open local file '%s' for writing: %s" \
+                        % (crt_file, repr(e)))
+
+            try:
+                self.ftp.cwd(self.remote_path)
+                self.ftp.retrbinary('RETR %s' % crt_file, file_local.write)
+                file_local.close()
+            except ftplib.error_perm as e:
+                raise api_exceptions.FileTransferException( \
+                        "Could not get file '%s' from Web Server: %s" \
+                        % (crt_file, repr(e)))
+
+    def put(self, files):
+        for crt_file in files:
+            crt_file = os.path.join(self.local_path, crt_file)
+
+            try:
+                file_local = open(crt_file, 'rb')
+            except IOError as e:
+                raise api_exceptions.FileTransferException( \
+                        "Could not open local file '%s' for reading: %s" \
+                        % (crt_file, repr(e)))
+                
+            try:
+                self.ftp.cwd(self.remote_path)
+                self.ftp.storbinary('STOR %s' % crt_file, file_local)
+                file_local.close()
+            except ftplib.error_perm as e:
+                raise api_exceptions.FileTransferException( \
+                        "Could not get file '%s' from Web Server: %s" \
+                        % (crt_file, repr(e)))
+
+    def close(self):
+        if self.ftp is not None:
+            self.ftp.quit()
diff --git a/cis/api/ftp_config.py b/cis/api/ftp_config.py
new file mode 100644 (file)
index 0000000..551cd7d
--- /dev/null
@@ -0,0 +1,8 @@
+"""
+Configuration file for FTPFileTransferer class.
+"""
+
+FTP_HOST = "localhost"
+FTP_USER = "calinburloiu"
+FTP_PASSWD = "Ps1st1h14_"
+FTP_ACCT = ""
index cb22887..84ea512 100755 (executable)
@@ -2,14 +2,17 @@
 
 import sys
 import config
-import cis_exceptions
 
 
 if __name__ == '__main__':
 #    transcoder = config.TRANSCODER_CLASS(sys.argv[1])
 #    transcoder.transcode('webm', "vorbis", "vp8", a_bitrate="128k", a_samplingrate=22050, a_channels=2, v_bitrate="256k", v_framerate=15, v_resolution="320x240", v_dar="4:3")
     
-    thumb_extractor = config.THUMB_EXTRACTOR_CLASS(sys.argv[1])
-    #print thumb_extractor.get_video_duration()
-    #thumb_extractor.extract_random_thumb()
-    print thumb_extractor.extract_summary_thumbs(5)
+#    thumb_extractor = config.THUMB_EXTRACTOR_CLASS(sys.argv[1])
+#    #print thumb_extractor.get_video_duration()
+#    #thumb_extractor.extract_random_thumb()
+#    print thumb_extractor.extract_summary_thumbs(5)
+
+    file_transfer = config.FILE_TRANSFERER_CLASS()
+    file_transfer.get(['vim_config.tar.gz'])
+    file_transfer.close()
index 7b01397..d71d4e3 100644 (file)
@@ -2,12 +2,13 @@
 
 # Make here all necessary imports required for API classes.
 from api import avhandling
+from api import file_transfer
 
 # External programs API classes.
 TRANSCODER_CLASS = avhandling.FFmpegTranscoder
 THUMB_EXTRACTOR_CLASS = avhandling.FFmpegThumbExtractor
 BT_CLIENT_CLASS = None # TODO
-FILE_TRANSFERER_CLASS = None # TODO
+FILE_TRANSFERER_CLASS = file_transfer.FTPFileTransferer
 
 # External programs binary file. None means default.
 TRANSCODER_BIN = None