mirror of
https://github.com/blackboxprogramming/BlackRoad-Operating-System.git
synced 2026-03-17 00:57:12 -05:00
Use timezone-aware timestamps and update tests
This commit is contained in:
@@ -11,6 +11,7 @@ from sqlalchemy import select
|
||||
from app.config import settings
|
||||
from app.database import get_db
|
||||
from app.models.user import User
|
||||
from app.utils import utc_now
|
||||
|
||||
# Password hashing
|
||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||
@@ -33,9 +34,9 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -
|
||||
"""Create a JWT access token"""
|
||||
to_encode = data.copy()
|
||||
if expires_delta:
|
||||
expire = datetime.utcnow() + expires_delta
|
||||
expire = utc_now() + expires_delta
|
||||
else:
|
||||
expire = datetime.utcnow() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
expire = utc_now() + timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
|
||||
to_encode.update({"exp": expire, "type": "access"})
|
||||
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
|
||||
@@ -45,7 +46,7 @@ def create_access_token(data: dict, expires_delta: Optional[timedelta] = None) -
|
||||
def create_refresh_token(data: dict) -> str:
|
||||
"""Create a JWT refresh token"""
|
||||
to_encode = data.copy()
|
||||
expire = datetime.utcnow() + timedelta(days=settings.REFRESH_TOKEN_EXPIRE_DAYS)
|
||||
expire = utc_now() + timedelta(days=settings.REFRESH_TOKEN_EXPIRE_DAYS)
|
||||
to_encode.update({"exp": expire, "type": "refresh"})
|
||||
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
|
||||
return encoded_jwt
|
||||
|
||||
@@ -4,6 +4,7 @@ from typing import Optional
|
||||
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Float, JSON, ForeignKey, Text
|
||||
from sqlalchemy.orm import relationship
|
||||
from app.database import Base
|
||||
from app.utils import utc_now
|
||||
|
||||
|
||||
class Device(Base):
|
||||
@@ -59,8 +60,8 @@ class Device(Base):
|
||||
owner = relationship("User", back_populates="devices")
|
||||
|
||||
# Timestamps
|
||||
created_at = Column(DateTime, default=datetime.utcnow)
|
||||
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
created_at = Column(DateTime, default=utc_now)
|
||||
updated_at = Column(DateTime, default=utc_now, onupdate=utc_now)
|
||||
|
||||
# Relations
|
||||
metrics = relationship("DeviceMetric", back_populates="device", cascade="all, delete-orphan")
|
||||
@@ -76,7 +77,7 @@ class DeviceMetric(Base):
|
||||
device_id = Column(Integer, ForeignKey("devices.id", ondelete="CASCADE"), nullable=False)
|
||||
|
||||
# Metric data
|
||||
timestamp = Column(DateTime, default=datetime.utcnow, index=True)
|
||||
timestamp = Column(DateTime, default=utc_now, index=True)
|
||||
cpu_usage = Column(Float)
|
||||
ram_usage = Column(Float)
|
||||
disk_usage = Column(Float)
|
||||
@@ -100,7 +101,7 @@ class DeviceLog(Base):
|
||||
device_id = Column(Integer, ForeignKey("devices.id", ondelete="CASCADE"), nullable=False)
|
||||
|
||||
# Log data
|
||||
timestamp = Column(DateTime, default=datetime.utcnow, index=True)
|
||||
timestamp = Column(DateTime, default=utc_now, index=True)
|
||||
level = Column(String(20), nullable=False) # info, warning, error, critical
|
||||
category = Column(String(50)) # system, network, service, hardware
|
||||
message = Column(Text, nullable=False)
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.database import get_db
|
||||
from app.models.user import User
|
||||
from app.models.ai_chat import Conversation, Message, MessageRole
|
||||
from app.auth import get_current_active_user
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/ai-chat", tags=["AI Chat"])
|
||||
|
||||
@@ -188,7 +189,7 @@ async def send_message(
|
||||
|
||||
# Update conversation
|
||||
conversation.message_count += 2
|
||||
conversation.updated_at = datetime.utcnow()
|
||||
conversation.updated_at = utc_now()
|
||||
|
||||
if not conversation.title or conversation.title == "New Conversation":
|
||||
# Auto-generate title from first message
|
||||
|
||||
@@ -13,6 +13,8 @@ import asyncio
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/health", tags=["health"])
|
||||
@@ -47,7 +49,7 @@ async def check_api_status(name: str, check_func) -> Dict[str, Any]:
|
||||
"name": name,
|
||||
"status": "connected" if result.get("connected") else "not_configured",
|
||||
"message": result.get("message", ""),
|
||||
"last_checked": datetime.utcnow().isoformat(),
|
||||
"last_checked": utc_now().isoformat(),
|
||||
"configuration": {
|
||||
k: v for k, v in result.items()
|
||||
if k.endswith("_configured") or k == "connected"
|
||||
@@ -60,7 +62,7 @@ async def check_api_status(name: str, check_func) -> Dict[str, Any]:
|
||||
"name": name,
|
||||
"status": "error",
|
||||
"message": f"Health check failed: {str(e)}",
|
||||
"last_checked": datetime.utcnow().isoformat(),
|
||||
"last_checked": utc_now().isoformat(),
|
||||
"configuration": {},
|
||||
"error": str(e)
|
||||
}
|
||||
@@ -154,7 +156,7 @@ async def check_all_apis():
|
||||
|
||||
return SystemHealthStatus(
|
||||
status=overall_status,
|
||||
timestamp=datetime.utcnow().isoformat(),
|
||||
timestamp=utc_now().isoformat(),
|
||||
total_apis=total_apis,
|
||||
connected_apis=connected_count,
|
||||
not_configured_apis=not_configured_count,
|
||||
|
||||
@@ -17,7 +17,7 @@ from app.auth import (
|
||||
)
|
||||
from app.services.blockchain import BlockchainService
|
||||
from app.services.crypto import wallet_crypto, WalletKeyEncryptionError
|
||||
from datetime import datetime
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/auth", tags=["Authentication"])
|
||||
|
||||
@@ -82,7 +82,7 @@ async def register(user_data: UserCreate, db: AsyncSession = Depends(get_db)):
|
||||
wallet_address=wallet_address,
|
||||
wallet_private_key=encrypted_private_key,
|
||||
balance=100.0, # Starting bonus
|
||||
created_at=datetime.utcnow()
|
||||
created_at=utc_now()
|
||||
)
|
||||
|
||||
db.add(user)
|
||||
@@ -131,7 +131,7 @@ async def login(
|
||||
)
|
||||
|
||||
# Update last login
|
||||
user.last_login = datetime.utcnow()
|
||||
user.last_login = utc_now()
|
||||
await db.commit()
|
||||
|
||||
# Create tokens
|
||||
|
||||
@@ -12,7 +12,6 @@ from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
import httpx
|
||||
from urllib.parse import urlparse, quote
|
||||
import hashlib
|
||||
@@ -21,6 +20,7 @@ from ..database import get_db
|
||||
from ..auth import get_current_user
|
||||
from ..models import User
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
from ..utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/browser", tags=["browser"])
|
||||
|
||||
@@ -142,7 +142,7 @@ async def add_bookmark(
|
||||
"title": bookmark.title,
|
||||
"url": bookmark.url,
|
||||
"folder": bookmark.folder,
|
||||
"created_at": datetime.utcnow().isoformat()
|
||||
"created_at": utc_now().isoformat()
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -208,10 +208,10 @@ async def add_history_entry(
|
||||
):
|
||||
"""Add a history entry"""
|
||||
new_entry = {
|
||||
"id": hashlib.md5(f"{entry.url}{datetime.utcnow()}".encode()).hexdigest()[:8],
|
||||
"id": hashlib.md5(f"{entry.url}{utc_now()}".encode()).hexdigest()[:8],
|
||||
"url": entry.url,
|
||||
"title": entry.title,
|
||||
"visited_at": datetime.utcnow().isoformat()
|
||||
"visited_at": utc_now().isoformat()
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -232,7 +232,7 @@ async def clear_history(
|
||||
@router.get("/search")
|
||||
async def web_search(
|
||||
q: str = Query(..., min_length=1, description="Search query"),
|
||||
engine: str = Query("duckduckgo", regex="^(duckduckgo|google|bing)$"),
|
||||
engine: str = Query("duckduckgo", pattern="^(duckduckgo|google|bing)$"),
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
"""
|
||||
@@ -397,7 +397,7 @@ async def open_new_tab(
|
||||
"""Open a new tab"""
|
||||
return {
|
||||
"tab": {
|
||||
"id": hashlib.md5(f"{url}{datetime.utcnow()}".encode()).hexdigest()[:8],
|
||||
"id": hashlib.md5(f"{url}{utc_now()}".encode()).hexdigest()[:8],
|
||||
"url": url,
|
||||
"title": "Loading...",
|
||||
"active": True
|
||||
|
||||
@@ -19,6 +19,7 @@ from ..database import get_db
|
||||
from ..auth import get_current_user
|
||||
from ..models import User, Device, Email, Post, Video, File, Conversation, Block, Transaction
|
||||
from pydantic import BaseModel
|
||||
from ..utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/dashboard", tags=["dashboard"])
|
||||
|
||||
@@ -201,7 +202,7 @@ async def get_dashboard_overview(
|
||||
},
|
||||
"services": services,
|
||||
"system_health": system_health,
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
|
||||
@@ -356,7 +357,7 @@ async def get_recent_activity(
|
||||
"icon": "📧",
|
||||
"action": "Received new email",
|
||||
"description": "Meeting reminder from Sarah",
|
||||
"timestamp": (datetime.utcnow() - timedelta(minutes=5)).isoformat()
|
||||
"timestamp": (utc_now() - timedelta(minutes=5)).isoformat()
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
@@ -364,7 +365,7 @@ async def get_recent_activity(
|
||||
"icon": "⛓️",
|
||||
"action": "Transaction completed",
|
||||
"description": "Sent 10 RoadCoins to wallet abc123",
|
||||
"timestamp": (datetime.utcnow() - timedelta(minutes=15)).isoformat()
|
||||
"timestamp": (utc_now() - timedelta(minutes=15)).isoformat()
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
@@ -372,7 +373,7 @@ async def get_recent_activity(
|
||||
"icon": "⛏️",
|
||||
"action": "Block mined",
|
||||
"description": "Mined block #1234, earned 50 RoadCoins",
|
||||
"timestamp": (datetime.utcnow() - timedelta(hours=1)).isoformat()
|
||||
"timestamp": (utc_now() - timedelta(hours=1)).isoformat()
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
@@ -380,7 +381,7 @@ async def get_recent_activity(
|
||||
"icon": "🥧",
|
||||
"action": "Device connected",
|
||||
"description": "Raspberry Pi 4 - Living Room came online",
|
||||
"timestamp": (datetime.utcnow() - timedelta(hours=2)).isoformat()
|
||||
"timestamp": (utc_now() - timedelta(hours=2)).isoformat()
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
@@ -388,7 +389,7 @@ async def get_recent_activity(
|
||||
"icon": "🌐",
|
||||
"action": "New like",
|
||||
"description": "Mike liked your post",
|
||||
"timestamp": (datetime.utcnow() - timedelta(hours=3)).isoformat()
|
||||
"timestamp": (utc_now() - timedelta(hours=3)).isoformat()
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.database import get_db
|
||||
from app.models.device import Device, DeviceMetric, DeviceLog
|
||||
from app.models.user import User
|
||||
from app.routers.auth import get_current_user
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/devices", tags=["devices"])
|
||||
|
||||
@@ -239,7 +240,7 @@ async def update_device(
|
||||
if device_data.description is not None:
|
||||
device.description = device_data.description
|
||||
|
||||
device.updated_at = datetime.utcnow()
|
||||
device.updated_at = utc_now()
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(device)
|
||||
@@ -265,7 +266,7 @@ async def device_heartbeat(
|
||||
# Update device status
|
||||
device.is_online = True
|
||||
device.status = "online"
|
||||
device.last_seen = datetime.utcnow()
|
||||
device.last_seen = utc_now()
|
||||
|
||||
# Update system info if provided
|
||||
if heartbeat_data.ip_address:
|
||||
@@ -308,7 +309,7 @@ async def device_heartbeat(
|
||||
# Save metric snapshot
|
||||
metric = DeviceMetric(
|
||||
device_id=device.id,
|
||||
timestamp=datetime.utcnow(),
|
||||
timestamp=utc_now(),
|
||||
cpu_usage=heartbeat_data.cpu_usage_percent,
|
||||
ram_usage=heartbeat_data.ram_usage_percent,
|
||||
disk_usage=heartbeat_data.disk_usage_percent,
|
||||
@@ -392,7 +393,7 @@ async def ssh_connect(
|
||||
"device_id": device_id,
|
||||
"ip_address": device.ip_address,
|
||||
"hostname": device.hostname,
|
||||
"connection_token": f"ssh_token_{device_id}_{datetime.utcnow().timestamp()}",
|
||||
"connection_token": f"ssh_token_{device_id}_{utc_now().timestamp()}",
|
||||
"status": "connected",
|
||||
"message": f"SSH connection established to {device.hostname or device.ip_address}"
|
||||
}
|
||||
@@ -448,7 +449,7 @@ async def ssh_execute_command(
|
||||
"command": command_data.command,
|
||||
"output": output,
|
||||
"exit_code": 0,
|
||||
"executed_at": datetime.utcnow().isoformat()
|
||||
"executed_at": utc_now().isoformat()
|
||||
}
|
||||
|
||||
|
||||
@@ -511,7 +512,7 @@ async def deploy_to_device(
|
||||
"deploy_path": deploy_config.deploy_path,
|
||||
"steps": deployment_steps,
|
||||
"status": "success",
|
||||
"deployed_at": datetime.utcnow().isoformat(),
|
||||
"deployed_at": utc_now().isoformat(),
|
||||
"message": "Deployment completed successfully"
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ import httpx
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/discord", tags=["discord"])
|
||||
@@ -304,5 +306,5 @@ async def discord_health_check():
|
||||
"service": "discord",
|
||||
"status": "operational" if DISCORD_BOT_TOKEN else "not_configured",
|
||||
"webhook_status": "operational" if DISCORD_WEBHOOK_URL else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.database import get_db
|
||||
from app.models.user import User
|
||||
from app.models.email import Email, EmailFolder, EmailFolderType
|
||||
from app.auth import get_current_active_user
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/email", tags=["Email"])
|
||||
|
||||
@@ -154,7 +155,7 @@ async def send_email(
|
||||
bcc=",".join(email_data.bcc) if email_data.bcc else None,
|
||||
is_read=False,
|
||||
is_draft=False,
|
||||
sent_at=datetime.utcnow()
|
||||
sent_at=utc_now()
|
||||
)
|
||||
|
||||
db.add(email)
|
||||
@@ -193,7 +194,7 @@ async def get_email(
|
||||
# Mark as read if recipient is viewing
|
||||
if email.recipient_id == current_user.id and not email.is_read:
|
||||
email.is_read = True
|
||||
email.read_at = datetime.utcnow()
|
||||
email.read_at = utc_now()
|
||||
await db.commit()
|
||||
|
||||
return email
|
||||
|
||||
@@ -11,6 +11,7 @@ from app.database import get_db
|
||||
from app.models.user import User
|
||||
from app.models.file import File, Folder
|
||||
from app.auth import get_current_active_user
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/files", tags=["Files"])
|
||||
|
||||
@@ -217,7 +218,7 @@ async def get_file(
|
||||
)
|
||||
|
||||
# Update last accessed
|
||||
file.last_accessed = datetime.utcnow()
|
||||
file.last_accessed = utc_now()
|
||||
await db.commit()
|
||||
|
||||
return file
|
||||
|
||||
@@ -19,6 +19,7 @@ import random
|
||||
from ..database import get_db
|
||||
from ..auth import get_current_user
|
||||
from ..models import User
|
||||
from ..utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/games", tags=["games"])
|
||||
|
||||
@@ -62,7 +63,7 @@ async def list_cities(
|
||||
"money": 45000,
|
||||
"level": 5,
|
||||
"created_at": "2024-01-01T00:00:00Z",
|
||||
"updated_at": datetime.utcnow().isoformat()
|
||||
"updated_at": utc_now().isoformat()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ async def list_commits(
|
||||
async def list_pull_requests(
|
||||
owner: str,
|
||||
repo: str,
|
||||
state: str = Query("open", regex="^(open|closed|all)$"),
|
||||
state: str = Query("open", pattern="^(open|closed|all)$"),
|
||||
page: int = Query(1, ge=1),
|
||||
per_page: int = Query(30, ge=1, le=100),
|
||||
current_user: User = Depends(get_current_user)
|
||||
@@ -220,7 +220,7 @@ async def list_pull_requests(
|
||||
async def list_issues(
|
||||
owner: str,
|
||||
repo: str,
|
||||
state: str = Query("open", regex="^(open|closed|all)$"),
|
||||
state: str = Query("open", pattern="^(open|closed|all)$"),
|
||||
page: int = Query(1, ge=1),
|
||||
per_page: int = Query(30, ge=1, le=100),
|
||||
current_user: User = Depends(get_current_user)
|
||||
|
||||
@@ -37,7 +37,7 @@ class InferenceRequest(BaseModel):
|
||||
async def list_models(
|
||||
search: Optional[str] = Query(None),
|
||||
filter_task: Optional[str] = Query(None, alias="task"),
|
||||
sort: str = Query("downloads", regex="^(downloads|likes|trending)$"),
|
||||
sort: str = Query("downloads", pattern="^(downloads|likes|trending)$"),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
@@ -146,7 +146,7 @@ async def run_inference(
|
||||
@router.get("/datasets")
|
||||
async def list_datasets(
|
||||
search: Optional[str] = Query(None),
|
||||
sort: str = Query("downloads", regex="^(downloads|likes|trending)$"),
|
||||
sort: str = Query("downloads", pattern="^(downloads|likes|trending)$"),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
@@ -194,7 +194,7 @@ async def get_dataset_info(
|
||||
@router.get("/spaces")
|
||||
async def list_spaces(
|
||||
search: Optional[str] = Query(None),
|
||||
sort: str = Query("likes", regex="^(likes|trending)$"),
|
||||
sort: str = Query("likes", pattern="^(likes|trending)$"),
|
||||
limit: int = Query(20, ge=1, le=100),
|
||||
current_user: User = Depends(get_current_user)
|
||||
):
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.database import get_db
|
||||
from app.models.blockchain import Block, Wallet
|
||||
from app.models.user import User
|
||||
from app.routers.auth import get_current_user
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/miner", tags=["miner"])
|
||||
|
||||
@@ -97,7 +98,7 @@ async def get_miner_status(
|
||||
"""Get current miner status and performance metrics."""
|
||||
uptime_seconds = 0
|
||||
if miner_state.started_at:
|
||||
uptime_seconds = int((datetime.utcnow() - miner_state.started_at).total_seconds())
|
||||
uptime_seconds = int((utc_now() - miner_state.started_at).total_seconds())
|
||||
|
||||
# Simulate some variance in hashrate
|
||||
current_hashrate = miner_state.hashrate_mhs
|
||||
@@ -242,7 +243,7 @@ async def control_miner(
|
||||
raise HTTPException(status_code=400, detail="Miner is already running")
|
||||
|
||||
miner_state.is_mining = True
|
||||
miner_state.started_at = datetime.utcnow()
|
||||
miner_state.started_at = utc_now()
|
||||
miner_state.hashrate_mhs = random.uniform(38.0, 45.0) # Simulate hashrate
|
||||
|
||||
if control.pool_url:
|
||||
@@ -268,7 +269,7 @@ async def control_miner(
|
||||
miner_state.is_mining = False
|
||||
await asyncio.sleep(1)
|
||||
miner_state.is_mining = True
|
||||
miner_state.started_at = datetime.utcnow()
|
||||
miner_state.started_at = utc_now()
|
||||
miner_state.hashrate_mhs = random.uniform(38.0, 45.0)
|
||||
|
||||
background_tasks.add_task(simulate_mining)
|
||||
@@ -314,5 +315,5 @@ async def get_pool_info(
|
||||
"pool_fee": "1%",
|
||||
"min_payout": 10.0,
|
||||
"payment_interval_hours": 24,
|
||||
"last_block_found": (datetime.utcnow() - timedelta(minutes=random.randint(5, 120))).isoformat(),
|
||||
"last_block_found": (utc_now() - timedelta(minutes=random.randint(5, 120))).isoformat(),
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import httpx
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/railway", tags=["railway"])
|
||||
@@ -389,5 +391,5 @@ async def railway_health_check():
|
||||
return {
|
||||
"service": "railway",
|
||||
"status": "operational" if RAILWAY_TOKEN else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import httpx
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/sentry", tags=["sentry"])
|
||||
@@ -376,5 +378,5 @@ async def sentry_health_check():
|
||||
return {
|
||||
"service": "sentry",
|
||||
"status": "operational" if SENTRY_AUTH_TOKEN else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -7,11 +7,12 @@ Provides endpoints for sending messages, managing channels, and interacting with
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
from pydantic import BaseModel
|
||||
from typing import List, Optional, Dict, Any
|
||||
from datetime import datetime
|
||||
import httpx
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/slack", tags=["slack"])
|
||||
@@ -277,5 +278,5 @@ async def slack_health_check():
|
||||
"service": "slack",
|
||||
"status": "operational" if SLACK_BOT_TOKEN else "not_configured",
|
||||
"webhook_status": "operational" if SLACK_WEBHOOK_URL else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -8,11 +8,12 @@ Stripe is a payment processing platform for online businesses.
|
||||
from fastapi import APIRouter, HTTPException, status
|
||||
from pydantic import BaseModel, EmailStr
|
||||
from typing import List, Optional, Dict, Any
|
||||
from datetime import datetime
|
||||
import httpx
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/stripe", tags=["stripe"])
|
||||
@@ -324,5 +325,5 @@ async def stripe_health_check():
|
||||
return {
|
||||
"service": "stripe",
|
||||
"status": "operational" if STRIPE_SECRET_KEY else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import base64
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/twilio", tags=["twilio"])
|
||||
@@ -255,5 +257,5 @@ async def twilio_health_check():
|
||||
return {
|
||||
"service": "twilio",
|
||||
"status": "operational" if (TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN) else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import httpx
|
||||
import os
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/vercel", tags=["vercel"])
|
||||
@@ -420,5 +422,5 @@ async def vercel_health_check():
|
||||
return {
|
||||
"service": "vercel",
|
||||
"status": "operational" if VERCEL_TOKEN else "not_configured",
|
||||
"timestamp": datetime.utcnow().isoformat()
|
||||
"timestamp": utc_now().isoformat()
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.database import get_db
|
||||
from app.models.user import User
|
||||
from app.models.video import Video, VideoView, VideoLike
|
||||
from app.auth import get_current_active_user
|
||||
from app.utils import utc_now
|
||||
|
||||
router = APIRouter(prefix="/api/videos", tags=["Videos"])
|
||||
|
||||
@@ -117,7 +118,7 @@ async def upload_video(
|
||||
category=video_data.category,
|
||||
tags=video_data.tags,
|
||||
is_public=True,
|
||||
published_at=datetime.utcnow()
|
||||
published_at=utc_now()
|
||||
)
|
||||
|
||||
db.add(video)
|
||||
|
||||
@@ -12,11 +12,11 @@ from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
|
||||
from ..database import get_db
|
||||
from ..auth import get_current_user
|
||||
from ..models import User, File, Folder
|
||||
from ..utils import utc_now
|
||||
from pydantic import BaseModel
|
||||
|
||||
router = APIRouter(prefix="/api/vscode", tags=["vscode"])
|
||||
@@ -120,7 +120,7 @@ async def update_file_content(
|
||||
raise HTTPException(status_code=404, detail="File not found")
|
||||
|
||||
# In a real implementation, save to S3 or file system
|
||||
file.updated_at = datetime.utcnow()
|
||||
file.updated_at = utc_now()
|
||||
file.size = len(content.encode('utf-8'))
|
||||
|
||||
await db.commit()
|
||||
|
||||
@@ -12,6 +12,8 @@ import httpx
|
||||
from enum import Enum
|
||||
import logging
|
||||
|
||||
from app.utils import utc_now
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -93,23 +95,23 @@ class APIClient:
|
||||
if response.status_code < 500:
|
||||
self.status = APIStatus.CONNECTED
|
||||
self.error_message = None
|
||||
self.last_check = datetime.utcnow()
|
||||
self.last_check = utc_now()
|
||||
return True
|
||||
else:
|
||||
self.status = APIStatus.ERROR
|
||||
self.error_message = f"Server error: {response.status_code}"
|
||||
self.last_check = datetime.utcnow()
|
||||
self.last_check = utc_now()
|
||||
return False
|
||||
|
||||
except httpx.TimeoutException:
|
||||
self.status = APIStatus.ERROR
|
||||
self.error_message = "Connection timeout"
|
||||
self.last_check = datetime.utcnow()
|
||||
self.last_check = utc_now()
|
||||
return False
|
||||
except Exception as e:
|
||||
self.status = APIStatus.ERROR
|
||||
self.error_message = str(e)
|
||||
self.last_check = datetime.utcnow()
|
||||
self.last_check = utc_now()
|
||||
logger.error(f"Health check failed for {self.name}: {e}")
|
||||
return False
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Blockchain service"""
|
||||
import hashlib
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, desc
|
||||
@@ -9,6 +8,7 @@ from app.models.blockchain import Block, Transaction, Wallet
|
||||
from app.models.user import User
|
||||
from app.config import settings
|
||||
from app.services.crypto import wallet_crypto, WalletKeyDecryptionError
|
||||
from app.utils import utc_now
|
||||
import secrets
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class BlockchainService:
|
||||
if existing:
|
||||
return existing
|
||||
|
||||
timestamp = datetime.utcnow()
|
||||
timestamp = utc_now()
|
||||
genesis_hash = BlockchainService.calculate_hash(0, str(timestamp), "0", [], 0)
|
||||
|
||||
genesis_block = Block(
|
||||
@@ -69,7 +69,7 @@ class BlockchainService:
|
||||
latest_block = await BlockchainService.create_genesis_block(db)
|
||||
|
||||
new_index = latest_block.index + 1
|
||||
timestamp = datetime.utcnow()
|
||||
timestamp = utc_now()
|
||||
previous_hash = latest_block.hash
|
||||
difficulty = settings.BLOCKCHAIN_DIFFICULTY
|
||||
|
||||
@@ -117,7 +117,7 @@ class BlockchainService:
|
||||
tx.block_index = new_block.index
|
||||
tx.is_confirmed = True
|
||||
tx.confirmations = 1
|
||||
tx.confirmed_at = datetime.utcnow()
|
||||
tx.confirmed_at = utc_now()
|
||||
|
||||
# Reward miner
|
||||
user.balance += settings.MINING_REWARD
|
||||
@@ -152,7 +152,7 @@ class BlockchainService:
|
||||
) from exc
|
||||
|
||||
# Generate transaction hash
|
||||
tx_data = f"{from_address}{to_address}{amount}{datetime.utcnow()}"
|
||||
tx_data = f"{from_address}{to_address}{amount}{utc_now()}"
|
||||
transaction_hash = hashlib.sha256(tx_data.encode()).hexdigest()
|
||||
|
||||
# Sign transaction (simplified)
|
||||
|
||||
4
backend/app/utils/__init__.py
Normal file
4
backend/app/utils/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
"""Utility helpers for the BlackRoad backend."""
|
||||
|
||||
from .datetime import utc_now # noqa: F401
|
||||
|
||||
9
backend/app/utils/datetime.py
Normal file
9
backend/app/utils/datetime.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""Datetime utilities."""
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
|
||||
def utc_now() -> datetime:
|
||||
"""Return a timezone-aware UTC datetime."""
|
||||
return datetime.now(timezone.utc)
|
||||
|
||||
Reference in New Issue
Block a user