teoo33 commited on
Commit
39c829b
·
verified ·
1 Parent(s): 5d690f6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -29
app.py CHANGED
@@ -89,31 +89,47 @@ def create_vector_db(docs):
89
  logger.error(f"خطا در ایجاد پایگاه داده وکتوری: {str(e)}")
90
  return None, f"خطا در پردازش وکتوری: {str(e)}"
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  def check_plagiarism(text):
93
  try:
94
- query = text[:100]
95
- # جستجوی گوگل فارسی
96
- url_fa = f"https://www.google.com/search?q={query}&hl=fa"
97
- response_fa = requests.get(url_fa, headers={"User-Agent": "Mozilla/5.0"})
98
- soup_fa = BeautifulSoup(response_fa.text, 'html.parser')
99
- results_fa = [h.get_text() for h in soup_fa.find_all('h3')[:5]]
100
- logger.info(f"نتایج گوگل فارسی: {results_fa}")
 
 
 
101
 
102
- # جستجو در SID.ir
103
- url_sid = f"https://www.sid.ir/Fa/Journal/SearchPaper.aspx?str={query}"
104
- response_sid = requests.get(url_sid, headers={"User-Agent": "Mozilla/5.0"})
105
- soup_sid = BeautifulSoup(response_sid.text, 'html.parser')
106
- results_sid = [item.get_text() for item in soup_sid.select('.title')[:5]]
107
- logger.info(f"نتایج SID.ir: {results_sid}")
108
 
109
- all_results = results_fa + results_sid
110
  if not all_results:
111
  return "درصد تشابه: 0.00%\n**متن‌های مشابه:** هیچ نتیجه‌ای یافت نشد."
112
 
113
  max_similarity = 0
114
  matched_texts = []
115
  for result in all_results:
116
- similarity = SequenceMatcher(None, text[:500], result).ratio()
117
  if similarity > max_similarity:
118
  max_similarity = similarity
119
  matched_texts = [result]
@@ -130,18 +146,19 @@ def check_plagiarism(text):
130
 
131
  def suggest_resources(text):
132
  try:
133
- query = " ".join(text.split()[:5])
134
- url_sid = f"https://www.sid.ir/Fa/Journal/SearchPaper.aspx?str={query}"
135
- response_sid = requests.get(url_sid, headers={"User-Agent": "Mozilla/5.0"})
136
- soup_sid = BeautifulSoup(response_sid.text, 'html.parser')
137
- papers_sid = [item.get_text().strip() for item in soup_sid.select('.title')[:3]]
 
138
 
139
  url_arxiv = f"https://arxiv.org/search/?query={query}&searchtype=all&source=header"
140
  response_arxiv = requests.get(url_arxiv, headers={"User-Agent": "Mozilla/5.0"})
141
  soup_arxiv = BeautifulSoup(response_arxiv.text, 'html.parser')
142
  papers_arxiv = [paper.get_text().strip() for paper in soup_arxiv.find_all('p', class_='title')[:2]]
143
 
144
- resources = papers_sid + papers_arxiv if papers_sid else papers_arxiv
145
  time.sleep(1)
146
  return resources if resources else ["منبعی یافت نشد."]
147
  except Exception as e:
@@ -152,8 +169,9 @@ def evaluate_quality(docs, sections):
152
  text = " ".join([doc.page_content for doc in docs])
153
  score = 0
154
  explanation = []
 
155
 
156
- # معیار 1: وجود و کیفیت منابع
157
  ref_count = len(re.findall(r"\[\d+\]|[A-Za-z]+\s+\d{4}", text))
158
  if ref_count > 10:
159
  score += 35
@@ -161,8 +179,10 @@ def evaluate_quality(docs, sections):
161
  elif ref_count > 0:
162
  score += 20
163
  explanation.append("منابع موجود اما محدود (کمتر از 10 ارجاع).")
 
164
  else:
165
  explanation.append("منابع کافی یافت نشد.")
 
166
 
167
  # معیار 2: انسجام متن
168
  words = text.split()
@@ -172,13 +192,15 @@ def evaluate_quality(docs, sections):
172
  explanation.append("انسجام متنی خوب (تمرکز بر موضوع اصلی).")
173
  else:
174
  explanation.append("انسجام متنی ضعیف (پراکندگی موضوعی).")
 
175
 
176
- # معیار 3: استفاده از جداول/شکل‌ها
177
  if re.search(r"جدول|شکل|Table|Figure", text, re.I):
178
  score += 20
179
  explanation.append("استفاده از جداول یا شکل‌ها برای پشتیبانی یافته‌ها.")
180
  else:
181
  explanation.append("عدم استفاده از جداول یا شکل‌ها.")
 
182
 
183
  # معیار 4: عمق تحلیل
184
  analysis_text = " ".join([doc.page_content for doc in sections.get("نتایج", []) + sections.get("بحث", [])])
@@ -187,9 +209,16 @@ def evaluate_quality(docs, sections):
187
  explanation.append("عمق تحلیل قابل قبول (بخش نتایج/بحث طولانی).")
188
  else:
189
  explanation.append("عمق تحلیل محدود (بخش نتایج/بحث کوتاه).")
 
 
 
 
 
 
 
190
 
191
  score = max(min(score, 100), 10)
192
- return score, "; ".join(explanation)
193
 
194
  llm_gemini = ChatGoogleGenerativeAI(model="gemini-pro", google_api_key=gemini_api_key, convert_system_message_to_human=True, temperature=0.5)
195
 
@@ -225,7 +254,7 @@ general_qa_prompt = PromptTemplate(
225
  )
226
 
227
  plagiarism_prompt = PromptTemplate(
228
- template="""درصد تشابه متن زیر با منابع عمومی و فارسی را گزارش دهید:
229
  **متن:**
230
  {context}
231
  **نتیجه:** {similarity}""",
@@ -237,8 +266,9 @@ quality_prompt = PromptTemplate(
237
  **متن:**
238
  {context}
239
  **امتیاز:** {score}/100
240
- **توضیحات:** {explanation}""",
241
- input_variables=["context", "score", "explanation"]
 
242
  )
243
 
244
  def create_conversation_chain(vector_store, docs, mode, language, detail_level, section=None):
@@ -301,9 +331,9 @@ def academic_chatbot(pdf_file, mode, query, language, detail_level, section_drop
301
  result = plagiarism_result
302
  elif mode == "ارزیابی کیفیت":
303
  context = " ".join([doc.page_content for doc in docs if section_dropdown == "کل سند" or doc in sections.get(section_dropdown, [])])
304
- score, explanation = evaluate_quality(docs, sections) # پاس دادن sections
305
  time.sleep(2)
306
- result = chain.invoke({"context": context[:5000], "score": score, "explanation": explanation})["text"]
307
  else:
308
  result = chain.invoke({"question": query, "chat_history": []})["answer"]
309
 
 
89
  logger.error(f"خطا در ایجاد پایگاه داده وکتوری: {str(e)}")
90
  return None, f"خطا در پردازش وکتوری: {str(e)}"
91
 
92
+ def translate_to_english(text):
93
+ try:
94
+ prompt = f"متن زیر را به انگلیسی ترجمه کنید:\n**متن:**\n{text[:1000]}\n**ترجمه:**"
95
+ model = genai.GenerativeModel('gemini-pro')
96
+ response = model.generate_content(prompt)
97
+ translated_text = response.text.split("**ترجمه:**")[-1].strip()
98
+ logger.info(f"متن ترجمه‌شده: {translated_text[:50]}...")
99
+ time.sleep(1)
100
+ return translated_text
101
+ except Exception as e:
102
+ logger.error(f"خطا در ترجمه: {str(e)}")
103
+ return text # در صورت خطا، متن اصلی رو برگردون
104
+
105
  def check_plagiarism(text):
106
  try:
107
+ # ترجمه به انگلیسی
108
+ translated_text = translate_to_english(text)
109
+ query = translated_text[:100]
110
+
111
+ # جستجو در Google Scholar
112
+ url_scholar = f"https://scholar.google.com/scholar?q={query}"
113
+ response_scholar = requests.get(url_scholar, headers={"User-Agent": "Mozilla/5.0"})
114
+ soup_scholar = BeautifulSoup(response_scholar.text, 'html.parser')
115
+ results_scholar = [h.get_text() for h in soup_scholar.find_all('h3')[:5]]
116
+ logger.info(f"نتایج Google Scholar: {results_scholar}")
117
 
118
+ # جستجو در arXiv
119
+ url_arxiv = f"https://arxiv.org/search/?query={query}&searchtype=all&source=header"
120
+ response_arxiv = requests.get(url_arxiv, headers={"User-Agent": "Mozilla/5.0"})
121
+ soup_arxiv = BeautifulSoup(response_arxiv.text, 'html.parser')
122
+ results_arxiv = [paper.get_text() for paper in soup_arxiv.find_all('p', class_='title')[:5]]
123
+ logger.info(f"نتایج arXiv: {results_arxiv}")
124
 
125
+ all_results = results_scholar + results_arxiv
126
  if not all_results:
127
  return "درصد تشابه: 0.00%\n**متن‌های مشابه:** هیچ نتیجه‌ای یافت نشد."
128
 
129
  max_similarity = 0
130
  matched_texts = []
131
  for result in all_results:
132
+ similarity = SequenceMatcher(None, translated_text[:500], result).ratio()
133
  if similarity > max_similarity:
134
  max_similarity = similarity
135
  matched_texts = [result]
 
146
 
147
  def suggest_resources(text):
148
  try:
149
+ translated_text = translate_to_english(text)
150
+ query = " ".join(translated_text.split()[:5])
151
+ url_scholar = f"https://scholar.google.com/scholar?q={query}"
152
+ response_scholar = requests.get(url_scholar, headers={"User-Agent": "Mozilla/5.0"})
153
+ soup_scholar = BeautifulSoup(response_scholar.text, 'html.parser')
154
+ papers_scholar = [h.get_text().strip() for h in soup_scholar.find_all('h3')[:3]]
155
 
156
  url_arxiv = f"https://arxiv.org/search/?query={query}&searchtype=all&source=header"
157
  response_arxiv = requests.get(url_arxiv, headers={"User-Agent": "Mozilla/5.0"})
158
  soup_arxiv = BeautifulSoup(response_arxiv.text, 'html.parser')
159
  papers_arxiv = [paper.get_text().strip() for paper in soup_arxiv.find_all('p', class_='title')[:2]]
160
 
161
+ resources = papers_scholar + papers_arxiv if papers_scholar else papers_arxiv
162
  time.sleep(1)
163
  return resources if resources else ["منبعی یافت نشد."]
164
  except Exception as e:
 
169
  text = " ".join([doc.page_content for doc in docs])
170
  score = 0
171
  explanation = []
172
+ suggestions = []
173
 
174
+ # معیار 1: منابع
175
  ref_count = len(re.findall(r"\[\d+\]|[A-Za-z]+\s+\d{4}", text))
176
  if ref_count > 10:
177
  score += 35
 
179
  elif ref_count > 0:
180
  score += 20
181
  explanation.append("منابع موجود اما محدود (کمتر از 10 ارجاع).")
182
+ suggestions.append("حداقل 5 منبع معتبر و مرتبط با موضوع اضافه کنید.")
183
  else:
184
  explanation.append("منابع کافی یافت نشد.")
185
+ suggestions.append("بخش منابع را با حداقل 10 ارجاع معتبر تکمیل کنید.")
186
 
187
  # معیار 2: انسجام متن
188
  words = text.split()
 
192
  explanation.append("انسجام متنی خوب (تمرکز بر موضوع اصلی).")
193
  else:
194
  explanation.append("انسجام متنی ضعیف (پراکندگی موضوعی).")
195
+ suggestions.append(f"کلمات کلیدی مرتبط با موضوع (مثل {word_freq[0][0] if word_freq else 'موضوع'}) را بیشتر به کار ببرید.")
196
 
197
+ # معیار 3: جداول/شکل‌ها
198
  if re.search(r"جدول|شکل|Table|Figure", text, re.I):
199
  score += 20
200
  explanation.append("استفاده از جداول یا شکل‌ها برای پشتیبانی یافته‌ها.")
201
  else:
202
  explanation.append("عدم استفاده از جداول یا شکل‌ها.")
203
+ suggestions.append("حداقل یک جدول یا شکل برای نمایش داده‌ها اضافه کنید.")
204
 
205
  # معیار 4: عمق تحلیل
206
  analysis_text = " ".join([doc.page_content for doc in sections.get("نتایج", []) + sections.get("بحث", [])])
 
209
  explanation.append("عمق تحلیل قابل قبول (بخش نتایج/بحث طولانی).")
210
  else:
211
  explanation.append("عمق تحلیل محدود (بخش نتایج/بحث کوتاه).")
212
+ suggestions.append("بخش نتایج و بحث را با جزئیات بیشتر (حداقل 1000 کلمه) گسترش دهید.")
213
+
214
+ # اصلاح خودکار ساده: اضافه کردن کلمات کلیدی به متن
215
+ auto_fix = ""
216
+ if "انسجام متنی ضعیف" in "; ".join(explanation):
217
+ keywords = [word[0] for word in word_freq[:3]] if word_freq else ["تحقیق", "نتایج", "روش"]
218
+ auto_fix = f"\n\n**اصلاح خودکار - کلمات کلیدی پیشنهادی:**\nدر متن از کلمات کلیدی زیر بیشتر استفاده شده است: {', '.join(keywords)}."
219
 
220
  score = max(min(score, 100), 10)
221
+ return score, "; ".join(explanation), "; ".join(suggestions), auto_fix
222
 
223
  llm_gemini = ChatGoogleGenerativeAI(model="gemini-pro", google_api_key=gemini_api_key, convert_system_message_to_human=True, temperature=0.5)
224
 
 
254
  )
255
 
256
  plagiarism_prompt = PromptTemplate(
257
+ template="""درصد تشابه متن زیر با منابع انگلیسی را گزارش دهید:
258
  **متن:**
259
  {context}
260
  **نتیجه:** {similarity}""",
 
266
  **متن:**
267
  {context}
268
  **امتیاز:** {score}/100
269
+ **توضیحات:** {explanation}
270
+ **پیشنهادات بهبود:** {suggestions}""",
271
+ input_variables=["context", "score", "explanation", "suggestions"]
272
  )
273
 
274
  def create_conversation_chain(vector_store, docs, mode, language, detail_level, section=None):
 
331
  result = plagiarism_result
332
  elif mode == "ارزیابی کیفیت":
333
  context = " ".join([doc.page_content for doc in docs if section_dropdown == "کل سند" or doc in sections.get(section_dropdown, [])])
334
+ score, explanation, suggestions, auto_fix = evaluate_quality(docs, sections)
335
  time.sleep(2)
336
+ result = chain.invoke({"context": context[:5000], "score": score, "explanation": explanation, "suggestions": suggestions})["text"] + auto_fix
337
  else:
338
  result = chain.invoke({"question": query, "chat_history": []})["answer"]
339