|
|
from flask import Flask, render_template, request, jsonify |
|
|
from flask_socketio import SocketIO, emit |
|
|
import threading |
|
|
import time |
|
|
import os |
|
|
import sys |
|
|
from selenium import webdriver |
|
|
from selenium.webdriver.chrome.options import Options |
|
|
import logging |
|
|
|
|
|
|
|
|
from tiktok import TikTokBot |
|
|
|
|
|
app = Flask(__name__) |
|
|
app.config['SECRET_KEY'] = 'your-secret-key-here' |
|
|
socketio = SocketIO(app, cors_allowed_origins="*") |
|
|
|
|
|
|
|
|
bot_status = { |
|
|
'is_running': False, |
|
|
'current_progress': 0, |
|
|
'total_comments': 0, |
|
|
'success_count': 0, |
|
|
'failed_count': 0, |
|
|
'current_comment': '', |
|
|
'status_message': 'Ready to start' |
|
|
} |
|
|
|
|
|
class ProgressCallback: |
|
|
def __init__(self, socketio): |
|
|
self.socketio = socketio |
|
|
self.current_progress = 0 |
|
|
self.total_comments = 0 |
|
|
self.success_count = 0 |
|
|
self.failed_count = 0 |
|
|
|
|
|
def update_progress(self, current, total, success, failed, comment_text=""): |
|
|
global bot_status |
|
|
|
|
|
self.current_progress = current |
|
|
self.total_comments = total |
|
|
self.success_count = success |
|
|
self.failed_count = failed |
|
|
|
|
|
|
|
|
bot_status['current_progress'] = current |
|
|
bot_status['total_comments'] = total |
|
|
bot_status['success_count'] = success |
|
|
bot_status['failed_count'] = failed |
|
|
bot_status['current_comment'] = comment_text |
|
|
|
|
|
|
|
|
self.socketio.emit('progress_update', { |
|
|
'current': current, |
|
|
'total': total, |
|
|
'success': success, |
|
|
'failed': failed, |
|
|
'comment_text': comment_text, |
|
|
'percentage': int((current / total) * 100) if total > 0 else 0 |
|
|
}) |
|
|
|
|
|
@app.route('/') |
|
|
def index(): |
|
|
return render_template('index.html') |
|
|
|
|
|
@app.route('/start_bot', methods=['POST']) |
|
|
def start_bot(): |
|
|
global bot_status |
|
|
|
|
|
if bot_status['is_running']: |
|
|
return jsonify({'error': 'Bot is already running'}), 400 |
|
|
|
|
|
data = request.get_json() |
|
|
video_url = data.get('video_url', '') |
|
|
comment_text = data.get('comment_text', '') |
|
|
num_comments = int(data.get('num_comments', 500)) |
|
|
|
|
|
if not video_url or not comment_text: |
|
|
return jsonify({'error': 'Video URL and comment text are required'}), 400 |
|
|
|
|
|
|
|
|
bot_thread = threading.Thread( |
|
|
target=run_tiktok_bot, |
|
|
args=(video_url, comment_text, num_comments) |
|
|
) |
|
|
bot_thread.daemon = True |
|
|
bot_thread.start() |
|
|
|
|
|
return jsonify({'message': 'Bot started successfully'}) |
|
|
|
|
|
@app.route('/stop_bot', methods=['POST']) |
|
|
def stop_bot(): |
|
|
global bot_status |
|
|
bot_status['is_running'] = False |
|
|
bot_status['status_message'] = 'Bot stopped by user' |
|
|
socketio.emit('bot_stopped', {'message': 'Bot stopped by user'}) |
|
|
return jsonify({'message': 'Bot stopped'}) |
|
|
|
|
|
@app.route('/status') |
|
|
def get_status(): |
|
|
return jsonify(bot_status) |
|
|
|
|
|
def run_tiktok_bot(video_url, comment_text, num_comments): |
|
|
global bot_status |
|
|
|
|
|
bot_status['is_running'] = True |
|
|
bot_status['current_progress'] = 0 |
|
|
bot_status['total_comments'] = num_comments |
|
|
bot_status['success_count'] = 0 |
|
|
bot_status['failed_count'] = 0 |
|
|
bot_status['status_message'] = 'Initializing bot...' |
|
|
|
|
|
socketio.emit('bot_started', { |
|
|
'message': 'Bot started', |
|
|
'total_comments': num_comments |
|
|
}) |
|
|
|
|
|
|
|
|
progress_callback = ProgressCallback(socketio) |
|
|
|
|
|
try: |
|
|
|
|
|
bot_status['status_message'] = 'Setting up browser...' |
|
|
socketio.emit('status_update', {'message': 'Setting up browser...'}) |
|
|
|
|
|
project_dir = os.path.dirname(os.path.abspath(__file__)) |
|
|
cache_dir = os.path.join(project_dir, "selenium_cache") |
|
|
|
|
|
if not os.path.exists(cache_dir): |
|
|
os.makedirs(cache_dir) |
|
|
|
|
|
chrome_options = Options() |
|
|
chrome_options.add_argument("--start-maximized") |
|
|
chrome_options.add_argument("--headless") |
|
|
chrome_options.add_argument("--disable-blink-features=AutomationControlled") |
|
|
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) |
|
|
chrome_options.add_experimental_option('useAutomationExtension', False) |
|
|
chrome_options.add_argument(f"user-data-dir={cache_dir}") |
|
|
chrome_options.add_argument("--log-level=3") |
|
|
chrome_options.add_argument("--disable-logging") |
|
|
chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) |
|
|
|
|
|
driver = webdriver.Chrome(options=chrome_options) |
|
|
|
|
|
|
|
|
bot = TikTokBot( |
|
|
driver=driver, |
|
|
login_email="foudmohammed914@gmail.com", |
|
|
login_password="009988Ppooii@@@@", |
|
|
cookies_file='tiktok_cookies.json', |
|
|
commented_file='commented_videos.json' |
|
|
) |
|
|
|
|
|
bot_status['status_message'] = 'Logging in...' |
|
|
socketio.emit('status_update', {'message': 'Logging in...'}) |
|
|
|
|
|
|
|
|
bot.login() |
|
|
|
|
|
bot_status['status_message'] = 'Starting to post comments...' |
|
|
socketio.emit('status_update', {'message': 'Starting to post comments...'}) |
|
|
|
|
|
|
|
|
success = bot.post_comment_on_video_with_progress( |
|
|
video_url, |
|
|
comment_text, |
|
|
num_comments, |
|
|
progress_callback |
|
|
) |
|
|
|
|
|
if success: |
|
|
bot_status['status_message'] = 'Comments posted successfully!' |
|
|
socketio.emit('bot_completed', { |
|
|
'message': 'Comments posted successfully!', |
|
|
'success': True |
|
|
}) |
|
|
else: |
|
|
bot_status['status_message'] = 'Failed to post comments.' |
|
|
socketio.emit('bot_completed', { |
|
|
'message': 'Failed to post comments.', |
|
|
'success': False |
|
|
}) |
|
|
|
|
|
except Exception as e: |
|
|
error_msg = f'Error: {str(e)}' |
|
|
bot_status['status_message'] = error_msg |
|
|
socketio.emit('bot_error', {'message': error_msg}) |
|
|
logging.error(f"Bot error: {e}") |
|
|
finally: |
|
|
bot_status['is_running'] = False |
|
|
try: |
|
|
driver.quit() |
|
|
except: |
|
|
pass |
|
|
|
|
|
@socketio.on('connect') |
|
|
def handle_connect(): |
|
|
emit('connected', {'message': 'Connected to server'}) |
|
|
|
|
|
emit('bot_status', bot_status) |
|
|
|
|
|
@socketio.on('disconnect') |
|
|
def handle_disconnect(): |
|
|
print('Client disconnected') |
|
|
|
|
|
if __name__ == '__main__': |
|
|
socketio.run(app, debug=True, host='0.0.0.0', port=7860, allow_unsafe_werkzeug=True) |
|
|
|