better time usings
This commit is contained in:
@@ -12,7 +12,7 @@ can call it from async routes via threadpool if needed.
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Dict, Optional
|
||||
|
||||
from jose import JWTError, jwt # type: ignore
|
||||
@@ -103,10 +103,10 @@ class AuthService:
|
||||
def _record_failure(self, identifier: str) -> None:
|
||||
rec = self._get_fail_record(identifier)
|
||||
rec["count"] += 1
|
||||
rec["last"] = datetime.utcnow()
|
||||
rec["last"] = datetime.now(timezone.utc)
|
||||
if rec["count"] >= self.max_attempts:
|
||||
rec["locked_until"] = (
|
||||
datetime.utcnow() + timedelta(seconds=self.lockout_seconds)
|
||||
datetime.now(timezone.utc) + timedelta(seconds=self.lockout_seconds)
|
||||
)
|
||||
|
||||
def _clear_failures(self, identifier: str) -> None:
|
||||
@@ -116,11 +116,11 @@ class AuthService:
|
||||
def _check_locked(self, identifier: str) -> None:
|
||||
rec = self._get_fail_record(identifier)
|
||||
lu = rec.get("locked_until")
|
||||
if lu and datetime.utcnow() < lu:
|
||||
if lu and datetime.now(timezone.utc) < lu:
|
||||
raise LockedOutError(
|
||||
"Too many failed attempts - temporarily locked out"
|
||||
)
|
||||
if lu and datetime.utcnow() >= lu:
|
||||
if lu and datetime.now(timezone.utc) >= lu:
|
||||
# lock expired, reset
|
||||
self._failed[identifier] = {
|
||||
"count": 0,
|
||||
@@ -155,13 +155,13 @@ class AuthService:
|
||||
def create_access_token(
|
||||
self, subject: str = "master", remember: bool = False
|
||||
) -> LoginResponse:
|
||||
expiry = datetime.utcnow() + timedelta(
|
||||
expiry = datetime.now(timezone.utc) + timedelta(
|
||||
hours=(168 if remember else self.token_expiry_hours)
|
||||
)
|
||||
payload = {
|
||||
"sub": subject,
|
||||
"exp": int(expiry.timestamp()),
|
||||
"iat": int(datetime.utcnow().timestamp()),
|
||||
"iat": int(datetime.now(timezone.utc).timestamp()),
|
||||
}
|
||||
token = jwt.encode(payload, self.secret, algorithm="HS256")
|
||||
|
||||
@@ -180,7 +180,7 @@ class AuthService:
|
||||
data = self.decode_token(token)
|
||||
exp_val = data.get("exp")
|
||||
expires_at = (
|
||||
datetime.utcfromtimestamp(exp_val) if exp_val is not None else None
|
||||
datetime.fromtimestamp(exp_val, timezone.utc) if exp_val is not None else None
|
||||
)
|
||||
return SessionModel(
|
||||
session_id=hashlib.sha256(token.encode()).hexdigest(),
|
||||
|
||||
@@ -11,7 +11,7 @@ import json
|
||||
import uuid
|
||||
from collections import deque
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Callable, Dict, List, Optional
|
||||
|
||||
@@ -183,7 +183,7 @@ class DownloadService:
|
||||
item.model_dump(mode="json")
|
||||
for item in self._failed_items
|
||||
],
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
}
|
||||
|
||||
with open(self._persistence_path, "w", encoding="utf-8") as f:
|
||||
@@ -225,7 +225,7 @@ class DownloadService:
|
||||
episode=episode,
|
||||
status=DownloadStatus.PENDING,
|
||||
priority=priority,
|
||||
added_at=datetime.utcnow(),
|
||||
added_at=datetime.now(timezone.utc),
|
||||
)
|
||||
|
||||
# Insert based on priority
|
||||
@@ -284,7 +284,7 @@ class DownloadService:
|
||||
if item_id in self._active_downloads:
|
||||
item = self._active_downloads[item_id]
|
||||
item.status = DownloadStatus.CANCELLED
|
||||
item.completed_at = datetime.utcnow()
|
||||
item.completed_at = datetime.now(timezone.utc)
|
||||
self._failed_items.append(item)
|
||||
del self._active_downloads[item_id]
|
||||
removed_ids.append(item_id)
|
||||
@@ -673,7 +673,7 @@ class DownloadService:
|
||||
try:
|
||||
# Update status
|
||||
item.status = DownloadStatus.DOWNLOADING
|
||||
item.started_at = datetime.utcnow()
|
||||
item.started_at = datetime.now(timezone.utc)
|
||||
self._active_downloads[item.id] = item
|
||||
|
||||
logger.info(
|
||||
@@ -715,7 +715,7 @@ class DownloadService:
|
||||
# Handle result
|
||||
if success:
|
||||
item.status = DownloadStatus.COMPLETED
|
||||
item.completed_at = datetime.utcnow()
|
||||
item.completed_at = datetime.now(timezone.utc)
|
||||
|
||||
# Track downloaded size
|
||||
if item.progress and item.progress.downloaded_mb:
|
||||
@@ -757,7 +757,7 @@ class DownloadService:
|
||||
except Exception as e:
|
||||
# Handle failure
|
||||
item.status = DownloadStatus.FAILED
|
||||
item.completed_at = datetime.utcnow()
|
||||
item.completed_at = datetime.now(timezone.utc)
|
||||
item.error = str(e)
|
||||
self._failed_items.append(item)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
from typing import Any, Callable, Dict, Optional
|
||||
|
||||
@@ -65,8 +65,8 @@ class ProgressUpdate:
|
||||
current: int = 0
|
||||
total: int = 0
|
||||
metadata: Dict[str, Any] = field(default_factory=dict)
|
||||
started_at: datetime = field(default_factory=datetime.utcnow)
|
||||
updated_at: datetime = field(default_factory=datetime.utcnow)
|
||||
started_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
updated_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
"""Convert progress update to dictionary."""
|
||||
@@ -254,7 +254,7 @@ class ProgressService:
|
||||
update.percent = 0.0
|
||||
|
||||
update.status = ProgressStatus.IN_PROGRESS
|
||||
update.updated_at = datetime.utcnow()
|
||||
update.updated_at = datetime.now(timezone.utc)
|
||||
|
||||
# Only broadcast if significant change or forced
|
||||
percent_change = abs(update.percent - old_percent)
|
||||
@@ -296,7 +296,7 @@ class ProgressService:
|
||||
update.message = message
|
||||
update.percent = 100.0
|
||||
update.current = update.total
|
||||
update.updated_at = datetime.utcnow()
|
||||
update.updated_at = datetime.now(timezone.utc)
|
||||
|
||||
if metadata:
|
||||
update.metadata.update(metadata)
|
||||
@@ -345,7 +345,7 @@ class ProgressService:
|
||||
update = self._active_progress[progress_id]
|
||||
update.status = ProgressStatus.FAILED
|
||||
update.message = error_message
|
||||
update.updated_at = datetime.utcnow()
|
||||
update.updated_at = datetime.now(timezone.utc)
|
||||
|
||||
if metadata:
|
||||
update.metadata.update(metadata)
|
||||
@@ -393,7 +393,7 @@ class ProgressService:
|
||||
update = self._active_progress[progress_id]
|
||||
update.status = ProgressStatus.CANCELLED
|
||||
update.message = message
|
||||
update.updated_at = datetime.utcnow()
|
||||
update.updated_at = datetime.now(timezone.utc)
|
||||
|
||||
# Move to history
|
||||
del self._active_progress[progress_id]
|
||||
|
||||
@@ -8,7 +8,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
|
||||
import structlog
|
||||
@@ -346,7 +346,7 @@ class WebSocketService:
|
||||
user_id: Optional user identifier for authentication
|
||||
"""
|
||||
metadata = {
|
||||
"connected_at": datetime.utcnow().isoformat(),
|
||||
"connected_at": datetime.now(timezone.utc).isoformat(),
|
||||
"user_id": user_id,
|
||||
}
|
||||
await self._manager.connect(websocket, connection_id, metadata)
|
||||
@@ -366,7 +366,7 @@ class WebSocketService:
|
||||
"""
|
||||
message = {
|
||||
"type": "download_progress",
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"data": {
|
||||
"download_id": download_id,
|
||||
**progress_data,
|
||||
@@ -385,7 +385,7 @@ class WebSocketService:
|
||||
"""
|
||||
message = {
|
||||
"type": "download_complete",
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"data": {
|
||||
"download_id": download_id,
|
||||
**result_data,
|
||||
@@ -404,7 +404,7 @@ class WebSocketService:
|
||||
"""
|
||||
message = {
|
||||
"type": "download_failed",
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"data": {
|
||||
"download_id": download_id,
|
||||
**error_data,
|
||||
@@ -420,7 +420,7 @@ class WebSocketService:
|
||||
"""
|
||||
message = {
|
||||
"type": "queue_status",
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"data": status_data,
|
||||
}
|
||||
await self._manager.broadcast_to_room(message, "downloads")
|
||||
@@ -436,7 +436,7 @@ class WebSocketService:
|
||||
"""
|
||||
message = {
|
||||
"type": f"system_{message_type}",
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"data": data,
|
||||
}
|
||||
await self._manager.broadcast(message)
|
||||
@@ -453,7 +453,7 @@ class WebSocketService:
|
||||
"""
|
||||
message = {
|
||||
"type": "error",
|
||||
"timestamp": datetime.utcnow().isoformat(),
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"data": {
|
||||
"code": error_code,
|
||||
"message": error_message,
|
||||
|
||||
Reference in New Issue
Block a user