import os import csv import json import itertools from flask import Flask, render_template, send_file, request, redirect, url_for # فقط ماژول‌هایی که برای مشاهده درخت و استخراج گراف نیاز هستند وارد می‌شوند # نکته مهم: ماژول Segmenter که مدل‌های سنگین لوکال را لود می‌کرد، کاملاً حذف شده است! from modules.api_handler import APIHandler from modules.data_manager import DataManager from modules.visualizer import Visualizer app = Flask(__name__) # مقداردهی اولیه ماژول‌ها (مدل‌های لوکال در این حالت لود نخواهند شد) api_handler = APIHandler() data_manager = DataManager() visualizer = Visualizer() @app.route('/', methods=['GET']) def index(): """نمایش لیست پروژه‌های قبلی در داشبورد (فقط نمایش)""" projects_dir = data_manager.base_projects_dir projects = [] if os.path.exists(projects_dir): projects = [d for d in os.listdir(projects_dir) if os.path.isdir(os.path.join(projects_dir, d))] projects.sort(reverse=True) # می‌توانیم یک پیام به صفحه index.html پاس بدهیم تا کاربر بداند در حالت فقط-خواندن است # البته نیازمند تغییر جزئی در index.html است، در غیر این صورت فقط پروژه‌ها لود می‌شوند. return render_template('index.html', projects=projects, view_mode=True) @app.route('/new_project', methods=['GET']) def new_project(): """جلوگیری از ایجاد پروژه جدید در حالت View Mode""" return """

شما در حالت فقط نمایش (View Mode) هستید.

در این حالت امکان ایجاد پروژه جدید و تحلیل متن وجود ندارد.

لطفاً برای ایجاد پروژه جدید، فایل اصلی app.py را اجرا کنید.

بازگشت به داشبورد
""" @app.route('/process', methods=['POST']) def process_text(): """مسدود کردن پردازش متن جدید در حالت View Mode""" return redirect(url_for('new_project')) @app.route('/tree/') def show_tree(project_name): """نمایش صفحه وب حاوی درخت سلسله‌مراتبی از پروژه‌های قبلی""" project_path = os.path.join(data_manager.base_projects_dir, project_name) tree_html_path = os.path.join(project_path, "tree_visualization.html") # بررسی وجود فایل درخت if not os.path.exists(tree_html_path): return f"فایل درخت برای پروژه '{project_name}' یافت نشد.", 404 return render_template('tree_view.html', project_name=project_name) @app.route('/tree_iframe/') def tree_iframe(project_name): """سرو کردن فایل HTML درخت برای نمایش در iframe""" project_path = os.path.join(data_manager.base_projects_dir, project_name) tree_html_path = os.path.join(project_path, "tree_visualization.html") return send_file(tree_html_path) @app.route('/graph//') def generate_and_show_graph(project_name, node_id): """ساخت گراف On-Demand در زمان کلیک روی نود (یا نمایش در صورت وجود از قبل)""" project_path = os.path.join(data_manager.base_projects_dir, project_name) graph_dir = os.path.join(project_path, f"{node_id}_graph") graph_html_path = os.path.join(graph_dir, "graph.html") # اگر گراف قبلاً ساخته شده بود، بلافاصله آن را نمایش بده (بدون نیاز به API) if os.path.exists(graph_html_path): return render_template('graph_view.html', project_name=project_name, node_id=node_id) # اگر گراف ساخته نشده بود، جملات نود را از CSV بخوان و با استفاده از API گراف را بساز node_sentences = [] tree_csv = os.path.join(project_path, "tree_data.csv") if not os.path.exists(tree_csv): return "فایل دیتای درخت (tree_data.csv) یافت نشد.", 404 with open(tree_csv, mode='r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: if row["segment_id"] == node_id: node_sentences = json.loads(row["original_sentences"]) break if not node_sentences: return "خطا: دیتای مربوط به این نود در فایل یافت نشد.", 404 # ۱. استخراج گزاره‌ها از API raw_props = api_handler.extract_propositions(node_sentences) propositions = [ {"proposition_id": i + 1, "sentence": " ".join(node_sentences), "proposition_text": p} for i, p in enumerate(raw_props) ] # ۲. بررسی تمام روابط دو به دو بین گزاره‌ها relations = [] scores = [] rel_id_counter = 1 for p1, p2 in itertools.combinations(propositions, 2): rel_desc = api_handler.check_relation(p1["proposition_text"], p2["proposition_text"]) if rel_desc and "ارتباط وجود ندارد" not in rel_desc: score = api_handler.score_relation(rel_desc) if score > 0: relations.append({ "relation_id": rel_id_counter, "source_proposition_id": p1["proposition_id"], "target_proposition_id": p2["proposition_id"], "relation_type": rel_desc }) scores.append({ "relation_id": rel_id_counter, "score": score }) rel_id_counter += 1 # ۳. ذخیره و رسم گراف data_manager.save_graph_data(project_path, node_id, propositions, relations, scores) visualizer.build_graph(propositions, relations, scores, graph_html_path) return render_template('graph_view.html', project_name=project_name, node_id=node_id) @app.route('/graph_iframe//') def graph_iframe(project_name, node_id): """سرو کردن فایل HTML گراف برای نمایش در iframe""" project_path = os.path.join(data_manager.base_projects_dir, project_name) graph_html_path = os.path.join(project_path, f"{node_id}_graph", "graph.html") if not os.path.exists(graph_html_path): return "فایل گراف یافت نشد.", 404 return send_file(graph_html_path) if __name__ == '__main__': # این اسکریپت را می‌توانید روی پورت دیگری (مثلاً 5001) اجرا کنید # تا بتوانید همزمان هم app.py اصلی و هم حالت View را در مرورگر باز داشته باشید. print("\n" + "=" * 50) print("🚀 در حال اجرای برنامه در حالت VIEW MODE (بدون مدل‌های لوکال)") print("=" * 50 + "\n") app.run(debug=True, port=5001)