1+ # Quarter OS - System Information Fetcher
2+
3+ try :
4+ import os
5+ import sys
6+ import json
7+ import shutil
8+ import time as tm
9+ import platform
10+ from colorama import Fore , Back , Style , init
11+ except ImportError as e :
12+ print (f"{ Fore .RED } Error: { e } { Style .RESET_ALL } " )
13+ print (f"{ Fore .LIGHTGREEN_EX } This tool only works on Quarter OS version Alpha 0.2.2 or later.{ Style .RESET_ALL } " )
14+ exit ()
15+ except Exception as e :
16+ print (f"{ Fore .RED } Error: { e } { Style .RESET_ALL } " )
17+ exit ()
18+
19+ init (autoreset = True )
20+
21+ qos_big_logo = """
22+ %%%%%%%%%%
23+ %%%%%%%%%%%%%%%%%%%%
24+ %%%%%%%%%%%%%%%%%%%%%%%%%%
25+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26+ %%%%%%%%%%%% %%%%%%%%%%%%
27+ %%%%%%%%%% %%%%%%%%%%
28+ %%%%%%%%% %%%%%%%%%
29+ %%%%%%%%% %%%%%%%%%
30+ %%%%%%%% %%%% %%%%%%%%
31+ %%%%%%%% %%%%%%%% %%%%%%%%
32+ %%%%%%%% %%%%%%%% %%%%%%%%
33+ %%%%%%%% %%%%% %%%%%%%%
34+ %%%%%%%%% %%% %%%%%%%%%
35+ %%%%%%%%% %%%%%%%%%%%%%%
36+ %%%%%%%%%% %%%%%%%%%%%%%
37+ %%%%%%%%%%%% %%%%%%%%%%%%
38+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40+ %%%%%%%%%%%%%%%%%%%% %%%%%%%%
41+ %%%%%%%%%% %%%%
42+ """
43+
44+ def get_package_value ():
45+ """获取Quarter OS中,Biscuit和Shizuku的软件包数量"""
46+ # 定义全局变量:biscuit_value和shizuku_value
47+ global biscuit_value , shizuku_value
48+ # 获取Biscuit软件包数量
49+ try :
50+ with open (os .path .join (".." , ".." , ".." , "system" , "shell" , "apps.json" ), "r" ) as biscuit_sys_file :
51+ biscuit_sys_data = json .load (biscuit_sys_file )
52+ biscuit_value_sys = len (biscuit_sys_data )
53+ with open (os .path .join (".." , ".." , "shell" , "apps.json" ), "r" ) as biscuit_3rd_file :
54+ biscuit_3rd_data = json .load (biscuit_3rd_file )
55+ biscuit_value_3rd = len (biscuit_3rd_data )
56+ biscuit_value = biscuit_value_sys + biscuit_value_3rd
57+ except (FileNotFoundError , json .JSONDecodeError , TypeError , KeyError , IndexError , AttributeError , ValueError , OSError , IOError ):
58+ # 若文件不存在或格式错误,则置0
59+ biscuit_value = 0
60+ except Exception as e :
61+ print (f"{ Fore .RED } Error: { e } { Style .RESET_ALL } " )
62+ sys .exit (1 )
63+ # 获取Shizuku软件包数量
64+ try :
65+ with open (os .path .join (".." , ".." , "shizuku" , "apps.json" ), "r" ) as shizuku_file :
66+ shizuku_data = json .load (shizuku_file )
67+ shizuku_value = len (shizuku_data )
68+ except (FileNotFoundError , json .JSONDecodeError , TypeError , KeyError , IndexError , AttributeError , ValueError , OSError , IOError ):
69+ # 若文件不存在或格式错误,则置0
70+ shizuku_value = 0
71+ except Exception as e :
72+ print (f"{ Fore .RED } Error: { e } { Style .RESET_ALL } " )
73+ sys .exit (1 )
74+
75+ def main ():
76+ # 获取Quarter OS的配置文件数据
77+ try :
78+ with open (os .path .join (".." , ".." , "config" , "config.json" )) as qos_config_file :
79+ config_data = json .load (qos_config_file )
80+ qos_version = config_data .get ("version" , "?" )
81+ qos_vercode = config_data .get ("vercode" , "?" )
82+ qos_name = config_data .get ("system_name" , "qos" )
83+ qos_path = config_data .get ("qos_path" , "unknown path" )
84+ qos_activate = config_data .get ("activate_statue" , False )
85+ qos_edition = config_data .get ("qos_edition" , "unknown edition" )
86+ last_login = config_data .get ("last_login" , "user" )
87+ except FileNotFoundError :
88+ print (f"{ Fore .RED } Error: Config file not found.{ Style .RESET_ALL } " )
89+ sys .exit (1 )
90+ except json .JSONDecodeError :
91+ print (f"{ Fore .RED } Error: Config file is not a valid JSON file.{ Style .RESET_ALL } " )
92+ sys .exit (1 )
93+ except Exception as e :
94+ print (f"{ Fore .RED } Error: { e } { Style .RESET_ALL } " )
95+ print (f"{ Fore .LIGHTGREEN_EX } This tool only works on Quarter OS version Alpha 0.2.2 or later.{ Style .RESET_ALL } " )
96+ sys .exit (1 )
97+
98+ get_package_value () # 获取Biscuit和Shizuku的软件包数量
99+
100+ # 从动态数据中获取信息
101+ item_qos_login = str (f"{ last_login } @{ qos_name } " )
102+ item_qos_version = str (f"{ qos_version } ({ qos_vercode } )" )
103+ item_qos_path = str (qos_path )
104+ item_qos_shell = str (f"KomShell - { qos_version } " )
105+ item_qos_pks = str (f"Biscuit ({ biscuit_value } ) | Shizuku ({ shizuku_value } )" )
106+ item_qos_edition = str (qos_edition )
107+ item_sys_platform = str (f"{ platform .system ()} { platform .release ()} " )
108+ item_sys_version = str (platform .version ())
109+ item_dev_name = str (platform .node ())
110+ item_sys_arch = str (platform .machine ())
111+ item_dev_cpu = str (platform .processor ())
112+ item_py_ver = str (platform .python_version ())
113+ item_py_exec = str (sys .executable )
114+
115+ # 准备输出信息的一些数据变量
116+ qos_logo_lines = qos_big_logo .split ('\n ' ) # 将logo分割成行(应该是22行)
117+ qos_logo_line_width = len (qos_logo_lines [0 ]) # logo每一行的长度(单位:字符)
118+ terminal_width = shutil .get_terminal_size ().columns # 获取终端宽度(单位:字符)
119+ div_line_width = terminal_width - len (qos_logo_lines [0 ]) - 2 # 分割线的长度(单位:字符)
120+
121+ # 输出信息的键(以列表形式存储)
122+ infos = [
123+ [" " , "" , 1 ],
124+ [f"{ Fore .LIGHTMAGENTA_EX } Quarter OS System Information Fetcher{ Fore .RESET } " , "" , 37 ],
125+ ["-" * div_line_width , "" , div_line_width ],
126+ [f"{ Fore .YELLOW } Quarter OS Login: { Style .RESET_ALL } " , item_qos_login , 18 ],
127+ [f"{ Fore .YELLOW } Quarter OS Version: { Style .RESET_ALL } " , item_qos_version , 20 ],
128+ [f"{ Fore .YELLOW } Quarter OS Path: { Style .RESET_ALL } " , item_qos_path , 17 ],
129+ [f"{ Fore .YELLOW } Quarter OS Shell: { Style .RESET_ALL } " , item_qos_shell , 18 ],
130+ [f"{ Fore .YELLOW } Quarter OS Packages: { Style .RESET_ALL } " , item_qos_pks , 21 ],
131+ [f"{ Fore .YELLOW } Quarter OS Edition: { Style .RESET_ALL } " , item_qos_edition if qos_activate else "" , 20 ],
132+ [f"{ Fore .CYAN } System Platform: { Style .RESET_ALL } " , item_sys_platform , 17 ],
133+ [f"{ Fore .CYAN } System Version: { Style .RESET_ALL } " , item_sys_version , 16 ],
134+ [f"{ Fore .CYAN } Device Name: { Style .RESET_ALL } " , item_dev_name , 13 ],
135+ [f"{ Fore .CYAN } System Architecture: { Style .RESET_ALL } " , item_sys_arch , 21 ],
136+ [f"{ Fore .CYAN } Device Processor: { Style .RESET_ALL } " , item_dev_cpu , 18 ],
137+ [f"{ Fore .CYAN } Python Version: { Style .RESET_ALL } " , item_py_ver , 16 ],
138+ [f"{ Fore .CYAN } Python Executable: { Style .RESET_ALL } " , item_py_exec , 19 ],
139+ [" " , "" , 1 ],
140+ [f"{ Fore .LIGHTGREEN_EX } Fetched at { tm .strftime ('%Y-%m-%d %H:%M:%S' , tm .localtime ())} { Style .RESET_ALL } " , "" , 30 ],
141+ [" " , "" , 1 ],
142+ [f"{ Back .BLACK } { Back .RED } { Back .GREEN } { Back .YELLOW } { Back .BLUE } { Back .MAGENTA } { Back .CYAN } { Back .WHITE } { Style .RESET_ALL } " , "" , 24 ],
143+ [f"{ Back .LIGHTBLACK_EX } { Back .LIGHTRED_EX } { Back .LIGHTGREEN_EX } { Back .LIGHTYELLOW_EX } { Back .LIGHTBLUE_EX } { Back .LIGHTMAGENTA_EX } { Back .LIGHTCYAN_EX } { Back .LIGHTWHITE_EX } { Style .RESET_ALL } " , "" , 24 ],
144+ [" " , "" , 1 ]
145+ ]
146+ # 其中,0为info的键,1为info的值,2为键的长度
147+
148+ # Logo和info的行数
149+ logo_lines_num = len (qos_logo_lines )
150+ infos_num = len (infos )
151+ if logo_lines_num > infos_num : # logo行数大于info行数,则需要补充空行
152+ need_lines_num = logo_lines_num
153+ else : # logo行数小于等于info行数,则直接输出
154+ need_lines_num = infos_num
155+
156+ # 循环打印一行logo和一条info
157+ for i in range (need_lines_num ):
158+ if i < logo_lines_num :
159+ logo_text = f"{ Fore .BLUE } { qos_logo_lines [i ]} { Style .RESET_ALL } "
160+ else :
161+ logo_text = " " * qos_logo_line_width
162+ if i < infos_num :
163+ used_space = qos_logo_line_width + 1 + infos [i ][2 ] + 1 # 最后留一个空字符
164+ free_space = terminal_width - used_space # 供info[i][1]使用的剩余空间
165+ dynamical_space = len (infos [i ][1 ]) # 计算当前值需要占用的空间
166+ combined_space = dynamical_space - free_space # 计算需要截断的字符长度(后面的部分)
167+ if combined_space > 0 : # 计算结果大于0,说明需要截断
168+ dyna_words = infos [i ][1 ][0 :dynamical_space - combined_space ] # 截断后的字符串
169+ else : # 计算结果小于等于0,说明不需要截断
170+ dyna_words = infos [i ][1 ] # 直接输出原字符串
171+ info_text = infos [i ][0 ] + dyna_words
172+ else :
173+ info_text = " " * (terminal_width - qos_logo_line_width - 1 )
174+ line_text = logo_text + " " + info_text
175+ print (line_text .ljust (terminal_width )) # 左对齐,右边用空格填充,打印出来
176+
177+ if __name__ == "__main__" :
178+ main ()
0 commit comments