| import streamlit as st |
| import requests |
| from urllib.parse import quote |
|
|
| st.set_page_config(page_title="Clean Biodiversity Explorer", layout="centered") |
| st.title("🌍 Clean Biodiversity Explorer (فلتر دقيق)") |
|
|
| country_to_code = { |
| "sudan": "SD", "السودان": "SD", |
| "egypt": "EG", "مصر": "EG", |
| "saudi arabia": "SA", "السعودية": "SA", |
| "uae": "AE", "الامارات": "AE", |
| "usa": "US", "الولايات المتحدة": "US", |
| "uk": "GB", "المملكة المتحدة": "GB" |
| } |
|
|
| search_types = { |
| "🐦 Birds": {"class": "Aves", "rank": "CLASS"}, |
| "🐍 Reptiles": {"class": "Reptilia", "rank": "CLASS"}, |
| "🐘 Mammals": {"class": "Mammalia", "rank": "CLASS"}, |
| "🦋 Insects": {"class": "Insecta", "rank": "CLASS"}, |
| "🐸 Amphibians": {"class": "Amphibia", "rank": "CLASS"}, |
| "🌳 غابات (نباتات)": {"kingdom": "Plantae", "taxonKey": 7707728, "rank": "KINGDOM"} |
| } |
|
|
| def get_country_code(user_input): |
| if not user_input: |
| return None |
| return country_to_code.get(user_input.strip().lower()) |
|
|
| def get_species(country_code, search_key): |
| url = "https://api.gbif.org/v1/occurrence/search" |
| params = { |
| "country": country_code.upper(), |
| "limit": 80, |
| "occurrence_status": "PRESENT" |
| } |
| search_info = search_types[search_key] |
| if "class" in search_info: |
| params["class"] = search_info["class"] |
| elif "kingdom" in search_info: |
| params["kingdom"] = search_info["kingdom"] |
| if "taxonKey" in search_info: |
| params["taxonKey"] = search_info["taxonKey"] |
|
|
| try: |
| r = requests.get(url, params=params, timeout=15) |
| r.raise_for_status() |
| data = r.json() |
| except: |
| return [] |
|
|
| results = data.get("results", []) |
| species_set = set() |
| species_list = [] |
| bad = ["sp.", "cf.", "aff.", "unknown", "unclassified", "indet.", "hybrid"] |
|
|
| for item in results: |
| |
| if "class" in search_info: |
| returned_class = item.get("class") |
| if returned_class != search_info["class"]: |
| continue |
| elif "kingdom" in search_info: |
| returned_kingdom = item.get("kingdom") |
| if returned_kingdom != search_info["kingdom"]: |
| continue |
|
|
| sp = item.get("species") or item.get("scientificName") |
| key = item.get("speciesKey") or item.get("taxonKey") |
| if not sp or not key or len(sp) < 5: |
| continue |
| if any(b in sp.lower() for b in bad): |
| continue |
| if sp not in species_set: |
| species_set.add(sp) |
| species_list.append((sp, key)) |
| if len(species_list) >= 12: |
| break |
| return species_list |
|
|
| def get_wikipedia_real_title(scientific_name): |
| search_url = "https://en.wikipedia.org/w/api.php" |
| params = { |
| "action": "query", |
| "list": "search", |
| "srsearch": scientific_name, |
| "format": "json", |
| "srlimit": 1 |
| } |
| try: |
| resp = requests.get(search_url, params=params, timeout=5) |
| resp.raise_for_status() |
| data = resp.json() |
| pages = data.get("query", {}).get("search", []) |
| if pages: |
| return pages[0]["title"] |
| except: |
| pass |
| return None |
|
|
| def make_links(species_name, species_key): |
| links = {} |
| links["GBIF"] = f"https://www.gbif.org/species/{species_key}" |
| real_title = get_wikipedia_real_title(species_name) |
| if real_title: |
| links["Wikipedia"] = f"https://en.wikipedia.org/wiki/{real_title.replace(' ', '_')}" |
| else: |
| links["Wikipedia"] = f"https://en.wikipedia.org/w/index.php?search={quote(species_name)}&title=Special:Search" |
| links["iNaturalist"] = f"https://www.inaturalist.org/search?q={quote(species_name)}" |
| links["Scholar"] = f"https://scholar.google.com/scholar?q={quote(species_name)}" |
| return links |
|
|
| user_country = st.text_input("🇺🇳 اسم الدولة (مثال: Sudan, السودان, Egypt, مصر)") |
| selected_type = st.selectbox("📂 اختر نوع البحث", list(search_types.keys())) |
|
|
| if st.button("🔍 بحث"): |
| if not user_country: |
| st.warning("يرجى إدخال اسم الدولة أولاً.") |
| st.stop() |
|
|
| country_code = get_country_code(user_country) |
| if not country_code: |
| st.error(f"❌ رمز البلد لـ '{user_country}' غير معروف.") |
| st.stop() |
|
|
| with st.spinner(f"جلب البيانات من GBIF ..."): |
| species_data = get_species(country_code, selected_type) |
|
|
| if not species_data: |
| st.warning(f"😕 لا توجد أنواع مطابقة لـ {selected_type} في {user_country}.") |
| st.stop() |
|
|
| st.success(f"✅ تم العثور على {len(species_data)} نوعاً") |
| st.subheader(f"📌 {selected_type} في {user_country}") |
|
|
| for name, key in species_data: |
| st.markdown(f"### 🍃 {name}") |
| links = make_links(name, key) |
| st.markdown( |
| f"🔗 [GBIF]({links['GBIF']}) | " |
| f"📘 [Wikipedia]({links['Wikipedia']}) | " |
| f"📸 [iNaturalist]({links['iNaturalist']}) | " |
| f"📚 [Google Scholar]({links['Scholar']})" |
| ) |
| st.markdown("---") |