cwadayi commited on
Commit
13d91c0
·
verified ·
1 Parent(s): da1a0d0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -10
app.py CHANGED
@@ -1,5 +1,5 @@
1
  import os
2
- # ✅ Avoid permission issues for Matplotlib config/cache
3
  os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
4
 
5
  import uuid
@@ -28,8 +28,7 @@ from matplotlib.colors import Normalize
28
  import matplotlib.cm as cm
29
  from matplotlib import font_manager as fm
30
 
31
- # ✅ Try to set a CJK-capable font for Chinese text
32
- # Install fonts-noto-cjk in container for best result
33
  possible_fonts = [
34
  "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
35
  "/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc",
@@ -48,9 +47,19 @@ else:
48
  # --- Environment Variables ---
49
  CHANNEL_ACCESS_TOKEN = os.getenv("CHANNEL_ACCESS_TOKEN")
50
  CHANNEL_SECRET = os.getenv("CHANNEL_SECRET")
51
- HF_SPACE_URL = os.getenv("SPACEURL") # e.g., https://your-space.hf.space
52
 
53
- # --- Writable static directory ---
 
 
 
 
 
 
 
 
 
 
 
54
  STATIC_DIR = os.getenv("STATIC_DIR", os.path.join(tempfile.gettempdir(), "static"))
55
  os.makedirs(STATIC_DIR, exist_ok=True)
56
 
@@ -99,6 +108,7 @@ def _iso(dt: datetime) -> str:
99
  return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S")
100
 
101
  def fetch_global_last24h_text(min_mag=5.0, limit=10) -> str:
 
102
  now_utc = datetime.now(timezone.utc)
103
  since = now_utc - timedelta(hours=24)
104
  params = {
@@ -120,14 +130,16 @@ def fetch_global_last24h_text(min_mag=5.0, limit=10) -> str:
120
  for f in features:
121
  p = f["properties"]
122
  t_utc = datetime.fromtimestamp(p["time"] / 1000, tz=timezone.utc)
 
123
  lines.append(
124
- f"震級: {p['mag']:.1f} | 時間: {t_utc.strftime('%H:%M')} (UTC)\n地點: {p.get('place','')}"
125
  )
126
  return "\n\n".join(lines)
127
  except Exception as e:
128
  return f"❌ 查詢失敗: {e}"
129
 
130
  def fetch_taiwan_df_this_year(min_mag=5.0) -> pd.DataFrame | str:
 
131
  now_utc = datetime.now(timezone.utc)
132
  start_of_year_utc = datetime(now_utc.year, 1, 1, tzinfo=timezone.utc)
133
  params = {
@@ -204,7 +216,7 @@ def create_and_save_map(df: pd.DataFrame) -> str:
204
  return filename
205
 
206
  def _base_url_for_images() -> str:
207
- # Always prefer HF_SPACE_URL for LINE
208
  if HF_SPACE_URL:
209
  return HF_SPACE_URL.rstrip("/")
210
  return request.url_root.rstrip("/")
@@ -228,6 +240,7 @@ def handle_message(event):
228
  with ApiClient(configuration) as api_client:
229
  line_bot_api = MessagingApi(api_client)
230
 
 
231
  if ("臺灣地震畫圖" in user_message) or ("台灣地震畫圖" in user_message):
232
  result = fetch_taiwan_df_this_year()
233
  if isinstance(result, pd.DataFrame):
@@ -251,12 +264,13 @@ def handle_message(event):
251
  line_bot_api.reply_message_with_http_info(reply)
252
  return
253
 
 
254
  if user_message == "/help":
255
  text = (
256
  "📖 地震預警 dayichen 指令說明\n\n"
257
  "➡️ /help\n 說明:顯示此幫助訊息。\n\n"
258
- "➡️ 地震\n 說明:查詢全球最近 24 小時內,M≥5.0 的顯著地震。\n\n"
259
- "➡️ 臺灣地震 / 台灣地震\n 說明:查詢今年以來台灣區域 M≥5.0 地震。\n\n"
260
  "➡️ 臺灣地震畫圖 / 台灣地震畫圖\n 說明:繪製今年台灣區域 M≥5.0 地震分佈圖並回傳圖片。\n\n"
261
  "➡️ 你好\n 說明:顯示歡迎訊息。"
262
  )
@@ -265,6 +279,7 @@ def handle_message(event):
265
  )
266
  return
267
 
 
268
  if ("臺灣地震" in user_message) or ("台灣地震" in user_message):
269
  result = fetch_taiwan_df_this_year()
270
  if isinstance(result, pd.DataFrame):
@@ -272,7 +287,7 @@ def handle_message(event):
272
  lines = [f"🇹🇼 今年 ({datetime.now(timezone.utc).year} 年) 台灣區域顯著地震 (M≥5.0),共 {count} 筆:", "-" * 20]
273
  for _, row in result.head(15).iterrows():
274
  t = row["time_utc"].strftime("%Y-%m-%d %H:%M")
275
- lines.append(f"震級: {row['magnitude']:.1f} | 時間: {t} (UTC)\n地點: {row['place']}")
276
  if count > 15:
277
  lines.append(f"... (還有 {count - 15} 筆,可用「臺灣地震畫圖」查看全部)")
278
  reply_text = "\n\n".join(lines)
@@ -283,6 +298,7 @@ def handle_message(event):
283
  )
284
  return
285
 
 
286
  if ("地震" in user_message) or ("quake" in user_message):
287
  reply_text = fetch_global_last24h_text()
288
  line_bot_api.reply_message_with_http_info(
@@ -290,6 +306,7 @@ def handle_message(event):
290
  )
291
  return
292
 
 
293
  if ("你好" in user_message) or ("hi" in user_message):
294
  line_bot_api.reply_message_with_http_info(
295
  ReplyMessageRequest(
 
1
  import os
2
+ # ✅ 避免 Matplotlib 在唯讀路徑寫入設定
3
  os.environ["MPLCONFIGDIR"] = "/tmp/matplotlib"
4
 
5
  import uuid
 
28
  import matplotlib.cm as cm
29
  from matplotlib import font_manager as fm
30
 
31
+ # ✅ 嘗試載入支援中文的字型
 
32
  possible_fonts = [
33
  "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
34
  "/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc",
 
47
  # --- Environment Variables ---
48
  CHANNEL_ACCESS_TOKEN = os.getenv("CHANNEL_ACCESS_TOKEN")
49
  CHANNEL_SECRET = os.getenv("CHANNEL_SECRET")
 
50
 
51
+ # HF_SPACE_URL 自動偵測(若未手動設定 SPACEURL)
52
+ HF_SPACE_URL = os.getenv("SPACEURL")
53
+ if not HF_SPACE_URL:
54
+ space_id = os.getenv("SPACE_ID") # e.g., username/space-name
55
+ if space_id and "/" in space_id:
56
+ author, name = space_id.split("/", 1)
57
+ HF_SPACE_URL = f"https://{author.replace('_','-')}-{name.replace('_','-')}.hf.space"
58
+ print(f"🔍 Auto-detected HF_SPACE_URL = {HF_SPACE_URL}")
59
+ else:
60
+ HF_SPACE_URL = "" # fallback 由 request.url_root 決定
61
+
62
+ # --- 可寫入的靜態目錄 ---
63
  STATIC_DIR = os.getenv("STATIC_DIR", os.path.join(tempfile.gettempdir(), "static"))
64
  os.makedirs(STATIC_DIR, exist_ok=True)
65
 
 
108
  return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S")
109
 
110
  def fetch_global_last24h_text(min_mag=5.0, limit=10) -> str:
111
+ """顯示近 24 小時全球 M≥min_mag 地震,含日期。"""
112
  now_utc = datetime.now(timezone.utc)
113
  since = now_utc - timedelta(hours=24)
114
  params = {
 
130
  for f in features:
131
  p = f["properties"]
132
  t_utc = datetime.fromtimestamp(p["time"] / 1000, tz=timezone.utc)
133
+ # ✅ 改用含日期格式
134
  lines.append(
135
+ f"震級: {p['mag']:.1f} | 日期時間: {t_utc.strftime('%Y-%m-%d %H:%M')} (UTC)\n地點: {p.get('place','')}"
136
  )
137
  return "\n\n".join(lines)
138
  except Exception as e:
139
  return f"❌ 查詢失敗: {e}"
140
 
141
  def fetch_taiwan_df_this_year(min_mag=5.0) -> pd.DataFrame | str:
142
+ """抓取今年台灣經緯度框內 M≥min_mag 地震的 DataFrame。"""
143
  now_utc = datetime.now(timezone.utc)
144
  start_of_year_utc = datetime(now_utc.year, 1, 1, tzinfo=timezone.utc)
145
  params = {
 
216
  return filename
217
 
218
  def _base_url_for_images() -> str:
219
+ # 盡量用公開的 HF Space URL,確保 LINE 能抓到圖
220
  if HF_SPACE_URL:
221
  return HF_SPACE_URL.rstrip("/")
222
  return request.url_root.rstrip("/")
 
240
  with ApiClient(configuration) as api_client:
241
  line_bot_api = MessagingApi(api_client)
242
 
243
+ # 繪圖
244
  if ("臺灣地震畫圖" in user_message) or ("台灣地震畫圖" in user_message):
245
  result = fetch_taiwan_df_this_year()
246
  if isinstance(result, pd.DataFrame):
 
264
  line_bot_api.reply_message_with_http_info(reply)
265
  return
266
 
267
+ # 說明
268
  if user_message == "/help":
269
  text = (
270
  "📖 地震預警 dayichen 指令說明\n\n"
271
  "➡️ /help\n 說明:顯示此幫助訊息。\n\n"
272
+ "➡️ 地震 / quake\n 說明:查詢全球最近 24 小時內,M≥5.0 的顯著地震(含日期時間)。\n\n"
273
+ "➡️ 臺灣地震 / 台灣地震\n 說明:查詢今年以來台灣區域 (21–26°N, 119–123°E) M≥5.0 地震(含日期時間)。\n\n"
274
  "➡️ 臺灣地震畫圖 / 台灣地震畫圖\n 說明:繪製今年台灣區域 M≥5.0 地震分佈圖並回傳圖片。\n\n"
275
  "➡️ 你好\n 說明:顯示歡迎訊息。"
276
  )
 
279
  )
280
  return
281
 
282
+ # 台灣清單(已含日期)
283
  if ("臺灣地震" in user_message) or ("台灣地震" in user_message):
284
  result = fetch_taiwan_df_this_year()
285
  if isinstance(result, pd.DataFrame):
 
287
  lines = [f"🇹🇼 今年 ({datetime.now(timezone.utc).year} 年) 台灣區域顯著地震 (M≥5.0),共 {count} 筆:", "-" * 20]
288
  for _, row in result.head(15).iterrows():
289
  t = row["time_utc"].strftime("%Y-%m-%d %H:%M")
290
+ lines.append(f"震級: {row['magnitude']:.1f} | 日期時間: {t} (UTC)\n地點: {row['place']}")
291
  if count > 15:
292
  lines.append(f"... (還有 {count - 15} 筆,可用「臺灣地震畫圖」查看全部)")
293
  reply_text = "\n\n".join(lines)
 
298
  )
299
  return
300
 
301
+ # 全球 24 小時(已含日期)
302
  if ("地震" in user_message) or ("quake" in user_message):
303
  reply_text = fetch_global_last24h_text()
304
  line_bot_api.reply_message_with_http_info(
 
306
  )
307
  return
308
 
309
+ # 打招呼
310
  if ("你好" in user_message) or ("hi" in user_message):
311
  line_bot_api.reply_message_with_http_info(
312
  ReplyMessageRequest(