Files
OSINT-Cheat-sheet/Script/SOCMINT-Twitter/app.py
T

95 lines
3.3 KiB
Python

import threading
from flask import Flask, jsonify, render_template, request
from xquik_client import XquikClient, XquikError, load_config
from cookie_client import (
cookie_tweet_search,
cookie_follower_explorer,
cookie_post_extractor,
cookie_article_extractor,
cookie_community_post_extractor,
CookieClientError,
)
app = Flask(__name__)
config = load_config()
MAX_CONCURRENT_REQUESTS = 3 # parallel execution slots
ACQUIRE_TIMEOUT = 15 # seconds to wait before returning 429
_sem = threading.Semaphore(MAX_CONCURRENT_REQUESTS)
@app.route("/")
def index():
return render_template("index.html")
@app.route("/api/run", methods=["POST"])
def run_tool():
body = request.get_json(silent=True) or {}
tool_type = body.get("toolType")
mode = body.get("mode", "api") # "api" | "cookie"
count = max(1, min(int(body.get("count", 20)), 200))
if not _sem.acquire(blocking=True, timeout=ACQUIRE_TIMEOUT):
return jsonify({
"ok": False,
"error": "Server is busy — max concurrent requests reached. Please try again shortly.",
}), 429
try:
if tool_type == "tweet_search_extractor":
query = body.get("searchQuery", "")
if mode == "cookie":
data = cookie_tweet_search(query, count=count, config=config)
else:
data = XquikClient(config).tweet_search(query)
elif tool_type == "follower_explorer":
username = body.get("targetUsername", "")
if mode == "cookie":
data = cookie_follower_explorer(username, count=count, config=config)
else:
data = XquikClient(config).follower_explorer(username)
elif tool_type == "article_extractor":
tweet_id = body.get("targetTweetId", "")
if mode == "cookie":
data = cookie_article_extractor(tweet_id, config=config)
else:
data = XquikClient(config).article_extractor(tweet_id)
elif tool_type == "community_post_extractor":
community_id = body.get("targetCommunityId", "")
if mode == "cookie":
data = cookie_community_post_extractor(community_id, count=count, config=config)
else:
data = XquikClient(config).community_post_extractor(community_id)
elif tool_type == "post_extractor":
username = body.get("targetUsername", "")
if mode == "cookie":
data = cookie_post_extractor(username, count=count, config=config)
else:
data = XquikClient(config).post_extractor(username)
else:
return jsonify({"ok": False, "error": f"Unknown toolType: {tool_type}"}), 400
return jsonify({"ok": True, "data": data})
except (XquikError, CookieClientError) as e:
return jsonify({"ok": False, "error": str(e)}), 400
except Exception as e: # noqa: BLE001
return jsonify({"ok": False, "error": f"Unexpected error: {e}"}), 500
finally:
_sem.release()
if __name__ == "__main__":
host = config.get("server", "host", fallback="127.0.0.1")
port = config.getint("server", "port", fallback=5000)
debug = config.getboolean("server", "debug", fallback=True)
app.run(host=host, port=port, debug=debug, threaded=True)