File size: 5,902 Bytes
b115c19 15c5812 b115c19 3baac0d b115c19 3baac0d 06942ac 3baac0d b115c19 2d5b0bc b115c19 06942ac b115c19 2d5b0bc b115c19 2d5b0bc 3baac0d 2d5b0bc b115c19 e15c1ef 2d5b0bc da0675a 2d5b0bc da0675a 2d5b0bc b115c19 2d5b0bc b115c19 8246dde 2d5b0bc b115c19 2d5b0bc da0675a 2d5b0bc da08f38 2d5b0bc e15c1ef 2d5b0bc e15c1ef 2d5b0bc 8246dde 4ce5d19 2d5b0bc da0675a 4ce5d19 89abe58 2d5b0bc da08f38 2d5b0bc 8246dde 2d5b0bc 15c5812 2d5b0bc da0675a 8246dde 2d5b0bc 8246dde 2d5b0bc 8969612 2d5b0bc da0675a 8969612 2d5b0bc 8969612 3baac0d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | import os
from typing import Any
from motor.motor_asyncio import AsyncIOMotorClient
from utils.logger import log
class Database:
def __init__(self):
self.client = None
self.db = None
async def init_db(self):
await self.connect()
try:
await self.db.command("ping")
log("✅ Database connection established and verified to 'username_sniper'.")
except Exception as e:
raise ConnectionError(f"🚨 Database failed to ping: {e}")
async def connect(self):
uri = os.environ.get("MONGO_URI")
if not uri:
raise ValueError("MONGO_URI not set.")
self.client = AsyncIOMotorClient(uri)
self.db = self.client["username_sniper"]
# --- SETTINGS MANAGER ---
async def load_settings(self, state_dict: dict):
if self.db is None: return
doc = await self.db.settings.find_one({"_id": "bot_settings"})
if not doc: return
keys = [
"checking_active", "sniping_active", "cycle_paused",
"check_interval", "snipe_interval", "autoclaim_on", "db_filter_on",
"total_checked", "total_available", "total_claimed",
"channel_claim_priority", "preferred_channel_account",
"watchdog_poll_interval", "fragment_sniping_active",
"fragment_autoclaim_on", "fragment_workers", "custom_claim_message",
"mute_minor_alerts", "smart_menu_on", "camper_interval", "custom_claim_gif", "custom_success_text"
]
for key in keys:
if key in doc:
state_dict[key] = doc[key]
async def save_setting(self, key: str, value):
if self.db is not None:
await self.db.settings.update_one({"_id": "bot_settings"}, {"$set": {key: value}}, upsert=True)
# --- ADMIN MANAGER ---
async def add_admin(self, user_id: int):
if self.db is not None:
await self.db.admins.update_one({"user_id": user_id}, {"$set": {"user_id": user_id}}, upsert=True)
async def get_admins(self) -> set:
if self.db is None: return set()
cursor = self.db.admins.find({}, {"user_id": 1})
docs = await cursor.to_list(length=None)
return {doc["user_id"] for doc in docs}
# --- UNAVAILABLE SET ---
async def get_unavailable_set(self) -> set:
if self.db is None: return set()
cursor = self.db.unavailable.find({}, {"username": 1})
docs = await cursor.to_list(length=None)
return {doc["username"] for doc in docs}
async def add_unavailable(self, username: str):
if self.db is not None:
await self.db.unavailable.update_one({"username": username}, {"$set": {"username": username}}, upsert=True)
async def remove_unavailable(self, username: str):
if self.db is not None:
await self.db.unavailable.delete_one({"username": username})
async def clear_unavailable(self):
if self.db is not None:
await self.db.unavailable.delete_many({})
# --- CUSTOM SNIPES ---
async def get_custom_snipes(self) -> list:
if self.db is None: return []
cursor = self.db.custom_snipes.find({}, {"username": 1})
docs = await cursor.to_list(length=None)
return [doc["username"] for doc in docs]
async def add_custom_snipe(self, username: str):
if self.db is not None:
await self.db.custom_snipes.update_one({"username": username}, {"$set": {"username": username}}, upsert=True)
# ⚡ NEW: Atomic Bulk Custom Snipe Write
async def add_custom_snipe_bulk(self, usernames: list):
if self.db is not None and usernames:
from pymongo import UpdateOne
operations = [UpdateOne({"username": u}, {"$set": {"username": u}}, upsert=True) for u in usernames]
for i in range(0, len(operations), 10000):
await self.db.custom_snipes.bulk_write(operations[i:i+10000])
async def remove_custom_snipe(self, username: str):
if self.db is not None:
await self.db.custom_snipes.delete_one({"username": username})
# --- WATCHDOG ---
async def get_watchdog(self) -> dict:
if self.db is None: return {}
cursor = self.db.watchdog.find({}, {"username": 1, "added_by": 1})
docs = await cursor.to_list(length=None)
return {doc["username"]: doc.get("added_by") for doc in docs}
async def add_watchdog(self, username: str, user_id: Any):
if self.db is not None:
await self.db.watchdog.update_one({"username": username}, {"$set": {"username": username, "added_by": user_id}}, upsert=True)
async def remove_watchdog(self, username: str):
if self.db is not None:
await self.db.watchdog.delete_one({"username": username})
# --- FRAGMENT CHECK ---
async def get_fragcheck(self) -> list:
if self.db is None: return []
cursor = self.db.fragcheck.find({}, {"username": 1})
docs = await cursor.to_list(length=None)
return [doc["username"] for doc in docs]
async def add_fragcheck(self, username: str):
if self.db is not None:
await self.db.fragcheck.update_one({"username": username}, {"$set": {"username": username}}, upsert=True)
# ⚡ NEW: Atomic Bulk Fragment Write
async def add_fragcheck_bulk(self, usernames: list):
if self.db is not None and usernames:
from pymongo import UpdateOne
operations = [UpdateOne({"username": u}, {"$set": {"username": u}}, upsert=True) for u in usernames]
for i in range(0, len(operations), 10000):
await self.db.fragcheck.bulk_write(operations[i:i+10000])
async def remove_fragcheck(self, username: str):
if self.db is not None:
await self.db.fragcheck.delete_one({"username": username})
db = Database() |