Update app.py
Browse files
app.py
CHANGED
|
@@ -25,6 +25,9 @@ if MONGODB_URI:
|
|
| 25 |
accounts_collection = db[COLLECTION_NAME]
|
| 26 |
mongo_client.admin.command('ping')
|
| 27 |
print("✅ MongoDB Connected!")
|
|
|
|
|
|
|
|
|
|
| 28 |
except ConnectionFailure as e:
|
| 29 |
print(f"❌ MongoDB Connection Failed: {e}")
|
| 30 |
mongo_client = None
|
|
@@ -60,20 +63,33 @@ def load_accounts_from_mongodb():
|
|
| 60 |
accounts_dict = {}
|
| 61 |
try:
|
| 62 |
if mongo_client:
|
|
|
|
| 63 |
cursor = accounts_collection.find({})
|
|
|
|
| 64 |
for doc in cursor:
|
|
|
|
| 65 |
acc_id = doc.pop("_id")
|
| 66 |
doc["session"] = None
|
| 67 |
doc["csrf"] = None
|
| 68 |
doc["status"] = False
|
| 69 |
-
doc["otp_logs"] = []
|
| 70 |
doc["sent_cache"] = []
|
| 71 |
doc["sms_cache"] = {}
|
| 72 |
doc["sms_counter"] = {}
|
| 73 |
doc["range_counter"] = {}
|
| 74 |
doc["last_cleanup"] = time.time()
|
| 75 |
accounts_dict[acc_id] = doc
|
|
|
|
| 76 |
print(f"📊 Loaded {len(accounts_dict)} accounts from MongoDB")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
except Exception as e:
|
| 78 |
print(f"❌ Error load from MongoDB: {e}")
|
| 79 |
return accounts_dict
|
|
@@ -81,22 +97,30 @@ def load_accounts_from_mongodb():
|
|
| 81 |
def save_accounts_to_mongodb(accounts_dict):
|
| 82 |
try:
|
| 83 |
if mongo_client:
|
|
|
|
|
|
|
| 84 |
for acc_id, acc in accounts_dict.items():
|
| 85 |
acc_copy = acc.copy()
|
| 86 |
acc_copy.pop("session", None)
|
| 87 |
acc_copy.pop("csrf", None)
|
| 88 |
-
if "otp_logs" in acc_copy and len(acc_copy["otp_logs"]) > 100:
|
| 89 |
-
acc_copy["otp_logs"] = acc_copy["otp_logs"][:100]
|
| 90 |
acc_copy.pop("sms_cache", None)
|
| 91 |
acc_copy.pop("sms_counter", None)
|
| 92 |
acc_copy.pop("range_counter", None)
|
| 93 |
acc_copy.pop("last_cleanup", None)
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
{"_id": acc_id},
|
| 96 |
{"$set": acc_copy},
|
| 97 |
upsert=True
|
| 98 |
)
|
| 99 |
-
|
|
|
|
|
|
|
|
|
|
| 100 |
except Exception as e:
|
| 101 |
print(f"❌ Error save to MongoDB: {e}")
|
| 102 |
|
|
@@ -143,6 +167,7 @@ def save_accounts_to_file(accounts_dict):
|
|
| 143 |
except Exception as e:
|
| 144 |
print(f"❌ Error save to file: {e}")
|
| 145 |
|
|
|
|
| 146 |
if mongo_client:
|
| 147 |
accounts = load_accounts_from_mongodb()
|
| 148 |
else:
|
|
@@ -831,6 +856,16 @@ def stream():
|
|
| 831 |
def api_logs():
|
| 832 |
return json.dumps(global_otp_logs[:100])
|
| 833 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 834 |
def run_account_scraper(account_id):
|
| 835 |
account = accounts.get(account_id)
|
| 836 |
if not account:
|
|
@@ -935,12 +970,27 @@ def main():
|
|
| 935 |
print("\n" + "="*70)
|
| 936 |
print(" 🔥 OTP MULTI ACCOUNT - FOURSTORE 🔥")
|
| 937 |
print("="*70)
|
| 938 |
-
|
| 939 |
-
|
| 940 |
if mongo_client:
|
| 941 |
-
print("
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 942 |
else:
|
| 943 |
-
print("
|
|
|
|
|
|
|
|
|
|
| 944 |
print(" 📋 LOGGING: FULL DETAIL")
|
| 945 |
print(" 🔒 EMAIL SENSOR: AKTIF")
|
| 946 |
print(" 🤖 AUTO LOGIN: AKTIF")
|
|
@@ -950,6 +1000,8 @@ def main():
|
|
| 950 |
print(" ⏰ 24 JAM MONITORING: AKTIF")
|
| 951 |
print("="*70 + "\n")
|
| 952 |
|
|
|
|
|
|
|
| 953 |
for acc_id, acc in accounts.items():
|
| 954 |
if "otp_logs" in acc and acc["otp_logs"]:
|
| 955 |
for log in acc["otp_logs"]:
|
|
@@ -958,6 +1010,7 @@ def main():
|
|
| 958 |
global_otp_logs.sort(key=lambda x: x.get('timestamp', 0), reverse=True)
|
| 959 |
print(f"📊 Total logs dimuat: {len(global_otp_logs)}")
|
| 960 |
|
|
|
|
| 961 |
for acc_id, acc in accounts.items():
|
| 962 |
if acc.get("status"):
|
| 963 |
masked = mask_email(acc['username'])
|
|
@@ -991,9 +1044,15 @@ def main():
|
|
| 991 |
time.sleep(300)
|
| 992 |
if mongo_client:
|
| 993 |
save_accounts_to_mongodb(accounts)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 994 |
else:
|
| 995 |
save_accounts_to_file(accounts)
|
| 996 |
-
|
| 997 |
|
| 998 |
if __name__ == "__main__":
|
| 999 |
try:
|
|
|
|
| 25 |
accounts_collection = db[COLLECTION_NAME]
|
| 26 |
mongo_client.admin.command('ping')
|
| 27 |
print("✅ MongoDB Connected!")
|
| 28 |
+
# Cek isi database
|
| 29 |
+
count = accounts_collection.count_documents({})
|
| 30 |
+
print(f"📊 Total dokumen di MongoDB: {count}")
|
| 31 |
except ConnectionFailure as e:
|
| 32 |
print(f"❌ MongoDB Connection Failed: {e}")
|
| 33 |
mongo_client = None
|
|
|
|
| 63 |
accounts_dict = {}
|
| 64 |
try:
|
| 65 |
if mongo_client:
|
| 66 |
+
print("📥 Loading accounts from MongoDB...")
|
| 67 |
cursor = accounts_collection.find({})
|
| 68 |
+
count = 0
|
| 69 |
for doc in cursor:
|
| 70 |
+
count += 1
|
| 71 |
acc_id = doc.pop("_id")
|
| 72 |
doc["session"] = None
|
| 73 |
doc["csrf"] = None
|
| 74 |
doc["status"] = False
|
| 75 |
+
doc["otp_logs"] = doc.get("otp_logs", [])
|
| 76 |
doc["sent_cache"] = []
|
| 77 |
doc["sms_cache"] = {}
|
| 78 |
doc["sms_counter"] = {}
|
| 79 |
doc["range_counter"] = {}
|
| 80 |
doc["last_cleanup"] = time.time()
|
| 81 |
accounts_dict[acc_id] = doc
|
| 82 |
+
|
| 83 |
print(f"📊 Loaded {len(accounts_dict)} accounts from MongoDB")
|
| 84 |
+
if count > 0:
|
| 85 |
+
print(f"✅ Data MongoDB berhasil dimuat: {count} akun")
|
| 86 |
+
# Tampilkan sample
|
| 87 |
+
for acc_id, acc in list(accounts_dict.items())[:2]:
|
| 88 |
+
email_masked = mask_email(acc.get('username', 'Unknown'))
|
| 89 |
+
log_count = len(acc.get('otp_logs', []))
|
| 90 |
+
print(f" - Akun: {email_masked} | OTP Logs: {log_count}")
|
| 91 |
+
else:
|
| 92 |
+
print("⚠️ Tidak ada data di MongoDB")
|
| 93 |
except Exception as e:
|
| 94 |
print(f"❌ Error load from MongoDB: {e}")
|
| 95 |
return accounts_dict
|
|
|
|
| 97 |
def save_accounts_to_mongodb(accounts_dict):
|
| 98 |
try:
|
| 99 |
if mongo_client:
|
| 100 |
+
print("💾 Saving accounts to MongoDB...")
|
| 101 |
+
saved_count = 0
|
| 102 |
for acc_id, acc in accounts_dict.items():
|
| 103 |
acc_copy = acc.copy()
|
| 104 |
acc_copy.pop("session", None)
|
| 105 |
acc_copy.pop("csrf", None)
|
|
|
|
|
|
|
| 106 |
acc_copy.pop("sms_cache", None)
|
| 107 |
acc_copy.pop("sms_counter", None)
|
| 108 |
acc_copy.pop("range_counter", None)
|
| 109 |
acc_copy.pop("last_cleanup", None)
|
| 110 |
+
|
| 111 |
+
# Batasi logs
|
| 112 |
+
if "otp_logs" in acc_copy and len(acc_copy["otp_logs"]) > 100:
|
| 113 |
+
acc_copy["otp_logs"] = acc_copy["otp_logs"][:100]
|
| 114 |
+
|
| 115 |
+
result = accounts_collection.update_one(
|
| 116 |
{"_id": acc_id},
|
| 117 |
{"$set": acc_copy},
|
| 118 |
upsert=True
|
| 119 |
)
|
| 120 |
+
if result.upserted_id or result.modified_count > 0:
|
| 121 |
+
saved_count += 1
|
| 122 |
+
|
| 123 |
+
print(f"💾 Saved {saved_count} accounts to MongoDB")
|
| 124 |
except Exception as e:
|
| 125 |
print(f"❌ Error save to MongoDB: {e}")
|
| 126 |
|
|
|
|
| 167 |
except Exception as e:
|
| 168 |
print(f"❌ Error save to file: {e}")
|
| 169 |
|
| 170 |
+
# Load accounts
|
| 171 |
if mongo_client:
|
| 172 |
accounts = load_accounts_from_mongodb()
|
| 173 |
else:
|
|
|
|
| 856 |
def api_logs():
|
| 857 |
return json.dumps(global_otp_logs[:100])
|
| 858 |
|
| 859 |
+
@app.route('/api/stats')
|
| 860 |
+
def api_stats():
|
| 861 |
+
return json.dumps({
|
| 862 |
+
"total_accounts": len(accounts),
|
| 863 |
+
"online_accounts": sum(1 for a in accounts.values() if a.get('status')),
|
| 864 |
+
"total_otp": len(global_otp_logs),
|
| 865 |
+
"mongo_connected": mongo_client is not None,
|
| 866 |
+
"mongo_docs": accounts_collection.count_documents({}) if mongo_client else 0
|
| 867 |
+
})
|
| 868 |
+
|
| 869 |
def run_account_scraper(account_id):
|
| 870 |
account = accounts.get(account_id)
|
| 871 |
if not account:
|
|
|
|
| 970 |
print("\n" + "="*70)
|
| 971 |
print(" 🔥 OTP MULTI ACCOUNT - FOURSTORE 🔥")
|
| 972 |
print("="*70)
|
| 973 |
+
|
| 974 |
+
# CEK MONGODB
|
| 975 |
if mongo_client:
|
| 976 |
+
print(" ✅ MongoDB: TERHUBUNG")
|
| 977 |
+
try:
|
| 978 |
+
count = accounts_collection.count_documents({})
|
| 979 |
+
print(f" 📊 Data di MongoDB: {count} akun")
|
| 980 |
+
|
| 981 |
+
# Coba baca sample
|
| 982 |
+
sample = accounts_collection.find_one()
|
| 983 |
+
if sample:
|
| 984 |
+
print(f" 📝 Sample akun: {mask_email(sample.get('username', 'Unknown'))}")
|
| 985 |
+
log_count = len(sample.get('otp_logs', []))
|
| 986 |
+
print(f" 📝 OTP logs: {log_count}")
|
| 987 |
+
except Exception as e:
|
| 988 |
+
print(f" ❌ Error cek MongoDB: {e}")
|
| 989 |
else:
|
| 990 |
+
print(" ⚠️ MongoDB: TIDAK TERHUBUNG (pakai file)")
|
| 991 |
+
|
| 992 |
+
print(f" ⚡ PORT: 7860")
|
| 993 |
+
print(f" 🌐 DOMAIN: {CUSTOM_DOMAIN}")
|
| 994 |
print(" 📋 LOGGING: FULL DETAIL")
|
| 995 |
print(" 🔒 EMAIL SENSOR: AKTIF")
|
| 996 |
print(" 🤖 AUTO LOGIN: AKTIF")
|
|
|
|
| 1000 |
print(" ⏰ 24 JAM MONITORING: AKTIF")
|
| 1001 |
print("="*70 + "\n")
|
| 1002 |
|
| 1003 |
+
# Muat ulang log dari akun yang ada
|
| 1004 |
+
print("📥 Memuat ulang logs dari akun tersimpan...")
|
| 1005 |
for acc_id, acc in accounts.items():
|
| 1006 |
if "otp_logs" in acc and acc["otp_logs"]:
|
| 1007 |
for log in acc["otp_logs"]:
|
|
|
|
| 1010 |
global_otp_logs.sort(key=lambda x: x.get('timestamp', 0), reverse=True)
|
| 1011 |
print(f"📊 Total logs dimuat: {len(global_otp_logs)}")
|
| 1012 |
|
| 1013 |
+
# Auto login untuk akun yang sudah login sebelumnya
|
| 1014 |
for acc_id, acc in accounts.items():
|
| 1015 |
if acc.get("status"):
|
| 1016 |
masked = mask_email(acc['username'])
|
|
|
|
| 1044 |
time.sleep(300)
|
| 1045 |
if mongo_client:
|
| 1046 |
save_accounts_to_mongodb(accounts)
|
| 1047 |
+
# Cek status MongoDB
|
| 1048 |
+
try:
|
| 1049 |
+
count = accounts_collection.count_documents({})
|
| 1050 |
+
print(f"💾 Auto-save: {count} akun tersimpan - {get_wib_time_str()}")
|
| 1051 |
+
except:
|
| 1052 |
+
print(f"💾 Auto-save - {get_wib_time_str()}")
|
| 1053 |
else:
|
| 1054 |
save_accounts_to_file(accounts)
|
| 1055 |
+
print(f"💾 Auto-save data - {get_wib_time_str()}")
|
| 1056 |
|
| 1057 |
if __name__ == "__main__":
|
| 1058 |
try:
|