2005年07月16日 星期六 12:18
我想得到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
2005年07月16日 星期六 14:25
还有,请问怎么把"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
2005年07月16日 星期六 14:42
我以前写过两篇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
2005年07月16日 星期六 19:06
网上有一个解析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
Zeuux © 2025
京ICP备05028076号