1+ # 2026-4-3 Silence
2+
3+ import os
4+ from widget import Widget , family , MEDIUM
5+
6+ def get_storage_info ():
7+ statvfs = os .statvfs ('/' )
8+ block_size = statvfs .f_frsize
9+ total = statvfs .f_blocks * block_size
10+ free = statvfs .f_bavail * block_size
11+ used = total - free
12+ used_percent = (used / total ) * 100 if total else 0
13+
14+ total_gb = total / (1024 ** 3 )
15+ used_gb = used / (1024 ** 3 )
16+ free_gb = free / (1024 ** 3 )
17+ return total_gb , used_gb , free_gb , used_percent
18+
19+ def render_widget ():
20+ total , used , free , percent = get_storage_info ()
21+
22+ bar_width = int (200 * (percent / 100 ))
23+ bar_width = min (200 , max (0 , bar_width ))
24+
25+ bg_color = ("#F1F5F9" , "#0F172A" )
26+ w = Widget (background = bg_color , padding = 16 )
27+
28+ with w .vstack (spacing = 12 ):
29+
30+ with w .hstack ():
31+ w .icon ("internaldrive" , size = 18 , color = "#3B82F6" )
32+ w .text ("存储空间" , size = 14 , weight = "semibold" , color = ("#0F172A" , "#F1F5F9" ))
33+ w .spacer ()
34+ w .text (f"{ percent :.0f} %" , size = 12 , weight = "medium" , color = "#3B82F6" )
35+
36+
37+ with w .hstack ():
38+ w .spacer ()
39+ with w .vstack ():
40+
41+ w .text ("" , size = 1 )
42+
43+ pass
44+
45+ w .progress (percent / 100 , color = "#3B82F6" , track_color = ("#E2E8F0" , "#334155" ), height = 8 )
46+
47+
48+ with w .hstack ():
49+ with w .vstack (align = "leading" , spacing = 4 ):
50+ w .text ("已用" , size = 11 , color = ("#64748B" , "#94A3B8" ))
51+ w .text (f"{ used :.1f} GB" , size = 15 , weight = "bold" , color = ("#0F172A" , "#F1F5F9" ))
52+ w .spacer ()
53+ with w .vstack (align = "trailing" , spacing = 4 ):
54+ w .text ("可用" , size = 11 , color = ("#64748B" , "#94A3B8" ))
55+ w .text (f"{ free :.1f} GB" , size = 15 , weight = "bold" , color = ("#10B981" , "#34D399" ))
56+ w .spacer ()
57+ with w .vstack (align = "trailing" , spacing = 4 ):
58+ w .text ("总计" , size = 11 , color = ("#64748B" , "#94A3B8" ))
59+ w .text (f"{ total :.1f} GB" , size = 15 , weight = "bold" , color = ("#0F172A" , "#F1F5F9" ))
60+
61+
62+ if free < 5 :
63+ w .text ("⚠️剩余不足5G快去删点片吧⚠️" , size = 10 , color = "#EF4444" , align = "center" )
64+
65+ w .render ()
66+
67+ if family == MEDIUM :
68+ render_widget ()
69+ else :
70+ w = Widget (background = ("#FFFFFF" , "#0B0F1A" ), padding = 16 )
71+ with w .vstack (align = "center" , spacing = 8 ):
72+ w .icon ("internaldrive" , size = 30 , color = "#3B82F6" )
73+ w .text ("请使用中尺寸小组件" , size = 14 , weight = "semibold" , color = ("#111" , "#EEE" ))
74+ w .render ()
0 commit comments