robust parser for timestamps
This commit is contained in:
parent
35d204d9b0
commit
dd4c417200
38
analytics.py
38
analytics.py
@ -56,6 +56,40 @@ def get_device_type(user_agent):
|
|||||||
else:
|
else:
|
||||||
return 'Other'
|
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):
|
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."""
|
"""Insert a file access record into the database and prune entries older than 10 minutes."""
|
||||||
global file_access_temp
|
global file_access_temp
|
||||||
@ -70,11 +104,11 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
|
|||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
''', (iso_ts, rel_path, filesize, mime, ip_address, user_agent, device_id, cached))
|
''', (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)
|
cutoff_time = datetime.now(timezone.utc).astimezone() - timedelta(minutes=10)
|
||||||
file_access_temp[:] = [
|
file_access_temp[:] = [
|
||||||
entry for entry in 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
|
# Add the new entry at the beginning of the list
|
||||||
|
|||||||
5
app.py
5
app.py
@ -364,7 +364,7 @@ def query_recent_connections():
|
|||||||
rows = a.return_file_access()
|
rows = a.return_file_access()
|
||||||
connections = [
|
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],
|
'full_path': row[1],
|
||||||
'filesize': row[2],
|
'filesize': row[2],
|
||||||
'mime_typ': row[3],
|
'mime_typ': row[3],
|
||||||
@ -384,6 +384,7 @@ def query_recent_connections():
|
|||||||
background_thread_running = False
|
background_thread_running = False
|
||||||
print("No clients connected; stopping query thread.")
|
print("No clients connected; stopping query thread.")
|
||||||
|
|
||||||
|
|
||||||
@socketio.on('connect')
|
@socketio.on('connect')
|
||||||
def handle_connect(auth=None):
|
def handle_connect(auth=None):
|
||||||
global clients_connected, background_thread_running
|
global clients_connected, background_thread_running
|
||||||
@ -405,7 +406,7 @@ def handle_request_initial_data():
|
|||||||
rows = a.return_file_access()
|
rows = a.return_file_access()
|
||||||
connections = [
|
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],
|
'full_path': row[1],
|
||||||
'filesize' : row[2],
|
'filesize' : row[2],
|
||||||
'mime_typ' : row[3],
|
'mime_typ' : row[3],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user