Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -216,7 +216,7 @@ st.markdown(f"""
|
|
| 216 |
</style>
|
| 217 |
""", unsafe_allow_html=True)
|
| 218 |
|
| 219 |
-
# --- 3. FUNCTIONS
|
| 220 |
|
| 221 |
def clean_isbn(isbn_str):
|
| 222 |
"""تنظيف وتصحيح ISBN"""
|
|
@@ -265,9 +265,10 @@ def search_web_context(isbn, title=None):
|
|
| 265 |
|
| 266 |
def enhanced_ai_librarian_analysis(isbn, meta_data, web_context):
|
| 267 |
"""تحليل محسن مع دقة عالية"""
|
|
|
|
| 268 |
if not client or not USE_AI:
|
| 269 |
st.info(languages.get_text("local_classification_mode", lang))
|
| 270 |
-
return fallback_local_classification(isbn, meta_data, web_context)
|
| 271 |
|
| 272 |
metadata_fetcher = EnhancedMetadataFetcher()
|
| 273 |
enhanced_meta = metadata_fetcher.fetch_metadata(isbn)
|
|
@@ -400,13 +401,13 @@ CRITICAL: The NLM classification must be accurate and specific to the main subje
|
|
| 400 |
st.warning(languages.get_text("ai_payment_warning", lang))
|
| 401 |
else:
|
| 402 |
st.error(languages.get_text("ai_unexpected_error", lang).format(e))
|
| 403 |
-
return fallback_local_classification(isbn, enhanced_meta, web_context)
|
| 404 |
except Exception as e:
|
| 405 |
st.error(languages.get_text("ai_unexpected_error", lang).format(str(e)))
|
| 406 |
-
return fallback_local_classification(isbn, enhanced_meta, web_context)
|
| 407 |
|
| 408 |
-
def fallback_local_classification(isbn, enhanced_meta, web_context):
|
| 409 |
-
"""تصنيف محلي متقدم مع بيانات افتراضية ذكية"""
|
| 410 |
nlm_classifier = AdvancedNLMClassifier()
|
| 411 |
nlm_result = nlm_classifier.classify_with_confidence(
|
| 412 |
enhanced_meta.get('title', ''),
|
|
@@ -420,7 +421,7 @@ def fallback_local_classification(isbn, enhanced_meta, web_context):
|
|
| 420 |
publisher = enhanced_meta.get('publisher', 'Unknown')
|
| 421 |
pub_year = enhanced_meta.get('published_date', '')
|
| 422 |
|
| 423 |
-
# توليد ملخص ذكي
|
| 424 |
if description and len(description) > 20:
|
| 425 |
summary = description[:500] + ('...' if len(description) > 500 else '')
|
| 426 |
else:
|
|
@@ -429,7 +430,7 @@ def fallback_local_classification(isbn, enhanced_meta, web_context):
|
|
| 429 |
f"Published by {publisher} in {pub_year if pub_year else 'unknown year'}. " \
|
| 430 |
f"The work covers key concepts in {nlm_result['nlm_description'].lower() if nlm_result['nlm_description'] else 'medicine'}."
|
| 431 |
|
| 432 |
-
# توليد محتويات افتراضية بناءً على التصنيف
|
| 433 |
main_topic = nlm_result.get('nlm_name', 'Medicine')
|
| 434 |
contents_templates = {
|
| 435 |
'Textbook': [
|
|
@@ -497,21 +498,72 @@ def fallback_local_classification(isbn, enhanced_meta, web_context):
|
|
| 497 |
"8. Review and self-assessment"
|
| 498 |
]
|
| 499 |
|
| 500 |
-
# توليد موضوعات MeSH
|
| 501 |
mesh_mapping = {
|
| 502 |
-
'W 18': [
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
'
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
'
|
| 513 |
-
|
| 514 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 515 |
}
|
| 516 |
|
| 517 |
nlm_code = nlm_result['nlm_code']
|
|
@@ -521,32 +573,37 @@ def fallback_local_classification(isbn, enhanced_meta, web_context):
|
|
| 521 |
mesh_subjects = subjects
|
| 522 |
break
|
| 523 |
if not mesh_subjects:
|
| 524 |
-
mesh_subjects = [
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
|
| 526 |
-
# تحديد الجمهور المستهدف
|
| 527 |
-
audience_category = "Medical Students and Healthcare Professionals"
|
| 528 |
-
audience_reason = "Based on medical content and typical audience for this subject area."
|
| 529 |
if 'Textbook' in nlm_result.get('nlm_name', ''):
|
| 530 |
-
audience_category = "
|
| 531 |
-
audience_reason =
|
| 532 |
elif 'Education' in nlm_result.get('nlm_name', ''):
|
| 533 |
-
audience_category = "
|
| 534 |
-
audience_reason =
|
| 535 |
elif 'Surgery' in nlm_result.get('nlm_name', ''):
|
| 536 |
-
audience_category = "
|
| 537 |
-
audience_reason =
|
|
|
|
|
|
|
|
|
|
| 538 |
|
| 539 |
-
# قرار الشراء
|
| 540 |
score = nlm_result['confidence_score']
|
| 541 |
if score >= 8:
|
| 542 |
-
acquisition_decision = "
|
| 543 |
-
acquisition_reason =
|
| 544 |
elif score >= 4:
|
| 545 |
-
acquisition_decision = "
|
| 546 |
-
acquisition_reason =
|
| 547 |
else:
|
| 548 |
-
acquisition_decision = "
|
| 549 |
-
acquisition_reason =
|
| 550 |
|
| 551 |
return {
|
| 552 |
'title': title,
|
|
@@ -738,10 +795,12 @@ if st.session_state.analysis_data:
|
|
| 738 |
if isbns:
|
| 739 |
st.markdown(f"**📋 Identifiers:** {' | '.join(isbns)}")
|
| 740 |
st.markdown("---")
|
| 741 |
-
decision = ai.get('acquisition_decision',
|
| 742 |
-
if "
|
| 743 |
pill_class = "status-high"
|
| 744 |
-
elif "
|
|
|
|
|
|
|
| 745 |
pill_class = "status-low"
|
| 746 |
else:
|
| 747 |
pill_class = "status-medium"
|
|
|
|
| 216 |
</style>
|
| 217 |
""", unsafe_allow_html=True)
|
| 218 |
|
| 219 |
+
# --- 3. FUNCTIONS ---
|
| 220 |
|
| 221 |
def clean_isbn(isbn_str):
|
| 222 |
"""تنظيف وتصحيح ISBN"""
|
|
|
|
| 265 |
|
| 266 |
def enhanced_ai_librarian_analysis(isbn, meta_data, web_context):
|
| 267 |
"""تحليل محسن مع دقة عالية"""
|
| 268 |
+
lang = st.session_state.language # استخدام اللغة الحالية
|
| 269 |
if not client or not USE_AI:
|
| 270 |
st.info(languages.get_text("local_classification_mode", lang))
|
| 271 |
+
return fallback_local_classification(isbn, meta_data, web_context, lang)
|
| 272 |
|
| 273 |
metadata_fetcher = EnhancedMetadataFetcher()
|
| 274 |
enhanced_meta = metadata_fetcher.fetch_metadata(isbn)
|
|
|
|
| 401 |
st.warning(languages.get_text("ai_payment_warning", lang))
|
| 402 |
else:
|
| 403 |
st.error(languages.get_text("ai_unexpected_error", lang).format(e))
|
| 404 |
+
return fallback_local_classification(isbn, enhanced_meta, web_context, lang)
|
| 405 |
except Exception as e:
|
| 406 |
st.error(languages.get_text("ai_unexpected_error", lang).format(str(e)))
|
| 407 |
+
return fallback_local_classification(isbn, enhanced_meta, web_context, lang)
|
| 408 |
|
| 409 |
+
def fallback_local_classification(isbn, enhanced_meta, web_context, lang='en'):
|
| 410 |
+
"""تصنيف محلي متقدم مع بيانات افتراضية ذكية وقابلية للترجمة"""
|
| 411 |
nlm_classifier = AdvancedNLMClassifier()
|
| 412 |
nlm_result = nlm_classifier.classify_with_confidence(
|
| 413 |
enhanced_meta.get('title', ''),
|
|
|
|
| 421 |
publisher = enhanced_meta.get('publisher', 'Unknown')
|
| 422 |
pub_year = enhanced_meta.get('published_date', '')
|
| 423 |
|
| 424 |
+
# توليد ملخص ذكي (يبقى بالإنجليزية)
|
| 425 |
if description and len(description) > 20:
|
| 426 |
summary = description[:500] + ('...' if len(description) > 500 else '')
|
| 427 |
else:
|
|
|
|
| 430 |
f"Published by {publisher} in {pub_year if pub_year else 'unknown year'}. " \
|
| 431 |
f"The work covers key concepts in {nlm_result['nlm_description'].lower() if nlm_result['nlm_description'] else 'medicine'}."
|
| 432 |
|
| 433 |
+
# توليد محتويات افتراضية بناءً على التصنيف (تبقى بالإنجليزية)
|
| 434 |
main_topic = nlm_result.get('nlm_name', 'Medicine')
|
| 435 |
contents_templates = {
|
| 436 |
'Textbook': [
|
|
|
|
| 498 |
"8. Review and self-assessment"
|
| 499 |
]
|
| 500 |
|
| 501 |
+
# توليد موضوعات MeSH مع ترجمة إذا وجدت
|
| 502 |
mesh_mapping = {
|
| 503 |
+
'W 18': [
|
| 504 |
+
languages.get_text("mesh_education_medical", lang),
|
| 505 |
+
languages.get_text("mesh_textbooks", lang),
|
| 506 |
+
languages.get_text("mesh_curriculum", lang)
|
| 507 |
+
],
|
| 508 |
+
'WB 100': [
|
| 509 |
+
languages.get_text("mesh_clinical_medicine", lang),
|
| 510 |
+
languages.get_text("mesh_diagnosis", lang),
|
| 511 |
+
languages.get_text("mesh_therapeutics", lang)
|
| 512 |
+
],
|
| 513 |
+
'WB 105': [
|
| 514 |
+
languages.get_text("mesh_emergency_medicine", lang),
|
| 515 |
+
languages.get_text("mesh_traumatology", lang),
|
| 516 |
+
languages.get_text("mesh_critical_care", lang)
|
| 517 |
+
],
|
| 518 |
+
'WO 100': [
|
| 519 |
+
languages.get_text("mesh_general_surgery", lang),
|
| 520 |
+
languages.get_text("mesh_surgical_procedures", lang)
|
| 521 |
+
],
|
| 522 |
+
'WS 1': [
|
| 523 |
+
languages.get_text("mesh_pediatrics", lang),
|
| 524 |
+
languages.get_text("mesh_child_development", lang),
|
| 525 |
+
languages.get_text("mesh_adolescent_medicine", lang)
|
| 526 |
+
],
|
| 527 |
+
'WG': [
|
| 528 |
+
languages.get_text("mesh_cardiology", lang),
|
| 529 |
+
languages.get_text("mesh_cardiovascular_diseases", lang),
|
| 530 |
+
languages.get_text("mesh_heart_diseases", lang)
|
| 531 |
+
],
|
| 532 |
+
'WL': [
|
| 533 |
+
languages.get_text("mesh_neurology", lang),
|
| 534 |
+
languages.get_text("mesh_nervous_system_diseases", lang),
|
| 535 |
+
languages.get_text("mesh_brain", lang)
|
| 536 |
+
],
|
| 537 |
+
'QS 1': [
|
| 538 |
+
languages.get_text("mesh_anatomy", lang),
|
| 539 |
+
languages.get_text("mesh_dissection", lang),
|
| 540 |
+
languages.get_text("mesh_embryology", lang)
|
| 541 |
+
],
|
| 542 |
+
'QV 1': [
|
| 543 |
+
languages.get_text("mesh_pharmacology", lang),
|
| 544 |
+
languages.get_text("mesh_pharmaceutical_preparations", lang),
|
| 545 |
+
languages.get_text("mesh_drug_therapy", lang)
|
| 546 |
+
],
|
| 547 |
+
'QZ 4': [
|
| 548 |
+
languages.get_text("mesh_pathology", lang),
|
| 549 |
+
languages.get_text("mesh_disease", lang),
|
| 550 |
+
languages.get_text("mesh_clinical_pathology", lang)
|
| 551 |
+
],
|
| 552 |
+
'WY 100': [
|
| 553 |
+
languages.get_text("mesh_nursing_care", lang),
|
| 554 |
+
languages.get_text("mesh_nursing_process", lang),
|
| 555 |
+
languages.get_text("mesh_clinical_nursing_research", lang)
|
| 556 |
+
],
|
| 557 |
+
'WA 1': [
|
| 558 |
+
languages.get_text("mesh_public_health", lang),
|
| 559 |
+
languages.get_text("mesh_preventive_medicine", lang),
|
| 560 |
+
languages.get_text("mesh_epidemiology", lang)
|
| 561 |
+
],
|
| 562 |
+
'WM 1': [
|
| 563 |
+
languages.get_text("mesh_psychiatry", lang),
|
| 564 |
+
languages.get_text("mesh_mental_disorders", lang),
|
| 565 |
+
languages.get_text("mesh_psychotherapy", lang)
|
| 566 |
+
]
|
| 567 |
}
|
| 568 |
|
| 569 |
nlm_code = nlm_result['nlm_code']
|
|
|
|
| 573 |
mesh_subjects = subjects
|
| 574 |
break
|
| 575 |
if not mesh_subjects:
|
| 576 |
+
mesh_subjects = [
|
| 577 |
+
languages.get_text("mesh_medicine", lang),
|
| 578 |
+
languages.get_text("mesh_medical_sciences", lang),
|
| 579 |
+
languages.get_text("mesh_health_occupations", lang)
|
| 580 |
+
]
|
| 581 |
|
| 582 |
+
# تحديد الجمهور المستهدف مع الترجمة
|
|
|
|
|
|
|
| 583 |
if 'Textbook' in nlm_result.get('nlm_name', ''):
|
| 584 |
+
audience_category = languages.get_text("audience_undergraduate", lang)
|
| 585 |
+
audience_reason = languages.get_text("audience_reason_textbook", lang)
|
| 586 |
elif 'Education' in nlm_result.get('nlm_name', ''):
|
| 587 |
+
audience_category = languages.get_text("audience_educators", lang)
|
| 588 |
+
audience_reason = languages.get_text("audience_reason_education", lang)
|
| 589 |
elif 'Surgery' in nlm_result.get('nlm_name', ''):
|
| 590 |
+
audience_category = languages.get_text("audience_surgeons", lang)
|
| 591 |
+
audience_reason = languages.get_text("audience_reason_surgery", lang)
|
| 592 |
+
else:
|
| 593 |
+
audience_category = languages.get_text("audience_medical_students", lang)
|
| 594 |
+
audience_reason = languages.get_text("audience_reason_default", lang)
|
| 595 |
|
| 596 |
+
# قرار الشراء مع الترجمة
|
| 597 |
score = nlm_result['confidence_score']
|
| 598 |
if score >= 8:
|
| 599 |
+
acquisition_decision = languages.get_text("decision_highly_recommended", lang)
|
| 600 |
+
acquisition_reason = languages.get_text("acquisition_reason_high", lang)
|
| 601 |
elif score >= 4:
|
| 602 |
+
acquisition_decision = languages.get_text("decision_recommended", lang)
|
| 603 |
+
acquisition_reason = languages.get_text("acquisition_reason_medium", lang)
|
| 604 |
else:
|
| 605 |
+
acquisition_decision = languages.get_text("decision_review_required", lang)
|
| 606 |
+
acquisition_reason = languages.get_text("acquisition_reason_low", lang)
|
| 607 |
|
| 608 |
return {
|
| 609 |
'title': title,
|
|
|
|
| 795 |
if isbns:
|
| 796 |
st.markdown(f"**📋 Identifiers:** {' | '.join(isbns)}")
|
| 797 |
st.markdown("---")
|
| 798 |
+
decision = ai.get('acquisition_decision', languages.get_text("decision_recommended", lang))
|
| 799 |
+
if decision == languages.get_text("decision_highly_recommended", lang):
|
| 800 |
pill_class = "status-high"
|
| 801 |
+
elif decision == languages.get_text("decision_recommended", lang):
|
| 802 |
+
pill_class = "status-medium"
|
| 803 |
+
elif decision == languages.get_text("decision_review_required", lang) or decision == languages.get_text("decision_optional", lang):
|
| 804 |
pill_class = "status-low"
|
| 805 |
else:
|
| 806 |
pill_class = "status-medium"
|