Python论坛  - 讨论区

标题:[python-chinese] 有关FTP

2005年07月16日 星期六 12:18

Leo Jay python.leojay at gmail.com
Sat Jul 16 12:18:06 HKT 2005

我想得到FTP里某个目录下所有文件及其日期信息,但dir()返回的是这样的结果:
-rw-r--r--   1 anonymous storage   6650384 Jul 10 06:09 nnow0130a.mp3
-rw-r--r--   1 anonymous storage  11638172 Jan  2  2005 nnow0130a0102.mp3
-rw-r--r--   1 anonymous storage  11638172 Jan  9  2005 nnow0130a0109.mp3
-rw-r--r--   1 anonymous storage  11638172 Jan 23 20:04 nnow0130a0123.mp3
-rw-r--r--   1 anonymous storage  11638172 Jan 30 08:48 nnow0130a0130.mp3
-rw-r--r--   1 anonymous storage  11638172 Feb  6 09:15 nnow0130a0206.mp3
-rw-r--r--   1 anonymous storage  11638172 Feb 13 08:22 nnow0130a0213.mp3
-rw-r--r--   1 anonymous storage  11054016 Feb 25 19:29 nnow0130a0220.mp3
-rw-r--r--   1 anonymous storage  11638172 Feb 27 07:15 nnow0130a0227.mp3
-rw-r--r--   1 anonymous storage  11638172 Mar  6 17:24 nnow0130a0306.mp3

这个结果只是字符串,那请问,怎么利用从FTP.dir()返回的信息呢?有没有什么好一点的方法呢?

谢谢
-- 
Best Regards,
Leo Jay

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年07月16日 星期六 14:25

Leo Jay python.leojay at gmail.com
Sat Jul 16 14:25:56 HKT 2005

还有,请问怎么把"Jan  9  2005"及"Mar  6 17:24"这种格式转成datetime的格式?

On 7/16/05, Leo Jay <python.leojay at gmail.com> wrote:
> 我想得到FTP里某个目录下所有文件及其日期信息,但dir()返回的是这样的结果:
> -rw-r--r--   1 anonymous storage   6650384 Jul 10 06:09 nnow0130a.mp3
> -rw-r--r--   1 anonymous storage  11638172 Jan  2  2005 nnow0130a0102.mp3
> -rw-r--r--   1 anonymous storage  11638172 Jan  9  2005 nnow0130a0109.mp3
> -rw-r--r--   1 anonymous storage  11638172 Jan 23 20:04 nnow0130a0123.mp3
> -rw-r--r--   1 anonymous storage  11638172 Jan 30 08:48 nnow0130a0130.mp3
> -rw-r--r--   1 anonymous storage  11638172 Feb  6 09:15 nnow0130a0206.mp3
> -rw-r--r--   1 anonymous storage  11638172 Feb 13 08:22 nnow0130a0213.mp3
> -rw-r--r--   1 anonymous storage  11054016 Feb 25 19:29 nnow0130a0220.mp3
> -rw-r--r--   1 anonymous storage  11638172 Feb 27 07:15 nnow0130a0227.mp3
> -rw-r--r--   1 anonymous storage  11638172 Mar  6 17:24 nnow0130a0306.mp3
> 
> 这个结果只是字符串,那请问,怎么利用从FTP.dir()返回的信息呢?有没有什么好一点的方法呢?
> 
> 谢谢
> --
> Best Regards,
> Leo Jay
> 


-- 
Best Regards,
Leo Jay

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年07月16日 星期六 14:42

limodou limodou at gmail.com
Sat Jul 16 14:42:43 HKT 2005

我以前写过两篇blog关于ftp的目录信息的解析:

[LINK]ftpparse http://www.donews.net/limodou/archive/2004/10/11/126963.aspx
[Python学习]我自已写的简单的ftpparse
http://www.donews.net/limodou/archive/2004/10/11/126994.aspx

因为我自已写的ftpparse只是为了个人使用,因此并不一定完全通用,并且没有对日期作处理,需要自已加上。你可以参考一下。

在 05-7-16,Leo Jay<python.leojay at gmail.com> 写道:
> 还有,请问怎么把"Jan  9  2005"及"Mar  6 17:24"这种格式转成datetime的格式?
> 
> On 7/16/05, Leo Jay <python.leojay at gmail.com> wrote:
> > 我想得到FTP里某个目录下所有文件及其日期信息,但dir()返回的是这样的结果:
> > -rw-r--r--   1 anonymous storage   6650384 Jul 10 06:09 nnow0130a.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Jan  2  2005 nnow0130a0102.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Jan  9  2005 nnow0130a0109.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Jan 23 20:04 nnow0130a0123.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Jan 30 08:48 nnow0130a0130.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Feb  6 09:15 nnow0130a0206.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Feb 13 08:22 nnow0130a0213.mp3
> > -rw-r--r--   1 anonymous storage  11054016 Feb 25 19:29 nnow0130a0220.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Feb 27 07:15 nnow0130a0227.mp3
> > -rw-r--r--   1 anonymous storage  11638172 Mar  6 17:24 nnow0130a0306.mp3
> >
> > 这个结果只是字符串,那请问,怎么利用从FTP.dir()返回的信息呢?有没有什么好一点的方法呢?
> >
> > 谢谢
> > --
> > Best Regards,
> > Leo Jay
> >
> 
> 
> --
> Best Regards,
> Leo Jay
> 
> _______________________________________________
> python-chinese list
> python-chinese at lists.python.cn
> http://python.cn/mailman/listinfo/python-chinese
> 
> 
> 


-- 
I like python! 
My Donews Blog: http://www.donews.net/limodou
New Google Maillist: http://groups-beta.google.com/group/python-cn

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

2005年07月16日 星期六 19:06

Jason Liu telecomliu at gmail.com
Sat Jul 16 19:06:59 HKT 2005

网上有一个解析FTP返回信息的C程序,我学习python时把它用python重新写了一遍。你看看合用不合用,里面应该有解析时间的能力。如果有错误也麻烦你指出来。

程序在附件里。

基本用法是
ftpparse(info)   ->ftpitem
info 是list返回的单个字符串。
ftpitem是包含所有解析信息的list,内容与下面的C struct对应

struct ftpparse {
  char *name; /* not necessarily 0-terminated */
  int flagtrycwd; /* 0 if cwd is definitely pointless, 1 otherwise */
  int flagtryretr; /* 0 if retr is definitely pointless, 1 otherwise */
  long size; /* number of octets */
  int mtimetype;
  time_t mtime; /* modification time */
  int idtype;
  char *id; /* not necessarily 0-terminated */
} ;
-------------- next part --------------
"""ftpparse(&fp;,buf,len) tries to parse one line of LIST output.

The line is an array of len characters stored in buf.
It should not include the terminating CR LF; so buf[len] is typically CR.

If ftpparse() can't find a filename, it returns 0.

If ftpparse() can find a filename, it fills in fp and returns 1.
fp is a struct ftpparse, defined below.
The name is an array of fp.namelen characters stored in fp.name;
fp.name points somewhere within buf.

struct ftpparse {
  char *name; /* not necessarily 0-terminated */
  int namelen;
  int flagtrycwd; /* 0 if cwd is definitely pointless, 1 otherwise */
  int flagtryretr; /* 0 if retr is definitely pointless, 1 otherwise */
  int sizetype;
  long size; /* number of octets */
  int mtimetype;
  time_t mtime; /* modification time */
  int idtype;
  char *id; /* not necessarily 0-terminated */
  int idlen;
} ;
"""
import time

class ftpparse_error(Exception):pass

FTPPARSE_SIZE_UNKNOWN = 0
FTPPARSE_SIZE_BINARY = 1 #size is the number of octets in TYPE I
FTPPARSE_SIZE_ASCII = 2 #size is the number of octets in TYPE A

FTPPARSE_MTIME_UNKNOWN = 0
FTPPARSE_MTIME_LOCAL = 1 #time is correct
FTPPARSE_MTIME_REMOTEMINUTE = 2 #time zone and secs are unknown
FTPPARSE_MTIME_REMOTEDAY = 3 #time zone and time of day are unknown

"""When a time zone is unknown, it is assumed to be GMT. You may want
to use localtime() for LOCAL times, along with an indication that the
time is correct in the local time zone, and gmtime() for REMOTE* times.
"""

FTPPARSE_ID_UNKNOWN = 0
FTPPARSE_ID_FULL = 1    #unique identifier for files on this FTP server

"""ftpparse.c, ftpparse.h: library for parsing FTP LIST responses
20001223
D. J. Bernstein, djb at cr.yp.to
http://cr.yp.to/ftpparse.html

Commercial use is fine, if you let me know what programs you're using this in.

Currently covered formats:
EPLF.
UNIX ls, with or without gid.
Microsoft FTP Service.
Windows NT FTP Server.
VMS.
WFTPD.
NetPresenz (Mac).
NetWare.
MSDOS.

Definitely not covered: 
Long VMS filenames, with information split across two lines.
NCSA Telnet FTP server. Has LIST = NLST (and bad NLST for directories).
"""
def totai(year, month, mday):
    if month >=2: month -=2
    else:
        month += 10
        year -= 1
    result = (mday - 1) * 10 + 5 + 306 * month
    result /= 10
    if result == 365:
        year -= 3
        result = 1460
    else: result = result + 365 * (year % 4)
    year /= 4
    result = result + 1461 * (year %25)
    year /= 25
    if result == 36524:
        year -= 3
        result = 146096
    else:  result = result + 36524 * (year % 4)
    year /= 4
    result = result + 146097 * (year - 5)
    result += 11017
    return result * 86400
#--------------------------------------------------------
#static int flagneedbase = 1;
#static time_t base; /* time() value on this OS at the beginning of 1970 TAI */
#static long now; /* current time */
#static int flagneedcurrentyear = 1;
#static long currentyear; /* approximation to current year */
__flagneedbase = True
__base = 0 #time() value on this OS at the beginning of 1970 TAI 
__now = 0
__flagneedcurrentyear = True
__currentyeat = 0
def initbase():
    global __flagneedbase, __base
    if not __flagneedbase: return

    __base = 0
#    t = time.gmtime(0)
    t = time.localtime(0)
    __base = -(totai(t[0], t[1]-1, t[2]) + t[3] * 3600 + t[4] * 60 + t[5])
    #assumes the right time_t, counting seconds.
    #base may be slightly off if time_t counts non-leap seconds.
    __flagneedbase = False

#--------------------------------------------------------------

def initnow():
    global __now, __flagneedcurrentyear, __base, __currentyear
    initbase()
    __now = int(time.time()) - __base

    if __flagneedcurrentyear:
        day = __now / 86400
        if __now%86400 < 0: day -= 1
        day -= 11017
        year = 5 + day / 146097
        day = day % 146097
        if day < 0:
            day += 146097
            year -= 1
        year *= 4
        if day == 146096:
            year += 3
            day = 36524
        else:
            year = year + day / 36524
            day %= 36524
        year *= 25
        year = year + day / 1461
        day %= 1461
        year *= 4
        if day == 1460:
            year += 3
            day = 365
        else:
            year = year + day / 365
            day %= 365
        day *= 10
        if (day + 5) / 306 >= 10: year += 1
        __currentyear = year
        __flagneedcurrentyear = False
#---------------------------------------------------

def guesstai(month, mday):
    global __currentyear, __now
    initnow()

    for year in range(__currentyear-1, __currentyear + 101):
        t = totai(year, month, mday)
        if __now - t < 350 * 86400: return t
#---------------------------------------------------

__months = ["jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"]

def getmonth(buf):
    global __months
    if len(buf) == 3:
        try:
            return __months.index(buf.lower())
        except:
            return -1
    return -1
#---------------------------------------------------

def getlong(buf):
    u = 0
    for c in buf:
        u = u * 10 + ord(c) - ord('0')
    return u
#---------------------------------------------------
class ftpitem(object):
    def __init__(self):
        self.name = ''
        self.flagtrycwd = False
        self.flagtryretr = False
        self.sizetype = FTPPARSE_SIZE_UNKNOWN
        self.size = 0
        self.mtimetype = FTPPARSE_MTIME_UNKNOWN
        self.mtime = 0
        self.idtype = FTPPARSE_ID_UNKNOWN
        self.id = ''

    def __repr__(self):
        s = 'name:' + self.name + ' size:' + str(self.size) + ' date:' + str(time.localtime(self.mtime))
        return s

    def __getdatetime(self):
        return time.localtime(self.mtime)
    def isdir(): return self.flagtrycwd
    def isfile(): return self.flagtryretr
    datetime = property(__getdatetime, doc="get file's datetime")
#---------------------------------------------------

def ftpparse(buf):
    fp = ftpitem()
    
    if len(buf) < 2: raise ftpparse_error(), 'list string is too short'
    blen = len(buf)
    if buf[0] == '+':
    #/* see http://pobox.com/~djb/proto/eplf.txt */
    #/* "+i8388621.29609,m824255902,/,\tdev" */
    #/* "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF" */
        i = 1
        for j in range(1, blen):
            if ord(buf[j]) == 9:
                fp.name = buf[j + 1:]
                return fp
            if buf[j] == ',':
                print buf[j], j, i
                if buf[i] == '/': fp.flagtrycwd = True
                elif buf[i] == 'r': fp.flagtryretr = True
                elif buf[i] == 's': 
                    fp.sizetype = FTPPARSE_SIZE_BINARY
                    fp.size = getlong(buf[i+1:j])
                elif buf[i] == 'm':
                    fp.mtimetype = FTPPARSE_MTIME_LOCAL
                    initbase()
                    fp.mtime = __base + getlong(buf[i+1: j])
                    #print __base + getlong(buf[i+1: j]), __base
                elif buf[i] == 'i':
                    fp.idtype = FTPPARSE_ID_FULL
                    fp.id = buf[i+1:]
                i = j + 1
        raise ftpparse_error(), ' list string in unknown format'
        #end of buf[0] == '+'
    #/* UNIX-style listing, without inum and without blocks */
    #/* "-rw-r--r--   1 root     other        531 Jan 29 03:26 README" */
    #/* "dr-xr-xr-x   2 root     other        512 Apr  8  1994 etc" */
    #/* "dr-xr-xr-x   2 root     512 Apr  8  1994 etc" */
    #/* "lrwxrwxrwx   1 root     other          7 Jan 25 00:17 bin -> usr/bin" */
    #/* Also produced by Microsoft's FTP servers for Windows: */
    #/* "----------   1 owner    group         1803128 Jul 10 10:18 ls-lR.Z" */
    #/* "d---------   1 owner    group               0 May  9 19:45 Softlib" */
    #/* Also WFTPD for MSDOS: */
    #/* "-rwxrwxrwx   1 noone    nogroup      322 Aug 19  1996 message.ftp" */
    #/* Also NetWare: */
    #/* "d [R----F--] supervisor            512       Jan 16 18:53    login" */
    #/* "- [R----F--] rhesus             214059       Oct 20 15:27    cx.exe" */
    #/* Also NetPresenz for the Mac: */
    #/* "-------r--         326  1391972  1392298 Nov 22  1995 MegaPhone.sit" */
    #/* "drwxrwxr-x               folder        2 May 10  1996 network" */
    elif buf[0] in ['b', 'c', 'd', 'l', 'p', 's', '-']:
        if buf[0] == 'd': fp.flagtrycwd = True
        elif buf[0] == '-': fp.flagtryretr = True
        elif buf[0] == 'l': 
            fp.flagtrycwd = True
            fp.flagtryretr = True

        state = 1
        i = 0;
        for j in range(1, blen):
            if buf[j] == ' ' and buf[j-1] != ' ':
                if state == 1: state = 2
                elif state == 2:
                    state = 3
                    if j-i == 6 and buf[i] == 'f': state = 4
                elif state == 3: state = 4
                elif state == 4:
                    size = getlong(buf[i:j])
                    state = 5
                elif state == 5:
                    month = getmonth(buf[i:j])
                    if month >= 0: state = 6
                    else: size = getlong(buf[i:j])
                elif state == 6:
                    mday = getlong(buf[i:j])
                    state = 7
                elif state == 7:
                    if j-i == 4 and buf[i+1] == ':':
                        hour = getlong(buf[i:i+1])
                        minute = getlong(buf[i+2:i+4])
                        fp.mtimetype = FTPPARSE_MTIME_REMOTEMINUTE
                        initbase()
                        fp.mtime = __base + quesstai(month, mdy) + hour * 3600 + minute * 60
                    elif j-i == 5 and buf[i+2] == ':':
                        hour = getlong(buf[i:i+2])
                        minute = getlong(buf[i+3:i+5])
                        fp.mtimetype = FTPPARSE_MTIME_REMOTEMINUTE
                        initbase()
                        fp.mtime = __base + guesstai(month,mday) + hour * 3600 + minute * 60
                    elif j-i >= 4:
                        year = getlong(buf[i:j])
                        fp.mtimetype = FTPPARSE_MTIME_REMOTEDAY
                        initbase()
                        fp.mtime = __base + totai(year, month, mday)
                    else: return 0
                    fp.name = buf[j+1:]
                    state = 8
                elif state == 8: pass
                i = j + 1
            while i < blen and buf[i] == ' ': i += 1

        if state != 8: 
            print state
            raise ftpparse_error(), 'list string in unknown format'

        fp.size = size
        fp.sizetype = FTPPARSE_SIZE_BINARY

#        if buf[0] == 'l': # maybe not suit for implement
#            if ' -> ' in fp.name:
#                idx = fp.name.index(' -> ')
#                fp.name = fp.name[:idx]

        #/* eliminate extra NetWare spaces */
        if buf[1] == ' ' or buf[1] == '[':
            fp.name = fp.name.lstrip()

        return fp
        #end of buf[0] in ['b', 'c', 'd', 'l', 'p', 's', '-']
    #/* MultiNet (some spaces removed from examples) */
    #/* "00README.TXT;1      2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)" */
    #/* "CORE.DIR;1          1  8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)" */
    #/* and non-MutliNet VMS: */
    #/* "CII-MANUAL.TEX;1  213/216  29-JAN-1996 03:33:12  [ANONYMOU,ANONYMOUS]   (RWED,RWED,,)" */
    if ';' in buf:
        i = buf.index(';')
        if '.DIR' in buf:
            idx = buf.index('.DIR')
            fp.name = buf[:idx]
            fp.flagtrycwd = True
        else:
            fp.name= buf[:i]
            fp.flagtrycwd = True
        try:
            while buf[i] != ' ': i += 1
            while buf[i] == ' ': i += 1
            while buf[i] != ' ': i += 1
            while buf[i] == ' ': i += 1
            j = i
            while buf[j] != '-': j += 1
            mday = getlong(buf[i:j])
            while buf[j] == '-': j += 1
            i = j
            while buf[j] != '-': j += 1
            month = getmonth(buf[i:j])
            if month < 0: raise
            while buf[j] == '-': j += 1
            i = j
            while buf[j] != ' ': j += 1
            year = getlong(buf[i:j])
            while buf[j] == ' ': j += 1
            i = j
            while buf[j] != ':': j += 1
            hour = getlong(buf[i:j])
            while buf[j] == ':': j += 1
            i = j
            while buf[j] != ':' and buf[j] != ' ': j += 1
            minute = getlong(buf[i:j])
        except:
            raise ftpparse_error, 'list string in unknown format'

        fp.mtimetype = FTPPARSE_MTIME_REMOTEMINUTE
        initbase()
        fp.mtime = __base + totai(year,month,mday) + hour * 3600 + minute * 60

        return fp

    #/* MSDOS format */
    #/* 04-27-00  09:09PM                 licensed */
    #/* 07-18-00  10:16AM                 pub */
    #/* 04-14-00  03:47PM                  589 readme.htm */
    if buf[0] in '0123456789':
        i = 0
        j = 0
        try:
            while buf[j] != '-': j += 1
            month = getlong(buf[i:j]) - 1
            while buf[j] == '-': j += 1
            i = j
            while buf[j] != '-': j += 1
            mday = getlong(buf[i:j])
            while buf[j] == '-': j += 1
            i = j
            while buf[j] != ' ': j += 1
            year = getlong(buf[i:j])
            if year < 50: year += 2000
            if year < 1000: year += 1900 #?
            while buf[j] == ' ': j += 1
            i = j
            while buf[j] != ':': j += 1
            hour = getlong(buf[i:j])
            while buf[j] == ':': j += 1
            i = j
            while buf[j] != 'A' and buf[j] != 'P': j += 1
            minute = getlong(buf[i:j])
            if hour == 12: hour = 0
            if buf[j] == 'A': j += 1
            if buf[j] == 'P':
                hour += 12
                j += 1
            if buf[j] == 'M': j += 1

            while buf[j] == ' ': j += 1
            if buf[j] == '<':
                fp.flagtrycwd = True
                while buf[j] != ' ': j += 1
            else:
                i = j
                while buf[j] != ' ': j += 1
                fp.size = getlong(buf[i:j])
                fp.sizetype = FTPPARSE_SIZE_BINARY
                fp['flagtrretr'] = True
            while buf[j] == ' ': j += 1

            fp.name = buf[j:]
        except:
            raise ftpparse_error, 'list string in unknown format'

        fp.mtimetype = FTPPARSE_MTIME_REMOTEMINUTE
        initbase()
        fp.mtime = __base + totai(year,month,mday) + hour * 3600 + minute * 60

        return fp

    raise ftpparse_error(), 'list string in unknown format'
#---------------------------------------------------------
def urltoftp(url):
    host = username = password = root = ''
    port = 21
    url = string.lower(url)
    url = string.strip(url)
    url = string.strip(url, '/')
    if 'ftp://' == url[:6]: url = url[6:] #remove "ftp://"
    if '/' in url:
        root = url[url.index('/'):]
        url = url[:url.index('/')]
    if '@' in url:
        acct = url[:url.index('@')]
        if ':' in acct:
            username = acct[:acct.index(':')]
            password = acct[(acct.index(':') + 1):]
        else:
            username = acct
        url = url[(url.index('@') + 1):]
    if ':' in url:
        host = url[:url.index(':')]
        try:
            port = int(url[(url.index(':') + 1):])
        except:
            pass
    else: host = url
    return host, username, password, port, root
if __name__ == "__main__":
    ls ="dr-xr-xr-x   2 root     other        512 Apr  8  1994 etc"
    fp = ftpparse(ls)
    print fp
    print fp.datetime

[导入自Mailman归档:http://www.zeuux.org/pipermail/zeuux-python]

如下红色区域有误,请重新填写。

    你的回复:

    请 登录 后回复。还没有在Zeuux哲思注册吗?现在 注册 !

    Zeuux © 2025

    京ICP备05028076号