[ftputil] Bug in synchronize_times()?
Christopher Arndt
chris.arndt at web.de
Sat Jul 2 23:12:18 CEST 2005
Hi,
I currently live in Galway, Ireland, so my timezone (GMT+DST) is one
hour behind the one the FTP Server of my webspace provider uses (CST).
So I tried to use synchronize_time() with the result that ftputil thinks
the files on my server are 1 _year_ behind and (logically) refuses to
set such a big time shift.
Looking in the source code, I found that synchronize_times() uses the
getmtime() method on a newly created file on the server, to determine
the server's idea of the current time.
Looking in ftp_stat.py you'll find the culprit in line 295-298:
if st_mtime > time.time() + self._host.time_shift() + 60.0:
# if it's in the future, use previous year
st_mtime = time.mktime( (year-1, month, day,
hour, minute, 0, 0, 0, -1) )
That is, getmtime() already tries to account for the timeshift, which is
not set yet, by the time synchronize_times() uses getmtime() to
determine the file's mtime!
Solution: either synchronize should employ it's own method of finding
out the mtime of the newly created file (but that would mean a lot of
code duplication) or the parse_line() method in the _Stat class should
provide some means to switch of the time shift temporarily.
I also tried to devise another method of finding out the server's idea
about it's local time by looking at the welcome message the server provides.
This is what the ProFTP server of my webspace provider gives:
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 23:00. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
You can see, that he gives the local time, but no date year or
whatsoever. This complicates the matter a bit, because you have to take
into account, that it's still the previous or the next day.
So I came up with the following crude hack:
import ftputil, time
class MyFTPHost(ftputil.FTPHost):
"""FTP host class that tries to find out the server time
from the welcome message.
"""
def __init__(self, *args, **kwargs):
ftputil.FTPHost.__init__(self, *args, **kwargs)
ltime = time.time()
stime = self._get_servertime(ltime)
if stime:
time_shift = stime - ltime
# round to nearest minute
self.set_time_shift(round(time_shift/60.)*60)
def _get_servertime(self, ltime):
"""Should be called immediately after connect."""
for line in self._session.getwelcome().split('\n'):
line = line.lower()
if line.find('local time') >= 0:
break
else:
return
import re
m = re.search('(\d\d):(\d\d)', line)
if m:
ltime = list(time.localtime(ltime))
hour, minute = int(m.group(1)), int(m.group(2))
if ltime[3] > 12 and abs(hour-ltime[3]) > 12:
ltime[2] += 1
ltime[3] = hour
ltime[4] = minute
ltime[5] = 0
ltime[8] = -1
return time.mktime(tuple(ltime))
It kinda works for me, but will probably not with other FTP server.
Cheers, Chris
More information about the ftputil
mailing list