Skip to content

Commit 0c8d20a

Browse files
Merge pull request #50 from jinwandalaohu66/submission/script_mna05y9m
2 parents e134af9 + c169d2e commit 0c8d20a

2 files changed

Lines changed: 337 additions & 2 deletions

File tree

script_library/index.json

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"format_version": 1,
3-
"data_version": 32,
4-
"updated": "2026-03-28T03:12:59.398Z",
3+
"data_version": 33,
4+
"updated": "2026-03-28T07:22:26.154Z",
55
"announcement": null,
66
"categories": [
77
{
@@ -821,6 +821,29 @@
821821
"updated": null,
822822
"status": "active",
823823
"lines": 87
824+
},
825+
{
826+
"id": "script_mna05y9m",
827+
"name": "今日油价",
828+
"name_en": "今日油价",
829+
"desc": "CITY_NAME = \"北京\" # ← 在这里修改城市名称",
830+
"desc_en": "CITY_NAME = \"北京\" # ← 在这里修改城市名称",
831+
"category": "widgets",
832+
"file": "scripts/widgets/script_mna05y9m.py",
833+
"thumbnail": null,
834+
"version": 1,
835+
"file_type": "py",
836+
"author": "一只菜鸡",
837+
"author_en": "一只菜鸡",
838+
"tags": [
839+
"community"
840+
],
841+
"requires": [],
842+
"min_app_version": "1.5.0",
843+
"added": "2026-03-28",
844+
"updated": null,
845+
"status": "active",
846+
"lines": 312
824847
}
825848
]
826849
}
Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
# 92-95每日油价桌面小组件
2+
# 数据来源:20121212.cn 油价接口
3+
# 城市可自定义设置
4+
# 注意:每次刷新都会从网络获取最新数据,无缓存
5+
6+
from widget import Widget, family, SMALL, MEDIUM, LARGE
7+
import datetime
8+
import json
9+
10+
# ═══════════════════════════════════════════════════════════
11+
# 配置区 - 设置你所在的城市
12+
# 支持城市:北京、上海、广州、深圳、杭州、南京、武汉、成都、重庆、西安、天津 等
13+
# ═══════════════════════════════════════════════════════════
14+
CITY_NAME = "北京" # ← 在这里修改城市名称
15+
16+
# ═══════════════════════════════════════════════════════════
17+
# 油价API接口
18+
# ═══════════════════════════════════════════════════════════
19+
OIL_PRICE_API = "https://20121212.cn/ci/index.php/iol/like/"
20+
21+
22+
def get_oil_price_from_api(city_name):
23+
"""
24+
从油价API获取数据
25+
接口:https://20121212.cn/ci/index.php/iol/like/{城市名}
26+
"""
27+
try:
28+
import requests
29+
except ImportError:
30+
return None
31+
32+
url = f"{OIL_PRICE_API}{city_name}"
33+
34+
try:
35+
resp = requests.get(url, timeout=10)
36+
text = resp.text
37+
resp.close()
38+
39+
# 解析JSON数据
40+
data = json.loads(text)
41+
42+
# 检查是否成功返回数据
43+
if isinstance(data, list) and len(data) > 0:
44+
item = data[0]
45+
46+
return {
47+
"price92": float(item.get("iol92", 0)),
48+
"price95": float(item.get("iol95", 0)),
49+
"price98": float(item.get("iol98", 0)),
50+
"price89": float(item.get("iol89", 0)),
51+
"price0": float(item.get("iol0", 0)),
52+
"price10": float(item.get("iol10", 0)),
53+
"price20": float(item.get("iol20", 0)),
54+
"price35": float(item.get("iol35", 0)),
55+
"ton92": item.get("ton92", ""),
56+
"ton95": item.get("ton95", ""),
57+
"ton98": item.get("ton98", ""),
58+
"update": item.get("date", ""),
59+
"city_raw": item.get("city", ""),
60+
}
61+
except Exception as e:
62+
print(f"API请求失败: {e}")
63+
64+
return None
65+
66+
67+
def get_oil_price(city_name=None):
68+
"""
69+
获取油价数据(直接请求API,不使用缓存)
70+
"""
71+
# 使用配置的城市名
72+
if not city_name:
73+
city_name = CITY_NAME
74+
75+
# 直接从API获取
76+
api_data = get_oil_price_from_api(city_name)
77+
if api_data:
78+
return api_data, city_name, True
79+
80+
# API不可用,返回失败状态
81+
return None, city_name, False
82+
83+
84+
# ═══════════════════════════════════════════════════════════
85+
# 主程序 - 小组件渲染
86+
# ═══════════════════════════════════════════════════════════
87+
88+
# 获取油价数据
89+
oil_data, current_city, data_ok = get_oil_price()
90+
now = datetime.datetime.now()
91+
92+
# 配色方案 - 暖白主题
93+
BG_COLOR = ("#FFFBEB", "#1C1917")
94+
CARD_BG = ("#FEF3C7", "#292524")
95+
TITLE_COLOR = ("#78350F", "#FDE68A")
96+
TEXT_COLOR = ("#92400E", "#D6D3D1")
97+
SUB_COLOR = ("#B45309", "#78716C")
98+
ACCENT_COLOR = ("#EA580C", "#FB923C")
99+
ERROR_COLOR = ("#DC2626", "#F87171")
100+
101+
# 创建小组件
102+
w = Widget(background=BG_COLOR, padding=14)
103+
104+
if family == SMALL:
105+
# ═══ SMALL (127×127pt) ═══
106+
# 极简设计:单行展示核心油价,居中显示
107+
with w.vstack(spacing=0, align="center"):
108+
w.spacer() # 顶部弹性
109+
110+
# 图标 + 标题
111+
w.icon("fuelpump.fill", size=16, color=ACCENT_COLOR)
112+
w.spacer(4)
113+
w.text("油价", size=11, weight="medium", color=SUB_COLOR)
114+
115+
w.spacer(6)
116+
117+
# 核心数据
118+
if data_ok and oil_data:
119+
price92 = oil_data.get("price92", 0)
120+
with w.hstack(spacing=8):
121+
w.text("92#", size=12, weight="semibold", color=TEXT_COLOR)
122+
w.text(f"¥{price92:.2f}", size=20, weight="bold",
123+
design="rounded", color=TITLE_COLOR)
124+
else:
125+
w.text("N/A", size=20, weight="bold",
126+
design="rounded", color=ERROR_COLOR)
127+
128+
w.spacer(4)
129+
130+
# 副标题
131+
if data_ok:
132+
w.text(current_city, size=10, color=SUB_COLOR)
133+
else:
134+
w.text("网络异常", size=10, color=ERROR_COLOR)
135+
136+
w.spacer() # 底部弹性
137+
138+
elif family == MEDIUM:
139+
# ═══ MEDIUM (301×127pt) ═══
140+
# 整体居中:标题行居中 + 卡片组居中
141+
with w.vstack(spacing=0, align="center"):
142+
w.spacer() # 顶部弹性
143+
144+
# 顶部标题行 - 居中
145+
with w.hstack(spacing=6, align="center"):
146+
w.icon("fuelpump.fill", size=14, color=ACCENT_COLOR)
147+
w.text(f"{current_city}今日油价", size=14, weight="semibold",
148+
color=TITLE_COLOR)
149+
w.spacer()
150+
if data_ok and oil_data and oil_data.get("update"):
151+
update_date = oil_data.get("update", "")
152+
try:
153+
date_str = datetime.datetime.strptime(update_date[:10], "%Y-%m-%d").strftime("%m-%d")
154+
except:
155+
date_str = update_date[:10]
156+
w.text(date_str, size=11, color=SUB_COLOR)
157+
else:
158+
w.text("加载中", size=11, color=ERROR_COLOR)
159+
160+
w.spacer() # 弹性撑开
161+
162+
# 主数据区 - 三列卡片居中
163+
if data_ok and oil_data:
164+
price92 = oil_data.get("price92", 0)
165+
price95 = oil_data.get("price95", 0)
166+
price98 = oil_data.get("price98", 0)
167+
168+
with w.hstack(spacing=6, align="center"):
169+
# 左侧 92号
170+
with w.card(background=CARD_BG, corner_radius=10,
171+
padding=10, spacing=0):
172+
with w.vstack(spacing=2, align="center"):
173+
w.text("92#", size=11, weight="semibold", color=SUB_COLOR)
174+
w.text(f"¥{price92:.2f}", size=20, weight="bold",
175+
design="rounded", color=TITLE_COLOR)
176+
w.text("元/升", size=9, color=SUB_COLOR)
177+
178+
# 中间 95号
179+
with w.card(background=CARD_BG, corner_radius=10,
180+
padding=10, spacing=0):
181+
with w.vstack(spacing=2, align="center"):
182+
w.text("95#", size=11, weight="semibold", color=SUB_COLOR)
183+
w.text(f"¥{price95:.2f}", size=20, weight="bold",
184+
design="rounded", color=TITLE_COLOR)
185+
w.text("元/升", size=9, color=SUB_COLOR)
186+
187+
# 右侧 98号
188+
with w.card(background=CARD_BG, corner_radius=10,
189+
padding=10, spacing=0):
190+
with w.vstack(spacing=2, align="center"):
191+
w.text("98#", size=11, weight="semibold", color=SUB_COLOR)
192+
w.text(f"¥{price98:.2f}", size=20, weight="bold",
193+
design="rounded", color=TITLE_COLOR)
194+
w.text("元/升", size=9, color=SUB_COLOR)
195+
else:
196+
# 网络异常时显示错误提示
197+
with w.card(background=CARD_BG, corner_radius=10,
198+
padding=16, spacing=0):
199+
with w.vstack(spacing=4, align="center"):
200+
w.icon("wifi.slash", size=24, color=ERROR_COLOR)
201+
w.text("无法获取油价数据", size=13, weight="medium",
202+
color=TEXT_COLOR)
203+
w.text("请检查网络连接", size=11, color=SUB_COLOR)
204+
205+
w.spacer() # 底部弹性
206+
207+
else:
208+
# ═══ LARGE (301×317pt) ═══
209+
# 完整展示:头部+价格卡片+底部提示,全部居中
210+
with w.vstack(spacing=0, align="center"):
211+
w.spacer() # 顶部弹性
212+
213+
# 头部标题区 - 居中
214+
with w.hstack(spacing=6, align="center"):
215+
w.icon("fuelpump.fill", size=18, color=ACCENT_COLOR)
216+
w.text(f"{current_city}今日油价", size=18, weight="semibold",
217+
color=TITLE_COLOR)
218+
w.spacer()
219+
if data_ok and oil_data and oil_data.get("update"):
220+
update_date = oil_data.get("update", "")
221+
try:
222+
date_str = datetime.datetime.strptime(update_date[:10], "%Y-%m-%d").strftime("%m月%d日")
223+
except:
224+
date_str = update_date[:10]
225+
w.text(date_str, size=12, color=SUB_COLOR)
226+
else:
227+
w.text("加载中", size=12, color=ERROR_COLOR)
228+
229+
w.spacer(12)
230+
231+
if data_ok and oil_data:
232+
price92 = oil_data.get("price92", 0)
233+
price95 = oil_data.get("price95", 0)
234+
price98 = oil_data.get("price98", 0)
235+
price0 = oil_data.get("price0", 0)
236+
update_date = oil_data.get("update", "")
237+
238+
# 价格卡片区 - 2x2布局,全部居中
239+
with w.hstack(spacing=8, align="center"):
240+
# 92号卡片
241+
with w.card(background=CARD_BG, corner_radius=12, padding=12):
242+
with w.vstack(spacing=2, align="center"):
243+
w.text("92# 汽油", size=12, weight="medium", color=SUB_COLOR)
244+
w.text(f"¥{price92:.2f}", size=26, weight="bold",
245+
design="rounded", color=TITLE_COLOR)
246+
w.text("元/升", size=10, color=SUB_COLOR)
247+
248+
# 95号卡片
249+
with w.card(background=CARD_BG, corner_radius=12, padding=12):
250+
with w.vstack(spacing=2, align="center"):
251+
w.text("95# 汽油", size=12, weight="medium", color=SUB_COLOR)
252+
w.text(f"¥{price95:.2f}", size=26, weight="bold",
253+
design="rounded", color=TITLE_COLOR)
254+
w.text("元/升", size=10, color=SUB_COLOR)
255+
256+
w.spacer(8)
257+
258+
with w.hstack(spacing=8, align="center"):
259+
# 98号卡片
260+
with w.card(background=CARD_BG, corner_radius=12, padding=12):
261+
with w.vstack(spacing=2, align="center"):
262+
w.text("98# 汽油", size=12, weight="medium", color=SUB_COLOR)
263+
w.text(f"¥{price98:.2f}", size=26, weight="bold",
264+
design="rounded", color=TITLE_COLOR)
265+
w.text("元/升", size=10, color=SUB_COLOR)
266+
267+
# 0号柴油卡片
268+
with w.card(background=CARD_BG, corner_radius=12, padding=12):
269+
with w.vstack(spacing=2, align="center"):
270+
w.text("0# 柴油", size=12, weight="medium", color=SUB_COLOR)
271+
w.text(f"¥{price0:.2f}", size=26, weight="bold",
272+
design="rounded", color=TITLE_COLOR)
273+
w.text("元/升", size=10, color=SUB_COLOR)
274+
275+
w.spacer() # 弹性撑开
276+
277+
# 底部提示区 - 居中
278+
with w.card(background=CARD_BG, corner_radius=10, padding=10):
279+
with w.hstack(spacing=8, align="center"):
280+
w.icon("info.circle.fill", size=14, color=ACCENT_COLOR)
281+
with w.vstack(spacing=1):
282+
w.text("数据来源:油价查询接口", size=10, color=SUB_COLOR)
283+
if update_date:
284+
w.text(f"更新时间 {update_date},实际价格以加油站为准",
285+
size=10, color=SUB_COLOR)
286+
else:
287+
w.text("实际价格以加油站为准",
288+
size=10, color=SUB_COLOR)
289+
else:
290+
# 网络异常时显示错误提示
291+
with w.card(background=CARD_BG, corner_radius=12, padding=20):
292+
with w.vstack(spacing=8, align="center"):
293+
w.icon("wifi.slash", size=36, color=ERROR_COLOR)
294+
w.text("无法获取油价数据", size=16, weight="semibold",
295+
color=TEXT_COLOR)
296+
w.text("请检查网络连接后刷新", size=12, color=SUB_COLOR)
297+
298+
w.spacer()
299+
300+
# 底部提示区
301+
with w.card(background=CARD_BG, corner_radius=10, padding=10):
302+
with w.hstack(spacing=8, align="center"):
303+
w.icon("exclamationmark.triangle.fill", size=14, color=ERROR_COLOR)
304+
with w.vstack(spacing=1):
305+
w.text("提示", size=10, weight="medium", color=TEXT_COLOR)
306+
w.text("确保网络连接正常,小组件将在下次刷新时重试",
307+
size=10, color=SUB_COLOR)
308+
309+
w.spacer() # 底部弹性
310+
311+
# 渲染小组件
312+
w.render()

0 commit comments

Comments
 (0)