""", unsafe_allow_html=True)
else:
st.markdown("")
# استایلها برای چرخش و پیام در حال فکر کردن
st.markdown("""
""", unsafe_allow_html=True)
import os
import re
import docx
import streamlit as st
import concurrent.futures
from hazm import Normalizer
from rapidfuzz import fuzz
from langchain.schema import SystemMessage, HumanMessage
folder_path = '46'
normalizer = Normalizer()
@st.cache_data(show_spinner="در حال پردازش اسناد... لطفاً صبور باشید.")
def load_and_process_documents(path):
def process_docx(filename):
try:
full_path = os.path.join(path, filename)
doc = docx.Document(full_path)
text = "\n".join([para.text for para in doc.paragraphs])
normalized = normalizer.normalize(text)
return filename, normalized
except Exception as e:
print(f"Error processing {filename}: {e}")
return filename, ""
filenames = [f for f in os.listdir(path) if f.endswith(".docx")]
doc_texts = {}
with concurrent.futures.ThreadPoolExecutor() as executor:
for filename, content in executor.map(process_docx, filenames):
doc_texts[filename] = content
return doc_texts
doc_texts = load_and_process_documents(folder_path)
# لیست کلمات توقف
stop_words = [
"است", "و", "با", "که", "در", "از", "برای", "به", "بر", "تا", "این", "آن", "یک", "کدام", "کجا", "هم", "همه",
"یا", "از", "بر", "همچنین", "می", "باید", "شود", "شد", "گفت", "گویا", "داشت", "داشتن", "کنند", "کنیم",
"کرد", "کردن", "نیز", "یا", "اگر", "ای", "اینکه", "نه", "باشید", "باشم", "باشی", "در حالی که", "مگر", "چرا"
]
# تابعی برای پاکسازی کلمات اضافی از سوال
def remove_stop_words(text, stop_words):
words = text.split()
return " ".join([word for word in words if word not in stop_words])
# تابعی برای استخراج کلمات از متن
def extract_keywords_from_text(text, query_words):
matched_lines = []
lines = text.split("\n")
# جستجو برای هر کلمه در هر خط
for line in lines:
if any(query_word in line for query_word in query_words):
matched_lines.append(line)
return matched_lines
# تابعی برای پاکسازی متن
def clean_text(text):
return re.sub(r'[^آ-ی۰-۹0-9،.؟!؛+\-* ]+', '', text)
# تابعی برای پیدا کردن نزدیکترین خطوط به سوال
def find_closest_lines(query, doc_texts, stop_words, top_n=10):
# حذف کلمات اضافی از سوال
cleaned_query = remove_stop_words(query, stop_words)
query_words = cleaned_query.split()
all_matched_lines = []
# بررسی محتوای فایلها
for filename, text in doc_texts.items():
matched_lines = extract_keywords_from_text(text, query_words)
for line in matched_lines:
similarity = fuzz.partial_ratio(query, line) # محاسبه شباهت خط با سوال
all_matched_lines.append((line, similarity))
# مرتب سازی بر اساس شباهت
all_matched_lines.sort(key=lambda x: x[1], reverse=True)
# انتخاب ۱۰ خط نزدیکتر
closest_lines = [line for line, _ in all_matched_lines[:top_n]]
return closest_lines
# حالا این رو در کد اصلی استفاده میکنیم:
if query:
# پیدا کردن ۱۰ خط نزدیکتر به سوال
closest_lines = find_closest_lines(query, doc_texts, stop_words, top_n=3)
if closest_lines:
prompt = f"""
لطفاً با توجه به سؤال زیر و محتوای خطوط مرتبط، یک پاسخ نهایی حرفهای، دقیق و روان تولید کن. فقط از متن خطوط مرتبط استفاده کن. اگر اطلاعات کافی در متن وجود ندارد، صادقانه اعلام کن.
سوال:
{query}
خطوط مرتبط:
{closest_lines}
پاسخ نهایی:
"""
response = llm([
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt)
])
rewritten = clean_text(response.content.strip())
st.markdown(f'
{rewritten}
', unsafe_allow_html=True)
else:
st.warning("هیچ خط مرتبطی پیدا نشد.")