""", 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)
with open("stopwords.txt", "r", encoding="utf-8") as f:
stop_words = set(line.strip() for line in f if line.strip())
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
from collections import Counter
import heapq
def summarize_text_by_frequency(text, num_sentences=1):
sentences = text.split('\n')
word_freq = Counter()
for sentence in sentences:
for word in sentence.split():
if word not in stop_words:
word_freq[word] += 1
sentence_scores = {}
for sentence in sentences:
for word in sentence.split():
if word in word_freq:
sentence_scores[sentence] = sentence_scores.get(sentence, 0) + word_freq[word]
summarized_sentences = heapq.nlargest(num_sentences, sentence_scores, key=sentence_scores.get)
return "\n".join(summarized_sentences)
def find_closest_lines(query, doc_texts, stop_words, top_n=15):
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
def remove_stop_phrases(text, stop_words):
for phrase in stop_words:
text = text.replace(phrase, "")
return text
if query:
closest_lines = find_closest_lines(query, doc_texts, stop_words, top_n=15)
# حذف استپوردها از خطوط و سپس پاکسازی نهایی متن
cleaned_closest_lines = [
remove_stop_phrases(line, stop_words)
for line in closest_lines
]
summarized_text = summarize_text_by_frequency("\n".join(cleaned_closest_lines), num_sentences=1)
summarized_cleaned = remove_stop_phrases(summarized_text, stop_words)
st.markdown(summarized_text)
if summarized_text:
prompt = f"""
لطفاً با توجه به سؤال زیر و محتوای خطوط مرتبط، یک پاسخ نهایی حرفهای، دقیق و روان تولید کن.
فقط از متن خطوط مرتبط استفاده کن و خلاصه بنویس. اطلاعات اضافی ننویس و فقط به سوال پاسخ بده.
در صورتی که اطلاعات کافی در متن وجود ندارد، صادقانه اعلام کن که اطلاعات کافی برای پاسخدهی موجود نیست.
سوال:
{query}
خطوط مرتبط:
{summarized_text}
پاسخ نهایی:
"""
# ارسال پیام به مدل به صورت صحیح
response = llm([
SystemMessage(content="تو رزم یار ارتش هستی و از کتاب و دیتای موجود به سوالات پاسخ میدی."),
HumanMessage(content=prompt)
])
# فرض بر این است که خروجی مدل به صورت دیکشنری است
rewritten = response.content.strip()
# نمایش نتیجه
st.markdown(f'
{rewritten}
', unsafe_allow_html=True)
else:
st.warning("هیچ خط مرتبطی پیدا نشد.")