robust parser for timestamps

This commit is contained in:
lelo 2025-04-02 09:36:13 +00:00
parent 35d204d9b0
commit dd4c417200
2 changed files with 42 additions and 7 deletions

View File

@ -56,6 +56,40 @@ def get_device_type(user_agent):
else:
return 'Other'
def parse_timestamp(ts_str):
try:
# Try the normal ISO parsing.
return datetime.fromisoformat(ts_str)
except ValueError as e:
if 'unconverted data remains' in str(e):
# Find where the timezone starts. Look for a '+' or '-' after the time.
for sign in ['+', '-']:
pos = ts_str.find(sign)
if pos != -1:
# Assume the base part is up to pos and then the tz part
base = ts_str[:pos]
tz_part = ts_str[pos:]
# Remove any colon from the tz part to help with parsing.
tz_clean = tz_part.replace(':', '')
# Try parsing the base part. It might or might not have fractional seconds.
try:
dt = datetime.fromisoformat(base)
except ValueError:
dt = datetime.strptime(base, '%Y-%m-%dT%H:%M:%S')
# Extract hours and minutes from the tz portion.
try:
offset_hours = int(tz_clean[1:3])
offset_minutes = int(tz_clean[3:5])
except Exception:
raise ValueError(f"Unable to parse timezone from {ts_str}")
offset = timedelta(hours=offset_hours, minutes=offset_minutes)
if tz_clean[0] == '-':
offset = -offset
# Return a timezone-aware datetime.
return dt.replace(tzinfo=timezone(offset))
# If it's some other ValueError, re-raise it.
raise
def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id, cached):
"""Insert a file access record into the database and prune entries older than 10 minutes."""
global file_access_temp
@ -70,11 +104,11 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
''', (iso_ts, rel_path, filesize, mime, ip_address, user_agent, device_id, cached))
# Remove entries older than 10 minutes
# Remove entries older than 10 minutes using our robust parser.
cutoff_time = datetime.now(timezone.utc).astimezone() - timedelta(minutes=10)
file_access_temp[:] = [
entry for entry in file_access_temp
if datetime.fromisoformat(entry[0]) >= cutoff_time
if parse_timestamp(entry[0]) >= cutoff_time
]
# Add the new entry at the beginning of the list

5
app.py
View File

@ -364,7 +364,7 @@ def query_recent_connections():
rows = a.return_file_access()
connections = [
{
'timestamp': datetime.strptime(row[0], '%Y-%m-%dT%H:%M:%S.%f').strftime('%d.%m.%Y %H:%M:%S'),
'timestamp': datetime.fromisoformat(row[0]).strftime('%d.%m.%Y %H:%M:%S'),
'full_path': row[1],
'filesize': row[2],
'mime_typ': row[3],
@ -384,6 +384,7 @@ def query_recent_connections():
background_thread_running = False
print("No clients connected; stopping query thread.")
@socketio.on('connect')
def handle_connect(auth=None):
global clients_connected, background_thread_running
@ -405,7 +406,7 @@ def handle_request_initial_data():
rows = a.return_file_access()
connections = [
{
'timestamp': datetime.strptime(row[0], '%Y-%m-%dT%H:%M:%S.%f').strftime('%d.%m.%Y %H:%M:%S'),
'timestamp': datetime.fromisoformat(row[0]).strftime('%d.%m.%Y %H:%M:%S'),
'full_path': row[1],
'filesize' : row[2],
'mime_typ' : row[3],