Spaces:
Sleeping
Sleeping
File size: 8,338 Bytes
9217eed 0237ea8 b72bf58 3589d5b e0b38bb 3589d5b 084da93 fd7f1a5 9e0f2af 42d9d3a 4d74383 2a3b5a5 42d9d3a 9e0f2af 4d74383 42d9d3a 9e0f2af 4d74383 42d9d3a 3589d5b 9e0f2af a8e0f0e ed79407 9e0f2af 0237ea8 9e0f2af 4d74383 42d9d3a 9e0f2af 084da93 a47481e 084da93 2a3b5a5 084da93 9e0f2af 084da93 9e0f2af 084da93 3589d5b 084da93 199a115 084da93 199a115 084da93 3589d5b 9e0f2af 084da93 9e0f2af 3589d5b 9e0f2af 084da93 752f720 9e0f2af 084da93 42d9d3a bddafba 084da93 bddafba 084da93 bddafba 084da93 bddafba 084da93 bddafba 2a3b5a5 9e0f2af 2a3b5a5 bddafba 199a115 9e0f2af 199a115 9e0f2af 42d9d3a 2a3b5a5 9e0f2af 4d74383 9e0f2af 2a3b5a5 9e0f2af 2a3b5a5 9e0f2af 752f720 9e0f2af 2a3b5a5 42d9d3a 752f720 9e0f2af 4d74383 b72bf58 9e0f2af ed79407 5804e94 42d9d3a 752f720 b72bf58 752f720 2a3b5a5 a7b000d 2a3b5a5 4d74383 a7b000d a8e0f0e 4d74383 a8e0f0e 9e0f2af ed79407 9e0f2af 4d74383 9e0f2af 42d9d3a e0b38bb 9e0f2af 2a3b5a5 752f720 9e0f2af 752f720 4d74383 752f720 199a115 4d74383 42d9d3a 9e0f2af 2a3b5a5 4d74383 199a115 4d74383 2a3b5a5 9e0f2af 199a115 2a3b5a5 9e0f2af 199a115 9e0f2af 2a3b5a5 42d9d3a b72bf58 42d9d3a | 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 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | import gradio as gr
import requests
import time
import random
from urllib.parse import urlparse, parse_qs
from threading import Event
from http.cookies import SimpleCookie
class ReportSender:
def __init__(self):
self.stop_event = Event()
self.is_running = False
def execute_reports_loop(self, master_url_batch, cookie_header, batch_count, current_status):
if self.is_running:
yield gr.update(), True, "Running"
return
if not master_url_batch or not master_url_batch.strip():
yield "Error: Report URL Batch is empty.", False, "Stopped"
return
if not cookie_header or not cookie_header.strip():
yield "Error: Cookie Header is missing.", False, "Stopped"
return
self.stop_event.clear()
self.is_running = True
master_urls = [u.strip() for u in master_url_batch.split('\n') if u.strip()]
num_urls = len(master_urls)
if not master_urls:
self.is_running = False
yield "Error: No valid URLs found.", False, "Stopped"
return
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
csrf_token = ""
try:
cookie_parser = SimpleCookie()
cookie_parser.load(cookie_header)
if 'tt_csrf_token' in cookie_parser:
csrf_token = cookie_parser['tt_csrf_token'].value
except Exception:
pass
headers = {
"User-Agent": USER_AGENT,
"Referer": "https://www.tiktok.com/",
"Cookie": cookie_header,
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "en-US,en;q=0.9",
}
if csrf_token:
headers["tt-csrf-token"] = csrf_token
headers["x-secsdk-csrf-token"] = csrf_token
log_history = f" Starting batch loop for {num_urls} report types...\n"
if csrf_token:
log_history += " CSRF Token applied.\n"
else:
log_history += " WARNING: No 'tt_csrf_token' found.\n"
yield log_history, self.is_running, "Running"
total_requests_sent = 0
while not self.stop_event.is_set():
for i, final_url in enumerate(master_urls):
if self.stop_event.is_set():
break
delay = random.uniform(1, 3)
time.sleep(delay)
try:
query_params = parse_qs(urlparse(final_url).query)
reason_code = query_params.get('reason', ['UNKNOWN'])[0]
report_type = query_params.get('report_type', ['??'])[0]
report_name = f"Reason: {reason_code} / Type: {report_type.upper()}"
except Exception:
report_name = f"URL #{i+1}"
try:
response = requests.get(final_url, headers=headers, timeout=10)
timestamp = time.strftime("%H:%M:%S")
total_requests_sent += 1
is_empty_success = response.status_code == 200 and not response.text.strip()
is_json_success = False
status_code_msg = "No Message"
status_code_val = "???"
if not is_empty_success:
try:
parsed = response.json()
status_code_val = parsed.get('status_code', -1)
status_code_msg = parsed.get('status_message', 'No Message')
if status_code_val == 0:
is_json_success = True
except:
status_code_msg = "Non-JSON Response"
status_code_val = response.status_code
is_success = is_empty_success or is_json_success
if is_success:
status_icon = "SUCCESS"
status_msg = "Request Sent"
else:
status_icon = "FAIL"
if not is_empty_success and not is_json_success:
status_msg = f"Failed ({response.status_code}): {status_code_msg}"
else:
status_msg = f"Failed ({response.status_code})"
log_entry = (
f"[{timestamp}] {status_icon} REQ ({total_requests_sent}): {report_name}\n"
f" Status: {status_msg} | Delay: {delay:.2f}s\n"
)
log_history += log_entry
yield log_history, self.is_running, "Running"
except requests.exceptions.Timeout:
log_history += f"[{time.strftime('%H:%M:%S')}] ERROR: Timeout.\n"
yield log_history, self.is_running, "Running"
except Exception as e:
log_history += f"[{time.strftime('%H:%M:%S')}] ERROR: {str(e)}\n"
yield log_history, self.is_running, "Running"
if batch_count != -1:
batch_count -= 1
if batch_count <= 0:
self.stop_event.set()
self.is_running = False
log_history += f"\n\nSTOPPED. Total Requests Sent: {total_requests_sent}."
yield log_history, self.is_running, "Stopped"
def stop_execution(self):
self.stop_event.set()
self.is_running = False
sender = ReportSender()
with gr.Blocks() as app:
gr.Markdown("# TikTok spam report")
is_running_state = gr.State(False)
current_status = gr.State("Stopped")
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### 1. Request Context")
cookie_input = gr.Textbox(
label="Full Browser Cookie Header",
lines=5, max_lines=5
)
gr.Markdown("### 2. Report URLs Batch")
master_url_batch_input = gr.Textbox(
label="Master Signed Report URLs",
lines=5, max_lines=10
)
gr.Markdown("### 3. Loop Control")
with gr.Row(equal_height=False):
batch_count_input = gr.Number(
label="Batch Count (-1 for infinite)",
value=-1, scale=1
)
status_box = gr.Textbox(label="Status", value="Stopped", interactive=False, scale=1)
with gr.Row():
send_btn = gr.Button("START Loop", variant="primary", scale=1)
stop_btn = gr.Button("STOP Loop", variant="stop", scale=1, interactive=False)
with gr.Column(scale=1):
gr.Markdown("### 4. Execution Logs")
logs_output = gr.Textbox(
show_label=False,
lines=20, max_lines=20,
autoscroll=True,
elem_id="log-box"
)
send_btn.click(
fn=lambda: (gr.update(interactive=False), gr.update(interactive=True)),
outputs=[send_btn, stop_btn],
queue=False
)
run_event = send_btn.click(
fn=sender.execute_reports_loop,
inputs=[master_url_batch_input, cookie_input, batch_count_input, current_status],
outputs=[logs_output, is_running_state, status_box],
)
run_event.then(
fn=lambda: (gr.update(interactive=True), gr.update(interactive=False)),
outputs=[send_btn, stop_btn]
)
stop_btn.click(
fn=sender.stop_execution,
inputs=None,
outputs=None,
cancels=[run_event],
queue=False
).then(
fn=lambda: (gr.update(interactive=True), gr.update(interactive=False), "Stopped"),
outputs=[send_btn, stop_btn, status_box],
queue=False
)
status_box.change(lambda x: x, inputs=status_box, outputs=current_status)
if __name__ == "__main__":
app.launch(theme=gr.themes.Soft()) |