r.go commited on
Commit
9770efd
·
0 Parent(s):
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ node_modules
2
+ cache_dir
3
+ .env
4
+ social_session
Dockerfile ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Declare build arguments globally before any FROM statement.
2
+ ARG PYTHON_VERSION=3.12.1
3
+
4
+ # ---------------------------
5
+ # Stage 1: Node build environment
6
+ # ---------------------------
7
+ FROM node:20-alpine3.16 AS node-builder
8
+
9
+ WORKDIR /app
10
+ # Copy the entire project from the build context.
11
+ COPY . .
12
+
13
+ # Install required Alpine packages.
14
+ RUN apk add --no-cache \
15
+ font-noto font-noto-cjk font-noto-extra \
16
+ gcompat libstdc++ libuuid \
17
+ vips-dev build-base jpeg-dev pango-dev cairo-dev \
18
+ imagemagick libssl1.1 && \
19
+ ln -s /lib/libresolv.so.2 /usr/lib/libresolv.so.2
20
+
21
+ # Install Node dependencies and install ts-node globally.
22
+ RUN npm install && \
23
+ npm install -g ts-node
24
+
25
+ # ---------------------------
26
+ # Stage 2: Python runtime environment
27
+ # ---------------------------
28
+ FROM python:${PYTHON_VERSION}-slim
29
+
30
+ # Update apt and install system dependencies.
31
+ RUN apt-get update && \
32
+ apt-get install -y --no-install-recommends \
33
+ fontconfig fonts-dejavu fonts-dejavu-core fonts-dejavu-extra \
34
+ fonts-liberation fonts-noto \
35
+ git && \
36
+ rm -rf /var/lib/apt/lists/*
37
+
38
+ # Set environment variables.
39
+ ENV PORT=7860
40
+
41
+ WORKDIR /app
42
+ # Copy the entire project from the build context.
43
+ COPY . .
44
+
45
+ # If the environment variables are set, clone the private repository.
46
+ RUN if [ -n "$GITHUB_USERNAME" ] && [ -n "$GITHUB_TOKEN" ] && [ -n "$GITHUB_REPO" ]; then \
47
+ echo "Cloning private repository into 'social_session'"; \
48
+ git clone https://$GITHUB_USERNAME:$GITHUB_TOKEN@github.com/$GITHUB_USERNAME/$GITHUB_REPO.git social_session; \
49
+ else \
50
+ echo "Skipping git clone: GITHUB_USERNAME, TOKEN, or GITHUB_REPO not set"; \
51
+ fi
52
+
53
+ # Expose the port used by the ASGI server.
54
+ EXPOSE 7860
55
+
56
+ # Install your Python dependencies from requirements.txt.
57
+ RUN pip install -r requirements.txt
58
+
59
+ # Start the server using uvicorn.
60
+ CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "8", "--timeout-keep-alive", "600"]
build.sh ADDED
@@ -0,0 +1 @@
 
 
1
+ docker run -p 7860:7860 $(docker build -q .)
main.py ADDED
@@ -0,0 +1,510 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import dotenv_values, load_dotenv
2
+ load_dotenv(override=True)
3
+
4
+ import os
5
+ import asyncio
6
+ from quart import Quart, jsonify
7
+ from twikit import Client
8
+ from datetime import datetime
9
+ import diskcache as dc
10
+ import re
11
+ import requests
12
+ import xmltodict
13
+ import urllib
14
+ import traceback
15
+ import threading
16
+ import json
17
+ import subprocess
18
+ import queue
19
+ from threads_util.main import Threads
20
+ import asyncpraw
21
+ import instagrapi
22
+ # print(
23
+ # os.environ.get("INSTA_USERNAME"), os.environ.get("INSTA_PASSWORD")/
24
+
25
+ # )
26
+ response_queue = queue.Queue()
27
+
28
+ def read_from_node(proc):
29
+ """Continuously read lines from the Node.js process's stdout and parse JSON when possible."""
30
+ buffer = ""
31
+ for line in iter(proc.stdout.readline, ''): # Read line by line
32
+ buffer += line
33
+ try:
34
+ print(buffer)
35
+ data = json.loads(buffer)
36
+ response_queue.put(data)
37
+ buffer = ""
38
+ except json.JSONDecodeError:
39
+ continue
40
+
41
+ # If the loop exits, the process has likely closed
42
+ print("Node.js process terminated unexpectedly.")
43
+ global node_proc
44
+ node_proc = subprocess.Popen(
45
+ ["npx", "ts-node", "scraper.ts"],
46
+ stdin=subprocess.PIPE,
47
+ stdout=subprocess.PIPE,
48
+ stderr=subprocess.PIPE,
49
+ text=True
50
+ )
51
+ # Restart the stdout and stderr reader threads for the new process:
52
+ threading.Thread(target=read_from_node, args=(node_proc,), daemon=True).start()
53
+ threading.Thread(target=read_stderr, args=(node_proc,), daemon=True).start()
54
+
55
+ def read_stderr(proc):
56
+ """Continuously read and log stderr output from the Node.js process."""
57
+ for line in iter(proc.stderr.readline, ''):
58
+ print(f"Node.js Error: {line.strip()}")
59
+
60
+ def send_to_node(proc, message, timeout=30):
61
+ """Send a message to the Node.js process and wait for a response."""
62
+ try:
63
+ proc.stdin.write(message + "\n")
64
+ proc.stdin.flush()
65
+
66
+ try:
67
+ response = response_queue.get(timeout=timeout)
68
+ return response
69
+ except queue.Empty:
70
+ return "Error: No response received from Node.js"
71
+
72
+ except BrokenPipeError:
73
+ return "Error: Broken pipe - Node.js process might have exited."
74
+ except Exception as e:
75
+ return f"Error writing to Node process: {e}"
76
+
77
+ node_proc = subprocess.Popen(
78
+ ["npx", "ts-node", "scraper.ts"],
79
+ stdin=subprocess.PIPE,
80
+ stdout=subprocess.PIPE,
81
+ stderr=subprocess.PIPE,
82
+ text=True
83
+ )
84
+
85
+ threading.Thread(target=read_from_node, args=(node_proc,), daemon=True).start()
86
+ threading.Thread(target=read_stderr, args=(node_proc,), daemon=True).start()
87
+ TWI_COOKIE_PATH = f"wsocial_session/{os.environ.get('TWI_USERNAME')}_cookies.json"
88
+ INSTA_COOKIE_PATH = f"social_session/insta_{os.environ.get('INSTA_USERNAME')}_cookies.json"
89
+ os.makedirs(os.path.dirname(TWI_COOKIE_PATH), exist_ok=True)
90
+ os.makedirs(os.path.dirname(INSTA_COOKIE_PATH), exist_ok=True)
91
+
92
+ app = Quart("Auto notifier thingy")
93
+ cache = dc.Cache('/tmp/cache_dir/')
94
+
95
+ x_client = Client('en-US')
96
+ insta_client = instagrapi.Client()
97
+ reddit_client = None
98
+ threads_client = Threads()
99
+
100
+ async def login_instagram():
101
+ if not os.path.exists(INSTA_COOKIE_PATH):
102
+ print("logging in")
103
+ insta_client.login(
104
+ os.environ.get("INSTA_USERNAME"), os.environ.get("INSTA_PASSWORD")
105
+ )
106
+ insta_client.dump_settings(INSTA_COOKIE_PATH)
107
+ else:
108
+ session = insta_client.load_settings(INSTA_COOKIE_PATH)
109
+ insta_client.set_settings(session)
110
+
111
+ insta_client.login(
112
+ os.environ.get("INSTA_USERNAME"), os.environ.get("INSTA_PASSWORD")
113
+ )
114
+ try:
115
+ insta_client.get_timeline_feed()
116
+ except instagrapi.exceptions.LoginRequired:
117
+ print("Session is invalid, need to login via username and password")
118
+ old_session = insta_client.get_settings()
119
+ # use the same device uuids across logins
120
+ insta_client.set_settings({})
121
+ insta_client.set_uuids(old_session["uuids"])
122
+
123
+ insta_client.login( os.environ.get("INSTA_USERNAME"), os.environ.get("INSTA_PASSWORD"))
124
+ insta_client.dump_settings(INSTA_COOKIE_PATH)
125
+
126
+ async def initialize_client():
127
+ global reddit_client
128
+ reddit_client = asyncpraw.Reddit(
129
+ client_id=os.environ.get("REDDIT_CLIENTAPI"),
130
+ client_secret=os.environ.get("REDDIT_CLIENTSECRET"),
131
+ username=os.environ.get("REDDIT_USERNAME"),
132
+ password=os.environ.get("REDDIT_PASSWORD"),
133
+ user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36",
134
+ )
135
+
136
+ if not os.path.exists(TWI_COOKIE_PATH):
137
+ print(TWI_COOKIE_PATH, "Login twi using pw")
138
+ await x_client.login(
139
+ auth_info_1=os.environ.get('TWI_USERNAME'),
140
+ auth_info_2=os.environ.get('TWI_EMAIL'),
141
+ password=os.environ.get('TWI_PASSWORD')
142
+ )
143
+ x_client.save_cookies(TWI_COOKIE_PATH)
144
+ else:
145
+ x_client.load_cookies(TWI_COOKIE_PATH)
146
+
147
+
148
+ @app.before_serving
149
+ async def before_serving():
150
+ await login_instagram()
151
+ await initialize_client()
152
+
153
+ def remove_circular(obj, seen=None):
154
+ if seen is None:
155
+ seen = set()
156
+ obj_id = id(obj)
157
+ if obj_id in seen:
158
+ return None
159
+ seen.add(obj_id)
160
+
161
+ if isinstance(obj, dict):
162
+ return {k: remove_circular(v, seen) for k, v in obj.items()}
163
+ elif isinstance(obj, list):
164
+ return [remove_circular(item, seen) for item in obj]
165
+ elif isinstance(obj, tuple):
166
+ return tuple(remove_circular(item, seen) for item in obj)
167
+ elif hasattr(obj, '__dict__'):
168
+ return remove_circular(obj.__dict__, seen)
169
+ else:
170
+ return obj
171
+
172
+ def remove_client(data):
173
+ if isinstance(data, dict):
174
+ return {k: remove_client(v) for k, v in data.items() if k != '_client' and k != 'user'}
175
+ elif isinstance(data, list):
176
+ return [remove_client(item) for item in data]
177
+ else:
178
+ return data
179
+
180
+ def serialize_tweet(tweet):
181
+ def parse_date(date_str):
182
+ try:
183
+ return datetime.strptime(date_str, "%a %b %d %H:%M:%S %z %Y").isoformat()
184
+ except (ValueError, AttributeError):
185
+ return date_str
186
+
187
+ return {
188
+ "id": tweet.id,
189
+ "text": tweet.full_text,
190
+ "created_at": parse_date(tweet.created_at),
191
+ "lang": tweet.lang,
192
+ "retweet_count": tweet.retweet_count,
193
+ "favorite_count": tweet.favorite_count,
194
+ "user": {
195
+ "id": tweet.user.id,
196
+ "screen_name": tweet.user.screen_name,
197
+ "name": tweet.user.name,
198
+ "followers_count": tweet.user.followers_count,
199
+ },
200
+ "media": [
201
+ {
202
+ **media
203
+ }
204
+ for media in (tweet.media or [])
205
+ ]
206
+ }
207
+
208
+ async def fetch_user_and_tweets(username):
209
+ userid = await x_client.get_user_by_screen_name(screen_name=username)
210
+ if userid is None:
211
+ return None, None
212
+
213
+ tweets = await x_client.get_user_tweets(user_id=userid.id, tweet_type='tweets', count=2)
214
+ return userid, tweets
215
+
216
+ @app.route('/twitter/<username>')
217
+ async def get_posts_twitter(username):
218
+ cache_key = f"user_tweets_{username}"
219
+
220
+ # Check cache first
221
+ if cache_key in cache:
222
+ serialized_tweets = cache[cache_key]
223
+ else:
224
+ userid, tweets = await fetch_user_and_tweets(username)
225
+ if userid is None:
226
+ return jsonify({"error": True, "errorlog": "User not found"}), 404
227
+
228
+ if tweets is None or len(tweets) == 0:
229
+ return jsonify({"error": True, "errorlog": "No tweets found for this user"}), 404
230
+
231
+ serialized_tweets = [serialize_tweet(tweet) for tweet in tweets]
232
+ # Store in cache
233
+ cache.set(cache_key, serialized_tweets, expire=300) # Cache for 5 minutes
234
+
235
+ return jsonify(serialized_tweets)
236
+
237
+
238
+ @app.route('/tiktok/<username>')
239
+ async def get_posts_tiktok(username):
240
+ cache_key = f"user_tiktok_{username}"
241
+
242
+ if cache_key in cache:
243
+ serialized_data = cache[cache_key]
244
+ else:
245
+ serialized_data = send_to_node(node_proc, username)
246
+ if isinstance(serialized_data, str):
247
+ return jsonify({"error": True, "errorlog": serialized_data}), 500
248
+ cache.set(cache_key, serialized_data, expire=300) # Cache for 5 minutes
249
+ return jsonify(serialized_data)
250
+
251
+
252
+ @app.route('/youtube/<path:channel_url>')
253
+ async def get_uploads_youtube(channel_url):
254
+ format_youtube_url = lambda url: f"https://youtube.com/channel/{url.split('/')[-1]}" if "/channel/" in url else f"https://www.youtube.com/@{url.split('@')[-1]}" if "youtube.com/@" in url else url
255
+ decoded_url = urllib.parse.unquote(channel_url)
256
+ yt_url = format_youtube_url(decoded_url)
257
+
258
+ cache_key = f"user_uploads_{yt_url}"
259
+ if cache_key in cache:
260
+ uploads = cache[cache_key]
261
+ else:
262
+ headers = {"User-Agent": "Mozilla/5.0"}
263
+ def get_last_url_segment(html):
264
+ """Extracts the last segment of the canonical URL from the HTML content."""
265
+ match = re.search(r'<link[^>]+rel=[\'"]canonical[\'"][^>]+href=[\'"]([^\'"]+)[\'"]', html)
266
+ if match:
267
+ return match.group(1).rstrip('/').split('/')[-1]
268
+ return None
269
+
270
+ def get_last_url_segment_from_webpage(url):
271
+ """Fetches the webpage and extracts the last URL segment from the canonical link."""
272
+
273
+ try:
274
+ response = requests.get(url, headers=headers, timeout=10)
275
+ if response.status_code == 200:
276
+ return get_last_url_segment(response.text)
277
+ else:
278
+ return jsonify({"error": True, "errorlog": f"Failed to fetch page. Status code: {response.status_code}"})
279
+ except requests.exceptions.RequestException as e:
280
+ return jsonify({"error":True, "errorlog": f"Request Failed ${e}"})
281
+
282
+ return None
283
+ last_segment = get_last_url_segment_from_webpage(yt_url)
284
+ if not isinstance(last_segment, str):
285
+ return last_segment
286
+ response = requests.get("https://www.youtube.com/feeds/videos.xml?channel_id=" + last_segment)
287
+ if response.status_code != 200:
288
+ return jsonify({"error": True, "errorlog": f"Failed to fetch page videos.xml. Status code: {response.status_code}"})
289
+ uploads = xmltodict.parse(response.text)
290
+
291
+ if uploads is None or len(uploads) == 0:
292
+ return jsonify({"error": True, "errorlog": "No uploads found for this user"}), 404
293
+
294
+ cache.set(cache_key, uploads, expire=300)
295
+ return jsonify(uploads)
296
+
297
+ @app.route('/twitch/<username>')
298
+ async def is_live_twitch(username):
299
+ # await requests.get("")
300
+ cache_key = f"user_twitch_{username}"
301
+
302
+ if cache_key in cache:
303
+ serialized_data = cache[cache_key]
304
+ else:
305
+ serialized_data = send_to_node(node_proc, f"twitch {username}")
306
+ if isinstance(serialized_data, str):
307
+ return jsonify({"error": True, "errorlog": serialized_data}), 500
308
+ if not serialized_data.get("error"):
309
+ cache.set(cache_key, serialized_data, expire=300) # Cache for 5 minutes
310
+ return jsonify(serialized_data)
311
+
312
+ # threads = Threads()
313
+ # threads = None
314
+ @app.route('/threads/<username>')
315
+ async def threads_user(username):
316
+ cache_key = f"user_threads_{username}"
317
+
318
+ if cache_key in cache:
319
+ serialized_data = cache[cache_key]
320
+ else:
321
+ serialized_dataid = threads_client.get_user_id(username)
322
+ if isinstance(serialized_dataid, str):
323
+ return jsonify({"error": True, "errorlog": serialized_dataid}), 500
324
+ serialized_data = threads_client.get_user_threads(serialized_dataid)
325
+ cache.set(cache_key, serialized_data, expire=300)
326
+ return jsonify(serialized_data)
327
+
328
+ def extract_serializable_sum(obj, visited=None):
329
+ """
330
+ Recursively extract the JSON-serializable parts of an object.
331
+ If a circular reference is detected (object already seen), return None.
332
+ For non-serializable objects that are not basic types, fallback to str(obj).
333
+ """
334
+ if visited is None:
335
+ visited = set()
336
+ obj_id = id(obj)
337
+ if obj_id in visited:
338
+ # circular reference detected – omit this branch
339
+ return None
340
+ visited.add(obj_id)
341
+
342
+ # If the object is already a basic type, return it.
343
+ if isinstance(obj, (str, int, float, bool)) or obj is None:
344
+ return obj
345
+
346
+ # If it is a list, tuple, or set, process each element.
347
+ elif isinstance(obj, (list, tuple, set)):
348
+ return [extract_serializable_sum(item, visited) for item in obj]
349
+
350
+ # If it is a dict, process each key and value.
351
+ elif isinstance(obj, dict):
352
+ new_dict = {}
353
+ # We assume keys are strings; if not, convert them to strings.
354
+ for key, value in obj.items():
355
+ # If the key is not a string, convert it.
356
+ if not isinstance(key, str):
357
+ key = str(key)
358
+ new_dict[key] = extract_serializable_sum(value, visited)
359
+ return new_dict
360
+
361
+ # If the object has a __dict__ attribute, use it.
362
+ elif hasattr(obj, '__dict__'):
363
+ data = {}
364
+ # For example, you might want to skip internal attributes that cause circular references.
365
+ for key, value in obj.__dict__.items():
366
+ # Skip known problematic keys (such as references to the Reddit instance)
367
+ if key.startswith('_reddit'):
368
+ continue
369
+ data[key] = extract_serializable_sum(value, visited)
370
+ return data
371
+
372
+ # Otherwise, try to let json.dumps do its job. If that fails, return a string representation.
373
+ else:
374
+ try:
375
+ json.dumps(obj)
376
+ return obj
377
+ except (TypeError, OverflowError):
378
+ return str(obj)
379
+
380
+ @app.route('/reddit/user/<username>')
381
+ async def reddit_user(username):
382
+ cache_key = f"user_redditor_{username}"
383
+
384
+ if cache_key in cache:
385
+ serialized_data = cache[cache_key]
386
+ else:
387
+ user = await reddit_client.redditor(username)
388
+ serialized_data = []
389
+ async for submission in user.new(limit=10):
390
+ serialized_data.append(extract_serializable_sum(submission))
391
+ cache.set(cache_key, serialized_data, expire=300)
392
+ return jsonify(serialized_data)
393
+
394
+ @app.route('/reddit/subreddit/<subreddit>')
395
+ async def reddit_subreddit(subreddit):
396
+ cache_key = f"group_reddit_{subreddit}"
397
+
398
+ if cache_key in cache:
399
+ serialized_data = cache[cache_key]
400
+ else:
401
+ print(subreddit)
402
+ subreddit_d = await reddit_client.subreddit(subreddit)
403
+ serialized_data = []
404
+ async for submission in subreddit_d.new(limit=10):
405
+ serialized_data.append(extract_serializable_sum(submission))
406
+ cache.set(cache_key, serialized_data, expire=300)
407
+ return jsonify(serialized_data)
408
+
409
+
410
+ @app.route('/instagram/<username>')
411
+ async def instagram_profile(username):
412
+ cache_key = f"user_instagram_{username}"
413
+
414
+ if cache_key in cache:
415
+ serialized_data = cache[cache_key]
416
+ else:
417
+ print(username)
418
+ if username.isnumeric():
419
+ print("numeric")
420
+ user_id = username
421
+ else:
422
+ user_id = insta_client.user_info_by_username(username)
423
+ vserialized_data = []
424
+ # async for submission in subreddit_d.new(limit=10):
425
+ # serialized_data.append(extract_serializable_sum(submission))
426
+ for media_obj in insta_client.user_medias_paginated(user_id.pk):
427
+ vserialized_data.append(extract_serializable_sum(media_obj))
428
+ serialized_data = {"userinfo": extract_serializable_sum(user_id), "data": vserialized_data}
429
+ cache.set(cache_key, serialized_data, expire=300)
430
+ return jsonify(extract_serializable_sum(serialized_data))
431
+
432
+ @app.route('/kick/<username>')
433
+ async def kick_streaming(username):
434
+ cache_key = f"user_kick{username}"
435
+
436
+ if cache_key in cache:
437
+ serialized_data = cache[cache_key]
438
+ else:
439
+ serialized_data = send_to_node(node_proc, f"kick {username}")
440
+ if isinstance(serialized_data, str):
441
+ return jsonify({"error": True, "errorlog": serialized_data}), 500
442
+ if not serialized_data.get("error"):
443
+ cache.set(cache_key, serialized_data, expire=300) # Cache for 5 minutes
444
+ # cache.set(cache_key, serialized_data, expire=300)
445
+ return jsonify(extract_serializable_sum(serialized_data))
446
+
447
+ @app.route('/backinstagram/<username>')
448
+ async def backinstagram_profile(username):
449
+ cache_key = f"user_backinstagram_{username}"
450
+
451
+ if cache_key in cache:
452
+ serialized_data = cache[cache_key]
453
+ else:
454
+ headers = {
455
+ 'accept': '*/*',
456
+ 'accept-language': 'en-US,en;q=0.9',
457
+ 'cache-control': 'no-cache',
458
+ 'pragma': 'no-cache',
459
+ 'priority': 'u=1, i',
460
+ # 'referer': 'https://www.instagram.com/miawaug/feed/',
461
+ 'sec-ch-prefers-color-scheme': 'dark',
462
+ 'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Google Chrome";v="132"',
463
+ 'sec-ch-ua-full-version-list': '"Not A(Brand";v="8.0.0.0", "Chromium";v="132.0.6834.160", "Google Chrome";v="132.0.6834.160"',
464
+ 'sec-ch-ua-mobile': '?0',
465
+ 'sec-ch-ua-model': '""',
466
+ 'sec-ch-ua-platform': '"Windows"',
467
+ 'sec-ch-ua-platform-version': '"19.0.0"',
468
+ 'sec-fetch-dest': 'empty',
469
+ 'sec-fetch-mode': 'cors',
470
+ 'sec-fetch-site': 'same-origin',
471
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36',
472
+ 'x-asbd-id': '129477',
473
+ 'x-ig-app-id': '936619743392459',
474
+ 'x-ig-www-claim': '0',
475
+ 'x-requested-with': 'XMLHttpRequest',
476
+ }
477
+
478
+ params = {
479
+ 'username': username,
480
+ }
481
+
482
+ response = requests.get('https://www.instagram.com/api/v1/users/web_profile_info/', params=params, headers=headers)
483
+ serialized_data = response.json()
484
+ # cache.set(cache_key, serialized_data, expire=300)
485
+ return jsonify(serialized_data)
486
+
487
+
488
+ @app.route('/')
489
+ async def main_route_defaultpage():
490
+ message = "Hello, there isn't any docs, so if you see this, you shouldn't be here<br><br>"
491
+ routes = [f"{rule.methods} {rule}<br>" for rule in app.url_map.iter_rules()]
492
+ return message + "".join(routes) # Message first, then endpoints
493
+ @app.errorhandler(404)
494
+ async def handle_not_found(error):
495
+ return jsonify({"error": True, "errorlog": "Not found"}), 404
496
+
497
+ @app.errorhandler(Exception)
498
+ async def handle_error(error):
499
+ # Capture the full stack trace
500
+ stack_trace = traceback.format_exc()
501
+ print(error, stack_trace)
502
+ # Return the error message and stack trace in the JSON response
503
+ return jsonify({
504
+ "error": True, "errorlog": str(error),
505
+ "stack_trace": stack_trace
506
+ }), 500
507
+
508
+ if __name__ == '__main__':
509
+ app.run(port=7860)
510
+ # asyncio.run(trending_videos())
package-lock.json ADDED
@@ -0,0 +1,1095 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "auto_notif",
3
+ "version": "1.0.0",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "auto_notif",
9
+ "version": "1.0.0",
10
+ "license": "ISC",
11
+ "dependencies": {
12
+ "@tobyg74/tiktok-api-dl": "^1.2.2",
13
+ "@xct007/tiktok-scraper": "^1.0.2",
14
+ "tiktok-signature": "^1.9.2",
15
+ "ts-node": "^10.9.2"
16
+ },
17
+ "devDependencies": {
18
+ "@types/node": "^22.13.1"
19
+ }
20
+ },
21
+ "node_modules/@cspotcode/source-map-support": {
22
+ "version": "0.8.1",
23
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
24
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "@jridgewell/trace-mapping": "0.3.9"
28
+ },
29
+ "engines": {
30
+ "node": ">=12"
31
+ }
32
+ },
33
+ "node_modules/@jridgewell/resolve-uri": {
34
+ "version": "3.1.2",
35
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
36
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
37
+ "license": "MIT",
38
+ "engines": {
39
+ "node": ">=6.0.0"
40
+ }
41
+ },
42
+ "node_modules/@jridgewell/sourcemap-codec": {
43
+ "version": "1.5.0",
44
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
45
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
46
+ "license": "MIT"
47
+ },
48
+ "node_modules/@jridgewell/trace-mapping": {
49
+ "version": "0.3.9",
50
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
51
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
52
+ "license": "MIT",
53
+ "dependencies": {
54
+ "@jridgewell/resolve-uri": "^3.0.3",
55
+ "@jridgewell/sourcemap-codec": "^1.4.10"
56
+ }
57
+ },
58
+ "node_modules/@tobyg74/tiktok-api-dl": {
59
+ "version": "1.2.2",
60
+ "resolved": "https://registry.npmjs.org/@tobyg74/tiktok-api-dl/-/tiktok-api-dl-1.2.2.tgz",
61
+ "integrity": "sha512-kwBz6hXUMxCItBugYx3elSFGbbZdGFn0PEYgXcoooH30ws9y8FDdpKgbFq9qH6uywhIT6Jg0WYAR9Izj4fDh6A==",
62
+ "license": "ISC",
63
+ "dependencies": {
64
+ "async-retry": "^1.3.3",
65
+ "axios": "^1.3.4",
66
+ "cheerio": "^1.0.0-rc.12",
67
+ "crypto-js": "^4.2.0",
68
+ "https-proxy-agent": "^7.0.5",
69
+ "qs": "^6.12.0",
70
+ "socks-proxy-agent": "^8.0.4",
71
+ "uuid": "^10.0.0"
72
+ }
73
+ },
74
+ "node_modules/@tsconfig/node10": {
75
+ "version": "1.0.11",
76
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
77
+ "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
78
+ "license": "MIT"
79
+ },
80
+ "node_modules/@tsconfig/node12": {
81
+ "version": "1.0.11",
82
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
83
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
84
+ "license": "MIT"
85
+ },
86
+ "node_modules/@tsconfig/node14": {
87
+ "version": "1.0.3",
88
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
89
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
90
+ "license": "MIT"
91
+ },
92
+ "node_modules/@tsconfig/node16": {
93
+ "version": "1.0.4",
94
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
95
+ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
96
+ "license": "MIT"
97
+ },
98
+ "node_modules/@types/node": {
99
+ "version": "22.13.1",
100
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
101
+ "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
102
+ "license": "MIT",
103
+ "dependencies": {
104
+ "undici-types": "~6.20.0"
105
+ }
106
+ },
107
+ "node_modules/@xct007/tiktok-scraper": {
108
+ "version": "1.0.2",
109
+ "resolved": "https://registry.npmjs.org/@xct007/tiktok-scraper/-/tiktok-scraper-1.0.2.tgz",
110
+ "integrity": "sha512-44WXeoTJcwZ2cjsl+mv6D9S39bkwFc2/vbdsF5xTPxZkhW8ZNDggZuYRFJZIS8e/zkL5d9kLzfwPxIvgdjO9mQ==",
111
+ "license": "MIT",
112
+ "dependencies": {
113
+ "axios": "^1.2.1"
114
+ }
115
+ },
116
+ "node_modules/acorn": {
117
+ "version": "8.14.0",
118
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
119
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
120
+ "license": "MIT",
121
+ "bin": {
122
+ "acorn": "bin/acorn"
123
+ },
124
+ "engines": {
125
+ "node": ">=0.4.0"
126
+ }
127
+ },
128
+ "node_modules/acorn-walk": {
129
+ "version": "8.3.4",
130
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
131
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
132
+ "license": "MIT",
133
+ "dependencies": {
134
+ "acorn": "^8.11.0"
135
+ },
136
+ "engines": {
137
+ "node": ">=0.4.0"
138
+ }
139
+ },
140
+ "node_modules/agent-base": {
141
+ "version": "7.1.3",
142
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
143
+ "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
144
+ "license": "MIT",
145
+ "engines": {
146
+ "node": ">= 14"
147
+ }
148
+ },
149
+ "node_modules/arg": {
150
+ "version": "4.1.3",
151
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
152
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
153
+ "license": "MIT"
154
+ },
155
+ "node_modules/async-retry": {
156
+ "version": "1.3.3",
157
+ "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz",
158
+ "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==",
159
+ "license": "MIT",
160
+ "dependencies": {
161
+ "retry": "0.13.1"
162
+ }
163
+ },
164
+ "node_modules/asynckit": {
165
+ "version": "0.4.0",
166
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
167
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
168
+ "license": "MIT"
169
+ },
170
+ "node_modules/axios": {
171
+ "version": "1.7.9",
172
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
173
+ "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
174
+ "license": "MIT",
175
+ "dependencies": {
176
+ "follow-redirects": "^1.15.6",
177
+ "form-data": "^4.0.0",
178
+ "proxy-from-env": "^1.1.0"
179
+ }
180
+ },
181
+ "node_modules/boolbase": {
182
+ "version": "1.0.0",
183
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
184
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
185
+ "license": "ISC"
186
+ },
187
+ "node_modules/call-bind-apply-helpers": {
188
+ "version": "1.0.1",
189
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
190
+ "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
191
+ "license": "MIT",
192
+ "dependencies": {
193
+ "es-errors": "^1.3.0",
194
+ "function-bind": "^1.1.2"
195
+ },
196
+ "engines": {
197
+ "node": ">= 0.4"
198
+ }
199
+ },
200
+ "node_modules/call-bound": {
201
+ "version": "1.0.3",
202
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
203
+ "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
204
+ "license": "MIT",
205
+ "dependencies": {
206
+ "call-bind-apply-helpers": "^1.0.1",
207
+ "get-intrinsic": "^1.2.6"
208
+ },
209
+ "engines": {
210
+ "node": ">= 0.4"
211
+ },
212
+ "funding": {
213
+ "url": "https://github.com/sponsors/ljharb"
214
+ }
215
+ },
216
+ "node_modules/cheerio": {
217
+ "version": "1.0.0",
218
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
219
+ "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
220
+ "license": "MIT",
221
+ "dependencies": {
222
+ "cheerio-select": "^2.1.0",
223
+ "dom-serializer": "^2.0.0",
224
+ "domhandler": "^5.0.3",
225
+ "domutils": "^3.1.0",
226
+ "encoding-sniffer": "^0.2.0",
227
+ "htmlparser2": "^9.1.0",
228
+ "parse5": "^7.1.2",
229
+ "parse5-htmlparser2-tree-adapter": "^7.0.0",
230
+ "parse5-parser-stream": "^7.1.2",
231
+ "undici": "^6.19.5",
232
+ "whatwg-mimetype": "^4.0.0"
233
+ },
234
+ "engines": {
235
+ "node": ">=18.17"
236
+ },
237
+ "funding": {
238
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
239
+ }
240
+ },
241
+ "node_modules/cheerio-select": {
242
+ "version": "2.1.0",
243
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
244
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
245
+ "license": "BSD-2-Clause",
246
+ "dependencies": {
247
+ "boolbase": "^1.0.0",
248
+ "css-select": "^5.1.0",
249
+ "css-what": "^6.1.0",
250
+ "domelementtype": "^2.3.0",
251
+ "domhandler": "^5.0.3",
252
+ "domutils": "^3.0.1"
253
+ },
254
+ "funding": {
255
+ "url": "https://github.com/sponsors/fb55"
256
+ }
257
+ },
258
+ "node_modules/combined-stream": {
259
+ "version": "1.0.8",
260
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
261
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
262
+ "license": "MIT",
263
+ "dependencies": {
264
+ "delayed-stream": "~1.0.0"
265
+ },
266
+ "engines": {
267
+ "node": ">= 0.8"
268
+ }
269
+ },
270
+ "node_modules/create-require": {
271
+ "version": "1.1.1",
272
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
273
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
274
+ "license": "MIT"
275
+ },
276
+ "node_modules/crypto-js": {
277
+ "version": "4.2.0",
278
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
279
+ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
280
+ "license": "MIT"
281
+ },
282
+ "node_modules/css-select": {
283
+ "version": "5.1.0",
284
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
285
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
286
+ "license": "BSD-2-Clause",
287
+ "dependencies": {
288
+ "boolbase": "^1.0.0",
289
+ "css-what": "^6.1.0",
290
+ "domhandler": "^5.0.2",
291
+ "domutils": "^3.0.1",
292
+ "nth-check": "^2.0.1"
293
+ },
294
+ "funding": {
295
+ "url": "https://github.com/sponsors/fb55"
296
+ }
297
+ },
298
+ "node_modules/css-what": {
299
+ "version": "6.1.0",
300
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
301
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
302
+ "license": "BSD-2-Clause",
303
+ "engines": {
304
+ "node": ">= 6"
305
+ },
306
+ "funding": {
307
+ "url": "https://github.com/sponsors/fb55"
308
+ }
309
+ },
310
+ "node_modules/debug": {
311
+ "version": "4.4.0",
312
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
313
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
314
+ "license": "MIT",
315
+ "dependencies": {
316
+ "ms": "^2.1.3"
317
+ },
318
+ "engines": {
319
+ "node": ">=6.0"
320
+ },
321
+ "peerDependenciesMeta": {
322
+ "supports-color": {
323
+ "optional": true
324
+ }
325
+ }
326
+ },
327
+ "node_modules/delayed-stream": {
328
+ "version": "1.0.0",
329
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
330
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
331
+ "license": "MIT",
332
+ "engines": {
333
+ "node": ">=0.4.0"
334
+ }
335
+ },
336
+ "node_modules/diff": {
337
+ "version": "4.0.2",
338
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
339
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
340
+ "license": "BSD-3-Clause",
341
+ "engines": {
342
+ "node": ">=0.3.1"
343
+ }
344
+ },
345
+ "node_modules/dom-serializer": {
346
+ "version": "2.0.0",
347
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
348
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
349
+ "license": "MIT",
350
+ "dependencies": {
351
+ "domelementtype": "^2.3.0",
352
+ "domhandler": "^5.0.2",
353
+ "entities": "^4.2.0"
354
+ },
355
+ "funding": {
356
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
357
+ }
358
+ },
359
+ "node_modules/domelementtype": {
360
+ "version": "2.3.0",
361
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
362
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
363
+ "funding": [
364
+ {
365
+ "type": "github",
366
+ "url": "https://github.com/sponsors/fb55"
367
+ }
368
+ ],
369
+ "license": "BSD-2-Clause"
370
+ },
371
+ "node_modules/domhandler": {
372
+ "version": "5.0.3",
373
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
374
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
375
+ "license": "BSD-2-Clause",
376
+ "dependencies": {
377
+ "domelementtype": "^2.3.0"
378
+ },
379
+ "engines": {
380
+ "node": ">= 4"
381
+ },
382
+ "funding": {
383
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
384
+ }
385
+ },
386
+ "node_modules/domutils": {
387
+ "version": "3.2.2",
388
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
389
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
390
+ "license": "BSD-2-Clause",
391
+ "dependencies": {
392
+ "dom-serializer": "^2.0.0",
393
+ "domelementtype": "^2.3.0",
394
+ "domhandler": "^5.0.3"
395
+ },
396
+ "funding": {
397
+ "url": "https://github.com/fb55/domutils?sponsor=1"
398
+ }
399
+ },
400
+ "node_modules/dunder-proto": {
401
+ "version": "1.0.1",
402
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
403
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
404
+ "license": "MIT",
405
+ "dependencies": {
406
+ "call-bind-apply-helpers": "^1.0.1",
407
+ "es-errors": "^1.3.0",
408
+ "gopd": "^1.2.0"
409
+ },
410
+ "engines": {
411
+ "node": ">= 0.4"
412
+ }
413
+ },
414
+ "node_modules/encoding-sniffer": {
415
+ "version": "0.2.0",
416
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
417
+ "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
418
+ "license": "MIT",
419
+ "dependencies": {
420
+ "iconv-lite": "^0.6.3",
421
+ "whatwg-encoding": "^3.1.1"
422
+ },
423
+ "funding": {
424
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
425
+ }
426
+ },
427
+ "node_modules/entities": {
428
+ "version": "4.5.0",
429
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
430
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
431
+ "license": "BSD-2-Clause",
432
+ "engines": {
433
+ "node": ">=0.12"
434
+ },
435
+ "funding": {
436
+ "url": "https://github.com/fb55/entities?sponsor=1"
437
+ }
438
+ },
439
+ "node_modules/es-define-property": {
440
+ "version": "1.0.1",
441
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
442
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
443
+ "license": "MIT",
444
+ "engines": {
445
+ "node": ">= 0.4"
446
+ }
447
+ },
448
+ "node_modules/es-errors": {
449
+ "version": "1.3.0",
450
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
451
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
452
+ "license": "MIT",
453
+ "engines": {
454
+ "node": ">= 0.4"
455
+ }
456
+ },
457
+ "node_modules/es-object-atoms": {
458
+ "version": "1.1.1",
459
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
460
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
461
+ "license": "MIT",
462
+ "dependencies": {
463
+ "es-errors": "^1.3.0"
464
+ },
465
+ "engines": {
466
+ "node": ">= 0.4"
467
+ }
468
+ },
469
+ "node_modules/follow-redirects": {
470
+ "version": "1.15.9",
471
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
472
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
473
+ "funding": [
474
+ {
475
+ "type": "individual",
476
+ "url": "https://github.com/sponsors/RubenVerborgh"
477
+ }
478
+ ],
479
+ "license": "MIT",
480
+ "engines": {
481
+ "node": ">=4.0"
482
+ },
483
+ "peerDependenciesMeta": {
484
+ "debug": {
485
+ "optional": true
486
+ }
487
+ }
488
+ },
489
+ "node_modules/form-data": {
490
+ "version": "4.0.1",
491
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
492
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
493
+ "license": "MIT",
494
+ "dependencies": {
495
+ "asynckit": "^0.4.0",
496
+ "combined-stream": "^1.0.8",
497
+ "mime-types": "^2.1.12"
498
+ },
499
+ "engines": {
500
+ "node": ">= 6"
501
+ }
502
+ },
503
+ "node_modules/fsevents": {
504
+ "version": "2.3.2",
505
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
506
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
507
+ "hasInstallScript": true,
508
+ "license": "MIT",
509
+ "optional": true,
510
+ "os": [
511
+ "darwin"
512
+ ],
513
+ "engines": {
514
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
515
+ }
516
+ },
517
+ "node_modules/function-bind": {
518
+ "version": "1.1.2",
519
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
520
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
521
+ "license": "MIT",
522
+ "funding": {
523
+ "url": "https://github.com/sponsors/ljharb"
524
+ }
525
+ },
526
+ "node_modules/get-intrinsic": {
527
+ "version": "1.2.7",
528
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
529
+ "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
530
+ "license": "MIT",
531
+ "dependencies": {
532
+ "call-bind-apply-helpers": "^1.0.1",
533
+ "es-define-property": "^1.0.1",
534
+ "es-errors": "^1.3.0",
535
+ "es-object-atoms": "^1.0.0",
536
+ "function-bind": "^1.1.2",
537
+ "get-proto": "^1.0.0",
538
+ "gopd": "^1.2.0",
539
+ "has-symbols": "^1.1.0",
540
+ "hasown": "^2.0.2",
541
+ "math-intrinsics": "^1.1.0"
542
+ },
543
+ "engines": {
544
+ "node": ">= 0.4"
545
+ },
546
+ "funding": {
547
+ "url": "https://github.com/sponsors/ljharb"
548
+ }
549
+ },
550
+ "node_modules/get-proto": {
551
+ "version": "1.0.1",
552
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
553
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
554
+ "license": "MIT",
555
+ "dependencies": {
556
+ "dunder-proto": "^1.0.1",
557
+ "es-object-atoms": "^1.0.0"
558
+ },
559
+ "engines": {
560
+ "node": ">= 0.4"
561
+ }
562
+ },
563
+ "node_modules/gopd": {
564
+ "version": "1.2.0",
565
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
566
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
567
+ "license": "MIT",
568
+ "engines": {
569
+ "node": ">= 0.4"
570
+ },
571
+ "funding": {
572
+ "url": "https://github.com/sponsors/ljharb"
573
+ }
574
+ },
575
+ "node_modules/has-symbols": {
576
+ "version": "1.1.0",
577
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
578
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
579
+ "license": "MIT",
580
+ "engines": {
581
+ "node": ">= 0.4"
582
+ },
583
+ "funding": {
584
+ "url": "https://github.com/sponsors/ljharb"
585
+ }
586
+ },
587
+ "node_modules/hasown": {
588
+ "version": "2.0.2",
589
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
590
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
591
+ "license": "MIT",
592
+ "dependencies": {
593
+ "function-bind": "^1.1.2"
594
+ },
595
+ "engines": {
596
+ "node": ">= 0.4"
597
+ }
598
+ },
599
+ "node_modules/htmlparser2": {
600
+ "version": "9.1.0",
601
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
602
+ "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
603
+ "funding": [
604
+ "https://github.com/fb55/htmlparser2?sponsor=1",
605
+ {
606
+ "type": "github",
607
+ "url": "https://github.com/sponsors/fb55"
608
+ }
609
+ ],
610
+ "license": "MIT",
611
+ "dependencies": {
612
+ "domelementtype": "^2.3.0",
613
+ "domhandler": "^5.0.3",
614
+ "domutils": "^3.1.0",
615
+ "entities": "^4.5.0"
616
+ }
617
+ },
618
+ "node_modules/https-proxy-agent": {
619
+ "version": "7.0.6",
620
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
621
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
622
+ "license": "MIT",
623
+ "dependencies": {
624
+ "agent-base": "^7.1.2",
625
+ "debug": "4"
626
+ },
627
+ "engines": {
628
+ "node": ">= 14"
629
+ }
630
+ },
631
+ "node_modules/iconv-lite": {
632
+ "version": "0.6.3",
633
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
634
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
635
+ "license": "MIT",
636
+ "dependencies": {
637
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
638
+ },
639
+ "engines": {
640
+ "node": ">=0.10.0"
641
+ }
642
+ },
643
+ "node_modules/ip-address": {
644
+ "version": "9.0.5",
645
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
646
+ "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
647
+ "license": "MIT",
648
+ "dependencies": {
649
+ "jsbn": "1.1.0",
650
+ "sprintf-js": "^1.1.3"
651
+ },
652
+ "engines": {
653
+ "node": ">= 12"
654
+ }
655
+ },
656
+ "node_modules/jsbn": {
657
+ "version": "1.1.0",
658
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
659
+ "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
660
+ "license": "MIT"
661
+ },
662
+ "node_modules/make-error": {
663
+ "version": "1.3.6",
664
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
665
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
666
+ "license": "ISC"
667
+ },
668
+ "node_modules/math-intrinsics": {
669
+ "version": "1.1.0",
670
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
671
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
672
+ "license": "MIT",
673
+ "engines": {
674
+ "node": ">= 0.4"
675
+ }
676
+ },
677
+ "node_modules/mime-db": {
678
+ "version": "1.52.0",
679
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
680
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
681
+ "license": "MIT",
682
+ "engines": {
683
+ "node": ">= 0.6"
684
+ }
685
+ },
686
+ "node_modules/mime-types": {
687
+ "version": "2.1.35",
688
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
689
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
690
+ "license": "MIT",
691
+ "dependencies": {
692
+ "mime-db": "1.52.0"
693
+ },
694
+ "engines": {
695
+ "node": ">= 0.6"
696
+ }
697
+ },
698
+ "node_modules/ms": {
699
+ "version": "2.1.3",
700
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
701
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
702
+ "license": "MIT"
703
+ },
704
+ "node_modules/nth-check": {
705
+ "version": "2.1.1",
706
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
707
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
708
+ "license": "BSD-2-Clause",
709
+ "dependencies": {
710
+ "boolbase": "^1.0.0"
711
+ },
712
+ "funding": {
713
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
714
+ }
715
+ },
716
+ "node_modules/object-inspect": {
717
+ "version": "1.13.3",
718
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
719
+ "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
720
+ "license": "MIT",
721
+ "engines": {
722
+ "node": ">= 0.4"
723
+ },
724
+ "funding": {
725
+ "url": "https://github.com/sponsors/ljharb"
726
+ }
727
+ },
728
+ "node_modules/parse5": {
729
+ "version": "7.2.1",
730
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
731
+ "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
732
+ "license": "MIT",
733
+ "dependencies": {
734
+ "entities": "^4.5.0"
735
+ },
736
+ "funding": {
737
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
738
+ }
739
+ },
740
+ "node_modules/parse5-htmlparser2-tree-adapter": {
741
+ "version": "7.1.0",
742
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
743
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
744
+ "license": "MIT",
745
+ "dependencies": {
746
+ "domhandler": "^5.0.3",
747
+ "parse5": "^7.0.0"
748
+ },
749
+ "funding": {
750
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
751
+ }
752
+ },
753
+ "node_modules/parse5-parser-stream": {
754
+ "version": "7.1.2",
755
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
756
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
757
+ "license": "MIT",
758
+ "dependencies": {
759
+ "parse5": "^7.0.0"
760
+ },
761
+ "funding": {
762
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
763
+ }
764
+ },
765
+ "node_modules/playwright": {
766
+ "version": "1.50.1",
767
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz",
768
+ "integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==",
769
+ "license": "Apache-2.0",
770
+ "dependencies": {
771
+ "playwright-core": "1.50.1"
772
+ },
773
+ "bin": {
774
+ "playwright": "cli.js"
775
+ },
776
+ "engines": {
777
+ "node": ">=18"
778
+ },
779
+ "optionalDependencies": {
780
+ "fsevents": "2.3.2"
781
+ }
782
+ },
783
+ "node_modules/playwright-chromium": {
784
+ "version": "1.50.1",
785
+ "resolved": "https://registry.npmjs.org/playwright-chromium/-/playwright-chromium-1.50.1.tgz",
786
+ "integrity": "sha512-0IKyCdwS5dDoGE3EqqfYtX24qF6+ef1UI6OLn2VUi2aHOgsI/KnESRm6/Ws0W78SrwhLi6lLlAL6fQISoO1cfw==",
787
+ "hasInstallScript": true,
788
+ "license": "Apache-2.0",
789
+ "dependencies": {
790
+ "playwright-core": "1.50.1"
791
+ },
792
+ "bin": {
793
+ "playwright": "cli.js"
794
+ },
795
+ "engines": {
796
+ "node": ">=18"
797
+ }
798
+ },
799
+ "node_modules/playwright-core": {
800
+ "version": "1.50.1",
801
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz",
802
+ "integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==",
803
+ "license": "Apache-2.0",
804
+ "bin": {
805
+ "playwright-core": "cli.js"
806
+ },
807
+ "engines": {
808
+ "node": ">=18"
809
+ }
810
+ },
811
+ "node_modules/proxy-from-env": {
812
+ "version": "1.1.0",
813
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
814
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
815
+ "license": "MIT"
816
+ },
817
+ "node_modules/qs": {
818
+ "version": "6.14.0",
819
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
820
+ "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
821
+ "license": "BSD-3-Clause",
822
+ "dependencies": {
823
+ "side-channel": "^1.1.0"
824
+ },
825
+ "engines": {
826
+ "node": ">=0.6"
827
+ },
828
+ "funding": {
829
+ "url": "https://github.com/sponsors/ljharb"
830
+ }
831
+ },
832
+ "node_modules/retry": {
833
+ "version": "0.13.1",
834
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
835
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
836
+ "license": "MIT",
837
+ "engines": {
838
+ "node": ">= 4"
839
+ }
840
+ },
841
+ "node_modules/safer-buffer": {
842
+ "version": "2.1.2",
843
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
844
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
845
+ "license": "MIT"
846
+ },
847
+ "node_modules/side-channel": {
848
+ "version": "1.1.0",
849
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
850
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
851
+ "license": "MIT",
852
+ "dependencies": {
853
+ "es-errors": "^1.3.0",
854
+ "object-inspect": "^1.13.3",
855
+ "side-channel-list": "^1.0.0",
856
+ "side-channel-map": "^1.0.1",
857
+ "side-channel-weakmap": "^1.0.2"
858
+ },
859
+ "engines": {
860
+ "node": ">= 0.4"
861
+ },
862
+ "funding": {
863
+ "url": "https://github.com/sponsors/ljharb"
864
+ }
865
+ },
866
+ "node_modules/side-channel-list": {
867
+ "version": "1.0.0",
868
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
869
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
870
+ "license": "MIT",
871
+ "dependencies": {
872
+ "es-errors": "^1.3.0",
873
+ "object-inspect": "^1.13.3"
874
+ },
875
+ "engines": {
876
+ "node": ">= 0.4"
877
+ },
878
+ "funding": {
879
+ "url": "https://github.com/sponsors/ljharb"
880
+ }
881
+ },
882
+ "node_modules/side-channel-map": {
883
+ "version": "1.0.1",
884
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
885
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
886
+ "license": "MIT",
887
+ "dependencies": {
888
+ "call-bound": "^1.0.2",
889
+ "es-errors": "^1.3.0",
890
+ "get-intrinsic": "^1.2.5",
891
+ "object-inspect": "^1.13.3"
892
+ },
893
+ "engines": {
894
+ "node": ">= 0.4"
895
+ },
896
+ "funding": {
897
+ "url": "https://github.com/sponsors/ljharb"
898
+ }
899
+ },
900
+ "node_modules/side-channel-weakmap": {
901
+ "version": "1.0.2",
902
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
903
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
904
+ "license": "MIT",
905
+ "dependencies": {
906
+ "call-bound": "^1.0.2",
907
+ "es-errors": "^1.3.0",
908
+ "get-intrinsic": "^1.2.5",
909
+ "object-inspect": "^1.13.3",
910
+ "side-channel-map": "^1.0.1"
911
+ },
912
+ "engines": {
913
+ "node": ">= 0.4"
914
+ },
915
+ "funding": {
916
+ "url": "https://github.com/sponsors/ljharb"
917
+ }
918
+ },
919
+ "node_modules/smart-buffer": {
920
+ "version": "4.2.0",
921
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
922
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
923
+ "license": "MIT",
924
+ "engines": {
925
+ "node": ">= 6.0.0",
926
+ "npm": ">= 3.0.0"
927
+ }
928
+ },
929
+ "node_modules/socks": {
930
+ "version": "2.8.3",
931
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
932
+ "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
933
+ "license": "MIT",
934
+ "dependencies": {
935
+ "ip-address": "^9.0.5",
936
+ "smart-buffer": "^4.2.0"
937
+ },
938
+ "engines": {
939
+ "node": ">= 10.0.0",
940
+ "npm": ">= 3.0.0"
941
+ }
942
+ },
943
+ "node_modules/socks-proxy-agent": {
944
+ "version": "8.0.5",
945
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
946
+ "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
947
+ "license": "MIT",
948
+ "dependencies": {
949
+ "agent-base": "^7.1.2",
950
+ "debug": "^4.3.4",
951
+ "socks": "^2.8.3"
952
+ },
953
+ "engines": {
954
+ "node": ">= 14"
955
+ }
956
+ },
957
+ "node_modules/sprintf-js": {
958
+ "version": "1.1.3",
959
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
960
+ "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
961
+ "license": "BSD-3-Clause"
962
+ },
963
+ "node_modules/tiktok-signature": {
964
+ "version": "1.9.2",
965
+ "resolved": "https://registry.npmjs.org/tiktok-signature/-/tiktok-signature-1.9.2.tgz",
966
+ "integrity": "sha512-Q/uFiqptlyJ8kTA5J45hmOjEdVMHOC6UTAzgzWC3RY73WYW7lThZOIictS5iCmfIsOkOWRQ1g2XLkzWg4tAzGA==",
967
+ "license": "MIT",
968
+ "dependencies": {
969
+ "playwright": "^1.41.2",
970
+ "playwright-chromium": "^1.41.2"
971
+ }
972
+ },
973
+ "node_modules/ts-node": {
974
+ "version": "10.9.2",
975
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
976
+ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
977
+ "license": "MIT",
978
+ "dependencies": {
979
+ "@cspotcode/source-map-support": "^0.8.0",
980
+ "@tsconfig/node10": "^1.0.7",
981
+ "@tsconfig/node12": "^1.0.7",
982
+ "@tsconfig/node14": "^1.0.0",
983
+ "@tsconfig/node16": "^1.0.2",
984
+ "acorn": "^8.4.1",
985
+ "acorn-walk": "^8.1.1",
986
+ "arg": "^4.1.0",
987
+ "create-require": "^1.1.0",
988
+ "diff": "^4.0.1",
989
+ "make-error": "^1.1.1",
990
+ "v8-compile-cache-lib": "^3.0.1",
991
+ "yn": "3.1.1"
992
+ },
993
+ "bin": {
994
+ "ts-node": "dist/bin.js",
995
+ "ts-node-cwd": "dist/bin-cwd.js",
996
+ "ts-node-esm": "dist/bin-esm.js",
997
+ "ts-node-script": "dist/bin-script.js",
998
+ "ts-node-transpile-only": "dist/bin-transpile.js",
999
+ "ts-script": "dist/bin-script-deprecated.js"
1000
+ },
1001
+ "peerDependencies": {
1002
+ "@swc/core": ">=1.2.50",
1003
+ "@swc/wasm": ">=1.2.50",
1004
+ "@types/node": "*",
1005
+ "typescript": ">=2.7"
1006
+ },
1007
+ "peerDependenciesMeta": {
1008
+ "@swc/core": {
1009
+ "optional": true
1010
+ },
1011
+ "@swc/wasm": {
1012
+ "optional": true
1013
+ }
1014
+ }
1015
+ },
1016
+ "node_modules/typescript": {
1017
+ "version": "5.7.3",
1018
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
1019
+ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
1020
+ "license": "Apache-2.0",
1021
+ "peer": true,
1022
+ "bin": {
1023
+ "tsc": "bin/tsc",
1024
+ "tsserver": "bin/tsserver"
1025
+ },
1026
+ "engines": {
1027
+ "node": ">=14.17"
1028
+ }
1029
+ },
1030
+ "node_modules/undici": {
1031
+ "version": "6.21.1",
1032
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
1033
+ "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==",
1034
+ "license": "MIT",
1035
+ "engines": {
1036
+ "node": ">=18.17"
1037
+ }
1038
+ },
1039
+ "node_modules/undici-types": {
1040
+ "version": "6.20.0",
1041
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
1042
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
1043
+ "license": "MIT"
1044
+ },
1045
+ "node_modules/uuid": {
1046
+ "version": "10.0.0",
1047
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
1048
+ "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
1049
+ "funding": [
1050
+ "https://github.com/sponsors/broofa",
1051
+ "https://github.com/sponsors/ctavan"
1052
+ ],
1053
+ "license": "MIT",
1054
+ "bin": {
1055
+ "uuid": "dist/bin/uuid"
1056
+ }
1057
+ },
1058
+ "node_modules/v8-compile-cache-lib": {
1059
+ "version": "3.0.1",
1060
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
1061
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
1062
+ "license": "MIT"
1063
+ },
1064
+ "node_modules/whatwg-encoding": {
1065
+ "version": "3.1.1",
1066
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
1067
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
1068
+ "license": "MIT",
1069
+ "dependencies": {
1070
+ "iconv-lite": "0.6.3"
1071
+ },
1072
+ "engines": {
1073
+ "node": ">=18"
1074
+ }
1075
+ },
1076
+ "node_modules/whatwg-mimetype": {
1077
+ "version": "4.0.0",
1078
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
1079
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
1080
+ "license": "MIT",
1081
+ "engines": {
1082
+ "node": ">=18"
1083
+ }
1084
+ },
1085
+ "node_modules/yn": {
1086
+ "version": "3.1.1",
1087
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
1088
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
1089
+ "license": "MIT",
1090
+ "engines": {
1091
+ "node": ">=6"
1092
+ }
1093
+ }
1094
+ }
1095
+ }
package.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "auto_notif",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1"
7
+ },
8
+ "keywords": [],
9
+ "author": "",
10
+ "license": "ISC",
11
+ "description": "",
12
+ "dependencies": {
13
+ "@tobyg74/tiktok-api-dl": "^1.2.2",
14
+ "@xct007/tiktok-scraper": "^1.0.2",
15
+ "tiktok-signature": "^1.9.2",
16
+ "ts-node": "^10.9.2"
17
+ },
18
+ "devDependencies": {
19
+ "@types/node": "^22.13.1"
20
+ }
21
+ }
requirements.txt ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ aiofiles==24.1.0
2
+ aiohappyeyeballs==2.4.6
3
+ aiohttp==3.11.12
4
+ aiosignal==1.3.2
5
+ aiosqlite==0.17.0
6
+ annotated-types==0.7.0
7
+ anyio==4.7.0
8
+ argon2-cffi==23.1.0
9
+ argon2-cffi-bindings==21.2.0
10
+ arrow==1.3.0
11
+ asttokens==3.0.0
12
+ async-lru==2.0.4
13
+ asyncpraw==7.8.1
14
+ asyncprawcore==2.4.0
15
+ attrs==24.2.0
16
+ babel==2.16.0
17
+ beautifulsoup4==4.12.3
18
+ bleach==6.2.0
19
+ blinker==1.9.0
20
+ certifi==2024.8.30
21
+ cffi==1.17.1
22
+ charset-normalizer==3.4.0
23
+ click==8.1.8
24
+ colorama==0.4.6
25
+ comm==0.2.2
26
+ contourpy==1.3.1
27
+ cycler==0.12.1
28
+ debugpy==1.8.9
29
+ decorator==5.1.1
30
+ defusedxml==0.7.1
31
+ diskcache==5.6.3
32
+ executing==2.1.0
33
+ fastjsonschema==2.21.1
34
+ filelock==3.13.1
35
+ filetype==1.2.0
36
+ Flask==3.1.0
37
+ fonttools==4.55.3
38
+ fqdn==1.5.1
39
+ frozenlist==1.5.0
40
+ fsspec==2024.2.0
41
+ gitdb==4.0.11
42
+ GitPython==3.1.43
43
+ h11==0.14.0
44
+ h2==4.2.0
45
+ hpack==4.1.0
46
+ httpcore==1.0.7
47
+ httpx==0.28.1
48
+ Hypercorn==0.17.3
49
+ hyperframe==6.1.0
50
+ idna==3.10
51
+ instagrapi==2.1.3
52
+ ipykernel==6.29.5
53
+ ipython==8.30.0
54
+ isoduration==20.11.0
55
+ itsdangerous==2.2.0
56
+ jedi==0.19.2
57
+ Jinja2==3.1.4
58
+ joblib==1.4.2
59
+ Js2Py_3.13==0.74.1
60
+ json5==0.10.0
61
+ jsonpointer==3.0.0
62
+ jsonschema==4.23.0
63
+ jsonschema-specifications==2024.10.1
64
+ jupyter-events==0.10.0
65
+ jupyter-lsp==2.2.5
66
+ jupyter-server-mathjax==0.2.6
67
+ jupyter_client==8.6.3
68
+ jupyter_core==5.7.2
69
+ jupyter_server==2.14.2
70
+ jupyter_server_terminals==0.5.3
71
+ jupyterlab==4.3.3
72
+ jupyterlab_git==0.50.2
73
+ jupyterlab_pygments==0.3.0
74
+ jupyterlab_server==2.27.3
75
+ kiwisolver==1.4.7
76
+ lxml==5.3.1
77
+ m3u8==6.0.0
78
+ MarkupSafe==3.0.2
79
+ matplotlib==3.9.3
80
+ matplotlib-inline==0.1.7
81
+ mistune==3.0.2
82
+ mpmath==1.3.0
83
+ multidict==6.1.0
84
+ nbclient==0.10.1
85
+ nbconvert==7.16.4
86
+ nbdime==4.0.2
87
+ nbformat==5.10.4
88
+ nest-asyncio==1.6.0
89
+ networkx==3.2.1
90
+ notebook_shim==0.2.4
91
+ numpy==2.2.0
92
+ overrides==7.7.0
93
+ packaging==24.2
94
+ pandas==2.2.3
95
+ pandocfilters==1.5.1
96
+ parso==0.8.4
97
+ pexpect==4.9.0
98
+ pillow==11.0.0
99
+ platformdirs==4.3.6
100
+ plotly==5.24.1
101
+ priority==2.0.0
102
+ prometheus_client==0.21.1
103
+ prompt_toolkit==3.0.48
104
+ propcache==0.2.1
105
+ psutil==6.1.0
106
+ ptyprocess==0.7.0
107
+ pure_eval==0.2.3
108
+ pycparser==2.22
109
+ pycryptodomex==3.21.0
110
+ pydantic==2.10.1
111
+ pydantic_core==2.27.1
112
+ Pygments==2.18.0
113
+ pyjsparser==2.7.1
114
+ pyotp==2.9.0
115
+ pyparsing==3.2.0
116
+ PySocks==1.7.1
117
+ python-dateutil==2.9.0.post0
118
+ python-dotenv==1.0.1
119
+ python-json-logger==3.2.0
120
+ pytz==2024.2
121
+ PyYAML==6.0.2
122
+ pyzmq==26.2.0
123
+ Quart==0.20.0
124
+ referencing==0.35.1
125
+ requests==2.32.3
126
+ rfc3339-validator==0.1.4
127
+ rfc3986-validator==0.1.1
128
+ rpds-py==0.22.3
129
+ scikit-learn==1.6.0
130
+ scipy==1.14.1
131
+ seaborn==0.13.2
132
+ Send2Trash==1.8.3
133
+ setuptools==75.6.0
134
+ six==1.17.0
135
+ smmap==5.0.1
136
+ sniffio==1.3.1
137
+ socksio==1.0.0
138
+ soupsieve==2.6
139
+ stack-data==0.6.3
140
+ sympy==1.13.1
141
+ tenacity==9.0.0
142
+ terminado==0.18.1
143
+ threadpoolctl==3.5.0
144
+ tinycss2==1.4.0
145
+ tornado==6.4.2
146
+ traitlets==5.14.3
147
+ twikit==2.3.3
148
+ types-python-dateutil==2.9.0.20241206
149
+ typing_extensions==4.12.2
150
+ tzdata==2024.2
151
+ tzlocal==5.2
152
+ update-checker==0.18.0
153
+ uri-template==1.3.0
154
+ urllib3==2.2.3
155
+ wcwidth==0.2.13
156
+ webcolors==24.11.1
157
+ webencodings==0.5.1
158
+ websocket-client==1.8.0
159
+ webvtt-py==0.5.1
160
+ Werkzeug==3.1.3
161
+ wsproto==1.2.0
162
+ xmltodict==0.14.2
163
+ yarl==1.18.3
scraper.ts ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // index.ts
2
+
3
+ import Signer from "tiktok-signature";
4
+ import axios, { AxiosResponse } from "axios";
5
+ import querystring from "querystring";
6
+ import { Browser, Page, BrowserContext } from "playwright";
7
+ import { exec } from 'child_process';
8
+ import { promisify } from 'util';
9
+ // import {DateTime} from 'luxon';
10
+ // Promisify exec for easier async/await usage
11
+ const execPromise = promisify(exec);
12
+
13
+ const TT_REQ_USER_AGENT =
14
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.56";
15
+
16
+ const queryParams = {
17
+ WebIdLastTime: "1739192062",
18
+ aid: "1988",
19
+ app_language: "en",
20
+ app_name: "tiktok_web",
21
+ browser_language: "en-US",
22
+ browser_name: "Mozilla",
23
+ browser_online: "true",
24
+ browser_platform: "Win32",
25
+ // Notice we use the decoded version for readability.
26
+ browser_version:
27
+ "5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0",
28
+ channel: "tiktok_web",
29
+ cookie_enabled: "true",
30
+ count: "35",
31
+ coverFormat: "2",
32
+ cursor: "0",
33
+ device_id: "7469772981536687624",
34
+ device_platform: "web_pc",
35
+ focus_state: "true",
36
+ from_page: "user",
37
+ history_len: "8",
38
+ is_fullscreen: "false",
39
+ is_page_visible: "true",
40
+ language: "en",
41
+ os: "windows",
42
+ priority_region: "RO",
43
+ referer: "https://www.tiktok.com/business-suite/messages?from=homepage&lang=en",
44
+ region: "RO",
45
+ root_referer: "https://www.tiktok.com/business-suite/messages?from=homepage&lang=en",
46
+ screen_height: "1080",
47
+ screen_width: "1920",
48
+ secUid:
49
+ "MS4wLjABAAAAAbt3ELTXRAMA0RVzgFjvOPEhWIKyDmY9pxPKUj5nJGIatb9xH7lTeIsU_322Sc0p",
50
+ tz_name: "Europe/Bucharest",
51
+ verifyFp: "verify_m6z21ydc_1d2kIOvr_Re3f_4Fit_AmQz_HL2g9Rui8xZp",
52
+ webcast_language: "en",
53
+ msToken:
54
+ "Gv-tA8UBoR9MrpShqSMLW5jqxKbjgqn1NJx3h2AWw3AYNZl3eKUG3855040l0RcW0Ap6uoknQRj5Iq7YuaSFeDqwAh0dubDNHQSaoYgziHNyXVdnDqIAz1WdoQx_mXEM860DcE64CXvr9nzcrBaiimxfwA==",
55
+ "X-Bogus": "DFSzswVuXEvANePAtkyrUO0EsCa-",
56
+ _signature: "_02B4Z6wo000019pWL7AAAIDCIaUS-UMYoj.aVisAAJFF2a"
57
+ };
58
+ const TT_REQ_PERM_URL =
59
+ `https://www.tiktok.com/api/post/item_list/?${new URLSearchParams(queryParams).toString()}`;
60
+
61
+ const parsedUrl = new URL(TT_REQ_PERM_URL);
62
+ const parsedQuery = querystring.parse(parsedUrl.search.slice(1));
63
+
64
+ interface SignerInterface {
65
+ init(): Promise<void>;
66
+ sign(url: string): Promise<{ "x-tt-params": string; signed_url: string }>;
67
+ navigator(): Promise<{ user_agent: string }>;
68
+ browser: Browser;
69
+ context: BrowserContext;
70
+ }
71
+
72
+ // Create a signer instance.
73
+ const signer: SignerInterface = new Signer(null, TT_REQ_USER_AGENT);
74
+
75
+ // Initialize the signer.
76
+ (async function () {
77
+ await signer.init();
78
+ })();
79
+
80
+ async function main(username: string): Promise<void> {
81
+ try {
82
+ const options = {
83
+ method: "GET",
84
+ url: "https://www.tiktok.com/@" + username,
85
+ };
86
+
87
+ const response = await axios(options);
88
+ const data: string = response.data;
89
+ const secUidMatch = data.match(/"secUid":"(.*?)"/);
90
+ const SEC_UID = secUidMatch ? secUidMatch[1] : "No secUid found";
91
+ console.log(SEC_UID)
92
+ const PARAMS = {
93
+ count: 30,
94
+ device_id: "7165118680723998211",
95
+ secUid: SEC_UID,
96
+ cursor: 0,
97
+ };
98
+
99
+ // Merge parsedQuery with PARAMS.
100
+ const mergedParams = { ...parsedQuery, ...PARAMS };
101
+
102
+ const qsObject = new URLSearchParams(mergedParams as any);
103
+ const qs = qsObject.toString();
104
+
105
+ const unsignedUrl = `https://www.tiktok.com/api/post/item_list/?${qs}`;
106
+ const signature = await signer.sign(unsignedUrl);
107
+ const navigatorData = await signer.navigator();
108
+ const { "x-tt-params": xTtParams, signed_url } = signature;
109
+ const { user_agent: userAgent } = navigatorData;
110
+
111
+ const res = await testApiReq({ userAgent, xTtParams, signed_url });
112
+ if(res.data.length == 0) {
113
+ throw new Error("No data")
114
+ }
115
+ console.log(JSON.stringify({...res.data, error: false}));
116
+ } catch (e) {
117
+ console.log(
118
+ JSON.stringify({ error: true, errorlog: String(e).trim() })
119
+ // return
120
+ );
121
+ }
122
+ }
123
+
124
+ async function twitch(fun: string): Promise<void> {
125
+ try {
126
+ if (!signer.context) {
127
+ console.log(
128
+ JSON.stringify({
129
+ error: true,
130
+ online: false,
131
+ errorlog: "Browser not initialized, please wait a moment",
132
+ })
133
+ );
134
+ return;
135
+ }
136
+ const p: Page = await signer.context.newPage();
137
+ await p.goto("https://www.twitch.tv/" + fun);
138
+ await p.waitForLoadState('networkidle')
139
+ const CheckUserStatus = await p.evaluate(() => {
140
+ try {
141
+ document.getElementsByClassName("home__lower-content")[0].remove()
142
+ const OfflineCheck = document.getElementsByClassName(
143
+ "channel-status-info channel-status-info--offline"
144
+ )[0]?.getElementsByTagName("p")[0].textContent;
145
+
146
+ const OnlineCheck = document.getElementsByClassName(
147
+ "tw-channel-status-text-indicator"
148
+ )[0];
149
+
150
+ console.log(OnlineCheck, OfflineCheck);
151
+
152
+ if (!OfflineCheck && !OnlineCheck) {
153
+ return { online: false, error: true, errorlog: "User not Found" };
154
+ } else if (OfflineCheck) {
155
+ return { online: false, error: false };
156
+ } else if (OnlineCheck) {
157
+ const getText = (selector: string): string => {
158
+ const element = document.querySelector(selector);
159
+ return element instanceof HTMLElement ? element.innerText : "";
160
+ };
161
+
162
+ const viewers = getText(
163
+ "p[data-a-target='animated-channel-viewers-count']"
164
+ );
165
+ const streamTime = getText(".live-time").split("\n")[0];
166
+ const title = getText('[data-a-target="stream-title"]');
167
+ const game = getText("a[data-a-target=stream-game-link] span");
168
+
169
+ if (!viewers && !streamTime && !title && !game) {
170
+ return { online: false, error: true };
171
+ }
172
+ return {
173
+ online: true,
174
+ viewers,
175
+ streamTime,
176
+ title,
177
+ game,
178
+ error: false,
179
+ };
180
+ }
181
+ } catch (e) {
182
+ return { online: false, error: true, errorlog: String(e) };
183
+ }
184
+ });
185
+
186
+ await p.close();
187
+ console.log(JSON.stringify(CheckUserStatus));
188
+ } catch (e) {
189
+ console.log(
190
+ JSON.stringify({ error: true, online: false, errorlog: String(e).trim() })
191
+ );
192
+ }
193
+ }
194
+
195
+
196
+ async function kick(fun: string): Promise<void> {
197
+ try {
198
+ const curlCommand = `curl_chrome116 'https://kick.com/api/v1/channels/${encodeURIComponent(fun)}'`;
199
+ const v = await execPromise(curlCommand.trim());
200
+ let k = (JSON.parse(v.stdout));
201
+ let u = k.livestream
202
+ if(!u) {
203
+ console.log(JSON.stringify({error: false, online: false}))
204
+ return
205
+ }
206
+ console.log(JSON.stringify({error: false, online: true, ...u}))
207
+ return;
208
+ } catch (e) {
209
+ console.log(
210
+ JSON.stringify({ error: true, online: false, errorlog: String(e).trim() })
211
+ );
212
+ }
213
+ }
214
+
215
+ interface TestApiReqParams {
216
+ userAgent: string;
217
+ xTtParams: string;
218
+ signed_url: string;
219
+ }
220
+
221
+ /**
222
+ * Makes an API request using axios.
223
+ */
224
+ async function testApiReq({
225
+ userAgent,
226
+ xTtParams,
227
+ signed_url,
228
+ }: TestApiReqParams): Promise<AxiosResponse<any>> {
229
+ const options = {
230
+ method: "GET",
231
+ headers: {
232
+ "user-agent": userAgent,
233
+ "x-tt-params": xTtParams,
234
+ },
235
+ url: signed_url,
236
+ };
237
+ return axios(options);
238
+ }
239
+
240
+ // if(true) {
241
+ // kick("akibell")
242
+ // // process.exit(0)
243
+ // }
244
+ process.stdin.on("data", (data: Buffer) => {
245
+ // return;
246
+ try {
247
+ const fun = data.toString().trim().split(" ");
248
+ switch (fun[0]) {
249
+ case "twitch":
250
+ twitch(fun.slice(1).join(" "));
251
+ break;
252
+ case "kick":
253
+ kick(fun.slice(1).join(" "));
254
+ break;
255
+ default:
256
+ // if (fun.length > 1) {
257
+ main(fun.join(" "));
258
+ // }
259
+ }
260
+ } catch (e) {
261
+ console.log(JSON.stringify({ error: true, errorlog: String(e) }));
262
+ }
263
+ });
threads_util/__pycache__/main.cpython-312.pyc ADDED
Binary file (5.48 kB). View file
 
threads_util/main.py ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+ import re
4
+ from urllib.parse import urlencode
5
+
6
+ class Threads:
7
+ API_URL = "https://www.threads.net/api/graphql"
8
+ TOKEN_URL = "https://www.threads.net/@instagram"
9
+ MAX_REDIRECTS = 20
10
+
11
+ DOC_IDS = {
12
+ "getUser": "23996318473300828",
13
+ "getUserThreads": "6232751443445612",
14
+ "getUserReplies": "6307072669391286",
15
+ "getPost": "5587632691339264",
16
+ "getPostLikers": "9360915773983802"
17
+ }
18
+
19
+ def __init__(self):
20
+ self.token = self.get_token()
21
+ self.default_headers = {
22
+ "Authority": "www.threads.net",
23
+ "Accept": "*/*",
24
+ "Accept-Language": "en-US,en;q=0.9",
25
+ "Cache-Control": "no-cache",
26
+ "Content-Type": "application/x-www-form-urlencoded",
27
+ "Connection": "keep-alive",
28
+ "Origin": "https://www.threads.net",
29
+ "Pragma": "no-cache",
30
+ "Sec-Fetch-Site": "same-origin",
31
+ "User-Agent": "python-requests",
32
+ "X-ASBD-ID": "129477",
33
+ "X-IG-App-ID": "238260118697367",
34
+ "X-FB-LSD": self.token
35
+ }
36
+
37
+ def get_token(self):
38
+ session = requests.Session()
39
+ session.max_redirects = self.MAX_REDIRECTS
40
+
41
+ response = session.get(self.TOKEN_URL, headers={"User-Agent": "python-requests"})
42
+ response.raise_for_status()
43
+
44
+ match = re.search(r'"token":"(\w+?)"', response.text)
45
+ if not match:
46
+ raise ValueError("Token not found in response")
47
+
48
+ return match.group(1)
49
+
50
+ def post_request(self, variables, doc_id, extra_headers=None):
51
+ headers = self.default_headers.copy()
52
+ if extra_headers:
53
+ headers.update(extra_headers)
54
+
55
+ data = {
56
+ "lsd": self.token,
57
+ "variables": json.dumps(variables),
58
+ "doc_id": doc_id
59
+ }
60
+
61
+ response = requests.post(self.API_URL, headers=headers, data=urlencode(data))
62
+ response.raise_for_status()
63
+ return response.json()
64
+
65
+ def get_post(self, post_id):
66
+ return self.post_request({"postID": post_id}, self.DOC_IDS["getPost"], {"X-FB-Friendly-Name": "BarcelonaPostPageQuery"})
67
+
68
+ def get_post_likers(self, media_id):
69
+ return self.post_request({"mediaID": media_id}, self.DOC_IDS["getPostLikers"])
70
+
71
+ def get_user(self, user_id):
72
+ return self.post_request({"userID": user_id}, self.DOC_IDS["getUser"], {"X-FB-Friendly-Name": "BarcelonaProfileRootQuery"})
73
+
74
+ def get_user_threads(self, user_id):
75
+ return self.post_request({"userID": user_id}, self.DOC_IDS["getUserThreads"], {"X-FB-Friendly-Name": "BarcelonaProfileThreadsTabQuery"})
76
+
77
+ def get_user_replies(self, user_id):
78
+ return self.post_request({"userID": user_id}, self.DOC_IDS["getUserReplies"], {"X-FB-Friendly-Name": "BarcelonaProfileRepliesTabQuery"})
79
+
80
+ def get_user_id(self, username):
81
+ url = f"https://www.threads.net/@{username}"
82
+ headers = self.default_headers.copy()
83
+ headers.update({
84
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
85
+ "Referer": url,
86
+ "Sec-Fetch-Dest": "document",
87
+ "Sec-Fetch-Mode": "navigate",
88
+ "Sec-Fetch-Site": "cross-site",
89
+ "Sec-Fetch-User": "?1",
90
+ "Upgrade-Insecure-Requests": "1"
91
+ })
92
+ headers.pop("X-ASBD-ID", None)
93
+ headers.pop("X-FB-LSD", None)
94
+ headers.pop("X-IG-App-ID", None)
95
+
96
+ response = requests.get(url, headers=headers)
97
+ response.raise_for_status()
98
+
99
+ match = re.search(r'"user_id":"(\d+)"', response.text)
100
+ if not match:
101
+ raise ValueError("User ID not found in response")
102
+
103
+ return int(match.group(1))
tsconfig.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "moduleResolution": "nodenext",
4
+ "esModuleInterop": true,
5
+ "module": "NodeNext",
6
+ "allowSyntheticDefaultImports": true,
7
+ // "typeRoots": ["./types"]
8
+ },
9
+ "include": [
10
+ "src/**/*",
11
+ "types/**/*"
12
+ ],
13
+
14
+ }
15
+
types/tiktok-signature.d.ts ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // types/tiktok-signature.d.ts
2
+
3
+
4
+ declare module "tiktok-signature" {
5
+ import { Browser } from "playwright";
6
+ interface SignerInterface {
7
+ init(): Promise<void>;
8
+ sign(url: string): Promise<{ "x-tt-params": string; signed_url: string }>;
9
+ navigator(): Promise<{ user_agent: string }>;
10
+ browser: Browser;
11
+ }
12
+
13
+ class Signer implements SignerInterface {
14
+ constructor(arg: any, userAgent: string);
15
+ init(): Promise<void>;
16
+ sign(url: string): Promise<{ "x-tt-params": string; signed_url: string }>;
17
+ navigator(): Promise<{ user_agent: string }>;
18
+ browser: Browser;
19
+ }
20
+
21
+ export = Signer;
22
+ }
23
+