File size: 4,787 Bytes
411c593
 
 
4521a27
411c593
 
 
 
 
 
4521a27
411c593
 
 
 
 
 
 
4521a27
411c593
c9f6ba1
411c593
c9f6ba1
411c593
 
 
c9f6ba1
 
411c593
4521a27
411c593
 
 
 
 
 
 
 
 
 
 
4521a27
 
c9f6ba1
411c593
 
 
4521a27
411c593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4521a27
c9f6ba1
411c593
 
 
c9f6ba1
411c593
4521a27
 
 
c9f6ba1
4521a27
 
c9f6ba1
4521a27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c9f6ba1
4521a27
 
c9f6ba1
4521a27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c9f6ba1
 
4521a27
411c593
 
4521a27
c9f6ba1
4521a27
c9f6ba1
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import cv2
import torch
import requests
import time
from PIL import Image
from supabase import create_client
from transformers import AutoImageProcessor, AutoModelForImageClassification
import os

# ===============================
# πŸ—„ Supabase Setup
# ===============================
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")

supabase = create_client(SUPABASE_URL, SUPABASE_KEY)

# ===============================
# πŸ€– Load NSFW Model (once)
# ===============================
print("πŸ”„ Loading NSFW model...")

model_name = "AdamCodd/vit-base-nsfw-detector"
processor = AutoImageProcessor.from_pretrained(model_name)
model = AutoModelForImageClassification.from_pretrained(model_name)

print("βœ… Model loaded")

# ===============================
# πŸ–Ό Image Check
# ===============================
def check_image(url):
    try:
        image = Image.open(requests.get(url, stream=True).raw).convert("RGB")
        inputs = processor(images=image, return_tensors="pt")

        with torch.no_grad():
            outputs = model(**inputs)

        probs = torch.softmax(outputs.logits, dim=1)
        return "explicit" if probs[0][1] > 0.5 else "safe"

    except Exception as e:
        print("❌ Image error:", e)
        return "safe"

# ===============================
# πŸŽ₯ Video Check
# ===============================
def check_video(url, frame_sample_rate=30):
    try:
        cap = cv2.VideoCapture(url)
        frame_count = 0

        while cap.isOpened():
            ret, frame = cap.read()
            if not ret:
                break

            if frame_count % frame_sample_rate == 0:
                img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
                inputs = processor(images=img, return_tensors="pt")

                with torch.no_grad():
                    outputs = model(**inputs)

                probs = torch.softmax(outputs.logits, dim=1)

                if probs[0][1] > 0.5:
                    cap.release()
                    return "explicit"

            frame_count += 1

        cap.release()
        return "safe"

    except Exception as e:
        print("❌ Video error:", e)
        return "safe"

# ===============================
# πŸ” MAIN WORKER LOOP
# ===============================
def moderation_worker():
    while True:
        try:
            print("\nπŸš€ Running moderation job...")

            # ===============================
            # πŸ–Ό Process Images
            # ===============================
            img_posts = supabase.table("posts") \
                .select("*") \
                .limit(10) \
                .execute().data

            for post in img_posts:
                existing = supabase.table("content_moderation") \
                    .select("id") \
                    .eq("post_id", post["id"]) \
                    .eq("post_type", "image") \
                    .execute()

                if len(existing.data) == 0:
                    result = check_image(post["image_url"])

                    supabase.table("content_moderation").insert({
                        "post_id": post["id"],
                        "post_type": "image",
                        "file_url": post["image_url"],
                        "result": result
                    }).execute()

                    print(f"πŸ–Ό IMAGE {post['id']} β†’ {result}")

            # ===============================
            # πŸŽ₯ Process Videos
            # ===============================
            vid_posts = supabase.table("trendz") \
                .select("*") \
                .limit(5) \
                .execute().data

            for post in vid_posts:
                existing = supabase.table("content_moderation") \
                    .select("id") \
                    .eq("post_id", post["id"]) \
                    .eq("post_type", "video") \
                    .execute()

                if len(existing.data) == 0:
                    result = check_video(post["video_url"])

                    supabase.table("content_moderation").insert({
                        "post_id": post["id"],
                        "post_type": "video",
                        "file_url": post["video_url"],
                        "result": result
                    }).execute()

                    print(f"πŸŽ₯ VIDEO {post['id']} β†’ {result}")

        except Exception as e:
            print("❌ Worker error:", e)

        # ⏱ WAIT 5 MINUTES
        print("⏳ Sleeping for 5 minutes...\n")
        time.sleep(300)


# ===============================
# ▢️ AUTO START
# ===============================
if __name__ == "__main__":
    print("πŸ”₯ Starting NSFW moderation worker...")
    moderation_worker()