Fix: Show domains with TLD in drops table + restore critical backend fixes
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
This commit is contained in:
@ -62,21 +62,16 @@ SWITCH_CONFIG = {
|
||||
}
|
||||
}
|
||||
|
||||
# Setup logging (avoid duplicate handlers)
|
||||
logger = logging.getLogger("pounce_zone_sync")
|
||||
logger.setLevel(logging.INFO)
|
||||
if not logger.handlers:
|
||||
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
|
||||
console = logging.StreamHandler()
|
||||
console.setFormatter(formatter)
|
||||
logger.addHandler(console)
|
||||
try:
|
||||
LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
|
||||
file_handler = logging.FileHandler(LOG_FILE)
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
except Exception:
|
||||
pass
|
||||
# Setup logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s [%(levelname)s] %(message)s',
|
||||
handlers=[
|
||||
logging.StreamHandler(),
|
||||
logging.FileHandler(LOG_FILE) if LOG_FILE.parent.exists() else logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ZoneSyncResult:
|
||||
@ -86,39 +81,15 @@ class ZoneSyncResult:
|
||||
self.success = False
|
||||
self.domain_count = 0
|
||||
self.drops_count = 0
|
||||
self.drops: list = [] # CRITICAL: List of (domain, tld) tuples for DB storage
|
||||
self.error: Optional[str] = None
|
||||
self.duration_seconds = 0
|
||||
|
||||
|
||||
async def get_db_session():
|
||||
"""Create async database session - ROBUST VERSION (reads .env directly)"""
|
||||
# Read DATABASE_URL directly from .env to avoid import issues when running standalone
|
||||
env_file = Path("/home/user/pounce/backend/.env")
|
||||
if not env_file.exists():
|
||||
env_file = Path(__file__).parent.parent / ".env"
|
||||
"""Create async database session"""
|
||||
from app.config import settings
|
||||
|
||||
db_url = None
|
||||
if env_file.exists():
|
||||
for line in env_file.read_text().splitlines():
|
||||
if line.startswith("DATABASE_URL="):
|
||||
db_url = line.split("=", 1)[1].strip().strip('"').strip("'")
|
||||
break
|
||||
|
||||
# Default to SQLite if not found
|
||||
if not db_url:
|
||||
db_url = "sqlite:///./domainwatch.db"
|
||||
logger.warning(f"DATABASE_URL not found in .env, using default: {db_url}")
|
||||
|
||||
# Convert to async driver
|
||||
if "sqlite://" in db_url and "aiosqlite" not in db_url:
|
||||
db_url = db_url.replace("sqlite://", "sqlite+aiosqlite://")
|
||||
elif "postgresql://" in db_url and "asyncpg" not in db_url:
|
||||
db_url = db_url.replace("postgresql://", "postgresql+asyncpg://")
|
||||
|
||||
logger.info(f"DB connection: {db_url[:50]}...")
|
||||
|
||||
engine = create_async_engine(db_url, echo=False)
|
||||
engine = create_async_engine(settings.database_url.replace("sqlite://", "sqlite+aiosqlite://"))
|
||||
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
||||
return async_session()
|
||||
|
||||
@ -578,7 +549,7 @@ async def main():
|
||||
results.append(result)
|
||||
|
||||
# Store drops IMMEDIATELY after each TLD (crash-safe)
|
||||
if result.drops:
|
||||
if hasattr(result, 'drops') and result.drops:
|
||||
await store_tld_drops(result.drops, tld)
|
||||
|
||||
# Rate limit: wait between downloads
|
||||
@ -643,4 +614,4 @@ async def main():
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit_code = asyncio.run(main())
|
||||
sys.exit(exit_code)
|
||||
sys.exit(exit_code)
|
||||
@ -416,14 +416,14 @@ export function DropsTab({ showToast }: DropsTabProps) {
|
||||
</div>
|
||||
|
||||
{sortedItems.map((item) => (
|
||||
<div key={item.domain} className="bg-[#020202] hover:bg-white/[0.02] transition-all">
|
||||
<div key={`${item.domain}.${item.tld}`} className="bg-[#020202] hover:bg-white/[0.02] transition-all">
|
||||
{/* Mobile Row */}
|
||||
<div className="lg:hidden p-3">
|
||||
<div className="flex items-center justify-between gap-3 mb-2">
|
||||
<div className="flex items-center gap-2 min-w-0 flex-1">
|
||||
<span className="text-sm shrink-0">{ALL_TLDS.find(t => t.tld === item.tld)?.flag || '🌐'}</span>
|
||||
<button onClick={() => openAnalyze(item.domain)} className="text-sm font-bold text-white font-mono truncate text-left">
|
||||
{item.domain}
|
||||
<button onClick={() => openAnalyze(`${item.domain}.${item.tld}`)} className="text-sm font-bold text-white font-mono truncate text-left">
|
||||
{item.domain}<span className="text-white/40">.{item.tld}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 shrink-0">
|
||||
@ -439,18 +439,18 @@ export function DropsTab({ showToast }: DropsTabProps) {
|
||||
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
onClick={() => track(item.domain)}
|
||||
disabled={tracking === item.domain}
|
||||
onClick={() => track(`${item.domain}.${item.tld}`)}
|
||||
disabled={tracking === `${item.domain}.${item.tld}`}
|
||||
className="flex-1 py-2 text-[10px] font-bold uppercase tracking-wider border border-white/[0.08] text-white/40 flex items-center justify-center gap-1.5"
|
||||
>
|
||||
{tracking === item.domain ? <Loader2 className="w-3 h-3 animate-spin" /> : <Eye className="w-3 h-3" />}
|
||||
{tracking === `${item.domain}.${item.tld}` ? <Loader2 className="w-3 h-3 animate-spin" /> : <Eye className="w-3 h-3" />}
|
||||
Track
|
||||
</button>
|
||||
<button onClick={() => openAnalyze(item.domain)} className="w-10 py-2 border border-white/[0.08] text-white/50 flex items-center justify-center">
|
||||
<button onClick={() => openAnalyze(`${item.domain}.${item.tld}`)} className="w-10 py-2 border border-white/[0.08] text-white/50 flex items-center justify-center">
|
||||
<Shield className="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<a
|
||||
href={`https://www.namecheap.com/domains/registration/results/?domain=${item.domain}`}
|
||||
href={`https://www.namecheap.com/domains/registration/results/?domain=${item.domain}.${item.tld}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex-1 py-2 bg-accent text-black text-[10px] font-bold uppercase flex items-center justify-center gap-1"
|
||||
@ -465,10 +465,10 @@ export function DropsTab({ showToast }: DropsTabProps) {
|
||||
<div className="flex items-center gap-2 min-w-0 flex-1">
|
||||
<span className="text-sm shrink-0">{ALL_TLDS.find(t => t.tld === item.tld)?.flag || '🌐'}</span>
|
||||
<button
|
||||
onClick={() => openAnalyze(item.domain)}
|
||||
onClick={() => openAnalyze(`${item.domain}.${item.tld}`)}
|
||||
className="text-sm font-bold text-white font-mono truncate group-hover:text-accent transition-colors text-left"
|
||||
>
|
||||
{item.domain}
|
||||
{item.domain}<span className="text-white/40 group-hover:text-accent/60">.{item.tld}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -487,20 +487,20 @@ export function DropsTab({ showToast }: DropsTabProps) {
|
||||
|
||||
<div className="flex items-center justify-end gap-1.5 opacity-50 group-hover:opacity-100 transition-opacity">
|
||||
<button
|
||||
onClick={() => track(item.domain)}
|
||||
disabled={tracking === item.domain}
|
||||
onClick={() => track(`${item.domain}.${item.tld}`)}
|
||||
disabled={tracking === `${item.domain}.${item.tld}`}
|
||||
className="w-6 h-6 flex items-center justify-center border border-white/10 text-white/30 hover:text-white hover:bg-white/5"
|
||||
>
|
||||
{tracking === item.domain ? <Loader2 className="w-3 h-3 animate-spin" /> : <Eye className="w-3 h-3" />}
|
||||
{tracking === `${item.domain}.${item.tld}` ? <Loader2 className="w-3 h-3 animate-spin" /> : <Eye className="w-3 h-3" />}
|
||||
</button>
|
||||
<button
|
||||
onClick={() => openAnalyze(item.domain)}
|
||||
onClick={() => openAnalyze(`${item.domain}.${item.tld}`)}
|
||||
className="w-6 h-6 flex items-center justify-center border border-white/10 text-white/30 hover:text-accent hover:border-accent/20 hover:bg-accent/10"
|
||||
>
|
||||
<Shield className="w-3 h-3" />
|
||||
</button>
|
||||
<a
|
||||
href={`https://www.namecheap.com/domains/registration/results/?domain=${item.domain}`}
|
||||
href={`https://www.namecheap.com/domains/registration/results/?domain=${item.domain}.${item.tld}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="h-6 px-2 bg-accent text-black text-[10px] font-bold flex items-center gap-1 hover:bg-white"
|
||||
|
||||
Reference in New Issue
Block a user