RubaAnam1 commited on
Commit
41b2aba
·
verified ·
1 Parent(s): c3c8828

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -69
app.py CHANGED
@@ -1,16 +1,11 @@
1
  import streamlit as st
2
  import requests
3
  from urllib.parse import quote
4
- import wikipediaapi
5
 
6
- # -----------------------------
7
- # إعدادات
8
- # -----------------------------
9
  st.set_page_config(page_title="Clean Biodiversity Explorer", layout="centered")
10
  st.title("🌍 Clean Biodiversity Explorer (بدون أخطاء)")
11
 
12
- # قاموس تحويل أسماء البلدان (عربي/إنجليزي) إلى كود GBIF (ISO2)
13
- # أضف دولاً أخرى بنفس الصيغة
14
  country_to_code = {
15
  "sudan": "SD", "السودان": "SD",
16
  "egypt": "EG", "مصر": "EG",
@@ -20,28 +15,20 @@ country_to_code = {
20
  "uk": "GB", "المملكة المتحدة": "GB"
21
  }
22
 
23
- # أنواع البحث + معامل GBIF المناسبة
24
  search_types = {
25
  "🐦 Birds": {"class": "Aves"},
26
  "🐍 Reptiles": {"class": "Reptilia"},
27
  "🐘 Mammals": {"class": "Mammalia"},
28
  "🦋 Insects": {"class": "Insecta"},
29
  "🐸 Amphibians": {"class": "Amphibia"},
30
- "🌳 غابات (نباتات)": {"kingdom": "Plantae", "limit_mode": "trees"} # نركز على النباتات
31
  }
32
 
33
- # -----------------------------
34
- # دالة تحويل اسم الدولة إلى كود
35
- # -----------------------------
36
  def get_country_code(user_input):
37
  if not user_input:
38
  return None
39
- key = user_input.strip().lower()
40
- return country_to_code.get(key, None)
41
 
42
- # -----------------------------
43
- # دالة الحصول على الأنواع من GBIF (بدون أخطاء)
44
- # -----------------------------
45
  def get_species(country_code, search_key):
46
  url = "https://api.gbif.org/v1/occurrence/search"
47
  params = {
@@ -49,27 +36,26 @@ def get_species(country_code, search_key):
49
  "limit": 80,
50
  "occurrence_status": "PRESENT"
51
  }
52
- # إضافة معاملات التصنيف حسب نوع البحث
53
- if "class" in search_types[search_key]:
54
- params["class"] = search_types[search_key]["class"]
55
- elif "kingdom" in search_types[search_key]:
56
- params["kingdom"] = search_types[search_key]["kingdom"]
57
- # لإظهار نباتات بارزة، نطلب "highertaxonKey" للنباتات الوعائية (اختياري)
58
- params["taxonKey"] = 7707728 # Tracheophyta (نباتات وعائية) للحصول على أشجار وشجيرات
59
-
60
  try:
61
  r = requests.get(url, params=params, timeout=15)
62
  r.raise_for_status()
63
  data = r.json()
64
- except Exception as e:
65
- st.error(f"⚠️ فشل الاتصال بـ GBIF: {str(e)}")
66
  return []
67
-
68
  results = data.get("results", [])
69
  species_set = set()
70
  species_list = []
71
  bad = ["sp.", "cf.", "aff.", "unknown", "unclassified", "indet.", "hybrid"]
72
-
73
  for item in results:
74
  sp = item.get("species") or item.get("scientificName")
75
  key = item.get("speciesKey") or item.get("taxonKey")
@@ -85,46 +71,48 @@ def get_species(country_code, search_key):
85
  return species_list
86
 
87
  # -----------------------------
88
- # دالة إنشاء روابط شغالة (بدون 404)
89
  # -----------------------------
90
- @st.cache_data(ttl=3600)
91
- def get_wikipedia_title(scientific_name):
92
- """تستخدم Wikipedia API للبحث عن صفحة حقيقية، وتعيد عنوانها أو None"""
93
- wiki = wikipediaapi.Wikipedia(user_agent="BiodiversityExplorer/1.0", language="en")
94
- # جرب الاسم العلمي كاملاً
95
- page = wiki.page(scientific_name)
96
- if page.exists():
97
- return page.title
98
- # جرب البحث عن كلمات أولية (مثلاً "Panthera leo" "Lion")
99
- words = scientific_name.split()
100
- if len(words) >= 2:
101
- simple_name = words[-1] # آخر كلمة غالباً هي الجنس أو النوع
102
- if len(simple_name) > 3:
103
- page2 = wiki.page(simple_name.title())
104
- if page2.exists():
105
- return page2.title
106
- # بحث حر - نرجع None ونعرض رابط بحث
 
 
 
 
 
107
  return None
108
 
109
  def make_links(species_name, species_key):
110
- links_dict = {}
111
- # GBIF (دائماً شغال)
112
- links_dict["GBIF"] = f"https://www.gbif.org/species/{species_key}"
113
 
114
- # Wikipedia - نحاول نحصل على صفحة حقيقية
115
- real_title = get_wikipedia_title(species_name)
116
  if real_title:
117
- links_dict["Wikipedia"] = f"https://en.wikipedia.org/wiki/{real_title.replace(' ', '_')}"
118
  else:
119
- # رابط بحث بدلاً من 404
120
- search_q = quote(species_name)
121
- links_dict["Wikipedia"] = f"https://en.wikipedia.org/w/index.php?search={search_q}&title=Special:Search"
122
 
123
- # iNaturalist و Google Scholar عادي
124
- links_dict["iNaturalist"] = f"https://www.inaturalist.org/search?q={quote(species_name)}"
125
- links_dict["Scholar"] = f"https://scholar.google.com/scholar?q={quote(species_name)}"
126
-
127
- return links_dict
128
 
129
  # -----------------------------
130
  # واجهة المستخدم
@@ -136,23 +124,22 @@ if st.button("🔍 بحث"):
136
  if not user_country:
137
  st.warning("يرجى إدخال اسم الدولة أولاً.")
138
  st.stop()
139
-
140
- # تحويل اسم الدولة إلى كود GBIF
141
  country_code = get_country_code(user_country)
142
  if not country_code:
143
- st.error(f"❌ لا أدري رمز البلد لـ '{user_country}'. الرجاء استخدام (Sudan, Egypt, Saudi Arabia, UAE, USA...)")
144
  st.stop()
145
-
146
- with st.spinner(f"جلب البيانات من GBIF لـ {user_country} ({country_code}) ..."):
147
  species_data = get_species(country_code, selected_type)
148
-
149
  if not species_data:
150
- st.warning(f"😕 لم يتم العثور على أنواع لـ {selected_type} في {user_country}. حاول دولة أخرى أو نوعاً مختلفاً.")
151
  st.stop()
152
-
153
  st.success(f"✅ تم العثور على {len(species_data)} نوعاً")
154
  st.subheader(f"📌 {selected_type} في {user_country}")
155
-
156
  for name, key in species_data:
157
  st.markdown(f"### 🍃 {name}")
158
  links = make_links(name, key)
 
1
  import streamlit as st
2
  import requests
3
  from urllib.parse import quote
 
4
 
 
 
 
5
  st.set_page_config(page_title="Clean Biodiversity Explorer", layout="centered")
6
  st.title("🌍 Clean Biodiversity Explorer (بدون أخطاء)")
7
 
8
+ # قاموس تحويل أسماء البلدان إلى كود GBIF
 
9
  country_to_code = {
10
  "sudan": "SD", "السودان": "SD",
11
  "egypt": "EG", "مصر": "EG",
 
15
  "uk": "GB", "المملكة المتحدة": "GB"
16
  }
17
 
 
18
  search_types = {
19
  "🐦 Birds": {"class": "Aves"},
20
  "🐍 Reptiles": {"class": "Reptilia"},
21
  "🐘 Mammals": {"class": "Mammalia"},
22
  "🦋 Insects": {"class": "Insecta"},
23
  "🐸 Amphibians": {"class": "Amphibia"},
24
+ "🌳 غابات (نباتات)": {"kingdom": "Plantae", "taxonKey": 7707728} # Tracheophyta
25
  }
26
 
 
 
 
27
  def get_country_code(user_input):
28
  if not user_input:
29
  return None
30
+ return country_to_code.get(user_input.strip().lower())
 
31
 
 
 
 
32
  def get_species(country_code, search_key):
33
  url = "https://api.gbif.org/v1/occurrence/search"
34
  params = {
 
36
  "limit": 80,
37
  "occurrence_status": "PRESENT"
38
  }
39
+ search_info = search_types[search_key]
40
+ if "class" in search_info:
41
+ params["class"] = search_info["class"]
42
+ elif "kingdom" in search_info:
43
+ params["kingdom"] = search_info["kingdom"]
44
+ if "taxonKey" in search_info:
45
+ params["taxonKey"] = search_info["taxonKey"]
46
+
47
  try:
48
  r = requests.get(url, params=params, timeout=15)
49
  r.raise_for_status()
50
  data = r.json()
51
+ except:
 
52
  return []
53
+
54
  results = data.get("results", [])
55
  species_set = set()
56
  species_list = []
57
  bad = ["sp.", "cf.", "aff.", "unknown", "unclassified", "indet.", "hybrid"]
58
+
59
  for item in results:
60
  sp = item.get("species") or item.get("scientificName")
61
  key = item.get("speciesKey") or item.get("taxonKey")
 
71
  return species_list
72
 
73
  # -----------------------------
74
+ # دالة ويكيبيديا بدون مكتبة إضافية (باستخدام requests)
75
  # -----------------------------
76
+ def get_wikipedia_real_title(scientific_name):
77
+ """
78
+ تبحث عن أفضل صفحة ويكيبيديا للاسم العلمي.
79
+ تستخدم API البحث لتعيد عنوان الصفحة الحقيقي أو None.
80
+ """
81
+ search_url = "https://en.wikipedia.org/w/api.php"
82
+ params = {
83
+ "action": "query",
84
+ "list": "search",
85
+ "srsearch": scientific_name,
86
+ "format": "json",
87
+ "srlimit": 1
88
+ }
89
+ try:
90
+ resp = requests.get(search_url, params=params, timeout=5)
91
+ resp.raise_for_status()
92
+ data = resp.json()
93
+ pages = data.get("query", {}).get("search", [])
94
+ if pages:
95
+ return pages[0]["title"]
96
+ except:
97
+ pass
98
  return None
99
 
100
  def make_links(species_name, species_key):
101
+ links = {}
102
+ # GBIF شغال دائماً
103
+ links["GBIF"] = f"https://www.gbif.org/species/{species_key}"
104
 
105
+ # بحث ويكيبيديا
106
+ real_title = get_wikipedia_real_title(species_name)
107
  if real_title:
108
+ links["Wikipedia"] = f"https://en.wikipedia.org/wiki/{real_title.replace(' ', '_')}"
109
  else:
110
+ # رابط بحث بدل 404
111
+ links["Wikipedia"] = f"https://en.wikipedia.org/w/index.php?search={quote(species_name)}&title=Special:Search"
 
112
 
113
+ links["iNaturalist"] = f"https://www.inaturalist.org/search?q={quote(species_name)}"
114
+ links["Scholar"] = f"https://scholar.google.com/scholar?q={quote(species_name)}"
115
+ return links
 
 
116
 
117
  # -----------------------------
118
  # واجهة المستخدم
 
124
  if not user_country:
125
  st.warning("يرجى إدخال اسم الدولة أولاً.")
126
  st.stop()
127
+
 
128
  country_code = get_country_code(user_country)
129
  if not country_code:
130
+ st.error(f"❌ رمز البلد لـ '{user_country}' غير معروف. استخدم: Sudan, Egypt, Saudi Arabia, UAE, USA أو العربية.")
131
  st.stop()
132
+
133
+ with st.spinner(f"جلب البيانات من GBIF لـ {user_country} ..."):
134
  species_data = get_species(country_code, selected_type)
135
+
136
  if not species_data:
137
+ st.warning(f"😕 لا توجد أنواع لـ {selected_type} في {user_country}.")
138
  st.stop()
139
+
140
  st.success(f"✅ تم العثور على {len(species_data)} نوعاً")
141
  st.subheader(f"📌 {selected_type} في {user_country}")
142
+
143
  for name, key in species_data:
144
  st.markdown(f"### 🍃 {name}")
145
  links = make_links(name, key)