fix timezone-aware timestamp
This commit is contained in:
parent
b500496176
commit
35d204d9b0
25
analytics.py
25
analytics.py
@ -1,6 +1,6 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
from flask import render_template, request, session
|
from flask import render_template, request, session
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta, timezone
|
||||||
import geoip2.database
|
import geoip2.database
|
||||||
from auth import require_secret
|
from auth import require_secret
|
||||||
import os
|
import os
|
||||||
@ -59,7 +59,8 @@ def get_device_type(user_agent):
|
|||||||
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
|
||||||
timestamp = datetime.now()
|
# Create a timezone-aware timestamp (local time with offset)
|
||||||
|
timestamp = datetime.now(timezone.utc).astimezone()
|
||||||
iso_ts = timestamp.isoformat()
|
iso_ts = timestamp.isoformat()
|
||||||
|
|
||||||
with log_db:
|
with log_db:
|
||||||
@ -70,7 +71,7 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
|
|||||||
''', (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
|
||||||
cutoff_time = datetime.now() - 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 datetime.fromisoformat(entry[0]) >= cutoff_time
|
||||||
@ -81,9 +82,19 @@ def log_file_access(rel_path, filesize, mime, ip_address, user_agent, device_id,
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def return_file_access():
|
def return_file_access():
|
||||||
"""Return recent file access logs from memory."""
|
"""Return recent file access logs from memory (the last 10 minutes)."""
|
||||||
global file_access_temp
|
global file_access_temp
|
||||||
return file_access_temp
|
if file_access_temp:
|
||||||
|
# Create a timezone-aware cutoff time
|
||||||
|
cutoff_time = datetime.now(timezone.utc).astimezone() - timedelta(minutes=10)
|
||||||
|
# Only keep entries with timestamps greater than or equal to cutoff_time
|
||||||
|
file_access_temp[:] = [
|
||||||
|
entry for entry in file_access_temp
|
||||||
|
if datetime.fromisoformat(entry[0]) >= cutoff_time
|
||||||
|
]
|
||||||
|
return file_access_temp
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
@require_secret
|
@require_secret
|
||||||
def connections():
|
def connections():
|
||||||
@ -162,7 +173,7 @@ def dashboard():
|
|||||||
if session['timeframe'] == 'last24hours':
|
if session['timeframe'] == 'last24hours':
|
||||||
# Group by hour: substr(timestamp, 12, 2) -> HH
|
# Group by hour: substr(timestamp, 12, 2) -> HH
|
||||||
query = f'''
|
query = f'''
|
||||||
SELECT substr(timestamp, 1, 13) AS bucket, COUNT(DISTINCT device_id) AS count
|
SELECT strftime('%Y-%m-%dT%H:00:00Z', replace(timestamp, 'T', ' ')) AS bucket, COUNT(DISTINCT device_id) AS count
|
||||||
FROM file_access_log
|
FROM file_access_log
|
||||||
WHERE timestamp >= ? {filetype_filter_sql}
|
WHERE timestamp >= ? {filetype_filter_sql}
|
||||||
GROUP BY bucket
|
GROUP BY bucket
|
||||||
@ -207,7 +218,7 @@ def dashboard():
|
|||||||
if session['timeframe'] == 'last24hours':
|
if session['timeframe'] == 'last24hours':
|
||||||
# Hour: substr(timestamp, 12, 2) -> HH
|
# Hour: substr(timestamp, 12, 2) -> HH
|
||||||
query = f'''
|
query = f'''
|
||||||
SELECT substr(timestamp, 1, 13) AS bucket, COUNT(*) AS count
|
SELECT strftime('%Y-%m-%dT%H:00:00Z', replace(timestamp, 'T', ' ')) AS bucket, COUNT(*) AS count
|
||||||
FROM file_access_log
|
FROM file_access_log
|
||||||
WHERE timestamp >= ? {filetype_filter_sql}
|
WHERE timestamp >= ? {filetype_filter_sql}
|
||||||
GROUP BY bucket
|
GROUP BY bucket
|
||||||
|
|||||||
48
convert_db.py
Normal file
48
convert_db.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sqlite3
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
# Name of your SQLite database file
|
||||||
|
DB_NAME = 'access_log.db'
|
||||||
|
|
||||||
|
def convert_naive_to_timezone_aware(naive_ts):
|
||||||
|
"""
|
||||||
|
Convert a naive ISO timestamp (assumed to be in local time) into a timezone-aware timestamp.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
dt = datetime.fromisoformat(naive_ts)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error parsing timestamp {naive_ts}: {e}")
|
||||||
|
return naive_ts # If parsing fails, return the original value
|
||||||
|
|
||||||
|
# If the timestamp is naive (i.e., no tzinfo), make it timezone-aware by assuming it's local time.
|
||||||
|
if dt.tzinfo is None:
|
||||||
|
# Get the local timezone info using the current time's offset.
|
||||||
|
local_tz = datetime.now(timezone.utc).astimezone().tzinfo
|
||||||
|
dt = dt.replace(tzinfo=local_tz)
|
||||||
|
return dt.isoformat()
|
||||||
|
else:
|
||||||
|
# Timestamp is already timezone-aware
|
||||||
|
return naive_ts
|
||||||
|
|
||||||
|
def update_database():
|
||||||
|
conn = sqlite3.connect(DB_NAME)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Fetch all records' IDs and timestamps
|
||||||
|
cursor.execute("SELECT id, timestamp FROM file_access_log")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
updated_count = 0
|
||||||
|
|
||||||
|
for rec_id, ts in rows:
|
||||||
|
new_ts = convert_naive_to_timezone_aware(ts)
|
||||||
|
if new_ts != ts:
|
||||||
|
cursor.execute("UPDATE file_access_log SET timestamp = ? WHERE id = ?", (new_ts, rec_id))
|
||||||
|
updated_count += 1
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
print(f"Updated {updated_count} records to timezone-aware timestamps.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
update_database()
|
||||||
@ -216,18 +216,18 @@
|
|||||||
const timeframe = "{{ timeframe }}"; // e.g., 'last24hours', '7days', '30days', or '365days'
|
const timeframe = "{{ timeframe }}"; // e.g., 'last24hours', '7days', '30days', or '365days'
|
||||||
const shiftedLabels = timeframeData.map(item => {
|
const shiftedLabels = timeframeData.map(item => {
|
||||||
if (timeframe === 'last24hours') {
|
if (timeframe === 'last24hours') {
|
||||||
// item.bucket will be something like "2025-04-01T15"
|
// item.bucket is now in the format "YYYY-MM-DDTHH:00:00Z"
|
||||||
const bucketDate = new Date(item.bucket + ":00:00"); // Convert to a full datetime by appending minutes and seconds.
|
const bucketDate = new Date(item.bucket);
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
// Check if this bucket corresponds to the current hour
|
// Check if this bucket corresponds to the current hour (in client's local time)
|
||||||
const isCurrentHour =
|
const isCurrentHour =
|
||||||
bucketDate.getFullYear() === now.getFullYear() &&
|
bucketDate.getFullYear() === now.getFullYear() &&
|
||||||
bucketDate.getMonth() === now.getMonth() &&
|
bucketDate.getMonth() === now.getMonth() &&
|
||||||
bucketDate.getDate() === now.getDate() &&
|
bucketDate.getDate() === now.getDate() &&
|
||||||
bucketDate.getHours() === now.getHours();
|
bucketDate.getHours() === now.getHours();
|
||||||
|
|
||||||
// If it is the current hour, use the current time as the end; otherwise, add one hour.
|
// For the current hour, use the current time as the bucket end.
|
||||||
const bucketEnd = isCurrentHour ? now : new Date(bucketDate.getTime() + 3600 * 1000);
|
const bucketEnd = isCurrentHour ? now : new Date(bucketDate.getTime() + 3600 * 1000);
|
||||||
|
|
||||||
return `${bucketDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} - ${bucketEnd.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
|
return `${bucketDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} - ${bucketEnd.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user