|
|
|
|
|
""" |
|
|
استخراج منابع استفاده نشده و ایجاد سیستم fallback سلسلهمراتبی |
|
|
Extract unused resources and create hierarchical fallback system |
|
|
""" |
|
|
|
|
|
import json |
|
|
import os |
|
|
import time |
|
|
from datetime import datetime |
|
|
from pathlib import Path |
|
|
from typing import Dict, List, Set |
|
|
|
|
|
def load_json_resources(): |
|
|
"""بارگذاری فایلهای JSON منابع""" |
|
|
base_path = Path(__file__).parent.parent / "api-resources" |
|
|
|
|
|
with open(base_path / "crypto_resources_unified_2025-11-11.json", 'r') as f: |
|
|
unified_resources = json.load(f) |
|
|
|
|
|
|
|
|
with open(base_path / "ultimate_crypto_pipeline_2025_NZasinich.json", 'r') as f: |
|
|
lines = f.readlines() |
|
|
|
|
|
json_content = ''.join(lines[1:]) |
|
|
ultimate_resources = json.loads(json_content) |
|
|
|
|
|
return unified_resources, ultimate_resources |
|
|
|
|
|
def extract_all_resources(unified_data): |
|
|
"""استخراج تمام منابع از فایل unified""" |
|
|
registry = unified_data['registry'] |
|
|
|
|
|
all_resources = { |
|
|
'rpc_nodes': registry.get('rpc_nodes', []), |
|
|
'block_explorers': registry.get('block_explorers', []), |
|
|
'market_data_apis': registry.get('market_data_apis', []), |
|
|
'news_apis': registry.get('news_apis', []), |
|
|
'sentiment_apis': registry.get('sentiment_apis', []), |
|
|
'onchain_analytics_apis': registry.get('onchain_analytics_apis', []), |
|
|
'whale_tracking_apis': registry.get('whale_tracking_apis', []), |
|
|
'hf_resources': registry.get('hf_resources', []), |
|
|
'cors_proxies': registry.get('cors_proxies', []), |
|
|
} |
|
|
|
|
|
return all_resources |
|
|
|
|
|
def extract_used_resources_from_project(): |
|
|
"""استخراج منابع استفاده شده در پروژه""" |
|
|
used_urls = set() |
|
|
used_names = set() |
|
|
used_models = set() |
|
|
|
|
|
|
|
|
files_to_check = [ |
|
|
'backend/services/hierarchical_fallback_config.py', |
|
|
'ai_models.py', |
|
|
'collectors/market_data.py', |
|
|
'collectors/news.py', |
|
|
'collectors/sentiment.py', |
|
|
] |
|
|
|
|
|
for file_path in files_to_check: |
|
|
if os.path.exists(file_path): |
|
|
with open(file_path, 'r') as f: |
|
|
content = f.read() |
|
|
|
|
|
|
|
|
if 'api.coingecko.com' in content: |
|
|
used_names.add('CoinGecko') |
|
|
if 'api.binance.com' in content: |
|
|
used_names.add('Binance') |
|
|
if 'pro-api.coinmarketcap.com' in content: |
|
|
used_names.add('CoinMarketCap') |
|
|
if 'api.etherscan.io' in content: |
|
|
used_names.add('Etherscan') |
|
|
if 'api.bscscan.com' in content: |
|
|
used_names.add('BscScan') |
|
|
if 'tronscan' in content.lower(): |
|
|
used_names.add('TronScan') |
|
|
if 'alternative.me' in content: |
|
|
used_names.add('Alternative.me') |
|
|
if 'cryptopanic' in content.lower(): |
|
|
used_names.add('CryptoPanic') |
|
|
|
|
|
|
|
|
if 'cardiffnlp' in content: |
|
|
used_models.add('cardiffnlp/twitter-roberta-base-sentiment-latest') |
|
|
if 'ProsusAI/finbert' in content: |
|
|
used_models.add('ProsusAI/finbert') |
|
|
if 'ElKulako/cryptobert' in content: |
|
|
used_models.add('ElKulako/cryptobert') |
|
|
|
|
|
return { |
|
|
'urls': used_urls, |
|
|
'names': used_names, |
|
|
'models': used_models |
|
|
} |
|
|
|
|
|
def categorize_unused_resources(all_resources, used_data): |
|
|
"""دستهبندی منابع استفاده نشده""" |
|
|
unused = {} |
|
|
|
|
|
for category, resources in all_resources.items(): |
|
|
unused[category] = [] |
|
|
|
|
|
for resource in resources: |
|
|
name = resource.get('name', '') |
|
|
base_url = resource.get('base_url', '') |
|
|
|
|
|
|
|
|
is_used = False |
|
|
for used_name in used_data['names']: |
|
|
if used_name.lower() in name.lower(): |
|
|
is_used = True |
|
|
break |
|
|
|
|
|
if not is_used: |
|
|
unused[category].append(resource) |
|
|
|
|
|
return unused |
|
|
|
|
|
def main(): |
|
|
"""تابع اصلی""" |
|
|
print("=" * 80) |
|
|
print("🔍 استخراج منابع استفاده نشده") |
|
|
print("=" * 80) |
|
|
print() |
|
|
|
|
|
|
|
|
print("📥 بارگذاری فایلهای JSON...") |
|
|
unified_data, ultimate_data = load_json_resources() |
|
|
|
|
|
|
|
|
print("📊 استخراج تمام منابع...") |
|
|
all_resources = extract_all_resources(unified_data) |
|
|
|
|
|
|
|
|
print("🔎 بررسی منابع استفاده شده در پروژه...") |
|
|
used_data = extract_used_resources_from_project() |
|
|
|
|
|
print(f"\n✅ منابع استفاده شده:") |
|
|
print(f" - Names: {len(used_data['names'])}") |
|
|
print(f" - Models: {len(used_data['models'])}") |
|
|
|
|
|
for name in sorted(used_data['names']): |
|
|
print(f" ✓ {name}") |
|
|
|
|
|
|
|
|
print("\n🔍 دستهبندی منابع استفاده نشده...") |
|
|
unused_resources = categorize_unused_resources(all_resources, used_data) |
|
|
|
|
|
|
|
|
print("\n📊 خلاصه منابع استفاده نشده:\n") |
|
|
|
|
|
total_unused = 0 |
|
|
for category, resources in unused_resources.items(): |
|
|
if resources: |
|
|
print(f" {category}: {len(resources)} منبع") |
|
|
total_unused += len(resources) |
|
|
|
|
|
print(f"\n 📈 جمع کل: {total_unused} منبع استفاده نشده") |
|
|
|
|
|
|
|
|
output_path = Path(__file__).parent.parent / "data" / "unused_resources.json" |
|
|
output_path.parent.mkdir(parents=True, exist_ok=True) |
|
|
|
|
|
output_data = { |
|
|
'summary': { |
|
|
'total_unused': total_unused, |
|
|
'used_services': list(used_data['names']), |
|
|
'used_models': list(used_data['models']), |
|
|
'categories': {k: len(v) for k, v in unused_resources.items() if v} |
|
|
}, |
|
|
'unused_by_category': unused_resources, |
|
|
'all_resources_count': sum(len(v) for v in all_resources.values()) |
|
|
} |
|
|
|
|
|
with open(output_path, 'w') as f: |
|
|
json.dump(output_data, f, indent=2) |
|
|
|
|
|
print(f"\n💾 نتایج ذخیره شد در: {output_path}") |
|
|
|
|
|
|
|
|
report_path = Path(__file__).parent.parent / "UNUSED_RESOURCES_REPORT.md" |
|
|
create_report(output_data, report_path, all_resources) |
|
|
|
|
|
print(f"📄 گزارش کامل: {report_path}") |
|
|
print("\n✅ اتمام!") |
|
|
|
|
|
def create_report(data, report_path, all_resources): |
|
|
"""ایجاد گزارش Markdown""" |
|
|
with open(report_path, 'w') as f: |
|
|
f.write("# 📊 گزارش منابع استفاده نشده\n\n") |
|
|
f.write(f"**تاریخ:** {time.strftime('%Y-%m-%d')}\n\n") |
|
|
|
|
|
f.write("## 📋 خلاصه\n\n") |
|
|
f.write(f"- **منابع کل:** {data['all_resources_count']}\n") |
|
|
f.write(f"- **استفاده شده:** {len(data['summary']['used_services'])} سرویس + {len(data['summary']['used_models'])} مدل\n") |
|
|
f.write(f"- **استفاده نشده:** {data['summary']['total_unused']}\n\n") |
|
|
|
|
|
f.write("## ✅ منابع استفاده شده\n\n") |
|
|
for name in sorted(data['summary']['used_services']): |
|
|
f.write(f"- ✓ {name}\n") |
|
|
|
|
|
f.write("\n## 🤖 مدلهای استفاده شده\n\n") |
|
|
for model in sorted(data['summary']['used_models']): |
|
|
f.write(f"- ✓ {model}\n") |
|
|
|
|
|
f.write("\n## 📊 منابع استفاده نشده به تفکیک دسته\n\n") |
|
|
|
|
|
for category, count in data['summary']['categories'].items(): |
|
|
if count > 0: |
|
|
f.write(f"\n### {category} ({count} منبع)\n\n") |
|
|
|
|
|
resources = data['unused_by_category'].get(category, []) |
|
|
for resource in resources[:10]: |
|
|
name = resource.get('name', 'Unknown') |
|
|
url = resource.get('base_url', '') |
|
|
free = resource.get('auth', {}).get('type', 'none') |
|
|
f.write(f"- **{name}**\n") |
|
|
f.write(f" - URL: `{url}`\n") |
|
|
f.write(f" - Auth: {free}\n") |
|
|
|
|
|
if len(resources) > 10: |
|
|
f.write(f"\n*... و {len(resources) - 10} منبع دیگر*\n") |
|
|
|
|
|
f.write("\n## 💡 توصیهها\n\n") |
|
|
f.write("1. اضافه کردن منابع رایگان به سیستم fallback\n") |
|
|
f.write("2. تست و validation منابع جدید\n") |
|
|
f.write("3. اولویتبندی براساس rate limit و قابلیت اعتماد\n") |
|
|
f.write("4. استفاده از CORS proxies برای منابع محدود\n") |
|
|
|
|
|
if __name__ == '__main__': |
|
|
main() |
|
|
|