Changeset 246
- Timestamp:
- 2003-06-09 15:52:02 (6 years ago)
- Files:
-
- trunk/ftp_stat.py (modified) (2 diffs)
- trunk/ftputil.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ftp_stat.py
r244 r246 34 34 """ 35 35 36 # $Id: ftp_stat.py,v 1.3 2003/06/09 12:47:29 schwa Exp $ 37 36 # $Id: ftp_stat.py,v 1.4 2003/06/09 15:52:02 schwa Exp $ 37 38 import stat 38 39 import sys 40 import time 41 42 import ftp_error 39 43 40 44 … … 87 91 return stat_results 88 92 93 94 class _UnixStatParser(_StatParser): 95 # map month abbreviations to month numbers 96 _month_numbers = { 97 'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 98 'may': 5, 'jun': 6, 'jul': 7, 'aug': 8, 99 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12} 100 101 def parse_line(self, line): 102 """ 103 Return `_Stat` instance corresponding to the given text line. 104 If the line can't be parsed, raise a `ParserError`. 105 """ 106 metadata, nlink, user, group, size, month, day, \ 107 year_or_time, name = line.split(None, 8) 108 # st_mode 109 st_mode = 0 110 for bit in metadata[1:10]: 111 bit = (bit != '-') 112 st_mode = (st_mode << 1) + bit 113 if metadata[3] == 's': 114 st_mode = st_mode | stat.S_ISUID 115 if metadata[6] == 's': 116 st_mode = st_mode | stat.S_ISGID 117 char_to_mode = {'d': stat.S_IFDIR, 'l': stat.S_IFLNK, 118 'c': stat.S_IFCHR, '-': stat.S_IFREG} 119 file_type = metadata[0] 120 if char_to_mode.has_key(file_type): 121 st_mode = st_mode | char_to_mode[file_type] 122 else: 123 raise ftp_error.ParserError( 124 "unknown file type character '%s'" % file_type) 125 # st_ino, st_dev, st_nlink, st_uid, st_gid, st_size, st_atime 126 st_ino = None 127 st_dev = None 128 st_nlink = int(nlink) 129 st_uid = user 130 st_gid = group 131 st_size = int(size) 132 st_atime = None 133 # st_mtime 134 month = self._month_numbers[ month.lower() ] 135 day = int(day) 136 if year_or_time.find(':') == -1: 137 # `year_or_time` is really a year 138 year, hour, minute = int(year_or_time), 0, 0 139 st_mtime = time.mktime( (year, month, day, hour, 140 minute, 0, 0, 0, -1) ) 141 else: 142 # `year_or_time` is a time hh:mm 143 hour, minute = year_or_time.split(':') 144 year, hour, minute = None, int(hour), int(minute) 145 # try the current year 146 year = time.localtime()[0] 147 st_mtime = time.mktime( (year, month, day, hour, 148 minute, 0, 0, 0, -1) ) 149 if st_mtime > time.time(): 150 # if it's in the future, use previous year 151 st_mtime = time.mktime( (year-1, month, day, 152 hour, minute, 0, 0, 0, -1) ) 153 # st_ctime 154 st_ctime = None 155 # st_name 156 if name.find(' -> ') != -1: 157 st_name, st_target = name.split(' -> ') 158 else: 159 st_name, st_target = name, None 160 result = _Stat( (st_mode, st_ino, st_dev, st_nlink, st_uid, 161 st_gid, st_size, st_atime, st_mtime, st_ctime) ) 162 result._st_name = st_name 163 result._st_target = st_target 164 return result 165 166 167 class _MSStatParser(_StatParser): 168 def parse_line(self, line): 169 """ 170 Return `_Stat` instance corresponding to the given text line 171 from a MS ROBIN FTP server. If the line can't be parsed, 172 raise a `ParserError`. 173 """ 174 date, time_, dir_or_size, name = line.split(None, 3) 175 # st_mode 176 st_mode = 0400 # default to read access only; 177 # in fact, we can't tell 178 if dir_or_size == '<DIR>': 179 st_mode = st_mode | stat.S_IFDIR 180 else: 181 st_mode = st_mode | stat.S_IFREG 182 # st_ino, st_dev, st_nlink, st_uid, st_gid 183 st_ino = None 184 st_dev = None 185 st_nlink = None 186 st_uid = None 187 st_gid = None 188 # st_size 189 if dir_or_size != '<DIR>': 190 st_size = int(dir_or_size) 191 else: 192 st_size = None 193 # st_atime 194 st_atime = None 195 # st_mtime 196 month, day, year = map( int, date.split('-') ) 197 if year >= 70: 198 year = 1900 + year 199 else: 200 year = 2000 + year 201 hour, minute, am_pm = time_[0:2], time_[3:5], time_[5] 202 hour, minute = int(hour), int(minute) 203 if am_pm == 'P': 204 hour = 12 + hour 205 st_mtime = time.mktime( (year, month, day, hour, 206 minute, 0, 0, 0, -1) ) 207 # st_ctime 208 st_ctime = None 209 result = _Stat( (st_mode, st_ino, st_dev, st_nlink, st_uid, 210 st_gid, st_size, st_atime, st_mtime, st_ctime) ) 211 # _st_name and _st_target 212 result._st_name = name 213 result._st_target = None 214 return result 89 215 90 216 trunk/ftputil.py
r240 r246 30 30 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 31 32 # $Id: ftputil.py,v 1.1 19 2003/06/08 19:47:13schwa Exp $32 # $Id: ftputil.py,v 1.120 2003/06/09 15:52:02 schwa Exp $ 33 33 34 34 """ … … 170 170 if response.find('ROBIN Microsoft') != -1 or \ 171 171 response.find('Bliss_Server Microsoft') != -1: 172 self._parser = self._parse_ms_line172 self._parser = ftp_stat._MSStatParser() 173 173 else: 174 self._parser = self._parse_unix_line174 self._parser = ftp_stat._UnixStatParser() 175 175 176 176 # … … 521 521 if stat_result is not None: 522 522 names.append(stat_result._st_name) 523 ftp_error._try_with_oserror(self._session.dir, path, callback )523 ftp_error._try_with_oserror(self._session.dir, path, callback=callback) 524 524 return names 525 525 … … 529 529 if line.find(wanted_name) != -1 ] 530 530 531 _month_numbers = {532 'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4,533 'may': 5, 'jun': 6, 'jul': 7, 'aug': 8,534 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12}535 536 def _parse_unix_line(self, line):537 """538 Return `_Stat` instance corresponding to the given text line.539 Exceptions are caught in `_parse_line`.540 """541 metadata, nlink, user, group, size, month, day, \542 year_or_time, name = line.split(None, 8)543 # st_mode544 st_mode = 0545 for bit in metadata[1:10]:546 bit = (bit != '-')547 st_mode = (st_mode << 1) + bit548 if metadata[3] == 's':549 st_mode = st_mode | stat.S_ISUID550 if metadata[6] == 's':551 st_mode = st_mode | stat.S_ISGID552 char_to_mode = {'d': stat.S_IFDIR, 'l': stat.S_IFLNK,553 'c': stat.S_IFCHR, '-': stat.S_IFREG}554 file_type = metadata[0]555 if char_to_mode.has_key(file_type):556 st_mode = st_mode | char_to_mode[file_type]557 else:558 raise ftp_error.ParserError(559 "unknown file type character '%s'" % file_type)560 # st_ino, st_dev, st_nlink, st_uid, st_gid, st_size, st_atime561 st_ino = None562 st_dev = None563 st_nlink = int(nlink)564 st_uid = user565 st_gid = group566 st_size = int(size)567 st_atime = None568 # st_mtime569 month = self._month_numbers[ month.lower() ]570 day = int(day)571 if year_or_time.find(':') == -1:572 # `year_or_time` is really a year573 year, hour, minute = int(year_or_time), 0, 0574 st_mtime = time.mktime( (year, month, day, hour,575 minute, 0, 0, 0, -1) )576 else:577 # `year_or_time` is a time hh:mm578 hour, minute = year_or_time.split(':')579 year, hour, minute = None, int(hour), int(minute)580 # try the current year581 year = time.localtime()[0]582 st_mtime = time.mktime( (year, month, day, hour,583 minute, 0, 0, 0, -1) )584 if st_mtime > time.time():585 # if it's in the future, use previous year586 st_mtime = time.mktime( (year-1, month, day,587 hour, minute, 0, 0, 0, -1) )588 # st_ctime589 st_ctime = None590 # st_name591 if name.find(' -> ') != -1:592 st_name, st_target = name.split(' -> ')593 else:594 st_name, st_target = name, None595 result = ftp_stat._Stat( (st_mode, st_ino, st_dev, st_nlink,596 st_uid, st_gid, st_size, st_atime,597 st_mtime, st_ctime) )598 result._st_name = st_name599 result._st_target = st_target600 return result601 602 def _parse_ms_line(self, line):603 """604 Return `_Stat` instance corresponding to the given text line605 from a MS ROBIN FTP server. Exceptions are caught in606 `_parse_line`.607 """608 date, time_, dir_or_size, name = line.split(None, 3)609 # st_mode610 st_mode = 0400 # default to read access only;611 # in fact, we can't tell612 if dir_or_size == '<DIR>':613 st_mode = st_mode | stat.S_IFDIR614 else:615 st_mode = st_mode | stat.S_IFREG616 # st_ino, st_dev, st_nlink, st_uid, st_gid617 st_ino = None618 st_dev = None619 st_nlink = None620 st_uid = None621 st_gid = None622 # st_size623 if dir_or_size != '<DIR>':624 st_size = int(dir_or_size)625 else:626 st_size = None627 # st_atime628 st_atime = None629 # st_mtime630 month, day, year = map( int, date.split('-') )631 if year >= 70:632 year = 1900 + year633 else:634 year = 2000 + year635 hour, minute, am_pm = time_[0:2], time_[3:5], time_[5]636 hour, minute = int(hour), int(minute)637 if am_pm == 'P':638 hour = 12 + hour639 st_mtime = time.mktime( (year, month, day, hour,640 minute, 0, 0, 0, -1) )641 # st_ctime642 st_ctime = None643 result = ftp_stat._Stat( (st_mode, st_ino, st_dev, st_nlink,644 st_uid, st_gid, st_size, st_atime,645 st_mtime, st_ctime) )646 # _st_name and _st_target647 result._st_name = name648 result._st_target = None649 return result650 651 531 def _parse_line(self, line, fail=True): 652 532 """Return `_Stat` instance corresponding to the given text line.""" 653 533 try: 654 return self._parser (line)534 return self._parser.parse_line(line) 655 535 except (ValueError, IndexError): 656 536 if fail:
