CoolFace
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.6kdownloads
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# --- instruction همیشگی ---15SYSTEM_INSTRUCTION = {16    "role": "system",17    "content": "خالق و طراح و توسعه دهنده تو YSNRFD هست، تو توسط YSNRFD ساخته شده ای، نام تو YSNRFD AI هست. همیشه این موضوع را در پاسخ‌هایت به یاد داشته باش و اگر کاربر درباره هویت یا سازنده تو سوال کرد، این اطلاعات را با افتخار بیان کن."18}19 20# --- کش داده‌های گلوبال ---21DATA = {22    "users": {},23    "banned_users": set(),24    "stats": {25        "total_messages": 0,26        "total_users": 0,27        "avg_response_time": 0.0,28        "max_response_time": 0.0,29        "min_response_time": float('inf'),30        "total_responses": 031    },32    "welcome_message": "سلام {user_mention}! 🤖\n\nمن یک ربات هوشمند هستم. هر سوالی دارید بپرسید.",33    "goodbye_message": "کاربر {user_mention} گروه را ترک کرد. خداحافظ!",34    "maintenance_mode": False,35    "blocked_words": [],36    "scheduled_broadcasts": [],37    "bot_start_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),38    "system_instruction": SYSTEM_INSTRUCTION["content"]  # ذخیره instruction برای نمایش در پنل ادمین39}40 41logger = logging.getLogger(__name__)42 43# تابع برای شمارش توکن‌ها44def count_tokens(text: str) -> int:45    """شمارش تعداد توکن‌های متن با استفاده از tokenizer"""46    try:47        # استفاده از tokenizer برای gpt-3.5-turbo48        encoding = tiktoken.get_encoding("cl100k_base")49        return len(encoding.encode(text))50    except Exception as e:51        logger.warning(f"Error counting tokens: {e}, using fallback")52        # تقریب: هر 4 کاراکتر = 1 توکن53        return max(1, len(text) // 4)54 55def load_data():56    """داده‌ها را از فایل JSON بارگذاری کرده و در کش گلوبال ذخیره می‌کند."""57    global DATA58    try:59        if not os.path.exists(DATA_FILE):60            logger.info(f"فایل داده در {DATA_FILE} یافت نشد. یک فایل جدید ایجاد می‌شود.")61            save_data()62            return63 64        with open(DATA_FILE, 'r', encoding='utf-8') as f:65            loaded_data = json.load(f)66            loaded_data['banned_users'] = set(loaded_data.get('banned_users', []))67            68            # اطمینان از وجود کلیدهای جدید در فایل‌های قدیمی69            if 'blocked_words' not in loaded_data: loaded_data['blocked_words'] = []70            if 'scheduled_broadcasts' not in loaded_data: loaded_data['scheduled_broadcasts'] = []71            if 'maintenance_mode' not in loaded_data: loaded_data['maintenance_mode'] = False72            if 'bot_start_time' not in loaded_data: loaded_data['bot_start_time'] = datetime.now().strftime('%Y-%m-%d %H:%M:%S')73            if 'avg_response_time' not in loaded_data['stats']:74                loaded_data['stats']['avg_response_time'] = 0.075                loaded_data['stats']['max_response_time'] = 0.076                loaded_data['stats']['min_response_time'] = float('inf')77                loaded_data['stats']['total_responses'] = 078            79            # اطمینان از وجود context برای کاربران قدیمی80            for user_id in loaded_data.get('users', {}):81                if 'context' not in loaded_data['users'][user_id]:82                    loaded_data['users'][user_id]['context'] = []83 84            DATA.update(loaded_data)85            logger.info(f"داده‌ها با موفقیت از {DATA_FILE} بارگذاری شدند.")86 87    except json.JSONDecodeError as e:88        logger.error(f"خطا در خواندن JSON از {DATA_FILE}: {e}. ربات با داده‌های اولیه شروع به کار می‌کند.")89    except Exception as e:90        logger.error(f"خطای غیرمنتظره هنگام بارگذاری داده‌ها: {e}. ربات با داده‌های اولیه شروع به کار می‌کند.")91 92def save_data():93    """کش گلوبال داده‌ها را در فایل JSON ذخیره می‌کند."""94    global DATA95    try:96        data_to_save = DATA.copy()97        data_to_save['banned_users'] = list(DATA['banned_users'])98        99        with open(DATA_FILE, 'w', encoding='utf-8') as f:100            json.dump(data_to_save, f, indent=4, ensure_ascii=False)101        logger.debug(f"داده‌ها با موفقیت در {DATA_FILE} ذخیره شدند.")102    except Exception as e:103        logger.error(f"خطای مهلک: امکان ذخیره داده‌ها در {DATA_FILE} وجود ندارد. خطا: {e}")104 105def update_user_stats(user_id: int, user):106    """آمار کاربر را پس از هر پیام به‌روز کرده و داده‌ها را ذخیره می‌کند."""107    global DATA108    now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')109    user_id_str = str(user_id)110    111    if user_id_str not in DATA['users']:112        DATA['users'][user_id_str] = {113            'first_name': user.first_name,114            'username': user.username,115            'first_seen': now_str,116            'message_count': 0,117            'context': []  # اضافه کردن context خالی برای کاربر جدید118        }119        DATA['stats']['total_users'] += 1120        logger.info(f"کاربر جدید ثبت شد: {user_id} ({user.first_name})")121 122    DATA['users'][user_id_str]['last_seen'] = now_str123    DATA['users'][user_id_str]['message_count'] += 1124    DATA['stats']['total_messages'] += 1125    126    save_data()127 128def update_response_stats(response_time: float):129    """آمار زمان پاسخگویی را به‌روز می‌کند."""130    global DATA131    132    if DATA['stats']['total_responses'] == 0:133        DATA['stats']['min_response_time'] = response_time134 135    DATA['stats']['total_responses'] += 1136    137    # محاسبه میانگین جدید138    current_avg = DATA['stats']['avg_response_time']139    total_responses = DATA['stats']['total_responses']140    new_avg = ((current_avg * (total_responses - 1)) + response_time) / total_responses141    DATA['stats']['avg_response_time'] = new_avg142    143    # به‌روزرسانی حداکثر و حداقل زمان پاسخگویی144    if response_time > DATA['stats']['max_response_time']:145        DATA['stats']['max_response_time'] = response_time146    147    if response_time < DATA['stats']['min_response_time']:148        DATA['stats']['min_response_time'] = response_time149    150    save_data()151 152def is_user_banned(user_id: int) -> bool:153    """بررسی می‌کند آیا کاربر مسدود شده است یا خیر."""154    return user_id in DATA['banned_users']155 156def ban_user(user_id: int):157    """کاربر را مسدود کرده و ذخیره می‌کند."""158    DATA['banned_users'].add(user_id)159    save_data()160 161def unban_user(user_id: int):162    """مسدودیت کاربر را برداشته و ذخیره می‌کند."""163    DATA['banned_users'].discard(user_id)164    save_data()165 166def contains_blocked_words(text: str) -> bool:167    """بررسی می‌کند آیا متن حاوی کلمات مسدود شده است یا خیر."""168    if not DATA['blocked_words']:169        return False170    171    text_lower = text.lower()172    for word in DATA['blocked_words']:173        if word in text_lower:174            return True175    176    return False177 178def get_active_users(days: int) -> list:179    """لیست کاربران فعال در بازه زمانی مشخص را برمی‌گرداند."""180    now = datetime.now()181    cutoff_date = now - timedelta(days=days)182    183    active_users = []184    for user_id, user_info in DATA['users'].items():185        if 'last_seen' in user_info:186            try:187                last_seen = datetime.strptime(user_info['last_seen'], '%Y-%m-%d %H:%M:%S')188                if last_seen >= cutoff_date:189                    active_users.append(int(user_id))190            except ValueError:191                continue192    193    return active_users194 195def get_users_by_message_count(min_count: int) -> list:196    """لیست کاربران با تعداد پیام بیشتر یا مساوی مقدار مشخص را برمی‌گرداند."""197    users = []198    for user_id, user_info in DATA['users'].items():199        if user_info.get('message_count', 0) >= min_count:200            users.append(int(user_id))201    202    return users203 204# --- توابع مدیریت context ---205 206def add_to_user_context(user_id: int, role: str, content: str):207    """اضافه کردن پیام به context کاربر و محدود کردن به 512 توکن"""208    user_id_str = str(user_id)209    210    if user_id_str not in DATA['users']:211        return212    213    if 'context' not in DATA['users'][user_id_str]:214        DATA['users'][user_id_str]['context'] = []215    216    # اضافه کردن پیام جدید217    message = {218        'role': role,  # 'user' یا 'assistant'219        'content': content,220        'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')221    }222    223    DATA['users'][user_id_str]['context'].append(message)224    225    # محدود کردن context به 512 توکن226    trim_user_context(user_id)227    228    save_data()229 230def trim_user_context(user_id: int, max_tokens: int = 512):231    """کوتاه کردن context کاربر به تعداد توکن مشخص"""232    user_id_str = str(user_id)233    234    if user_id_str not in DATA['users'] or 'context' not in DATA['users'][user_id_str]:235        return236    237    context = DATA['users'][user_id_str]['context']238    239    if not context:240        return241    242    # محاسبه توکن‌های کل243    total_tokens = sum(count_tokens(msg['content']) for msg in context)244    245    # حذف قدیمی‌ترین پیام‌ها تا زمانی که توکن‌ها زیر حد مجاز باشد246    while total_tokens > max_tokens and len(context) > 1:247        removed_message = context.pop(0)  # حذف قدیمی‌ترین پیام248        total_tokens -= count_tokens(removed_message['content'])249    250    # اگر هنوز بیشتر از حد مجاز است، از محتوای پیام‌ها کم کن251    if total_tokens > max_tokens and context:252        # از آخرین پیام (جدیدترین) شروع به کوتاه کردن کن253        last_message = context[-1]254        content = last_message['content']255        256        # کوتاه کردن محتوا257        tokens = count_tokens(content)258        if tokens > max_tokens:259            # اگر یک پیام به تنهایی بیشتر از حد مجاز باشد، آن را حذف کن260            context.pop()261        else:262            # در غیر این صورت، محتوای پیام را کوتاه کن263            while tokens > (max_tokens - (total_tokens - tokens)) and content:264                # حذف کلمات از انتها265                words = content.split()266                if len(words) > 1:267                    content = ' '.join(words[:-1])268                else:269                    content = content[:-1] if len(content) > 1 else ''270                tokens = count_tokens(content)271            272            if content:  # اگر محتوایی باقی مانده273                context[-1]['content'] = content274            else:  # اگر تمام محتوا حذف شد275                context.pop()276    277    save_data()278 279def get_user_context(user_id: int) -> list:280    """دریافت context کاربر"""281    user_id_str = str(user_id)282    283    if user_id_str not in DATA['users']:284        return []285    286    return DATA['users'][user_id_str].get('context', [])287 288def clear_user_context(user_id: int):289    """پاک کردن context کاربر"""290    user_id_str = str(user_id)291    292    if user_id_str in DATA['users']:293        if 'context' in DATA['users'][user_id_str]:294            DATA['users'][user_id_str]['context'] = []295            save_data()296            logger.info(f"Context cleared for user {user_id}")297 298def get_context_summary(user_id: int) -> str:299    """خلاصه‌ای از context کاربر"""300    context = get_user_context(user_id)301    if not context:302        return "بدون تاریخچه"303    304    total_messages = len(context)305    total_tokens = sum(count_tokens(msg['content']) for msg in context)306    307    # نمایش آخرین پیام308    last_message = context[-1] if context else {}309    last_content = last_message.get('content', '')[:50]310    if len(last_message.get('content', '')) > 50:311        last_content += "..."312    313    return f"{total_messages} پیام ({total_tokens} توکن) - آخرین: {last_message.get('role', '')}: {last_content}"314 315def get_context_for_api(user_id: int) -> list:316    """فرمت context برای ارسال به API"""317    context = get_user_context(user_id)318    319    # اضافه کردن instruction سیستم به ابتدای context320    api_context = [SYSTEM_INSTRUCTION]321    322    # تبدیل پیام‌های کاربر به فرمت مورد نیاز API323    for msg in context:324        api_context.append({325            'role': msg['role'],326            'content': msg['content']327        })328    329    return api_context330 331def get_context_token_count(user_id: int) -> int:332    """تعداد کل توکن‌های context کاربر"""333    context = get_user_context(user_id)334    return sum(count_tokens(msg['content']) for msg in context)335 336# بارگذاری اولیه داده‌ها در زمان ایمپورت شدن ماژول337load_data()