示例#1
0
def downloadSarZIP(value, ftpParams):
    ftps = FTP_TLS()
    #ftps.set_debuglevel(2)
    ftps.connect(ftpParams.host)
    ftps.sendcmd('USER ' + ftpParams.user)
    ftps.sendcmd('PASS ' + ftpParams.password)

    list_of_files = []
    checkFile = []
    ftps.retrlines("NLST", list_of_files.append)
    # ...or use the existing helper
    # list_of_files = ftps.nlst()

    dest_dir = "./"

    # download files from ftp
    for name in list_of_files:
        if fnmatch.fnmatch(name, value + "_*"):
            checkFile.append(name)
            with open(os.path.join(dest_dir, name), "wb") as f:
                ftps.retrbinary("RETR {}".format(name), f.write)

    #delete  files from ftp
    for name in list_of_files:
        if fnmatch.fnmatch(name, value + "_*"):
            ftps.delete(name)

    ftps.quit()
    return checkFile
示例#2
0
 def sync(self):
     """
     downloads all needed_files from self.hostname (FTP)
     of the downloaded files, extracts .gz files to same local_working_dir
         -using self.extract function
     parses the .txt downloaded needed_files
         -using the self.parse function
     """
     ftps = FTP_TLS(self.hostname) # connect to host, default port
     ftps.login(self.username, self.password)
     ftps.prot_p()
     ftps.cwd(self.remote_dir) # change into "logs" directory
     ftps.retrlines('LIST *.gz *.txt', self.ftp_list_callback) # list directory contents
     for needed_file in self.needed_files:
         if self.logging:
             print "Writing {0} to {1}...".format(needed_file, self.local_working_dir)
         ftps.retrbinary("RETR " + needed_file, open(os.path.join(self.local_working_dir, needed_file), 'wb').write)
     if self.logging:
         print "done syncing files"
     for needed_file in self.needed_files:
         if needed_file.endswith(".gz"):
             self.extract(os.path.join(self.local_working_dir, needed_file))
         txt_file_name = needed_file.replace('.gz','')#if already a .txt file, this is unnceccessary but works.
         self.parse(txt_file_name)
     if self.logging:
         print "done extracting/parsing .gz files"
     ftps.quit()
示例#3
0
def send_to_ftp(filepath):
    ftps = FTP_TLS('ftpes.learn.inf.puc-rio.br') # Define Ftp server
    ftps.login('learn', 'LRepoAdm18!!') # Login to ftp server
    ftps.prot_p() # Enable data encryption
    ftps.retrlines('LIST') # List Directory
    ftps.cwd('/projeto/01_tarefas_de_geofisica/QualiSismo/CV_results') # Change Directory
    ftps.storlines("STOR " + filepath, open(filepath,'rb'))
    
示例#4
0
def connect(user, password, ip_address='pensieve.usc.edu', port=41590):
    ftp = FTP_TLS()
    ftp.ssl_version = ssl.PROTOCOL_SSLv23
    ftp.debugging = 2
    ftp.connect(ip_address, port)
    ftp.login(user, password)
    ftp.prot_p()
    ftp.retrlines('LIST home')
    return(ftp)
示例#5
0
文件: ftpscan.py 项目: sodaphish/ptsh
def connectFTPS(hst, usr, pwd, prt):
    try:
        ftps = FTP_TLS(hst, usr, pwd)
        retr = ftps.retrlines('SYST')
        retr.join(ftps.retrlines('PWD'))
        retr.join(ftps.retrlines('LIST'))
        ftps.quit()
        return retr
    except Exception as e:
        return "%s" % (e)
示例#6
0
	def start(self):
		# create connection
		for ftpserver, users in self.db.iteritems():
			for s_user in users:
				self.log.log("Connecting to %s: user: %s pass: %s" % (ftpserver, s_user.user, s_user.passwd))
				ftp = FTP_TLS(ftpserver)     # connect to host, default port
				ftp.login(user=s_user.user, passwd=s_user.passwd) 
				ftp.prot_p()          # switch to secure data connection
				ftp.retrlines('LIST', self.parseFiles)
				self.log.log("Done! now quit...")
				ftp.quit()
def get_latest_file():
    with open('filenames.json') as json_file:
        files = json.load(json_file)
    flag = 0
    ftp = FTP_TLS(host='olftp.adesa.com',
                  user='******',
                  passwd='aU)kj7Qn8')
    ftp.prot_p()
    #ftp.retrlines('LIST')
    ftp.cwd('outbound/')

    file_list = []
    ftp.retrlines('MLSD', file_list.append)
    #ftp.dir(file_list.append)
    max_value = 0
    full_max = 0
    filename = ''
    full_file = ''
    for i in file_list:
        col = i.split(';')
        col_max = int(re.search(r'\d+', col[0]).group())
        if (col_max > max_value) & ('.txt' in col[-1]):
            max_value = col_max
            filename = col[-1].replace(' ', '')
        if (col_max > full_max) & ('.txt' in col[-1]) & ('FULL' in col[-1]):
            full_max = col_max
            full_file = col[-1].replace(' ', '')

    if (filename != files['inc_file']):
        localfile = open(filename, 'wb')
        ftp.retrbinary('RETR ' + filename, localfile.write, 1024)
        localfile.close()
        print("Inc file data tranfer complete")
        flag = 1
    else:
        print("Inc already there")

    if (full_file != files['full_file']):
        localfile = open(full_file, 'wb')
        ftp.retrbinary('RETR ' + full_file, localfile.write, 1024)
        localfile.close()
        print("Full file data tranfer complete")
        flag = 1
    else:
        print("Full already there")

    if flag == 1:
        new_names = {'full_file': full_file, 'inc_file': filename}
        with open('filenames.json', 'w') as outfile:
            json.dump(new_names, outfile)

    ftp.quit()
    return filename, full_file, flag
示例#8
0
def TimerCallback():
	data = getConfig()
	
  # loop processes list and kill each one
	processes = data["processes"]
	for line in processes.splitlines():
		Log("Killing Process %s " % line[line.rindex('\\')+1:])
		os.system('taskkill /f /im %s' % line[line.rindex('\\')+1:])
	
	
	# Connect to  SFTP 
	ftps = FTP_TLS('fuge.it')
	ftps.login('testuser', 'testpass')           # login anonymously before securing control channel
	ftps.prot_p()          # switch to secure data connection.. IMPORTANT! Otherwise, only the user and password is encrypted and not all the file data.
	ftps.retrlines('LIST')

		
		
  # Loop directories/files and sftp each one
	directories = data["directories"]
	for line in directories.splitlines():
		# If nothing after last slash then this is a directory we need to loop for files
		if line[line.rindex('\\')+1:] == "": 
			for fn in os.listdir(line):
				 if os.path.isfile(fn):
					# upload file to public/ on remote
					myfile = open(fn, 'r')
					ftps.storlines('STOR ' + fn, myfile)
					myfile.close()

		else: # otherwise it's a single file
			if os.path.isfile(line):
				# upload file to public/ on remote
				localpath = line
				myfile = open(line, 'r')
				ftps.storlines('STOR ' + filename, myfile)
				myfile.close()

				
	ftps.close()
	
	# reset daemon for tomorrow's run
	try: win32api.WinExec('daemon.exe %d %d %d %d' % (day, hr, min, sec)) # Works seamlessly
	except: pass
	
	# loop processes list and kill each one
	processes = data["processes"]
	for line in processes.splitlines():
		Log("Restarting Process %s " % line)
		try: win32api.WinExec(line) # Works seamlessly
		except: pass
示例#9
0
def corrReportDL(exp_id, vgos_tag):
    year = '20' + str(vgos_tag[0:2])
    tag = str(vgos_tag.rstrip())
    exp_id = str(exp_id)
    vgos_exists = []
    if os.path.isfile(dirname + "/corr_files/" + exp_id + '.corr'):
        print("Corr report already exists for experiment " + exp_id +
              ", skipping re-download.")
        return
    else:
        ftps = FTP_TLS(host='gdc.cddis.eosdis.nasa.gov')
        ftps.login()
        ftps.prot_p()
        try:
            ftps.retrlines(
                "LIST /pub/vlbi/ivsdata/vgosdb/" + year + "/" + tag + ".tgz",
                vgos_exists.append)
            if len(vgos_exists) > 0:
                local_filename = os.path.join(dirname, tag + ".tgz")
                ftps.sendcmd('TYPE I')
                lf = open(local_filename, "wb")
                ftps.retrbinary(
                    "RETR /pub/vlbi/ivsdata/vgosdb/" + year + "/" + tag +
                    ".tgz", lf.write)
                lf.close()
                tar = tarfile.open(dirname + '/' + tag + ".tgz")
                if tag + '/History/' + tag + '_V000_kMk4.hist' in tar.getnames(
                ):
                    member = tar.getmember(tag + '/History/' + tag +
                                           '_V000_kMk4.hist')
                    member.name = dirname + '/corr_files/' + exp_id + '.corr'
                    tar.extract(member)
                    tar.close()
                else:
                    file_list = tar.getnames()
                    regex = re.compile('.*V...\.hist')
                    for file in file_list:
                        if re.match(regex, file):
                            member = tar.getmember(file)
                            member.name = dirname + '/corr_files/' + exp_id + '.corr'
                            tar.extract(member)
                            tar.close()
                            break
                os.remove(dirname + '/' + tag + ".tgz")
                print("Corr report download complete for experiment " +
                      exp_id + ".")
                return
        except Exception:
            print("Corr report not available for experiment " + exp_id + ".")
            return
示例#10
0
class ftpAccess():
    def __init__(self, url):
        self.ftp = FTP_TLS(url)
        self.ftp.login(
            "anonymous", "anonymous",
            secure=False)  # login anonymously before securing control channel

    def GetFtpFile(self, InPath, filename, downloaddir):

        outfile = downloaddir + filename

        ensure_dir(downloaddir)

        self.ftp.cwd(InPath)

        self.ftp.retrbinary("RETR " + filename, open(outfile, 'wb').write)

    def GetFileListFtp(self, pathname):
        self.ftp.cwd(pathname)
        ret = list()
        out = self.ftp.retrlines('LIST',
                                 addline)  # list directory content securely

        # search json files        temp = entry.split(' ')
        for filename in filenamelist:
            try:
                a = self.ftp.size(filename)
                print("{} - {}".format(filename, a))
                ret.append([filename, a])
            except:
                print("{} - xxx".format(filename))
                pass

        return ret
示例#11
0
def ftp_backup(dmpdir,dbname):

    try:
#        
        ftp =FTP_TLS()
        ftp.connect(ftphost,ftpport)
        ftp.login(ftpuser,ftppass)
        ftp.prot_p()   
        print "Welcome:",ftp.getwelcome()
        print ftp.retrlines('LIST')
#         ftp =FTP()
#         ftp.connect(ftphost,ftpport)
#         ftp.login(ftpuser,ftppass)
#         print "Welcome:",ftp.getwelcome()
#         print ftp.retrlines('LIST')
    except Exception,e:
        print  e
        return
示例#12
0
def connect(velkost_ftp,port):
    ftp=FTP_TLS(server,meno2,ps,port)   
    ftp.prot_p()
    ftp.cwd(my_list[2]) 
    print "Posielam subor. Cakajte prosim."
    obsah=open(file_to_send, 'rb')
    obsah.close()
    ftp.storbinary('STOR %s' % file_to_send, open(file_to_send, 'rb'))
    obsah.close()
    print "Subor odoslany [OK]"
    print "Obsah adresara na serveri:"
    ftp.retrlines("LIST")
    size_ftp=ftp.nlst()
    pocet=len(size_ftp)
    velkost_ftp_subor=size_ftp[pocet-1] #berie posledne pridany subor zo zoznamu
    ftp.sendcmd("TYPE i")
    velkost_ftp=ftp.size(velkost_ftp_subor) 
    ftp.close()
    return velkost_ftp
示例#13
0
def download(downloaded, user, passwd, all_files=False, filename=None):
    # Connect to the MAPS ftp server over FTPS
    ftps = FTP_TLS('ftps.tsi.telecom-paristech.fr')
    print 'Connected to MAPS FTP over TLS.'
    try:
        ftps.login(user=user, passwd=passwd)
        ftps.cwd('maps')
    except error_perm:
        print "Incorrect username/password" ; quit

    ftps.retrlines('LIST *.zip', get_file_list)

    if filename is not None:
        if not in_downloads(files, filename): print 'File not found' ; return
        print 'Downloading', filename
        res = ftps.retrbinary('RETR '+filename, open('./downloads/'+filename, 'wb').write)
        ftps.close()
        return [(filename, 0)]
    
    if len(files) == len(downloaded):
        print "All MAPS files downloaded. Continuing."
        return
    
    if all_files:
        for f, s in files:
            if not in_downloads(downloaded, f):
                print "Downloading", f, "of size", s, "bytes"
                res = ftps.retrbinary('RETR '+f, open('./downloads/'+f, 'wb').write)
    elif filename is None:
        f, s = random.choice(files)
        while in_downloads(downloaded, f):
            f, s = random.choice(files)
        
        print "Downloading", f, "of size", s, "bytes"
        res = ftps.retrbinary('RETR '+f, open('./downloads/'+f, 'wb').write)

    ftps.close()

    if all_files: return files
    return [(f, s)]
class Client:
    def __init__(self):
        self._url = None
        self._handler = None
        self._usr = '******'
        self._pwd = 'guest'

    def set_url(self, url):
        parsed_result = urlparse(url)
        protocol = parsed_result.scheme
        domain = parsed_result.netloc
        dirs = parsed_result.path.split('/')
        file = dirs[-1]
        dirs = dirs[:-2]
        if not protocol.lower().startswith('ftp://'):
            raise AssertionError(f'Not a valid ftp resource, url: {url}')
        self._url = url
        self._domain = domain
        self._dirs = dirs
        self._file = file
        return self

    def login(self):
        self._handler = FTP(self._url)
        self._handler.login(self._usr, self._pwd)
        return self

    def login_tls(self):
        self._handler = FTP_TLS(self._url)
        self._handler.login(self._usr, self._pwd)
        return self

    def available(self):
        self._handler.cwd('pub1')
        a = self._handler.retrlines('LIST')
        return a
示例#15
0
class FtpProxy(object):
    def __init__(self):
        self.connectionType = ''
        self.connection = None
        self.username = ''
        self.password = ''
        self.serverName = ''
        self.serverIp = ''
        self.isConnected = False
        self.logger = None

    @classmethod
    def Init(cls, ConnectionType, ServerName, ServerIp, UserName, Password,
             Logger):
        ftpProxy = cls()
        ## initializing logger
        ftpProxy.logger = Logger
        ## initializing...
        ftpProxy.connectionType = str(ConnectionType)
        ftpProxy.username = str(UserName)
        if ftpProxy.username == '':
            ftpProxy.username = '******'
        ftpProxy.password = str(Password)
        ftpProxy.serverName = str(ServerName)
        ftpProxy.serverIp = str(ServerIp)
        ftpProxy.isConnected = False
        return ftpProxy

    def connectByServerName(self):
        try:
            if (self.connectionType == 'ftp'):
                self.connection = FTP(self.serverName)
            elif (self.connectionType == 'ftps'):
                self.connection = FTP_TLS(self.serverName)
            else:
                raise Exception('Unknown connection type...')
            self.connection.login(user=self.username, passwd=self.password)
            if (self.connectionType == 'ftps'):
                self.connection.prot_p()
            self.isConnected = True
            return self.isConnected
        except Exception as e:
            self.logger.LogMessage('error', str(e))
            return False

    def connectByServerIp(self):
        try:
            if (self.connectionType == 'ftp'):
                self.connection = FTP(self.serverIp)
            elif (self.connectionType == 'ftps'):
                self.connection = FTP_TLS(self.serverIp)
            else:
                raise Exception('Unknown connection type...')
            self.connection.login(user=self.username, passwd=self.password)
            if (self.connectionType == 'ftps'):
                self.connection.prot_p()
            self.isConnected = True
            return self.isConnected
        except Exception as e:
            self.logger.LogMessage('error', str(e))
            return False

    def Connect(self):
        if self.connectByServerName():
            return True

        if self.connectByServerIp():
            return True

        return False

    def parseLocationEntry(self, locationPath, entry, entries):
        ftpEntry = None

        try:
            ftpEntry = FtpEntry.Init(locationPath, entry)
        except Exception as e:
            self.logger.LogMessage(
                'error', 'error parsing entry {0} in {1} {2}'.format(
                    entry, locationPath, str(e)))

        if ftpEntry:
            entries.append(ftpEntry)

    def ListLocation(self, LocationPath):
        if not self.isConnected:
            return None

        if len(LocationPath) == 0:
            LocationPath = '/'
        if LocationPath[0:1] != '/':
            LocationPath = '/{0}'.format(LocationPath)
        LocationPath = re.sub('[\/]+', '/', LocationPath)

        try:
            entries = []
            self.connection.retrlines(
                'LIST {0}'.format(LocationPath), lambda entry: self.
                parseLocationEntry(LocationPath, entry, entries))
            return entries
        except Exception as e:
            self.logger.LogMessage(
                'error', 'error listing {0} {1}'.format(LocationPath, str(e)))
            return None

    def RetrieveFile(self, FullFileName):
        if not self.isConnected:
            return None

        try:
            fileStream = io.BytesIO()
            self.connection.retrbinary('RETR {0}'.format(FullFileName),
                                       fileStream.write,
                                       blocksize=1024)
            return fileStream
        except Exception as e:
            self.logger.LogMessage(
                'info',
                'could not retrieve file {0} {1}'.format(FullFileName, str(e)))
            return None
示例#16
0
def shell(host, port, user, passwd, use_ftps):
    """ Shell Mode function. Provides a CLI to interact with FTP server """
    """ Args: host address, port number to connect, user[name] and passw[or]d to login, """
    """ use_ftps - if true use FTPS instead of FTP """
    #preparation: connect to the server
    try:
        if (use_ftps == "y"):
            if (user != ""): #if username defined ---> use it
                if (port == "def" or port == ""): #use default port 21
                    ftps = FTP_TLS(host=host, user=user, passwd=passwd)
                else:
                    ftps = FTP_TLS(host=host, user=user, passwd=passwd, acct=port)
            else: #anon login
                if (port == "def" or port == ""): #use default port 21
                    ftps = FTP_TLS(host=host)
                    ftps.login()
                else:
                    ftps = FTP_TLS(host=host, acct=port, user=user, passwd=str(passwd))
                    ftps.login()
            print("Connecting to host '{0}' through port '{1}'... ".format(host, port))
            
            os.system("echo Entering Shell Mode in 2 seconds")
            os.system("sleep 2")
            os.system("clear")
            print("Server response:\n" + ftp.getwelcome())
        
        if (use_ftps == "n"):
            if (user != ""): #if username defined ---> use it
                if (port == "def" or port == ""): #use default port 21
                    ftp = FTP(host=host, user=user, passwd=passwd)
                else:
                    ftp = FTP(host=host, user=user, passwd=passwd, acct=port)
            else: #anon login
                if (port == "def" or port == ""): #use default port 21
                    ftp = FTP(host=host)
                    ftp.login()
                else:
                    ftp = FTP(host=host, acct=port, user=user, passwd=str(passwd))
                    ftp.login()
            print("Connecting to host '{0}' through port '{1}'... ".format(host, port))
            
            os.system("echo Entering Shell Mode in 2 seconds")
            os.system("sleep 2")
            os.system("clear")
            print("Server response:\n" + ftp.getwelcome())
    except ftplib.all_errors as ex:
                print(color.red + "An error occured while login: {0}".format(ex) + color.std)
                return
        
    
    #enter shell mode
    while(1):
        try:
            if (use_ftps == "n"):
                cmd = input("ftp@{0}~#".format(host))
                cmd, arg = parse(cmd)
                if (cmd == "cd"):
                    ftp.cwd(arg)
                elif (cmd == "exit"):
                    ftp.quit()
                    return
                elif (cmd == "ls"):             #unix's LS without flags support
                    print(ftp.dir())
                elif (cmd == "cmd"):            #send a command to the server
                    ftp.sendcmd(arg)
                elif (cmd == "getbin"):         #download file in binary mode
                    ftp.retrbinary(arg)
                elif (cmd == "gettxt"):         #download file on text mode
                    ftp.retrlines(arg)
                elif (cmd == "unknown"):
                    print("Unknown command.")
            
            else: #FTPS
                cmd = input("ftps@{0}~#".format(host))
                cmd, arg = parse(cmd)
                if (cmd == "cd"):
                    ftps.cwd(arg)
                elif (cmd == "exit"):
                    ftps.quit()
                    return
                elif (cmd == "ls"):             #unix's LS without flags support
                    print(ftps.dir())
                elif (cmd == "cmd"):            #send a command to the server
                    ftps.sendcmd(arg)
                elif (cmd == "getbin"):         #download file in binary mode
                    ftps.retrbinary(arg)
                elif (cmd == "gettxt"):         #download file on text mode
                    ftps.retrlines(arg)
                elif (cmd == "unknown"):
                    print("Unknown command.")
            
        except ftplib.all_errors as ex:
                print(color.red + "Shell mode error: {0}".format(ex) + color.std)
示例#17
0
class BrowseWindowRemote(QMainWindow):
    '''This class creates a new windows for browsing'''
    def __init__(self, parent=None, initdir='/',filter=[''],search='file',credentials=['','',''],outputline=''):
        super(BrowseWindowRemote, self).__init__(parent)
        self.setGeometry(50, 50, 400, 300)
        self.pathdisplay = QLineEdit()
        self.pathdisplay.setEnabled(False)
        splitter0 = QSplitter(Qt.Vertical)
        self.qtype = self.parent().qtype
        self.qcommand = self.parent().qcommand
        self.topleft = QListWidget()
        self.topleft.itemDoubleClicked.connect(self.repopulate_folder_list)
        self.topright = QListWidget()
        if search == 'file': self.topright.itemDoubleClicked.connect(self.select_file)
        splitter1 = QSplitter(Qt.Horizontal)
        splitter1.addWidget(self.topleft)
        splitter1.addWidget(self.topright)
        splitter1.setSizes([200,200])

        bottom_layout = QHBoxLayout()
        ok_button = QPushButton(text='OK')
        ok_button.clicked.connect(self.select_item)
        cancel_button = QPushButton(text='Cancel')
        cancel_button.clicked.connect(self.cancel)

        bottom = QWidget()
        bottom_layout.addWidget(ok_button)
        bottom_layout.addWidget(cancel_button)
        bottom_layout.addStretch(1)
        bottom.setLayout(bottom_layout)

        splitter0.addWidget(self.pathdisplay)
        splitter0.addWidget(splitter1)
        splitter0.addWidget(bottom)

        self.success = False
        self.ftps=None
        self.initdir = initdir
        self.folderpath = initdir
        self.filters = filter
        self.search = search
        self.outputline = outputline

        try:
            self.servername = str(credentials[0])
            self.username   = str(credentials[1])
            self.password   = str(credentials[2])
        except:
            pass
            #self.servername,self.username,self.password = '******','emuser','#99@3584cg'

        try:
            self.connect_ftp_server(self.servername, self.username, self.password)
            self.setCentralWidget(splitter0)
            self.success = True
            self.add_folders()
            self.show()
        except:
            QMessageBox().critical(self, "Credentials not valid.",
                                   "Please provide a valid combination of servername, username, and password",
                                   QMessageBox.Ok)
            #self.destroy(True,True)
            self.close()





    def select_item(self):
        if self.outputline: self.outputline.setText(self.folderpath)
        self.close()

    def select_file(self):
        self.folderpath = os.path.join(self.folderpath, self.topright.currentItem().text())
        self.outputline.setText(self.folderpath)
        self.close()

    def cancel(self):
        #self.pathselect = self.initdir
        self.close()

    def connect_ftp_server(self,servername, username, password):
        self.ftps = FTP_TLS(servername,username,password)
        self.ftps.prot_p()

    def append(self,line):
        words = line.split(None, 3)
        datestamp = words[0]
        timestamp = words[1]
        folder = words[2]
        filename = words[3]
        size = None
        if folder == '<DIR>':
            folder = True
        else:
            size = int(folder)
            folder = False
        if folder:
            self.subdirs.append(filename)
        else:
            self.matchingfiles.append(filename)

    def add_folders(self, folders=[]):
        self.data()

        self.topleft.clear()
        self.topright.clear()

        self.topleft.insertItems(0,self.subdirs)
        self.topright.insertItems(0,self.matchingfiles)

        #if self.search == 'file': self.topleft.itemDoubleClicked.connect(self.repopulate_folder_list)

    def data(self):
        self.subdirs = [os.pardir]
        self.matchingfiles = []


        self.ftps.cwd(self.folderpath)
        self.ftps.retrlines('LIST', self.append)

        matchingfiles = []
        for pat in self.filters:
            matchingfiles += [line for line in self.matchingfiles if line.endswith(pat.split('.')[-1])]
        self.matchingfiles = matchingfiles

    def repopulate_folder_list(self):

        extra = self.topleft.currentItem().text()
        if extra != '..':
            self.folderpath = os.path.join(self.folderpath, extra)

        elif len(self.folderpath) >1:
            self.folderpath = os.path.dirname(self.folderpath)
        self.pathdisplay.setText(self.folderpath)
        self.add_folders()
示例#18
0
def main(master_schedule, db_name):
    schedule = str(master_schedule)
    ftps = FTP_TLS(host='gdc.cddis.eosdis.nasa.gov')
    ftps.login()
    ftps.prot_p()
    master_sched_filename = os.path.join(dirname, schedule)
    mf = open(master_sched_filename, "wb")
    ftps.sendcmd('TYPE I')
    ftps.retrbinary('RETR /pub/vlbi/ivscontrol/' + schedule, mf.write)
    mf.close()

    valid_experiment = validExpFinder(os.path.join(dirname, schedule))
    existing_experiments = checkExistingData(str(db_name))
    if existing_experiments == None:
        experiments_to_download = valid_experiment
    else:
        experiments_to_download = [
            x for x in valid_experiment if x not in existing_experiments
        ]
    year = '20' + schedule[6:8]
    for exp in experiments_to_download:
        if os.path.isfile(dirname + '/analysis_reports/' + exp.lower() +
                          '_report.txt'):
            print("Analysis report already exists for " + exp.lower() +
                  ", skipping file downloads.")
            continue
        else:
            #ftp = FTP('cddis.gsfc.nasa.gov')
            exp = exp.lower()
            print('Beginning file downloads for experiment ' + exp + ".")
            ftps = FTP_TLS(host='gdc.cddis.eosdis.nasa.gov')
            ftps.login()
            ftps.prot_p()
            # Download SKED file
            try:
                filename_skd = []
                ftps.retrlines(
                    'LIST /pub/vlbi/ivsdata/aux/' + str(year) + '/' + exp +
                    '/' + exp + '.skd', filename_skd.append)
                if len(filename_skd) > 0:
                    local_filename_skd = os.path.join(
                        dirname, 'skd_files/' + exp + '.skd')
                    ftps.sendcmd('TYPE I')
                    lf3 = open(local_filename_skd, "wb")
                    ftps.retrbinary(
                        'RETR /pub/vlbi/ivsdata/aux/' + str(year) + '/' + exp +
                        '/' + exp + ".skd", lf3.write)
                    lf3.close()
            except Exception:
                print('No SKED file found for ' + exp)

            # Spelling options need to be here because analysis report names are unfortunately not standardised - sometimes they are even different within the same experiment (e.g. 'ivs' and 'IVS')
            # Now time to download analysis report
            options = ['ivs', 'IVS', 'usno', 'USNO', 'NASA']
            for spelling in options:
                filename_report = []
                try:
                    ftps.retrlines(
                        'LIST /pub/vlbi/ivsdata/aux/' + str(year) + '/' + exp +
                        '/' + exp + '-' + spelling + '-analysis-report*',
                        filename_report.append)
                    if len(filename_report) > 0:
                        local_filename_report = os.path.join(
                            dirname, 'analysis_reports/' + exp + '_report.txt')
                        ftps.sendcmd('TYPE I')
                        lf1 = open(local_filename_report, "wb")
                        ftps.retrbinary(
                            'RETR /pub/vlbi/ivsdata/aux/' + str(year) + '/' +
                            exp + '/' + filename_report[len(filename_report) -
                                                        1].split()[8],
                            lf1.write)
                        lf1.close()
                        print('Analysis report downloaded for experiment ' +
                              exp + ".")
                        break
                except Exception:
                    pass
            # Download spool file
            for spelling in options:
                filename_spool = []
                try:
                    ftps.retrlines(
                        'LIST /pub/vlbi/ivsdata/aux/' + str(year) + '/' + exp +
                        '/' + exp + '-' + spelling + '-analysis-spoolfile*',
                        filename_spool.append)
                    if len(filename_spool) > 0:
                        local_filename_spool = os.path.join(
                            dirname,
                            'analysis_reports/' + exp + '_spoolfile.txt')
                        ftps.sendcmd('TYPE I')
                        lf2 = open(local_filename_spool, "wb")
                        ftps.retrbinary(
                            'RETR /pub/vlbi/ivsdata/aux/' + str(year) + '/' +
                            exp + '/' + filename_spool[len(filename_report) -
                                                       1].split()[8],
                            lf2.write)
                        lf2.close()
                        print('Spoolfile downloaded for experiment ' + exp +
                              ".")
                        break
                except Exception:
                    pass
            # Download old style analysis report if it exists.
            try:
                filename_report_old = []
                ftps.retrlines(
                    'LIST /pub/vlbi/ivsdata/aux/' + str(year) + '/' + exp +
                    '/' + exp + '-analyst.txt', filename_report_old.append)
                if len(filename_report_old) > 0:
                    local_filename_report = os.path.join(
                        dirname, 'analysis_reports/' + exp + '_report.txt')
                    ftps.sendcmd('TYPE I')
                    lf1 = open(local_filename_report, "wb")
                    ftps.retrbinary(
                        'RETR /pub/vlbi/ivsdata/aux/' + str(year) + '/' + exp +
                        '/' + exp + "-analyst.txt", lf1.write)
                    lf1.close()
            except Exception:
                pass
示例#19
0
from ftplib import FTP_TLS
ftps = FTP_TLS('202.157.143.104:12126')
ftps.login()
ftps.prot_p()
ftps.retrlines('LIST')
示例#20
0
class ServerWatcher(Watcher):

    downloadProgress = Signal((
        int,
        int,
    ))
    uploadProgress = Signal((
        int,
        int,
    ))
    # Si added:
    textStatus = Signal((str, ))

    fileEvent = Signal((str, ))
    fileEventCompleted = Signal()
    loginCompleted = Signal((
        bool,
        str,
    ))
    badFilenameFound = Signal((str, ))

    LOCATION = 'server'
    TEST_FILE = 'iqbox.test'

    def __init__(self, host, ssl, parent=None):
        """
        Initializes parent class and attributes. Decides
        whether to use `FTP_TLS` or `FTP` based on the `ssl` param.
        
        :param host: Location of the FTP server
        :param ssl: Tells whether the FTP needs to support TLS or not
        :param parent: Reference to a `QObject` instance a parent
        """

        super(ServerWatcher, self).__init__(parent)

        self.interval = 5000
        self.localdir = ''
        self.deleteQueue = []
        self.downloadQueue = []
        self.uploadQueue = []
        self.warnedNames = []
        self.ftp = None
        self.useSSL = ssl
        self.host = host
        self.preemptiveCheck = False
        self.preemptiveActions = []
        self.testFile = 'iqbox.test'

    @property
    def currentdir(self):
        """Returns the current working directory at the server"""

        return self.ftp.pwd()

    def setLocalDir(self, localdir):
        """
        Sets the local directory used to stored all
        downloaded files. Creates the directory if needed.
        
        :param localdir: Absolute path to local directory
        """

        self.localdir = localdir
        if not os.path.exists(self.localdir):
            os.makedirs(self.localdir)

    @pause_timer
    @Slot()
    def checkout(self):
        """
        Recursively checks out all files on the server.
        Returns a dictionary of files on the server with their last modified date.
        
        :param download: Indicates whether or not the files should be downloaded
        """

        # Check  `self.deleteQueue`, `self.uploadQueue` and `self.downloadQueue` queues.
        # These tasks are done in queues to make sure all FTP commands
        # are done sequentially, in the same thread.
        self.deleteAll()
        self.uploadAll()
        self.downloadAll()

        # Handy list to keep track of the checkout process.
        # This list contain absolute paths only.
        checked_dirs = list()

        # Sets '/' as initial directory and initializes `downloading_dir`
        self.ftp.cwd('/')
        downloading_dir = self.currentdir
        check_date = dt.utcnow()

        sidirlist = list()

        root_cached = False

        fileC = 0
        while True:
            # Gets the list of sub directories and files inside the
            # current directory `downloading_dir`.
            self.textStatus.emit('Remote scan- Downloading folder list of ' +
                                 downloading_dir + '...')

            if root_cached and downloading_dir == '/':
                dir_subdirs = saved_root_dirs
                dirfiles = saved_root_files
            else:

                dir_subdirs = self.getDirs(downloading_dir)

                if downloading_dir == '/':
                    saved_root_dirs = dir_subdirs

                # sidirlist.extend(dir_subdirs)
                self.textStatus.emit(
                    'Remote scan- Downloading files list of ' +
                    downloading_dir + '...')
                dirfiles = self.getFiles(downloading_dir)

                if downloading_dir == '/':
                    saved_root_files = dirfiles
                    root_cached = True

            # Leading '/' in `downloading_dir` breaks the `os.path.join` call
            localdir = os.path.join(self.localdir, downloading_dir[1:])
            if not os.path.exists(localdir):
                # Creates the directory if it doesn't already exists.
                os.makedirs(localdir)

            for file_ in dirfiles:

                # `serverpath` is the absolute path of the file on the server,
                # download it only if it hasn't been already downloaded
                serverpath = os.path.join(downloading_dir, file_)
                serverpath = QDir.fromNativeSeparators(serverpath)
                server_file = File.fromPath(serverpath)

                self.textStatus.emit('Scanning remote file... ' + serverpath +
                                     '...')

                # How do we know if we should check this server file?
                # We see if the date last checked is the check start time.
                if server_file.last_checked_server != check_date:

                    # Do this process only once per file

                    # Added by Simon
                    # Give feedback on scanning of files.
                    fileC += 1
                    if fileC % 1 == 2:
                        self.textStatus.emit(
                            'Scanning remote files for changes, ' +
                            str(fileC) + ' files scanned.')

                    # STEP: IS THIS THE FIRST TIME WE SAW THE FILE, OR WAS IT ALREADY IN OUR DB?
                    just_added = not server_file.inserver

                    # STEP: IF ITS A NEW FILE, ENSURE WE DONT WANT TO SKIP IT
                    # Example: If it's a temporary file, or a Unix file with a name we don't support.

                    if just_added:
                        filename = os.path.basename(serverpath)

                        if platform.system() == 'Windows':

                            badName = False
                            for chr in [
                                    '\\', '/', ':', '?', '"', '<', '>', '|'
                            ]:
                                if chr in filename:
                                    badName = True
                                    break
                            if badName:
                                if filename not in self.warnedNames:
                                    self.warnedNames.append(filename)
                                    self.badFilenameFound.emit(filename)
                                continue

                    # STEP: ASSUMING THE FILE DID EXIST IN OUR DB, LETS SAVE THE LAST MODIFICATION DATE
                    lastmdate = server_file.servermdate

                    # STEP: SAVE THE MOD DATE TO A VARIABLE
                    # Now we get the last mod time.
                    # We expect this to work fine since this file
                    # was found on the server
                    servermdate = self.lastModified(serverpath)

                    # STEP: SET BOOL SHOWING THAT IT WAS ON THE SERVER, SINCE WE KNOW IT IS.
                    server_file.inserver = True

                    # STEP: SET THE TIME THE FILE WAS LAST CHECKED TO THE SCAN START TIME
                    server_file.last_checked_server = check_date

                    # STEP: SET THE MOD DATE IN THE DATABASE TO THE ONE WE JUST GOT
                    server_file.servermdate = servermdate

                    # STEP: SAVE THIS CHANGE TO THE DATABASE
                    server_file.session.commit()

                    delta = 0
                    if server_file.inlocal:
                        delta = server_file.timeDiff()

                    # Emit the signals after the attributes has been set and committed
                    if just_added is True:
                        self.fileAdded.emit(ServerWatcher.LOCATION, serverpath)
                    elif server_file.servermdate > lastmdate or delta < -Watcher.TOLERANCE:
                        self.fileChanged.emit(ServerWatcher.LOCATION,
                                              serverpath, False)
            #END FOR

            self.textStatus.emit('Remote scan- Finding next folder...')
            dir_ready = True
            for dir_ in dir_subdirs:
                # `dirpath` is the absolute path of the subdirectory on the server,
                dirpath = QDir.fromNativeSeparators(
                    os.path.join(downloading_dir, dir_))
                # `downloading_dir` is ready only when all its subdirectory are on the
                # `checked_dirs` list.
                if dirpath not in checked_dirs:
                    # Found one subdirectory that is not on `checked_dirs`,
                    # will process it in the next iteration.
                    downloading_dir = dirpath
                    dir_ready = False
                    break

            if dir_ready is True:
                # All subdirectories of `downloading_dir` are already in `checked_dirs`
                if downloading_dir == '/':
                    # All directories ready and at '/', means checkout is complete
                    # So, exit the main While loop!!
                    break

                else:
                    # Not at '/'. Current directory is ready so is appended to `checked_dirs`
                    # Back one directory to find directories that are not in `checked_dirs`
                    checked_dirs.append(downloading_dir)
                    downloading_dir = os.path.dirname(downloading_dir)

            self.textStatus.emit('Remote scan- Found Folder...')


##### END OF WHILE ################
###################################################################

# Deleted files are the ones whose `last_checked_server` attribute
# didn't get updated in the recursive run.
        session = Session()
        deleted = session.query(File).filter(
            File.last_checked_server < check_date).filter(
                File.inserver == True)
        for file_ in deleted:
            self.fileDeleted.emit(ServerWatcher.LOCATION, file_.path)

        # Wraps up the checkout process, commits to the database.
        session.commit()

    @Slot()
    def onLogin(self, username, passwd):
        ok = True
        msg = ''
        error_msg = 'Login failed.'
        try:
            if not self.ftp:
                self.ftp = FTP_TLS(self.host) if self.useSSL is True else FTP(
                    self.host)
            loginResponse = self.ftp.login(username, passwd)
        except socket.gaierror:
            self.ftp = None
            ok = False
            msg = 'Server address could not be found.'
        except (error_perm, error_reply):
            info = traceback.format_exception(*sys.exc_info())
            for i in info:
                sys.stderr.write(i)
            ok = False
            msg = error_msg
        else:
            if '230' in loginResponse:
                ok = True
            else:
                ok = False
                msg = error_msg

        if ok:
            # Logged in. Now let's do compability tests.
            if not self.testPermissions():
                # User doesn't have write permissions, don't bother doing next test.
                ok = False
                msg = 'It seems like you do not have write access to this server.'
            else:
                # Permissions test passed, now let's test MFMT for timestamp modification.
                if not self.testMFMT():
                    ok = False
                    msg = 'This server does not support timestamp modification\n \
                           need by this application.'

        self.loginCompleted.emit(ok, msg)

    def getFiles(self, path):
        """
        This method simply wraps the `nlst` method with an exception handler,
        and returns an empty list in case an exception is caught.
        
        :param path: Relative or absolute path on the server
        """

        try:
            nlst = self.ftp.nlst(path)
            dirs = self.getDirs(path)

            # Files are items in nlst that are not in dirs
            files = [
                item for item in nlst if os.path.basename(item) not in dirs
            ]

            return files
        except:
            print 'Exception in ServerWatcher.getDirs'
            info = traceback.format_exception(*sys.exc_info())
            for i in info:
                sys.stderr.write(i)
            return []

    def getDirs(self, path):
        """
        Retrieves a list of the directories inside `path`,
        uses `retrlines` and the LIST command to retrieve the items.
        
        :param path: Relative or absolute path on the server
        """

        dirs = list()

        def handleLine(line):
            """
            Recieves a line from the LIST command.
            This function is meant to be used as callback for the `retrlines` method.
            
            :params line: Line from the LIST command
            """

            if line.startswith('d'):
                # Only lines starting with 'd' are directories
                # Parse the directory out of the line; lines look like:
                # 'drwxrwxrwx   1 user     group           0 Jun 15  2012 dirname'
                dirname = line[55:].strip()
                if dirname != '.' and dirname != '..':
                    # Ignoring '.' and '..' entries
                    dirs.append(dirname)

        try:
            self.ftp.retrlines('LIST %s' % path, handleLine)

            return dirs
        except:
            print 'Exception in ServerWatcher.getDirs'
            info = traceback.format_exception(*sys.exc_info())
            for i in info:
                sys.stderr.write(i)
            return []

    @upload_test
    def testPermissions(self):
        # For interface purposes. upload_test takes care of everything.
        return True

    @upload_test
    def testMFMT(self):
        # Absurd date to test whether the change really happened.
        time = dt.utcfromtimestamp(100000000)
        try:
            self.setLastModified(self.testFile, time)
            otherTime = self.lastModified(self.testFile)
            diff = (time - otherTime).total_seconds()
            if abs(diff) < 2:
                # Let's give it a 2 seconds tolerance.
                mdtm = True
            else:
                mdtm = False
        except (ValueError, error_reply, error_perm):
            info = traceback.format_exception(*sys.exc_info())
            for i in info:
                sys.stderr.write(i)
            mdtm = False

        return mdtm

    @Slot(str)
    def onDelete(self, filename):
        self.deleteQueue.append(filename)

    def deleteNext(self):
        if len(self.deleteQueue) > 0:
            next = self.deleteQueue.pop(0)
            self.deleteFile(next)

    def deleteAll(self):
        for filename in self.deleteQueue:
            self.deleteFile(filename)

        self.deleteQueue = []

    @Slot(str)
    def deleteFile(self, filename):
        """
        Deletes the file `filename` to the server
        
        :param filename: Absolute or relative path to the file
        """

        try:
            print 'Deleting %s' % filename
            self.ftp.delete(filename)
            return True
        except (error_reply, error_perm):
            print 'Error deleting %s' % filename
            return False

        self.fileEventCompleted.emit()

    @Slot(str)
    def onDownload(self, filename):
        self.downloadQueue.append(filename)

    def downloadNext(self):
        if len(self.downloadQueue) > 0:
            next = self.downloadQueue.pop(0)
            self.downloadFile(next)

    def downloadAll(self):
        for filename in self.downloadQueue:
            self.downloadFile(filename)

        self.downloadQueue = []

    @Slot(str, str)
    def downloadFile(self, filename, localpath=None):
        """
        Performs a binary download to the file `filename` located on the server.
        `filename` parameter can be either absolute or relative, though it can
        fail for relative paths if the current directory is not appropiate.
        
        :param filename: Relative or absolute path to the file
        :param localpath: Absolute local path where the file will be saved
        """
        def handleChunk(chunk):
            """
            Receives chuncks of data downloaded from the server.
            This function is meant to be used as callback for the `retrbinary` method.
            
            :params chunk: Chunk of downloaded bytes to be written into the file
            """

            # Simply writes the received data into the file `self.downloading`
            self.downloading.write(chunk)
            self.download_progress += len(chunk)
            self.downloadProgress.emit(self.download_size,
                                       self.download_progress)

        if localpath is None:
            localpath = self.localFromServer(filename)

        localdir = os.path.dirname(localpath)
        if not os.path.exists(localdir):
            # Creates the directory if it doesn't already exists.
            os.makedirs(localdir)

        print 'Downloading: %s to %s' % (filename, localpath)
        try:
            with open(localpath, 'wb') as f:
                # Opens the file at `localname` which will hold the downloaded file.
                # Object attributes regarding download status are updated accordingly.
                self.fileEvent.emit(filename)
                self.downloading = f
                self.download_progress = 0

                self.download_size = int(
                    self.ftp.sendcmd('SIZE %s' % filename).split(' ')[-1])
                self.ftp.retrbinary('RETR %s' % filename, handleChunk)

                print 'Download finished'

                # Let's set the same modified time to that on the server.
                with File.fromPath(filename) as downloadedfile:
                    mdate = LocalWatcher.lastModified(localpath)
                    downloadedfile.localmdate = mdate
                    downloadedfile.servermdate = mdate

                self.setLastModified(filename, mdate)

                downloaded = True
        except (IOError, OSError):
            downloaded = False
            self.ioError.emit(localpath)
        except (error_reply, error_perm) as ftperr:
            print 'Error downloading %s, %s' % (filename, ftperr)
            downloaded = False

        # TODO: Sometimes the file doesn't complete properly.
        # in that case we maybe shouldn't call this?
        self.fileEventCompleted.emit()

        return downloaded

    @Slot(str)
    def onUpload(self, filename):
        self.uploadQueue.append(filename)

    def uploadNext(self):
        if len(self.uploadQueue) > 0:
            next = self.uploadQueue.pop(0)
            self.uploadFile(next)

    def uploadAll(self):
        for filename in self.uploadQueue:
            self.uploadFile(filename)

        self.uploadQueue = []

    @Slot(str)
    def uploadFile(self, filename):
        """
        Uploads the file `filename` to the server, creating
        the needed directories.
        
        :param filename: Absolute or relative path to the file
        """
        def handle(buf):
            """This function is meant to be used as callback for the `storbinary` method."""

            self.upload_progress += 1024
            self.uploadProgress.emit(self.upload_size, self.upload_progress)

        # Creates the directory where the file will be uploaded to
        self.mkpath(os.path.dirname(filename))

        localpath = self.localFromServer(filename)
        print 'Uploading %s to %s' % (localpath, filename)

        try:
            # Uploads file and updates its modified date in the server
            # to match the date in the local filesystem.
            self.upload_progress = 0
            self.upload_size = os.path.getsize(localpath)
            self.fileEvent.emit(localpath)
            self.ftp.storbinary('STOR %s' % filename, open(localpath, 'rb'),
                                1024, handle)
            print 'Upload finished'
            with File.fromPath(filename) as uploaded:
                modified = uploaded.localmdate
                uploaded.servermdate = modified

                self.setLastModified(filename, modified)

            uploaded = True

        except (IOError, OSError):
            uploaded = False
            self.ioError.emit(localpath)
        except (error_reply, error_perm, OSError) as err:
            print 'Error uploading %s, %s' % (filename, err)
            uploaded = False

        # TODO: Sometimes the file doesn't complete properly.
        # in that case we maybe shouldn't call this?
        self.fileEventCompleted.emit()

        return uploaded

    def lastModified(self, filename):
        """
        Uses the MDTM FTP command to find the last modified timestamp
        of the file `filename`.
        Returns a `datetime.datetime` object in UTC representing the file's
        last modified date and time.
        
        :param filename: Relative or absolute path to the file
        """

        timestamp = self.ftp.sendcmd('MDTM %s' % filename)
        if '213 ' not in timestamp:
            # Second chance was found to be needed in some cases.
            timestamp = self.ftp.sendcmd('MDTM %s' % filename)

        timestamp = timestamp.split(' ')[-1]
        dateformat = '%Y%m%d%H%M%S.%f' if '.' in timestamp else '%Y%m%d%H%M%S'

        try:
            mtime = dt.strptime(timestamp, dateformat)
        except ValueError:
            mtime = dt.utcnow()

        return mtime

    def setLastModified(self, serverpath, newtime):
        """
        Uses the MFMT or MDTM FTP commands to set `newtime` as the modified timestamp of the
        file `serverpath` on the server. 

        :param serverpath: Relative or absolute path to the file
        :param newtime: datedatime object holding the required time
        """
        cmds = ['MFMT', 'MDTM']
        for cmd in cmds:
            try:
                self.ftp.sendcmd(
                    '%s %s %s' %
                    (cmd, newtime.strftime('%Y%m%d%H%M%S'), serverpath))
                return
            except (error_perm, error_reply) as e:
                if cmd == cmds[len(cmds) - 1]:
                    # If is the last comand, re-raise the exception, else
                    # keep trying.
                    raise e
                else:
                    continue

    def mkpath(self, path):
        """
        Creates the path `path` on the server by recursively 
        created folders, if needed.
        
        :param path: Absolute path on the server to be created
        """

        try:
            self.ftp.cwd(path)
        except error_perm:
            # `cwd` call failed. Need to create some folders
            make_dir = '/'
            steps = path.split('/')
            for step in steps:
                if len(step) == 0:
                    continue
                make_dir += '%s/' % step
                try:
                    self.ftp.mkd(make_dir)
                except error_perm:
                    # Probably already exists
                    continue
        else:
            # `cwd` call succeed. No need to create
            # any folders
            self.ftp.cwd('/')
            return

    @Slot(str, str)
    def added(self, location, serverpath):
        super(ServerWatcher, self).added(location, serverpath)

        def actionFromPath(serverpath):
            f = File()
            fileExistsOnServer = True
            try:
                f.servermdate = self.lastModified(serverpath)
            except error_perm:
                fileExistsOnServer = False
                f.servermdate = 0

            f.localmdate = LocalWatcher.lastModified(
                self.localFromServer(serverpath))
            diff = f.timeDiff()
            action = None
            if abs(diff) > Watcher.TOLERANCE:
                if not fileExistsOnServer or diff > 0:
                    action = FileAction(serverpath, FileAction.UPLOAD,
                                        ServerWatcher.LOCATION)
                else:
                    action = FileAction(serverpath, FileAction.DOWNLOAD,
                                        LocalWatcher.LOCATION)

            return action

        if self.preemptiveCheck:
            if location == ServerWatcher.LOCATION:
                localpath = self.localFromServer(serverpath)
                if not os.path.exists(localpath):
                    action = FileAction(serverpath, FileAction.DOWNLOAD,
                                        ServerWatcher.LOCATION)
                    self.preemptiveActions.append(action)
                else:
                    action = actionFromPath(serverpath)
                    if action is not None:
                        self.preemptiveActions.append(action)

            elif location == LocalWatcher.LOCATION:
                try:
                    self.ftp.sendcmd('SIZE %s' % serverpath)
                except (error_reply, error_perm):
                    exists = False
                else:
                    exists = True
                if not exists:
                    action = FileAction(serverpath, FileAction.UPLOAD,
                                        LocalWatcher.LOCATION)
                    self.preemptiveActions.append(action)
                else:
                    action = actionFromPath(serverpath)
                    if action is not None:
                        self.preemptiveActions.append(action)

    @Slot(str, str)
    def changed(self, location, serverpath):
        super(ServerWatcher, self).changed(location, serverpath)

    @Slot(str, str)
    def deleted(self, location, serverpath):
        super(ServerWatcher, self).deleted(location, serverpath)
        with File.fromPath(serverpath) as deleted:
            deleted.inserver = False
示例#21
0
class FTPSession(object):
    """ Attempt to create some robustness and performance to FTPing """

    def __init__(self, server, username, password, tmpdir="/tmp", timeout=60):
        """Build a FTP session """
        self.conn = None
        self.server = server
        self.username = username
        self.password = password
        self.tmpdir = tmpdir
        self.timeout = timeout

    def _connect(self):
        """Connect to FTP server """
        if self.conn is not None:
            return
        logging.debug("Creating new connection to server %s", self.server)
        not_connected = True
        attempt = 1
        while not_connected and attempt < 6:
            try:
                self.conn = FTP_TLS(self.server, timeout=self.timeout)
                self.conn.login(self.username, self.password)
                self.conn.prot_p()
                not_connected = False
            except Exception as exp:
                logging.debug(exp)
                time.sleep(5)
                self.close()
            attempt += 1
        if not_connected is True:
            raise Exception("Failed to make FTP connection after 5 tries!")

    def _reconnect(self):
        """ First attempt to shut down connection and then reconnect """
        logging.debug("_reconnect() was called...")
        try:
            self.conn.quit()
            self.conn.close()
        except:
            pass
        finally:
            self.conn = None
        self._connect()

    def _put(self, path, localfn, remotefn):
        """ """
        self.chdir(path)
        sz = os.path.getsize(localfn)
        if sz > 14000000000:
            # Step 1 Split this big file into 14GB chunks, each file will have
            # suffix .aa then .ab then .ac etc
            basefn = os.path.basename(localfn)
            cmd = "split --bytes=14000M %s %s/%s." % (localfn, self.tmpdir, basefn)
            subprocess.call(cmd, shell=True, stderr=subprocess.PIPE)
            files = glob.glob("%s/%s.??" % (self.tmpdir, basefn))
            for filename in files:
                suffix = filename.split(".")[-1]
                self.conn.storbinary("STOR %s.%s" % (remotefn, suffix), open(filename))
                os.unlink(filename)
        else:
            logging.debug("_put '%s' to '%s'", localfn, remotefn)
            self.conn.storbinary("STOR %s" % (remotefn,), open(localfn))
        return True

    def close(self):
        """ Good bye """
        try:
            self.conn.quit()
            self.conn.close()
        except:
            pass
        finally:
            self.conn = None

    def chdir(self, path):
        if self.pwd() == path.rstrip("/"):
            return
        self.conn.cwd("/")
        for dirname in path.split("/"):
            if dirname == "":
                continue
            bah = []
            self.conn.retrlines("NLST", bah.append)
            if dirname not in bah:
                logging.debug("Creating directory '%s'", dirname)
                self.conn.mkd(dirname)
            logging.debug("Changing to directory '%s'", dirname)
            self.conn.cwd(dirname)

    def pwd(self):
        """ Low friction function to get connectivity """
        self._connect()
        pwd = exponential_backoff(self.conn.pwd)
        if pwd is None:
            self._reconnect()
            pwd = exponential_backoff(self.conn.pwd)
        logging.debug("pwd() is currently '%s'", pwd)
        return pwd

    def put_file(self, path, localfn, remotefn):
        """ Put the File """
        res = exponential_backoff(self._put, path, localfn, remotefn)
        if not res:
            self._reconnect()
            res = exponential_backoff(self._put, path, localfn, remotefn)
            if not res:
                logging.error("Double Failure to upload filename: '%s'", localfn)

    def put_files(self, path, localfns, remotefns):
        """ Put the File """
        for localfn, remotefn in zip(localfns, remotefns):
            self.put_file(path, localfn, remotefn)
示例#22
0
class FTPSession(object):
    """ Attempt to create some robustness and performance to FTPing """
    def __init__(self, server, username, password, tmpdir='/tmp', timeout=60):
        """Build a FTP session """
        self.conn = None
        self.server = server
        self.username = username
        self.password = password
        self.tmpdir = tmpdir
        self.timeout = timeout

    def _connect(self):
        """Connect to FTP server """
        if self.conn is not None:
            return
        logging.debug('Creating new connection to server %s', self.server)
        not_connected = True
        attempt = 1
        while not_connected and attempt < 6:
            try:
                self.conn = FTP_TLS(self.server, timeout=self.timeout)
                self.conn.login(self.username, self.password)
                self.conn.prot_p()
                not_connected = False
            except Exception as exp:
                logging.debug(exp)
                time.sleep(5)
                self.close()
            attempt += 1
        if not_connected is True:
            raise Exception("Failed to make FTP connection after 5 tries!")

    def _reconnect(self):
        """ First attempt to shut down connection and then reconnect """
        logging.debug('_reconnect() was called...')
        try:
            self.conn.quit()
            self.conn.close()
        except:
            pass
        finally:
            self.conn = None
        self._connect()

    def _put(self, path, localfn, remotefn):
        """ """
        self.chdir(path)
        sz = os.path.getsize(localfn)
        if sz > 14000000000:
            # Step 1 Split this big file into 14GB chunks, each file will have
            # suffix .aa then .ab then .ac etc
            basefn = os.path.basename(localfn)
            cmd = "split --bytes=14000M %s %s/%s." % (localfn, self.tmpdir,
                                                      basefn)
            subprocess.call(cmd, shell=True, stderr=subprocess.PIPE)
            files = glob.glob("%s/%s.??" % (self.tmpdir, basefn))
            for filename in files:
                suffix = filename.split(".")[-1]
                self.conn.storbinary('STOR %s.%s' % (remotefn, suffix),
                                     open(filename))
                os.unlink(filename)
        else:
            logging.debug("_put '%s' to '%s'", localfn, remotefn)
            self.conn.storbinary('STOR %s' % (remotefn, ), open(localfn))
        return True

    def close(self):
        """ Good bye """
        try:
            self.conn.quit()
            self.conn.close()
        except:
            pass
        finally:
            self.conn = None

    def chdir(self, path):
        if self.pwd() == path.rstrip("/"):
            return
        self.conn.cwd("/")
        for dirname in path.split("/"):
            if dirname == '':
                continue
            bah = []
            self.conn.retrlines('NLST', bah.append)
            if dirname not in bah:
                logging.debug("Creating directory '%s'", dirname)
                self.conn.mkd(dirname)
            logging.debug("Changing to directory '%s'", dirname)
            self.conn.cwd(dirname)

    def pwd(self):
        """ Low friction function to get connectivity """
        self._connect()
        pwd = exponential_backoff(self.conn.pwd)
        if pwd is None:
            self._reconnect()
            pwd = exponential_backoff(self.conn.pwd)
        logging.debug("pwd() is currently '%s'", pwd)
        return pwd

    def put_file(self, path, localfn, remotefn):
        """ Put the File """
        res = exponential_backoff(self._put, path, localfn, remotefn)
        if not res:
            self._reconnect()
            res = exponential_backoff(self._put, path, localfn, remotefn)
            if not res:
                logging.error("Double Failure to upload filename: '%s'",
                              localfn)
                return False
        return True

    def put_files(self, path, localfns, remotefns):
        """ Put the File """
        res = []
        for localfn, remotefn in zip(localfns, remotefns):
            res.append(self.put_file(path, localfn, remotefn))
        return res
def sendFtp(server, port, user, password):
    displayOptionsFTP(server, port, user, password)
    textPad.configure(state='normal')
    if (is_tls_ftp_checked.get() == 1):
        try:
            textPad.insert('end', "Initializing FTP_TLS\n")
            ftps = FTP_TLS()
            textPad.insert('end', "\t -> success\n")
            textPad.insert('end',
                           "Connecting to " + server + ":" + port + "\n")
            ftps.connect(server, int(port))
            textPad.insert('end', "\t -> success\n")
            if (is_auth_ftp_checked.get() == 1):
                textPad.insert('end',
                               "Trying to connect with anonymous login\n")
                ftps.login()
                textPad.insert('end', "\t -> success\n")
                textPad.see("end")
            else:
                textPad.insert(
                    'end', "Logging in with " + user + ":" + password + "\n")
                textPad.see("end")
                ftps.login(user=user, passwd=password)
                textPad.insert('end', "\t -> success\n")
                textPad.see("end")
            ftps.prot_p()
            textPad.see("end")
            listing = []
            textPad.insert('end', "--Listing directories:\n")
            ftps.retrlines("LIST", listing.append)
            textPad.insert('end', "\n".join(listing))
            textPad.insert('end', "\n\t -> success\n")
            textPad.see("end")
            ftps.close()
        except Exception as e:
            textPad.configure(state='normal')
            textPad.insert('end', "Exception raised: {}\n".format(e))
        textPad.config(state=DISABLED)
    else:
        try:
            textPad.insert('end', "---Starting FTP checking------------\n")
            textPad.insert('end', "Initializing FTP\n")
            ftp = FTP()
            textPad.insert('end', "\t -> success\n")
            textPad.insert('end',
                           "Connecting to " + server + ":" + port + "\n")
            ftp.connect(server, int(port))
            textPad.insert('end', "\t -> success\n")
            if (is_auth_ftp_checked.get() == 1):
                textPad.insert('end',
                               "Trying to connect with anonymous login\n")
                ftp.login()
                textPad.insert('end', "\t -> success\n")
                textPad.see("end")
            else:
                textPad.insert(
                    'end', "Logging in with " + user + ":" + password + "\n")
                textPad.see("end")
                ftp.login(user=user, passwd=password)
                textPad.insert('end', "\t -> success\n")
                textPad.see("end")
            ftp.prot_p()
            textPad.see("end")
            listing = []
            textPad.insert('end', "--Listing directories:\n")
            ftp.retrlines("LIST", listing.append)
            textPad.insert('end', "\n".join(listing))
            textPad.insert('end', "\n\t -> success\n")
            textPad.see("end")
            ftp.close()
        except Exception as e:
            textPad.configure(state='normal')
            textPad.insert('end', "Exception raised: {}\n".format(e))
        textPad.config(state=DISABLED)
示例#24
0
from ftplib import FTP_TLS
ftps = FTP_TLS('127.0.0.1:8021','user','12345',keyfile='privateKey.key')
ftps.login()           # login anonymously before securing control channel
ftps.prot_p()          # switch to secure data connection
print ftps.retrlines('LIST')
示例#25
0
from ftplib import FTP_TLS
ftps = FTP_TLS()
ftps.connect('127.0.0.1', 5000)
ftps.login('user', '12345')           # login anonymously before securing control channel
ftps.prot_p()          # switch to secure data connection
ftps.retrlines('LIST') # list directory content securely
示例#26
0
    except (IOError, OSError):
        LOG_MAIN.error("Noting variable set")
        LOG_MAIN.error("OS ERROR : " + str(OSError))
        LOG_MAIN.error("OR OS IOError: " + str(IOError))

    if __autopilot__.upper() == 'TRUE':
        # region ftp_connection
        try:
            FTP_TLS.port = int(V_FTPS_PORT)
            ftp_conn = FTP_TLS(V_FTPS_SERVER)
            ftp_conn.login(V_FTPS_USER, V_FTPS_PASS)
            ftp_conn.prot_p()
            if ftp_conn:
                ftps_chdir(ftp_conn, V_FTPS_RMT_DIR)
                ftp_conn.retrlines('LIST')

                data = []
                ftp_conn.dir(data.append)
                coln = []
                for line in data:
                    col = line.split()
                    coln.append(col[-1])
                # print(get_lasted_file_name_glob(coln))

                lastFile = get_lasted_file_name_glob(coln)
                ftps_download(ftp_conn, lastFile, __dlftpsfiles__,
                              V_FTPS_RMT_DIR)
                __pathlastfile__ = __dlftpsfiles__ + lastFile

                try:
示例#27
0
url_requested = request.urlopen(url)  # Ubuntu
#url_requested = urllib.urlopen(url) # Raspi
if 200 == url_requested.code:
    html_content = str(url_requested.read())

# "b'" am Anfang, CR und "'" am Ende entfernen
temp_clean0 = re.sub(r"b'<!DOC", "<!DOC", html_content)
temp_clean1 = re.sub(r"\\n", "", temp_clean0)
temp_clean2 = re.sub(r"ml>'", "ml>", temp_clean1)
print(temp_clean2)

datei = open(htmlfile, 'w')
datei.write(temp_clean2)
datei.close()

#
# ftp/TLS Transfer
#
ftps = FTP_TLS(ftpurl)
ftps.login(ftpuser, ftppass)
ftps.prot_p(
)  # switch to secure data connection.. IMPORTANT! Otherwise, only the user and password is encrypted and not all the file data.
ftps.retrlines('LIST')

myfile = open(htmlfile, 'rb')
ftps.storbinary("STOR test.html", myfile, blocksize=8192)

ftps.close()
myfile.close()
示例#28
0
class ServerWatcher(Watcher):

    downloadProgress = Signal((int, int,))
    uploadProgress = Signal((int, int,))
    # Si added:
    textStatus = Signal((str,))
    
    fileEvent = Signal((str,))
    fileEventCompleted = Signal()    
    loginCompleted = Signal((bool, str,))
    badFilenameFound = Signal((str,))

    LOCATION = 'server'
    TEST_FILE = 'iqbox.test'
    
    def __init__(self, host, ssl, parent=None):
        """
        Initializes parent class and attributes. Decides
        whether to use `FTP_TLS` or `FTP` based on the `ssl` param.
        
        :param host: Location of the FTP server
        :param ssl: Tells whether the FTP needs to support TLS or not
        :param parent: Reference to a `QObject` instance a parent
        """
        
        super(ServerWatcher, self).__init__(parent)
        
        self.interval = 5000
        self.localdir = ''
        self.deleteQueue = []
        self.downloadQueue = []
        self.uploadQueue = []
        self.warnedNames = []
        self.ftp = None 
        self.useSSL = ssl
        self.host = host
        self.preemptiveCheck = False
        self.preemptiveActions = []
        self.testFile = 'iqbox.test'
        
    @property
    def currentdir(self):
        """Returns the current working directory at the server"""
        
        return self.ftp.pwd()
        
    def setLocalDir(self, localdir):
        """
        Sets the local directory used to stored all
        downloaded files. Creates the directory if needed.
        
        :param localdir: Absolute path to local directory
        """
        
        self.localdir = localdir
        if not os.path.exists(self.localdir):
            os.makedirs(self.localdir)
    
    @pause_timer
    @Slot()
    def checkout(self):
        """
        Recursively checks out all files on the server.
        Returns a dictionary of files on the server with their last modified date.
        
        :param download: Indicates whether or not the files should be downloaded
        """
        
        # Check  `self.deleteQueue`, `self.uploadQueue` and `self.downloadQueue` queues.
        # These tasks are done in queues to make sure all FTP commands
        # are done sequentially, in the same thread.
        self.deleteAll()
        self.uploadAll()
        self.downloadAll()
        
        # Handy list to keep track of the checkout process.
        # This list contain absolute paths only.
        checked_dirs = list()

        # Sets '/' as initial directory and initializes `downloading_dir`
        self.ftp.cwd('/')
        downloading_dir = self.currentdir
        check_date = dt.utcnow()

        sidirlist = list()

        root_cached = False
        
        fileC = 0
        while True:
            # Gets the list of sub directories and files inside the 
            # current directory `downloading_dir`.
            self.textStatus.emit('Remote scan- Downloading folder list of '+downloading_dir+'...')
            
            if root_cached and downloading_dir == '/':
                dir_subdirs = saved_root_dirs
                dirfiles = saved_root_files
            else:
                
                dir_subdirs = self.getDirs(downloading_dir)
            
                if downloading_dir == '/':
                    saved_root_dirs = dir_subdirs
    
                # sidirlist.extend(dir_subdirs)
                self.textStatus.emit('Remote scan- Downloading files list of '+downloading_dir+'...')            
                dirfiles = self.getFiles(downloading_dir)
     
                if downloading_dir == '/':
                    saved_root_files = dirfiles
                    root_cached = True
                
           
            # Leading '/' in `downloading_dir` breaks the `os.path.join` call
            localdir = os.path.join(self.localdir, downloading_dir[1:])
            if not os.path.exists(localdir):
                # Creates the directory if it doesn't already exists.
                os.makedirs(localdir)
            
            for file_ in dirfiles:
                                
                # `serverpath` is the absolute path of the file on the server,
                # download it only if it hasn't been already downloaded
                serverpath = os.path.join(downloading_dir, file_)
                serverpath = QDir.fromNativeSeparators(serverpath)
                server_file = File.fromPath(serverpath)

                self.textStatus.emit('Scanning remote file... '+serverpath+'...')

                # How do we know if we should check this server file?
                # We see if the date last checked is the check start time.
                if server_file.last_checked_server != check_date:
                    
                    # Do this process only once per file
    
                    # Added by Simon
                    # Give feedback on scanning of files.
                    fileC += 1
                    if fileC % 1 == 2:
                        self.textStatus.emit('Scanning remote files for changes, '+str(fileC)+' files scanned.')
                        
                    
                    # STEP: IS THIS THE FIRST TIME WE SAW THE FILE, OR WAS IT ALREADY IN OUR DB?
                    just_added = not server_file.inserver

                    # STEP: IF ITS A NEW FILE, ENSURE WE DONT WANT TO SKIP IT
                    # Example: If it's a temporary file, or a Unix file with a name we don't support.
                    
                    if just_added:    
                        filename = os.path.basename(serverpath)
     
                        if platform.system() == 'Windows':
                            
                            badName = False
                            for chr in ['\\', '/', ':', '?', '"', '<', '>', '|']:
                                if chr in filename:
                                    badName = True
                                    break
                            if badName:
                                if filename not in self.warnedNames:
                                    self.warnedNames.append(filename)
                                    self.badFilenameFound.emit(filename)
                                continue
                        
                    
                    # STEP: ASSUMING THE FILE DID EXIST IN OUR DB, LETS SAVE THE LAST MODIFICATION DATE
                    lastmdate = server_file.servermdate
                    
                    # STEP: SAVE THE MOD DATE TO A VARIABLE
                    # Now we get the last mod time.
                    # We expect this to work fine since this file
                    # was found on the server
                    servermdate = self.lastModified(serverpath)
                    
                    # STEP: SET BOOL SHOWING THAT IT WAS ON THE SERVER, SINCE WE KNOW IT IS.
                    server_file.inserver = True
                    
                    # STEP: SET THE TIME THE FILE WAS LAST CHECKED TO THE SCAN START TIME
                    server_file.last_checked_server = check_date
                    
                    # STEP: SET THE MOD DATE IN THE DATABASE TO THE ONE WE JUST GOT
                    server_file.servermdate = servermdate
                    
                    # STEP: SAVE THIS CHANGE TO THE DATABASE
                    server_file.session.commit()
                    
                    delta = 0
                    if server_file.inlocal:
                        delta = server_file.timeDiff()

                    # Emit the signals after the attributes has been set and committed
                    if just_added is True:
                        self.fileAdded.emit(ServerWatcher.LOCATION, serverpath)
                    elif server_file.servermdate > lastmdate or delta < -Watcher.TOLERANCE:
                        self.fileChanged.emit(ServerWatcher.LOCATION, serverpath, False) 
            #END FOR            
            
            self.textStatus.emit('Remote scan- Finding next folder...')
            dir_ready = True
            for dir_ in dir_subdirs:
                # `dirpath` is the absolute path of the subdirectory on the server,
                dirpath = QDir.fromNativeSeparators(os.path.join(downloading_dir, dir_))
                # `downloading_dir` is ready only when all its subdirectory are on the 
                # `checked_dirs` list.
                if dirpath not in checked_dirs:
                    # Found one subdirectory that is not on `checked_dirs`,
                    # will process it in the next iteration.
                    downloading_dir = dirpath
                    dir_ready = False
                    break
                    
            if dir_ready is True:
                # All subdirectories of `downloading_dir` are already in `checked_dirs`
                if downloading_dir == '/':
                    # All directories ready and at '/', means checkout is complete
                    # So, exit the main While loop!!
                    break
                    
                else:
                    # Not at '/'. Current directory is ready so is appended to `checked_dirs`
                    # Back one directory to find directories that are not in `checked_dirs`
                    checked_dirs.append(downloading_dir)
                    downloading_dir = os.path.dirname(downloading_dir)
            
            self.textStatus.emit('Remote scan- Found Folder...')
                    
##### END OF WHILE ################
###################################################################
        
        # Deleted files are the ones whose `last_checked_server` attribute 
        # didn't get updated in the recursive run.
        session = Session()
        deleted = session.query(File).filter(File.last_checked_server < check_date).filter(File.inserver == True)
        for file_ in deleted:
            self.fileDeleted.emit(ServerWatcher.LOCATION, file_.path)
        
        # Wraps up the checkout process, commits to the database.
        session.commit()
                
    @Slot()
    def onLogin(self, username, passwd):
        ok = True
        msg = ''
        error_msg = 'Login failed.'
        try:
            if not self.ftp:
                self.ftp = FTP_TLS(self.host) if self.useSSL is True else FTP(self.host)
            loginResponse = self.ftp.login(username, passwd)
        except socket.gaierror:
            self.ftp = None
            ok = False
            msg = 'Server address could not be found.' 
        except (error_perm, error_reply):
            info = traceback.format_exception(*sys.exc_info())
            for i in info: sys.stderr.write(i)
            ok = False
            msg = error_msg 
        else:
            if '230' in loginResponse:
                ok = True
            else:
                ok = False
                msg = error_msg
        
        if ok:
            # Logged in. Now let's do compability tests.
            if not self.testPermissions():
                # User doesn't have write permissions, don't bother doing next test.
                ok = False
                msg = 'It seems like you do not have write access to this server.' 
            else:
                # Permissions test passed, now let's test MFMT for timestamp modification.
                if not self.testMFMT():
                    ok = False
                    msg = 'This server does not support timestamp modification\n \
                           need by this application.'

        self.loginCompleted.emit(ok, msg)
        
    def getFiles(self, path):
        """
        This method simply wraps the `nlst` method with an exception handler,
        and returns an empty list in case an exception is caught.
        
        :param path: Relative or absolute path on the server
        """
        
        try:
            nlst = self.ftp.nlst(path)
            dirs = self.getDirs(path)
            
            # Files are items in nlst that are not in dirs
            files = [item for item in nlst if os.path.basename(item) not in dirs]
            
            return files
        except:
            print 'Exception in ServerWatcher.getDirs'
            info = traceback.format_exception(*sys.exc_info())
            for i in info: sys.stderr.write(i)
            return []
             
    def getDirs(self, path):
        """
        Retrieves a list of the directories inside `path`,
        uses `retrlines` and the LIST command to retrieve the items.
        
        :param path: Relative or absolute path on the server
        """
        
        dirs = list()
        def handleLine(line):
            """
            Recieves a line from the LIST command.
            This function is meant to be used as callback for the `retrlines` method.
            
            :params line: Line from the LIST command
            """

            if line.startswith('d'):
                # Only lines starting with 'd' are directories
                # Parse the directory out of the line; lines look like:
                # 'drwxrwxrwx   1 user     group           0 Jun 15  2012 dirname'
                dirname = line[55:].strip()
                if dirname != '.' and dirname != '..':
                    # Ignoring '.' and '..' entries
                    dirs.append(dirname)
        
        try:
            self.ftp.retrlines('LIST %s' % path, handleLine)
            
            return dirs
        except:
            print 'Exception in ServerWatcher.getDirs'
            info = traceback.format_exception(*sys.exc_info())
            for i in info: sys.stderr.write(i)
            return []
    
    @upload_test
    def testPermissions(self):
        # For interface purposes. upload_test takes care of everything.
        return True

    @upload_test
    def testMFMT(self):
        # Absurd date to test whether the change really happened.
        time = dt.utcfromtimestamp(100000000)
        try:
            self.setLastModified(self.testFile, time)
            otherTime = self.lastModified(self.testFile)
            diff = (time - otherTime).total_seconds()
            if abs(diff) < 2:
                # Let's give it a 2 seconds tolerance.
                mdtm = True
            else:
                mdtm = False
        except (ValueError, error_reply, error_perm):
            info = traceback.format_exception(*sys.exc_info())
            for i in info: sys.stderr.write(i)
            mdtm = False
        
        return mdtm

    @Slot(str)
    def onDelete(self, filename):
        self.deleteQueue.append(filename)
        
    def deleteNext(self):
        if len(self.deleteQueue) > 0:
            next = self.deleteQueue.pop(0)
            self.deleteFile(next)
    
    def deleteAll(self):
        for filename in self.deleteQueue:
            self.deleteFile(filename)
            
        self.deleteQueue = []
    
    @Slot(str)
    def deleteFile(self, filename):
        """
        Deletes the file `filename` to the server
        
        :param filename: Absolute or relative path to the file
        """
        
        try:
            print 'Deleting %s' % filename
            self.ftp.delete(filename)
            return True
        except (error_reply, error_perm):
            print 'Error deleting %s' % filename
            return False

        self.fileEventCompleted.emit()
        
    @Slot(str)
    def onDownload(self, filename):
        self.downloadQueue.append(filename)
        
    def downloadNext(self):
        if len(self.downloadQueue) > 0:
            next = self.downloadQueue.pop(0)
            self.downloadFile(next)
            
    def downloadAll(self):
        for filename in self.downloadQueue:
            self.downloadFile(filename)
            
        self.downloadQueue = []
    
    @Slot(str, str)   
    def downloadFile(self, filename, localpath=None):
        """
        Performs a binary download to the file `filename` located on the server.
        `filename` parameter can be either absolute or relative, though it can
        fail for relative paths if the current directory is not appropiate.
        
        :param filename: Relative or absolute path to the file
        :param localpath: Absolute local path where the file will be saved
        """
        
        def handleChunk(chunk):
            """
            Receives chuncks of data downloaded from the server.
            This function is meant to be used as callback for the `retrbinary` method.
            
            :params chunk: Chunk of downloaded bytes to be written into the file
            """
        
            # Simply writes the received data into the file `self.downloading`
            self.downloading.write(chunk)
            self.download_progress += len(chunk)
            self.downloadProgress.emit(self.download_size, self.download_progress)
        
        if localpath is None:
            localpath = self.localFromServer(filename)
        
        localdir = os.path.dirname(localpath)
        if not os.path.exists(localdir):
            # Creates the directory if it doesn't already exists.
            os.makedirs(localdir)
        
        print 'Downloading: %s to %s' % (filename, localpath) 
        try:
            with open(localpath, 'wb') as f:
                # Opens the file at `localname` which will hold the downloaded file.
                # Object attributes regarding download status are updated accordingly.
                self.fileEvent.emit(filename)
                self.downloading = f
                self.download_progress = 0

                self.download_size = int(self.ftp.sendcmd('SIZE %s' % filename).split(' ')[-1])
                self.ftp.retrbinary('RETR %s' % filename, handleChunk)
                
                print 'Download finished'
                
                # Let's set the same modified time to that on the server.
                with File.fromPath(filename) as downloadedfile:
                    mdate = LocalWatcher.lastModified(localpath)
                    downloadedfile.localmdate = mdate
                    downloadedfile.servermdate = mdate
                    
                self.setLastModified(filename, mdate)

                downloaded = True
        except (IOError, OSError):
            downloaded = False
            self.ioError.emit(localpath)
        except (error_reply, error_perm) as ftperr:
            print 'Error downloading %s, %s' % (filename, ftperr)
            downloaded = False
        
        # TODO: Sometimes the file doesn't complete properly.
        # in that case we maybe shouldn't call this?
        self.fileEventCompleted.emit()
        
        return downloaded
    
    @Slot(str)
    def onUpload(self, filename):
        self.uploadQueue.append(filename)
    
    def uploadNext(self):
        if len(self.uploadQueue) > 0:
            next = self.uploadQueue.pop(0)
            self.uploadFile(next)
            
    def uploadAll(self):
        for filename in self.uploadQueue:
            self.uploadFile(filename)
            
        self.uploadQueue = []
            
    @Slot(str)
    def uploadFile(self, filename):
        """
        Uploads the file `filename` to the server, creating
        the needed directories.
        
        :param filename: Absolute or relative path to the file
        """
        
        def handle(buf):
            """This function is meant to be used as callback for the `storbinary` method."""
        
            self.upload_progress += 1024
            self.uploadProgress.emit(self.upload_size, self.upload_progress)
        
        
        # Creates the directory where the file will be uploaded to
        self.mkpath(os.path.dirname(filename))
        
        localpath = self.localFromServer(filename)
        print 'Uploading %s to %s' % (localpath, filename)
        
        try:
            # Uploads file and updates its modified date in the server
            # to match the date in the local filesystem.
            self.upload_progress = 0
            self.upload_size = os.path.getsize(localpath)
            self.fileEvent.emit(localpath)
            self.ftp.storbinary('STOR %s' % filename,
                                open(localpath, 'rb'), 
                                1024,
                                handle)
            print 'Upload finished'
            with File.fromPath(filename) as uploaded:
                modified = uploaded.localmdate
                uploaded.servermdate = modified
                
                self.setLastModified(filename, modified)
            
            uploaded = True

        except (IOError, OSError):
            uploaded = False
            self.ioError.emit(localpath)
        except (error_reply, error_perm, OSError) as err:
            print 'Error uploading %s, %s' % (filename, err)
            uploaded = False
            
        # TODO: Sometimes the file doesn't complete properly.
        # in that case we maybe shouldn't call this?            
        self.fileEventCompleted.emit()
        
        return uploaded
            
    def lastModified(self, filename):
        """
        Uses the MDTM FTP command to find the last modified timestamp
        of the file `filename`.
        Returns a `datetime.datetime` object in UTC representing the file's
        last modified date and time.
        
        :param filename: Relative or absolute path to the file
        """
        
        timestamp = self.ftp.sendcmd('MDTM %s' % filename)
        if '213 ' not in timestamp:
            # Second chance was found to be needed in some cases.
            timestamp = self.ftp.sendcmd('MDTM %s' % filename)
            
        timestamp = timestamp.split(' ')[-1]
        dateformat = '%Y%m%d%H%M%S.%f' if '.' in timestamp else '%Y%m%d%H%M%S'
        
        try:
            mtime = dt.strptime(timestamp, dateformat)
        except ValueError:
            mtime = dt.utcnow()

        return mtime

    def setLastModified(self, serverpath, newtime):
        """
        Uses the MFMT or MDTM FTP commands to set `newtime` as the modified timestamp of the
        file `serverpath` on the server. 

        :param serverpath: Relative or absolute path to the file
        :param newtime: datedatime object holding the required time
        """
        cmds = ['MFMT', 'MDTM']
        for cmd in cmds:
            try:
                self.ftp.sendcmd(
                        '%s %s %s' % (cmd, newtime.strftime('%Y%m%d%H%M%S'), serverpath))
                return
            except (error_perm, error_reply) as e:
                if cmd == cmds[len(cmds) - 1]:
                    # If is the last comand, re-raise the exception, else
                    # keep trying.
                    raise e
                else:
                    continue
    
    def mkpath(self, path):
        """
        Creates the path `path` on the server by recursively 
        created folders, if needed.
        
        :param path: Absolute path on the server to be created
        """
        
        try:
            self.ftp.cwd(path)
        except error_perm:
            # `cwd` call failed. Need to create some folders
            make_dir = '/' 
            steps = path.split('/')
            for step in steps:
                if len(step) == 0:
                    continue
                make_dir += '%s/' % step
                try:
                    self.ftp.mkd(make_dir)
                except error_perm:
                    # Probably already exists
                    continue
        else:
            # `cwd` call succeed. No need to create
            # any folders
            self.ftp.cwd('/')
            return
            
    @Slot(str, str)
    def added(self, location, serverpath):
        super(ServerWatcher, self).added(location, serverpath)
        
        def actionFromPath(serverpath):
            f = File()
            fileExistsOnServer = True
            try:    
                f.servermdate = self.lastModified(serverpath)
            except error_perm:
                fileExistsOnServer = False
                f.servermdate = 0
            
            f.localmdate = LocalWatcher.lastModified(self.localFromServer(serverpath))
            diff = f.timeDiff()
            action = None
            if abs(diff) > Watcher.TOLERANCE:
                if not fileExistsOnServer or diff > 0:
                    action = FileAction(serverpath, FileAction.UPLOAD, ServerWatcher.LOCATION)
                else:
                    action = FileAction(serverpath, FileAction.DOWNLOAD, LocalWatcher.LOCATION)
            
            return action
            
        if self.preemptiveCheck:
            if location == ServerWatcher.LOCATION:
                localpath = self.localFromServer(serverpath)
                if not os.path.exists(localpath):
                    action = FileAction(serverpath, FileAction.DOWNLOAD, ServerWatcher.LOCATION)
                    self.preemptiveActions.append(action)
                else:
                    action = actionFromPath(serverpath)
                    if action is not None:
                        self.preemptiveActions.append(action) 

            elif location == LocalWatcher.LOCATION:
                try:
                    self.ftp.sendcmd('SIZE %s' % serverpath)
                except (error_reply, error_perm):
                    exists = False
                else:
                    exists = True
                if not exists:
                    action = FileAction(serverpath, FileAction.UPLOAD, LocalWatcher.LOCATION)
                    self.preemptiveActions.append(action)
                else:
                    action = actionFromPath(serverpath)
                    if action is not None:
                        self.preemptiveActions.append(action) 

    @Slot(str, str)
    def changed(self, location, serverpath):
        super(ServerWatcher, self).changed(location, serverpath)
            
    @Slot(str, str)
    def deleted(self, location, serverpath):
        super(ServerWatcher, self).deleted(location, serverpath)
        with File.fromPath(serverpath) as deleted:
            deleted.inserver = False