LogicGoInfotechSpaces commited on
Commit
bb8d3b6
·
verified ·
1 Parent(s): f6241b2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -161
app.py CHANGED
@@ -8,12 +8,11 @@ import numpy as np
8
  import threading
9
  import subprocess
10
  import logging
11
- from datetime import datetime
12
 
13
  import insightface
14
  from insightface.app import FaceAnalysis
15
  from huggingface_hub import hf_hub_download
16
-
17
  from fastapi import FastAPI, UploadFile, File, HTTPException, Response, Depends, Security, Form
18
  from fastapi.responses import RedirectResponse
19
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
@@ -320,14 +319,90 @@ async def face_swap_api(
320
 
321
  # ------------------------------------------------------------------
322
  # # MEDIA_CLICKS (ONLY IF user_id PRESENT
323
- # # MEDIA_CLICKS (ONLY IF user_id PRESENT)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  if user_id:
325
  try:
326
  user_oid = ObjectId(user_id.strip())
327
  now = datetime.utcnow()
328
 
 
 
 
 
329
  # -------------------------------------------------
330
- # STEP 1: Ensure root fields exist (NO inc here)
331
  # -------------------------------------------------
332
  await media_clicks_col.update_one(
333
  {"userId": user_oid},
@@ -335,14 +410,59 @@ async def face_swap_api(
335
  "$setOnInsert": {
336
  "userId": user_oid,
337
  "createdAt": now,
338
- "ai_edit_complete": 0
 
339
  }
340
  },
341
  upsert=True
342
  )
343
 
344
  # -------------------------------------------------
345
- # STEP 2: Try updating existing subCategory
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
  # -------------------------------------------------
347
  update_result = await media_clicks_col.update_one(
348
  {
@@ -363,7 +483,7 @@ async def face_swap_api(
363
  )
364
 
365
  # -------------------------------------------------
366
- # STEP 3: Push subCategory if missing
367
  # -------------------------------------------------
368
  if update_result.matched_count == 0:
369
  await media_clicks_col.update_one(
@@ -387,7 +507,7 @@ async def face_swap_api(
387
  )
388
 
389
  logger.info(
390
- "[MEDIA_CLICK] user=%s subCategory=%s ai_edit_complete++",
391
  user_id,
392
  str(subcategory_oid)
393
  )
@@ -395,53 +515,6 @@ async def face_swap_api(
395
  except Exception as media_err:
396
  logger.error(f"MEDIA_CLICK ERROR: {media_err}")
397
 
398
-
399
-
400
-
401
-
402
- # if user_id:
403
- # try:
404
- # user_oid = ObjectId(user_id.strip())
405
- # now = datetime.utcnow()
406
-
407
- # # 1) Try updating existing subCategory
408
- # update_result = await media_clicks_col.update_one(
409
- # {
410
- # "userId": user_oid,
411
- # "subCategories.subCategoryId": subcategory_oid
412
- # },
413
- # {
414
- # "$set": {
415
- # "updatedAt": now,
416
- # "subCategories.$.lastClickedAt": now
417
- # },
418
- # "$inc": {
419
- # "subCategories.$.click_count": 1
420
- # }
421
- # }
422
- # )
423
-
424
- # # 2) If no subCategory exists → push new one (or create doc)
425
- # if update_result.matched_count == 0:
426
- # await media_clicks_col.update_one(
427
- # { "userId": user_oid },
428
- # {
429
- # "$setOnInsert": { "createdAt": now },
430
- # "$set": { "updatedAt": now },
431
- # "$push": {
432
- # "subCategories": {
433
- # "subCategoryId": subcategory_oid,
434
- # "click_count": 1,
435
- # "lastClickedAt": now
436
- # }
437
- # }
438
- # },
439
- # upsert=True
440
- # )
441
-
442
- # except Exception as media_err:
443
- # logger.error(f"MEDIA_CLICK ERROR: {media_err}")
444
-
445
  # # ------------------------------------------------------------------
446
  # # CASE 2 : target_category_id → DigitalOcean path (unchanged logic)
447
  # # ------------------------------------------------------------------
@@ -484,10 +557,9 @@ async def face_swap_api(
484
  # Replicate the old indexing logic based on sorted filenames
485
  for idx, filename in enumerate(original_filenames, start=1):
486
  cid = f"{category.lower()}image_{idx}"
487
-
488
  # Optional: Replicate the thumb file check for 100% parity
489
  # if filename in thumb_filenames and cid == target_category_id:
490
-
491
  # Simpler check just on the ID, assuming thumb files are present
492
  if cid == target_category_id:
493
  # Construct the final target URL using the full prefix and the filename
@@ -500,7 +572,6 @@ async def face_swap_api(
500
 
501
  if not target_url:
502
  raise HTTPException(404, "Target categoryId not found")
503
-
504
  # # ------------------------------------------------------------------
505
  # # DOWNLOAD TARGET IMAGE
506
  # # ------------------------------------------------------------------
@@ -544,7 +615,6 @@ async def face_swap_api(
544
  "result_url": result_url
545
  }
546
 
547
-
548
  except Exception as e:
549
  end_time = datetime.utcnow()
550
  response_time_ms = (end_time - start_time).total_seconds() * 1000
@@ -560,108 +630,6 @@ async def face_swap_api(
560
 
561
  raise HTTPException(500, f"Face swap failed: {str(e)}")
562
 
563
-
564
-
565
-
566
- #-------------------------------------------------------------------------------------------------------------------------------#
567
- ####OLD CODE------------------------------------------------------------------------------------
568
- # @fastapi_app.post("/face-swap", dependencies=[Depends(verify_token)])
569
- # async def face_swap_api(
570
- # source: UploadFile = File(...),
571
- # target_category_id: str = Form(...),
572
- # credentials: HTTPAuthorizationCredentials = Security(security)
573
- # ):
574
- # start_time = datetime.utcnow() # start timer
575
- # try:
576
- # # Read source image
577
- # src_bytes = await source.read()
578
-
579
- # # Save source to Spaces
580
- # src_key = f"faceswap/source/{uuid.uuid4().hex}_{source.filename}"
581
- # upload_to_spaces(src_bytes, src_key, content_type=source.content_type)
582
-
583
- # # Find target image URL from categoryId
584
- # client = get_spaces_client()
585
- # base_prefix = "faceswap/target/"
586
- # resp = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=base_prefix, Delimiter="/")
587
- # categories = [prefix["Prefix"].split("/")[2] for prefix in resp.get("CommonPrefixes", [])]
588
- # target_url = None
589
- # for category in categories:
590
- # original_prefix = f"faceswap/target/{category}/original/"
591
- # thumb_prefix = f"faceswap/target/{category}/thumb/"
592
- # original_objects = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=original_prefix)
593
- # thumb_objects = client.list_objects_v2(Bucket=DO_SPACES_BUCKET, Prefix=thumb_prefix)
594
- # original_files = [obj["Key"].split("/")[-1] for obj in original_objects.get("Contents", []) if obj["Key"].endswith(".png")]
595
- # thumb_files = [obj["Key"].split("/")[-1] for obj in thumb_objects.get("Contents", []) if obj["Key"].endswith(".png")]
596
- # for idx, filename in enumerate(sorted(original_files), start=1):
597
- # cid = f"{category.lower()}image_{idx}"
598
- # if filename in thumb_files and cid == target_category_id:
599
- # target_url = f"https://{DO_SPACES_BUCKET}.blr1.digitaloceanspaces.com/{original_prefix}{filename}"
600
- # break
601
- # if target_url:
602
- # break
603
- # if not target_url:
604
- # raise HTTPException(status_code=404, detail="Target categoryId not found")
605
-
606
- # # Download target image from Spaces
607
- # resp = requests.get(target_url)
608
- # if resp.status_code != 200:
609
- # raise HTTPException(status_code=404, detail="Target image not found in Spaces")
610
- # tgt_bytes = resp.content
611
-
612
- # # Decode for processing
613
- # src_array = np.frombuffer(src_bytes, np.uint8)
614
- # tgt_array = np.frombuffer(tgt_bytes, np.uint8)
615
- # src_bgr = cv2.imdecode(src_array, cv2.IMREAD_COLOR)
616
- # tgt_bgr = cv2.imdecode(tgt_array, cv2.IMREAD_COLOR)
617
- # if src_bgr is None or tgt_bgr is None:
618
- # raise HTTPException(status_code=400, detail="Invalid image data")
619
-
620
- # src_rgb = cv2.cvtColor(src_bgr, cv2.COLOR_BGR2RGB)
621
- # tgt_rgb = cv2.cvtColor(tgt_bgr, cv2.COLOR_BGR2RGB)
622
-
623
- # # Run face swap pipeline
624
- # final_img, final_path, err = face_swap_and_enhance(src_rgb, tgt_rgb)
625
- # if err:
626
- # raise HTTPException(status_code=500, detail=err)
627
-
628
- # # Upload result to Spaces
629
- # with open(final_path, "rb") as f:
630
- # result_bytes = f.read()
631
- # result_key = f"faceswap/result/{uuid.uuid4().hex}_enhanced.png"
632
- # result_url = upload_to_spaces(result_bytes, result_key, content_type="image/png")
633
-
634
- # # Calculate response time
635
- # end_time = datetime.utcnow()
636
- # response_time_ms = (end_time - start_time).total_seconds() * 1000
637
-
638
- # # Log response time only
639
- # if database is not None:
640
- # await database.api_logs.insert_one({
641
- # "endpoint": "/face-swap",
642
- # "status": "success",
643
- # "response_time_ms": response_time_ms,
644
- # "timestamp": end_time
645
- # })
646
-
647
- # return {"result_key": result_key, "result_url": result_url}
648
-
649
- # except Exception as e:
650
- # # Log response time even on error
651
- # end_time = datetime.utcnow()
652
- # response_time_ms = (end_time - start_time).total_seconds() * 1000
653
- # if database is not None:
654
- # await database.api_logs.insert_one({
655
- # "endpoint": "/face-swap",
656
- # "status": "fail",
657
- # "response_time_ms": response_time_ms,
658
- # "timestamp": end_time,
659
- # "error": str(e)
660
- # })
661
- # raise HTTPException(status_code=500, detail=f"Face swap failed: {str(e)}")
662
-
663
-
664
-
665
  @fastapi_app.get("/preview/{result_key:path}")
666
  async def preview_result(result_key: str):
667
  try:
 
8
  import threading
9
  import subprocess
10
  import logging
11
+ from datetime import datetime,timedelta
12
 
13
  import insightface
14
  from insightface.app import FaceAnalysis
15
  from huggingface_hub import hf_hub_download
 
16
  from fastapi import FastAPI, UploadFile, File, HTTPException, Response, Depends, Security, Form
17
  from fastapi.responses import RedirectResponse
18
  from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
 
319
 
320
  # ------------------------------------------------------------------
321
  # # MEDIA_CLICKS (ONLY IF user_id PRESENT
322
+ # if user_id:
323
+ # try:
324
+ # user_oid = ObjectId(user_id.strip())
325
+ # now = datetime.utcnow()
326
+
327
+ # # -------------------------------------------------
328
+ # # STEP 1: Ensure root fields exist (NO inc here)
329
+ # # -------------------------------------------------
330
+ # await media_clicks_col.update_one(
331
+ # {"userId": user_oid},
332
+ # {
333
+ # "$setOnInsert": {
334
+ # "userId": user_oid,
335
+ # "createdAt": now,
336
+ # "ai_edit_complete": 0
337
+ # }
338
+ # },
339
+ # upsert=True
340
+ # )
341
+
342
+ # # -------------------------------------------------
343
+ # # STEP 2: Try updating existing subCategory
344
+ # # -------------------------------------------------
345
+ # update_result = await media_clicks_col.update_one(
346
+ # {
347
+ # "userId": user_oid,
348
+ # "subCategories.subCategoryId": subcategory_oid
349
+ # },
350
+ # {
351
+ # "$inc": {
352
+ # "subCategories.$.click_count": 1,
353
+ # "ai_edit_complete": 1
354
+ # },
355
+ # "$set": {
356
+ # "subCategories.$.lastClickedAt": now,
357
+ # "ai_edit_last_date": now,
358
+ # "updatedAt": now
359
+ # }
360
+ # }
361
+ # )
362
+
363
+ # # -------------------------------------------------
364
+ # # STEP 3: Push subCategory if missing
365
+ # # -------------------------------------------------
366
+ # if update_result.matched_count == 0:
367
+ # await media_clicks_col.update_one(
368
+ # {"userId": user_oid},
369
+ # {
370
+ # "$inc": {
371
+ # "ai_edit_complete": 1
372
+ # },
373
+ # "$set": {
374
+ # "ai_edit_last_date": now,
375
+ # "updatedAt": now
376
+ # },
377
+ # "$push": {
378
+ # "subCategories": {
379
+ # "subCategoryId": subcategory_oid,
380
+ # "click_count": 1,
381
+ # "lastClickedAt": now
382
+ # }
383
+ # }
384
+ # }
385
+ # )
386
+
387
+ # logger.info(
388
+ # "[MEDIA_CLICK] user=%s subCategory=%s ai_edit_complete++",
389
+ # user_id,
390
+ # str(subcategory_oid)
391
+ # )
392
+
393
+ # except Exception as media_err:
394
+ # logger.error(f"MEDIA_CLICK ERROR: {media_err}")
395
  if user_id:
396
  try:
397
  user_oid = ObjectId(user_id.strip())
398
  now = datetime.utcnow()
399
 
400
+ # Normalize dates (UTC midnight)
401
+ today_date = datetime(now.year, now.month, now.day)
402
+ yesterday_date = today_date - timedelta(days=1)
403
+
404
  # -------------------------------------------------
405
+ # STEP 1: Ensure root document exists
406
  # -------------------------------------------------
407
  await media_clicks_col.update_one(
408
  {"userId": user_oid},
 
410
  "$setOnInsert": {
411
  "userId": user_oid,
412
  "createdAt": now,
413
+ "ai_edit_complete": 0,
414
+ "ai_edit_daily_count": []
415
  }
416
  },
417
  upsert=True
418
  )
419
 
420
  # -------------------------------------------------
421
+ # STEP 2: Handle DAILY USAGE (binary per day)
422
+ # -------------------------------------------------
423
+
424
+ doc = await media_clicks_col.find_one(
425
+ {"userId": user_oid},
426
+ {"ai_edit_daily_count": 1}
427
+ )
428
+
429
+ daily_entries = doc.get("ai_edit_daily_count", []) if doc else []
430
+
431
+ existing_dates = {
432
+ entry["date"].date(): entry["count"]
433
+ for entry in daily_entries
434
+ }
435
+
436
+ daily_updates = []
437
+
438
+ # Insert yesterday if missing
439
+ if yesterday_date.date() not in existing_dates:
440
+ daily_updates.append({
441
+ "date": yesterday_date,
442
+ "count": 0
443
+ })
444
+
445
+ # Insert today if missing
446
+ if today_date.date() not in existing_dates:
447
+ daily_updates.append({
448
+ "date": today_date,
449
+ "count": 1
450
+ })
451
+
452
+ if daily_updates:
453
+ await media_clicks_col.update_one(
454
+ {"userId": user_oid},
455
+ {
456
+ "$push": {
457
+ "ai_edit_daily_count": {
458
+ "$each": daily_updates
459
+ }
460
+ }
461
+ }
462
+ )
463
+
464
+ # -------------------------------------------------
465
+ # STEP 3: Try updating existing subCategory
466
  # -------------------------------------------------
467
  update_result = await media_clicks_col.update_one(
468
  {
 
483
  )
484
 
485
  # -------------------------------------------------
486
+ # STEP 4: Push subCategory if missing
487
  # -------------------------------------------------
488
  if update_result.matched_count == 0:
489
  await media_clicks_col.update_one(
 
507
  )
508
 
509
  logger.info(
510
+ "[MEDIA_CLICK] user=%s subCategory=%s ai_edit_complete++ daily_tracked",
511
  user_id,
512
  str(subcategory_oid)
513
  )
 
515
  except Exception as media_err:
516
  logger.error(f"MEDIA_CLICK ERROR: {media_err}")
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  # # ------------------------------------------------------------------
519
  # # CASE 2 : target_category_id → DigitalOcean path (unchanged logic)
520
  # # ------------------------------------------------------------------
 
557
  # Replicate the old indexing logic based on sorted filenames
558
  for idx, filename in enumerate(original_filenames, start=1):
559
  cid = f"{category.lower()}image_{idx}"
560
+
561
  # Optional: Replicate the thumb file check for 100% parity
562
  # if filename in thumb_filenames and cid == target_category_id:
 
563
  # Simpler check just on the ID, assuming thumb files are present
564
  if cid == target_category_id:
565
  # Construct the final target URL using the full prefix and the filename
 
572
 
573
  if not target_url:
574
  raise HTTPException(404, "Target categoryId not found")
 
575
  # # ------------------------------------------------------------------
576
  # # DOWNLOAD TARGET IMAGE
577
  # # ------------------------------------------------------------------
 
615
  "result_url": result_url
616
  }
617
 
 
618
  except Exception as e:
619
  end_time = datetime.utcnow()
620
  response_time_ms = (end_time - start_time).total_seconds() * 1000
 
630
 
631
  raise HTTPException(500, f"Face swap failed: {str(e)}")
632
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
633
  @fastapi_app.get("/preview/{result_key:path}")
634
  async def preview_result(result_key: str):
635
  try: