Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -502,45 +502,69 @@ def build_verify_links(name: str, issn: Optional[str], sourceid: str = "") -> di
|
|
| 502 |
}
|
| 503 |
|
| 504 |
|
| 505 |
-
def
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 516 |
if len(by_field) > 1:
|
| 517 |
spread = ", ".join(f"{f['quartile']} in {f['field']}" for f in by_field)
|
| 518 |
-
|
| 519 |
-
|
| 520 |
-
|
| 521 |
-
|
|
|
|
| 522 |
|
| 523 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 524 |
"requested": True, "source": "Verified from journal data", "year": "2025",
|
| 525 |
"category": scimago.get("categories", ""), "metric_value": None,
|
| 526 |
"percentile": f"Rank #{scimago.get('rank', '—')} globally" if scimago.get("rank") else None,
|
| 527 |
"quartile": q if q and q != "-" else None,
|
| 528 |
-
"interpretation":
|
| 529 |
"verification_status": "Confirmed", "h_index": scimago.get("h_index"),
|
| 530 |
-
|
| 531 |
-
# From journals.db. Absent when the CSV fallback served this
|
| 532 |
-
# lookup, so every reader must tolerate None/False.
|
| 533 |
-
"quartiles_by_field": by_field,
|
| 534 |
-
"sjr": scimago.get("sjr"),
|
| 535 |
-
"indexation_state": scimago.get("state"),
|
| 536 |
-
"indexation_message": scimago.get("state_message"),
|
| 537 |
-
"warn": bool(scimago.get("warn")),
|
| 538 |
-
"currently_indexed": scimago.get("currently_indexed", True),
|
| 539 |
-
"successor_title": scimago.get("successor_title"),
|
| 540 |
-
"oa_diamond": bool(scimago.get("oa_diamond")),
|
| 541 |
-
"from_scopus": bool(scimago.get("from_scopus")),
|
| 542 |
-
"from_scimago": bool(scimago.get("from_scimago", True)),
|
| 543 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 544 |
elif oa_pct:
|
| 545 |
return {
|
| 546 |
"requested": True, "source": "OpenAlex-derived percentile", "year": "2025",
|
|
@@ -635,12 +659,10 @@ def enrich_extended(extended: list) -> list:
|
|
| 635 |
# It is deliberately False for the 6,855 that were merely renamed:
|
| 636 |
# telling a researcher that a journal which changed its name is a
|
| 637 |
# quality risk is worse than saying nothing at all.
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
j
|
| 642 |
-
j["oa_diamond"] = bool((scimago or {}).get("oa_diamond"))
|
| 643 |
-
j["quartiles_by_field"] = (scimago or {}).get("quartiles_by_field") or []
|
| 644 |
|
| 645 |
j["verify_links"] = build_verify_links(j.get("name", ""), issn, sourceid)
|
| 646 |
j["ku_apc_covered"] = is_ku_apc_covered(publisher, q)
|
|
|
|
| 502 |
}
|
| 503 |
|
| 504 |
|
| 505 |
+
def _index_extras(scimago: Optional[dict]) -> dict:
|
| 506 |
+
"""
|
| 507 |
+
journals.db-only fields, guarded.
|
| 508 |
+
|
| 509 |
+
Additive metadata must never be able to fail a request. If anything in
|
| 510 |
+
here raises, the caller still gets a complete ranking block from the
|
| 511 |
+
fields that predate the journals.db work. The warning names the journal so
|
| 512 |
+
a recurring failure is traceable rather than silent.
|
| 513 |
+
"""
|
| 514 |
+
if not scimago:
|
| 515 |
+
return {}
|
| 516 |
+
try:
|
| 517 |
+
return {
|
| 518 |
+
"quartiles_by_field": scimago.get("quartiles_by_field") or [],
|
| 519 |
+
"sjr": scimago.get("sjr"),
|
| 520 |
+
"indexation_state": scimago.get("state"),
|
| 521 |
+
"indexation_message": scimago.get("state_message"),
|
| 522 |
+
"warn": bool(scimago.get("warn")),
|
| 523 |
+
"currently_indexed": scimago.get("currently_indexed", True),
|
| 524 |
+
"successor_title": scimago.get("successor_title"),
|
| 525 |
+
"oa_diamond": bool(scimago.get("oa_diamond")),
|
| 526 |
+
"from_scopus": bool(scimago.get("from_scopus")),
|
| 527 |
+
"from_scimago": bool(scimago.get("from_scimago", True)),
|
| 528 |
+
}
|
| 529 |
+
except Exception as e: # noqa: BLE001
|
| 530 |
+
logger.warning("[JournalIndex] extras failed for %r: %s: %s",
|
| 531 |
+
(scimago or {}).get("title", "?"), type(e).__name__, e)
|
| 532 |
+
return {}
|
| 533 |
+
|
| 534 |
+
|
| 535 |
+
def _quartile_interpretation(scimago: Optional[dict]) -> str:
|
| 536 |
+
"""
|
| 537 |
+
Per-field quartile sentence, guarded, with the original wording as the
|
| 538 |
+
fallback. 46% of ranked journals rank differently across their own subject
|
| 539 |
+
areas, so the spread is worth showing — but never at the cost of the call.
|
| 540 |
+
"""
|
| 541 |
+
try:
|
| 542 |
+
by_field = (scimago or {}).get("quartiles_by_field") or []
|
| 543 |
if len(by_field) > 1:
|
| 544 |
spread = ", ".join(f"{f['quartile']} in {f['field']}" for f in by_field)
|
| 545 |
+
return f"Quartile varies by subject area: {spread}."
|
| 546 |
+
except Exception as e: # noqa: BLE001
|
| 547 |
+
logger.warning("[JournalIndex] quartile spread failed: %s", e)
|
| 548 |
+
return (f"Quartile verified from journal metadata "
|
| 549 |
+
f"(2025 dataset, matched by ISSN {(scimago or {}).get('matched_issn', '')}).")
|
| 550 |
|
| 551 |
+
|
| 552 |
+
def enrich_ranking(journal: dict, scimago: Optional[dict], oa_pct: Optional[dict]) -> dict:
|
| 553 |
+
if scimago:
|
| 554 |
+
q = scimago.get("quartile", "")
|
| 555 |
+
out = {
|
| 556 |
"requested": True, "source": "Verified from journal data", "year": "2025",
|
| 557 |
"category": scimago.get("categories", ""), "metric_value": None,
|
| 558 |
"percentile": f"Rank #{scimago.get('rank', '—')} globally" if scimago.get("rank") else None,
|
| 559 |
"quartile": q if q and q != "-" else None,
|
| 560 |
+
"interpretation": _quartile_interpretation(scimago),
|
| 561 |
"verification_status": "Confirmed", "h_index": scimago.get("h_index"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 562 |
}
|
| 563 |
+
# journals.db extras are merged in, never inlined. If the index or its
|
| 564 |
+
# shape misbehaves the response is still complete and correct — the
|
| 565 |
+
# caller simply does not get the extra keys.
|
| 566 |
+
out.update(_index_extras(scimago))
|
| 567 |
+
return out
|
| 568 |
elif oa_pct:
|
| 569 |
return {
|
| 570 |
"requested": True, "source": "OpenAlex-derived percentile", "year": "2025",
|
|
|
|
| 659 |
# It is deliberately False for the 6,855 that were merely renamed:
|
| 660 |
# telling a researcher that a journal which changed its name is a
|
| 661 |
# quality risk is worse than saying nothing at all.
|
| 662 |
+
#
|
| 663 |
+
# Merged through the guarded helper for the same reason as above: a
|
| 664 |
+
# quick-match row must not be able to fail the whole request.
|
| 665 |
+
j.update(_index_extras(scimago))
|
|
|
|
|
|
|
| 666 |
|
| 667 |
j["verify_links"] = build_verify_links(j.get("name", ""), issn, sourceid)
|
| 668 |
j["ku_apc_covered"] = is_ku_apc_covered(publisher, q)
|