Team Ai
Datasetpublic

ysn-rfd/text-dataset-tiny-code-script-py-format

USED of tahamajs/medicine_ds_persian for .parquet file USED of Alijafarixcs2/persian-it-llama2-2k for .parquet file USED of Abirate/english_quotes for .jsonl file NEW FILES (05/12/2025) NEW FILES (12/26/2025) NEW FILES (02/15/2026)

sourceHugging Faceapache-2.0updated 4mo agoView on Hugging Face
3likes1.7kdownloads
data_manager.py329 linesDownload Raw Back to Version2_Context
1# data_manager.py2 3import os4import json5import logging6from datetime import datetime, timedelta7import tiktoken  # برای شمارش توکن‌ها8 9# --- تنظیمات مسیر فایل‌ها ---10BASE_DIR = os.path.dirname(os.path.abspath(__file__))11DATA_FILE = os.path.join(BASE_DIR, "bot_data.json")12LOG_FILE = os.path.join(BASE_DIR, "bot.log")13 14# --- کش داده‌های گلوبال ---15DATA = {16    "users": {},17    "banned_users": set(),18    "stats": {19        "total_messages": 0,20        "total_users": 0,21        "avg_response_time": 0.0,22        "max_response_time": 0.0,23        "min_response_time": float('inf'),24        "total_responses": 025    },26    "welcome_message": "سلام {user_mention}! 🤖\n\nمن یک ربات هوشمند هستم. هر سوالی دارید بپرسید.",27    "goodbye_message": "کاربر {user_mention} گروه را ترک کرد. خداحافظ!",28    "maintenance_mode": False,29    "blocked_words": [],30    "scheduled_broadcasts": [],31    "bot_start_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')32}33 34logger = logging.getLogger(__name__)35 36# تابع برای شمارش توکن‌ها37def count_tokens(text: str) -> int:38    """شمارش تعداد توکن‌های متن با استفاده از tokenizer"""39    try:40        # استفاده از tokenizer برای gpt-3.5-turbo41        encoding = tiktoken.get_encoding("cl100k_base")42        return len(encoding.encode(text))43    except Exception as e:44        logger.warning(f"Error counting tokens: {e}, using fallback")45        # تقریب: هر 4 کاراکتر = 1 توکن46        return max(1, len(text) // 4)47 48def load_data():49    """داده‌ها را از فایل JSON بارگذاری کرده و در کش گلوبال ذخیره می‌کند."""50    global DATA51    try:52        if not os.path.exists(DATA_FILE):53            logger.info(f"فایل داده در {DATA_FILE} یافت نشد. یک فایل جدید ایجاد می‌شود.")54            save_data()55            return56 57        with open(DATA_FILE, 'r', encoding='utf-8') as f:58            loaded_data = json.load(f)59            loaded_data['banned_users'] = set(loaded_data.get('banned_users', []))60            61            # اطمینان از وجود کلیدهای جدید در فایل‌های قدیمی62            if 'blocked_words' not in loaded_data: loaded_data['blocked_words'] = []63            if 'scheduled_broadcasts' not in loaded_data: loaded_data['scheduled_broadcasts'] = []64            if 'maintenance_mode' not in loaded_data: loaded_data['maintenance_mode'] = False65            if 'bot_start_time' not in loaded_data: loaded_data['bot_start_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')66            if 'avg_response_time' not in loaded_data['stats']:67                loaded_data['stats']['avg_response_time'] = 0.068                loaded_data['stats']['max_response_time'] = 0.069                loaded_data['stats']['min_response_time'] = float('inf')70                loaded_data['stats']['total_responses'] = 071            72            # اطمینان از وجود context برای کاربران قدیمی73            for user_id in loaded_data.get('users', {}):74                if 'context' not in loaded_data['users'][user_id]:75                    loaded_data['users'][user_id]['context'] = []76 77            DATA.update(loaded_data)78            logger.info(f"داده‌ها با موفقیت از {DATA_FILE} بارگذاری شدند.")79 80    except json.JSONDecodeError as e:81        logger.error(f"خطا در خواندن JSON از {DATA_FILE}: {e}. ربات با داده‌های اولیه شروع به کار می‌کند.")82    except Exception as e:83        logger.error(f"خطای غیرمنتظره هنگام بارگذاری داده‌ها: {e}. ربات با داده‌های اولیه شروع به کار می‌کند.")84 85def save_data():86    """کش گلوبال داده‌ها را در فایل JSON ذخیره می‌کند."""87    global DATA88    try:89        data_to_save = DATA.copy()90        data_to_save['banned_users'] = list(DATA['banned_users'])91        92        with open(DATA_FILE, 'w', encoding='utf-8') as f:93            json.dump(data_to_save, f, indent=4, ensure_ascii=False)94        logger.debug(f"داده‌ها با موفقیت در {DATA_FILE} ذخیره شدند.")95    except Exception as e:96        logger.error(f"خطای مهلک: امکان ذخیره داده‌ها در {DATA_FILE} وجود ندارد. خطا: {e}")97 98def update_user_stats(user_id: int, user):99    """آمار کاربر را پس از هر پیام به‌روز کرده و داده‌ها را ذخیره می‌کند."""100    global DATA101    now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')102    user_id_str = str(user_id)103    104    if user_id_str not in DATA['users']:105        DATA['users'][user_id_str] = {106            'first_name': user.first_name,107            'username': user.username,108            'first_seen': now_str,109            'message_count': 0,110            'context': []  # اضافه کردن context خالی برای کاربر جدید111        }112        DATA['stats']['total_users'] += 1113        logger.info(f"کاربر جدید ثبت شد: {user_id} ({user.first_name})")114 115    DATA['users'][user_id_str]['last_seen'] = now_str116    DATA['users'][user_id_str]['message_count'] += 1117    DATA['stats']['total_messages'] += 1118    119    save_data()120 121def update_response_stats(response_time: float):122    """آمار زمان پاسخگویی را به‌روز می‌کند."""123    global DATA124    125    if DATA['stats']['total_responses'] == 0:126        DATA['stats']['min_response_time'] = response_time127 128    DATA['stats']['total_responses'] += 1129    130    # محاسبه میانگین جدید131    current_avg = DATA['stats']['avg_response_time']132    total_responses = DATA['stats']['total_responses']133    new_avg = ((current_avg * (total_responses - 1)) + response_time) / total_responses134    DATA['stats']['avg_response_time'] = new_avg135    136    # به‌روزرسانی حداکثر و حداقل زمان پاسخگویی137    if response_time > DATA['stats']['max_response_time']:138        DATA['stats']['max_response_time'] = response_time139    140    if response_time < DATA['stats']['min_response_time']:141        DATA['stats']['min_response_time'] = response_time142    143    save_data()144 145def is_user_banned(user_id: int) -> bool:146    """بررسی می‌کند آیا کاربر مسدود شده است یا خیر."""147    return user_id in DATA['banned_users']148 149def ban_user(user_id: int):150    """کاربر را مسدود کرده و ذخیره می‌کند."""151    DATA['banned_users'].add(user_id)152    save_data()153 154def unban_user(user_id: int):155    """مسدودیت کاربر را برداشته و ذخیره می‌کند."""156    DATA['banned_users'].discard(user_id)157    save_data()158 159def contains_blocked_words(text: str) -> bool:160    """بررسی می‌کند آیا متن حاوی کلمات مسدود شده است یا خیر."""161    if not DATA['blocked_words']:162        return False163    164    text_lower = text.lower()165    for word in DATA['blocked_words']:166        if word in text_lower:167            return True168    169    return False170 171def get_active_users(days: int) -> list:172    """لیست کاربران فعال در بازه زمانی مشخص را برمی‌گرداند."""173    now = datetime.now()174    cutoff_date = now - timedelta(days=days)175    176    active_users = []177    for user_id, user_info in DATA['users'].items():178        if 'last_seen' in user_info:179            try:180                last_seen = datetime.strptime(user_info['last_seen'], '%Y-%m-%d %H:%M:%S')181                if last_seen >= cutoff_date:182                    active_users.append(int(user_id))183            except ValueError:184                continue185    186    return active_users187 188def get_users_by_message_count(min_count: int) -> list:189    """لیست کاربران با تعداد پیام بیشتر یا مساوی مقدار مشخص را برمی‌گرداند."""190    users = []191    for user_id, user_info in DATA['users'].items():192        if user_info.get('message_count', 0) >= min_count:193            users.append(int(user_id))194    195    return users196 197# --- توابع مدیریت context ---198 199def add_to_user_context(user_id: int, role: str, content: str):200    """اضافه کردن پیام به context کاربر و محدود کردن به ۱۰۲۴ توکن"""  # از 512 به 1024 تغییر یافت201    user_id_str = str(user_id)202    203    if user_id_str not in DATA['users']:204        return205    206    if 'context' not in DATA['users'][user_id_str]:207        DATA['users'][user_id_str]['context'] = []208    209    # اضافه کردن پیام جدید210    message = {211        'role': role,  # 'user' یا 'assistant'212        'content': content,213        'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')214    }215    216    DATA['users'][user_id_str]['context'].append(message)217    218    # محدود کردن context به ۱۰۲۴ توکن  # از 512 به 1024 تغییر یافت219    trim_user_context(user_id)220    221    save_data()222 223# خط 165 را پیدا کنید و تغییر دهید:224def trim_user_context(user_id: int, max_tokens: int = 1024):  # از 512 به 1024 تغییر یافت225    """کوتاه کردن context کاربر به تعداد توکن مشخص"""226    user_id_str = str(user_id)227    228    if user_id_str not in DATA['users'] or 'context' not in DATA['users'][user_id_str]:229        return230    231    context = DATA['users'][user_id_str]['context']232    233    if not context:234        return235    236    # محاسبه توکن‌های کل237    total_tokens = sum(count_tokens(msg['content']) for msg in context)238    239    # حذف قدیمی‌ترین پیام‌ها تا زمانی که توکن‌ها زیر حد مجاز باشد240    while total_tokens > max_tokens and len(context) > 1:241        removed_message = context.pop(0)  # حذف قدیمی‌ترین پیام242        total_tokens -= count_tokens(removed_message['content'])243    244    # اگر هنوز بیشتر از حد مجاز است، از محتوای پیام‌ها کم کن245    if total_tokens > max_tokens and context:246        # از آخرین پیام (جدیدترین) شروع به کوتاه کردن کن247        last_message = context[-1]248        content = last_message['content']249        250        # کوتاه کردن محتوا251        tokens = count_tokens(content)252        if tokens > max_tokens:253            # اگر یک پیام به تنهایی بیشتر از حد مجاز باشد، آن را حذف کن254            context.pop()255        else:256            # در غیر این صورت، محتوای پیام را کوتاه کن257            while tokens > (max_tokens - (total_tokens - tokens)) and content:258                # حذف کلمات از انتها259                words = content.split()260                if len(words) > 1:261                    content = ' '.join(words[:-1])262                else:263                    content = content[:-1] if len(content) > 1 else ''264                tokens = count_tokens(content)265            266            if content:  # اگر محتوایی باقی مانده267                context[-1]['content'] = content268            else:  # اگر تمام محتوا حذف شد269                context.pop()270    271    save_data()272 273def get_user_context(user_id: int) -> list:274    """دریافت context کاربر"""275    user_id_str = str(user_id)276    277    if user_id_str not in DATA['users']:278        return []279    280    return DATA['users'][user_id_str].get('context', [])281 282def clear_user_context(user_id: int):283    """پاک کردن context کاربر"""284    user_id_str = str(user_id)285    286    if user_id_str in DATA['users']:287        if 'context' in DATA['users'][user_id_str]:288            DATA['users'][user_id_str]['context'] = []289            save_data()290            logger.info(f"Context cleared for user {user_id}")291 292def get_context_summary(user_id: int) -> str:293    """خلاصه‌ای از context کاربر"""294    context = get_user_context(user_id)295    if not context:296        return "بدون تاریخچه"297    298    total_messages = len(context)299    total_tokens = sum(count_tokens(msg['content']) for msg in context)300    301    # نمایش آخرین پیام302    last_message = context[-1] if context else {}303    last_content = last_message.get('content', '')[:50]304    if len(last_message.get('content', '')) > 50:305        last_content += "..."306    307    return f"{total_messages} پیام ({total_tokens} توکن) - آخرین: {last_message.get('role', '')}: {last_content}"308 309def get_context_for_api(user_id: int) -> list:310    """فرمت context برای ارسال به API"""311    context = get_user_context(user_id)312    313    # تبدیل به فرمت مورد نیاز API314    api_context = []315    for msg in context:316        api_context.append({317            'role': msg['role'],318            'content': msg['content']319        })320    321    return api_context322 323def get_context_token_count(user_id: int) -> int:324    """تعداد کل توکن‌های context کاربر"""325    context = get_user_context(user_id)326    return sum(count_tokens(msg['content']) for msg in context)327 328# بارگذاری اولیه داده‌ها در زمان ایمپورت شدن ماژول329load_data()