2015-07-16 15 views
5

Làm cách nào để tạo os.walk duyệt cây thư mục của cơ sở dữ liệu FTP (nằm trên máy chủ từ xa)? Cách mã được cấu trúc tại là (bình luận cung cấp):Mở rộng chức năng os.walk của Python trên máy chủ FTP

import fnmatch, os, ftplib 

def find(pattern, startdir=os.curdir): #find function taking variables for both desired file and the starting directory 
    for (thisDir, subsHere, filesHere) in os.walk(startdir): #each of the variables change as the directory tree is walked 
     for name in subsHere + filesHere: #going through all of the files and subdirectories 
      if fnmatch.fnmatch(name, pattern): #if the name of one of the files or subs is the same as the inputted name 
       fullpath = os.path.join(thisDir, name) #fullpath equals the concatenation of the directory and the name 
       yield fullpath #return fullpath but anew each time 

def findlist(pattern, startdir = os.curdir, dosort=False): 
    matches = list(find(pattern, startdir)) #find with arguments pattern and startdir put into a list data structure 
    if dosort: matches.sort() #isn't dosort automatically False? Is this statement any different from the same thing but with a line in between 
    return matches 

#def ftp(
#specifying where to search. 

if __name__ == '__main__': 
    import sys 
    namepattern, startdir = sys.argv[1], sys.argv[2] 
    for name in find(namepattern, startdir): print (name) 

Tôi nghĩ rằng tôi cần phải xác định một chức năng mới (ví dụ: def ftp()) để thêm chức năng này vào các mã trên. Tuy nhiên, tôi sợ rằng chức năng os.walk sẽ, theo mặc định, chỉ đi bộ các cây thư mục của máy tính mà mã được chạy.

Có cách nào để tôi có thể mở rộng chức năng của os.walk để có thể duyệt qua cây thư mục từ xa (qua FTP) không?

+0

https: // pypi .python.org/pypi/ftptool/0.5.1 –

+0

Tôi đang cố gắng tránh bất kỳ giao diện nào ngoài 'ftplib'. Đây có phải là có thể làm gì? Disclaimer: Tôi đã cố gắng 'ftptool' và không thể làm cho nó để làm những gì tôi muốn. Như vậy, đoạn mã trên là bản phục hồi Python của lệnh 'find' của Linux. Tôi đang cố gắng để mở rộng nó bằng cách kết hợp một chuyển đổi FTP để 'os.walk'. – warship

+0

Nếu ai đó có thể chỉ cho tôi cách thực hiện lại điều này trong 'ftptool' theo cách hoạt động cho cơ sở dữ liệu FTP từ xa, tôi cũng sẽ chấp nhận điều này như một câu trả lời. – warship

Trả lời

1

Tất cả những gì bạn cần là sử dụng mô-đun ftplib của python. Kể từ os.walk() được dựa trên thuật toán tìm kiếm theo chiều rộng đầu tiên, bạn cần phải tìm các thư mục và tên tệp tại mỗi lần lặp lại, sau đó tiếp tục truyền tải đệ quy từ thư mục đầu tiên. Tôi đã triển khai this algorithm khoảng 2 năm trước để sử dụng làm trung tâm của FTPwalker, đây là gói tối ưu để duyệt qua các cây thư mục cực lớn Thông qua FTP.

from os import path as ospath 


class FTPWalk: 
    """ 
    This class is contain corresponding functions for traversing the FTP 
    servers using BFS algorithm. 
    """ 
    def __init__(self, connection): 
     self.connection = connection 

    def listdir(self, _path): 
     """ 
     return files and directory names within a path (directory) 
     """ 

     file_list, dirs, nondirs = [], [], [] 
     try: 
      self.connection.cwd(_path) 
     except Exception as exp: 
      print ("the current path is : ", self.connection.pwd(), exp.__str__(),_path) 
      return [], [] 
     else: 
      self.connection.retrlines('LIST', lambda x: file_list.append(x.split())) 
      for info in file_list: 
       ls_type, name = info[0], info[-1] 
       if ls_type.startswith('d'): 
        dirs.append(name) 
       else: 
        nondirs.append(name) 
      return dirs, nondirs 

    def walk(self, path='/'): 
     """ 
     Walk through FTP server's directory tree, based on a BFS algorithm. 
     """ 
     dirs, nondirs = self.listdir(path) 
     yield path, dirs, nondirs 
     for name in dirs: 
      path = ospath.join(path, name) 
      yield from self.walk(path) 
      # In python2 use: 
      # for path, dirs, nondirs in self.walk(path): 
      #  yield path, dirs, nondirs 
      self.connection.cwd('..') 
      path = ospath.dirname(path) 

Bây giờ cho việc sử dụng lớp này, bạn có thể chỉ cần tạo một đối tượng kết nối sử dụng ftplib mô-đun và vượt qua các đối tượng đối tượng để FTPWalk và chỉ vòng qua walk() chức năng:

In [2]: from test import FTPWalk 

In [3]: import ftplib 

In [4]: connection = ftplib.FTP("ftp.uniprot.org") 

In [5]: connection.login() 
Out[5]: '230 Login successful.' 

In [6]: ftpwalk = FTPWalk(connection) 

In [7]: for i in ftpwalk.walk(): 
      print(i) 
    ...:  
('/', ['pub'], []) 
('/pub', ['databases'], ['robots.txt']) 
('/pub/databases', ['uniprot'], []) 
('/pub/databases/uniprot', ['current_release', 'previous_releases'], ['LICENSE', 'current_release/README', 'current_release/knowledgebase/complete', 'previous_releases/', 'current_release/relnotes.txt', 'current_release/uniref']) 
('/pub/databases/uniprot/current_release', ['decoy', 'knowledgebase', 'rdf', 'uniparc', 'uniref'], ['README', 'RELEASE.metalink', 'changes.html', 'news.html', 'relnotes.txt']) 
... 
... 
... 
0

Im sẽ giả sử đây là những gì bạn muốn ... mặc dù thực sự tôi không có ý tưởng

ssh = paramiko.SSHClient() 
ssh.connect(server, username=username, password=password) 
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("locate my_file.txt") 
print ssh_stdout 

này sẽ đòi hỏi các máy chủ từ xa để có gói mlocate sudo apt-get install mlocate; sudo updatedb();

+0

Một số cơ sở dữ liệu tôi đang kết nối để có lỗi này: 'paramiko.ssh_exception.S SHException: Server 'ftp.server.org' không tìm thấy trong known_hosts'. Điều này có nghĩa là tôi không thể ssh với họ bằng cách sử dụng paramiko? Tôi sẽ thử phương pháp 'mlocate' và đăng cập nhật. – warship

+1

@warship Điều đó rõ ràng là có được các lỗi như vậy với giao thức như vậy. Bản chất của SSH là kết nối an toàn. – Kasramvd

Các vấn đề liên quan