metafetch 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metafetch-1.0.0/LICENSE +21 -0
- metafetch-1.0.0/PKG-INFO +170 -0
- metafetch-1.0.0/README.md +125 -0
- metafetch-1.0.0/metafetch.egg-info/PKG-INFO +170 -0
- metafetch-1.0.0/metafetch.egg-info/SOURCES.txt +10 -0
- metafetch-1.0.0/metafetch.egg-info/dependency_links.txt +1 -0
- metafetch-1.0.0/metafetch.egg-info/entry_points.txt +2 -0
- metafetch-1.0.0/metafetch.egg-info/requires.txt +1 -0
- metafetch-1.0.0/metafetch.egg-info/top_level.txt +1 -0
- metafetch-1.0.0/metafetch.py +650 -0
- metafetch-1.0.0/setup.cfg +4 -0
- metafetch-1.0.0/setup.py +54 -0
metafetch-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 MetaFetch
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
metafetch-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: metafetch
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A beautiful, fast, and comprehensive system information tool
|
|
5
|
+
Home-page: https://github.com/volksgeistt/metafetch
|
|
6
|
+
Author: Ujjawal Singh / @volksgeistt
|
|
7
|
+
Author-email: unrealvolksgeist@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Bug Reports, https://github.com/volksgeistt/metafetch/issues
|
|
10
|
+
Project-URL: Source, https://github.com/volksgeistt/metafetch
|
|
11
|
+
Project-URL: Documentation, https://github.com/volksgeistt/metafetch/blob/main/README.md
|
|
12
|
+
Keywords: system information neofetch system-info cli terminal
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Topic :: System :: Systems Administration
|
|
27
|
+
Classifier: Topic :: Utilities
|
|
28
|
+
Requires-Python: >=3.6
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: psutil>=5.8.0
|
|
32
|
+
Dynamic: author
|
|
33
|
+
Dynamic: author-email
|
|
34
|
+
Dynamic: classifier
|
|
35
|
+
Dynamic: description
|
|
36
|
+
Dynamic: description-content-type
|
|
37
|
+
Dynamic: home-page
|
|
38
|
+
Dynamic: keywords
|
|
39
|
+
Dynamic: license
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
Dynamic: project-url
|
|
42
|
+
Dynamic: requires-dist
|
|
43
|
+
Dynamic: requires-python
|
|
44
|
+
Dynamic: summary
|
|
45
|
+
|
|
46
|
+
# MetaFetch
|
|
47
|
+
A beautiful, fast, and comprehensive system information tool inspired by neofetch, written in Python with enhanced cross-platform support.
|
|
48
|
+
```bash
|
|
49
|
+
- john@desktop
|
|
50
|
+
.o+` -------------
|
|
51
|
+
`ooo/ OS: Ubuntu 22.04.3 LTS
|
|
52
|
+
`+oooo: Kernel: 5.15.0-84-generic
|
|
53
|
+
`+oooooo: Uptime: 2d 14h 32m
|
|
54
|
+
-+oooooo+: Packages: 2847 (apt), 23 (pip)
|
|
55
|
+
`/:-:++oooo+: Shell: bash 5.1.16
|
|
56
|
+
`/++++/+++++++: Desktop: GNOME
|
|
57
|
+
`/++++++++++++++: Terminal: gnome-terminal
|
|
58
|
+
`/+++ooooooooo+/` CPU: Intel i7-9700K (8C)
|
|
59
|
+
./ooosssso++osssssso+` GPU: NVIDIA GeForce RTX 3070
|
|
60
|
+
.oossssso-````/ossssss+` Memory: 8.2GB / 32.0GB (26%)
|
|
61
|
+
-osssssso. :ssssssso. Disk: 245.8GB / 931.5GB (26%)
|
|
62
|
+
:osssssss/ osssso+++. Network: eth0 (192.168.1.100)
|
|
63
|
+
/ossssssss/ +ssssooo/- Resolution: 2560x1440
|
|
64
|
+
`/ossssso+/:- -:/+osssso+-
|
|
65
|
+
`+sso+:-` `.-/+oso: ███████████████████████████
|
|
66
|
+
`++:. `-/+/ ███████████████████████████
|
|
67
|
+
.` `/
|
|
68
|
+
```
|
|
69
|
+
---
|
|
70
|
+
## 🌟 Features
|
|
71
|
+
- Cross-Platform Support: Works seamlessly on Linux, macOS, and Windows
|
|
72
|
+
- Comprehensive System Info: Display detailed information about your system
|
|
73
|
+
- Beautiful ASCII Art: Platform-specific ASCII logos with colorful output
|
|
74
|
+
- Multiple Display Modes: Full, minimal, and color palette display options
|
|
75
|
+
- Package Manager Detection: Supports multiple package managers (apt, dnf, pacman, brew, pip, npm, etc.)
|
|
76
|
+
- Desktop Environment Detection: Automatically detects DE and WM
|
|
77
|
+
- Network Interface Information: Shows active network interfaces
|
|
78
|
+
- Performance Monitoring: Real-time memory, disk, and swap usage
|
|
79
|
+
- Customizable Output: Easy to extend and modify
|
|
80
|
+
---
|
|
81
|
+
## 🚀 Installation
|
|
82
|
+
**Prerequisites**
|
|
83
|
+
- Make sure you have Python 3.6 or higher installed:
|
|
84
|
+
```bash
|
|
85
|
+
python --version
|
|
86
|
+
```
|
|
87
|
+
**Install from Source**
|
|
88
|
+
1. Clone the repository:
|
|
89
|
+
```bash
|
|
90
|
+
git clone https://github.com/volksgeistt/metafetch
|
|
91
|
+
cd metafetch
|
|
92
|
+
```
|
|
93
|
+
2. Install dependencies:
|
|
94
|
+
```bash
|
|
95
|
+
pip install -r requirements.txt
|
|
96
|
+
```
|
|
97
|
+
3. Make it executable (Linux/macOS):
|
|
98
|
+
```bash
|
|
99
|
+
chmod +x metafetch.py
|
|
100
|
+
```
|
|
101
|
+
**System-wide Installation (Optional)**
|
|
102
|
+
Create a link to use `metafetch` from anywhere:
|
|
103
|
+
```bash
|
|
104
|
+
# Linux/macOS
|
|
105
|
+
sudo ln -s $(pwd)/metafetch.py /usr/local/bin/metafetch
|
|
106
|
+
|
|
107
|
+
# Or add to your PATH
|
|
108
|
+
export PATH="$PATH:$(pwd)"
|
|
109
|
+
```
|
|
110
|
+
---
|
|
111
|
+
## 📖 Usage
|
|
112
|
+
**Basic:**
|
|
113
|
+
```bash
|
|
114
|
+
python metafetch.py
|
|
115
|
+
# or if installed globally
|
|
116
|
+
metafetch
|
|
117
|
+
```
|
|
118
|
+
**Command Line Options:**
|
|
119
|
+
```bash
|
|
120
|
+
metafetch [OPTIONS]
|
|
121
|
+
|
|
122
|
+
Options:
|
|
123
|
+
-m, --minimal Display minimal system information
|
|
124
|
+
-c, --colors Show color palette demonstration
|
|
125
|
+
--version Show version information
|
|
126
|
+
-h, --help Show help message
|
|
127
|
+
```
|
|
128
|
+
---
|
|
129
|
+
## Examples
|
|
130
|
+
**Full system information (default):**
|
|
131
|
+
```bash
|
|
132
|
+
metafetch
|
|
133
|
+
```
|
|
134
|
+
**Minimal display:**
|
|
135
|
+
```
|
|
136
|
+
metafetch -m
|
|
137
|
+
```
|
|
138
|
+
**Color palette:**
|
|
139
|
+
```bash
|
|
140
|
+
metafetch -c
|
|
141
|
+
```
|
|
142
|
+
---
|
|
143
|
+
## 🎨 Customization
|
|
144
|
+
MetaFetch is highly customizable. You can modify:
|
|
145
|
+
- Colors: Edit the colors dictionary in the `metafetch` class
|
|
146
|
+
- ASCII Art: Modify the `get_ascii_art()` method
|
|
147
|
+
- Information Fields: Add or remove fields in the `collect_info()` method
|
|
148
|
+
- Display Format: Customize the `display()` method
|
|
149
|
+
---
|
|
150
|
+
## 🔧 Supported Systems
|
|
151
|
+
**Operating Systems**
|
|
152
|
+
- Linux: All major distributions (Ubuntu, Debian, Fedora, Arch, etc.)
|
|
153
|
+
- macOS: macOS 10.12+ (Sierra and later)
|
|
154
|
+
- Windows: Windows 10/11
|
|
155
|
+
|
|
156
|
+
**Package Managers**
|
|
157
|
+
- Linux: apt, dnf/yum, pacman, portage, xbps, apk
|
|
158
|
+
- macOS: brew
|
|
159
|
+
- Cross-platform: pip, conda, npm, gem, cargo
|
|
160
|
+
|
|
161
|
+
**Desktop Environments**
|
|
162
|
+
- GNOME, KDE Plasma, XFCE, MATE, Cinnamon
|
|
163
|
+
- Window Managers: i3, bspwm, awesome, dwm, openbox, fluxbox
|
|
164
|
+
---
|
|
165
|
+
<div align="center">
|
|
166
|
+
<sub>Built with ❤️ by <a href="https://github.com/volksgeistt">Ujjawal Singh</a></sub>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# MetaFetch
|
|
2
|
+
A beautiful, fast, and comprehensive system information tool inspired by neofetch, written in Python with enhanced cross-platform support.
|
|
3
|
+
```bash
|
|
4
|
+
- john@desktop
|
|
5
|
+
.o+` -------------
|
|
6
|
+
`ooo/ OS: Ubuntu 22.04.3 LTS
|
|
7
|
+
`+oooo: Kernel: 5.15.0-84-generic
|
|
8
|
+
`+oooooo: Uptime: 2d 14h 32m
|
|
9
|
+
-+oooooo+: Packages: 2847 (apt), 23 (pip)
|
|
10
|
+
`/:-:++oooo+: Shell: bash 5.1.16
|
|
11
|
+
`/++++/+++++++: Desktop: GNOME
|
|
12
|
+
`/++++++++++++++: Terminal: gnome-terminal
|
|
13
|
+
`/+++ooooooooo+/` CPU: Intel i7-9700K (8C)
|
|
14
|
+
./ooosssso++osssssso+` GPU: NVIDIA GeForce RTX 3070
|
|
15
|
+
.oossssso-````/ossssss+` Memory: 8.2GB / 32.0GB (26%)
|
|
16
|
+
-osssssso. :ssssssso. Disk: 245.8GB / 931.5GB (26%)
|
|
17
|
+
:osssssss/ osssso+++. Network: eth0 (192.168.1.100)
|
|
18
|
+
/ossssssss/ +ssssooo/- Resolution: 2560x1440
|
|
19
|
+
`/ossssso+/:- -:/+osssso+-
|
|
20
|
+
`+sso+:-` `.-/+oso: ███████████████████████████
|
|
21
|
+
`++:. `-/+/ ███████████████████████████
|
|
22
|
+
.` `/
|
|
23
|
+
```
|
|
24
|
+
---
|
|
25
|
+
## 🌟 Features
|
|
26
|
+
- Cross-Platform Support: Works seamlessly on Linux, macOS, and Windows
|
|
27
|
+
- Comprehensive System Info: Display detailed information about your system
|
|
28
|
+
- Beautiful ASCII Art: Platform-specific ASCII logos with colorful output
|
|
29
|
+
- Multiple Display Modes: Full, minimal, and color palette display options
|
|
30
|
+
- Package Manager Detection: Supports multiple package managers (apt, dnf, pacman, brew, pip, npm, etc.)
|
|
31
|
+
- Desktop Environment Detection: Automatically detects DE and WM
|
|
32
|
+
- Network Interface Information: Shows active network interfaces
|
|
33
|
+
- Performance Monitoring: Real-time memory, disk, and swap usage
|
|
34
|
+
- Customizable Output: Easy to extend and modify
|
|
35
|
+
---
|
|
36
|
+
## 🚀 Installation
|
|
37
|
+
**Prerequisites**
|
|
38
|
+
- Make sure you have Python 3.6 or higher installed:
|
|
39
|
+
```bash
|
|
40
|
+
python --version
|
|
41
|
+
```
|
|
42
|
+
**Install from Source**
|
|
43
|
+
1. Clone the repository:
|
|
44
|
+
```bash
|
|
45
|
+
git clone https://github.com/volksgeistt/metafetch
|
|
46
|
+
cd metafetch
|
|
47
|
+
```
|
|
48
|
+
2. Install dependencies:
|
|
49
|
+
```bash
|
|
50
|
+
pip install -r requirements.txt
|
|
51
|
+
```
|
|
52
|
+
3. Make it executable (Linux/macOS):
|
|
53
|
+
```bash
|
|
54
|
+
chmod +x metafetch.py
|
|
55
|
+
```
|
|
56
|
+
**System-wide Installation (Optional)**
|
|
57
|
+
Create a link to use `metafetch` from anywhere:
|
|
58
|
+
```bash
|
|
59
|
+
# Linux/macOS
|
|
60
|
+
sudo ln -s $(pwd)/metafetch.py /usr/local/bin/metafetch
|
|
61
|
+
|
|
62
|
+
# Or add to your PATH
|
|
63
|
+
export PATH="$PATH:$(pwd)"
|
|
64
|
+
```
|
|
65
|
+
---
|
|
66
|
+
## 📖 Usage
|
|
67
|
+
**Basic:**
|
|
68
|
+
```bash
|
|
69
|
+
python metafetch.py
|
|
70
|
+
# or if installed globally
|
|
71
|
+
metafetch
|
|
72
|
+
```
|
|
73
|
+
**Command Line Options:**
|
|
74
|
+
```bash
|
|
75
|
+
metafetch [OPTIONS]
|
|
76
|
+
|
|
77
|
+
Options:
|
|
78
|
+
-m, --minimal Display minimal system information
|
|
79
|
+
-c, --colors Show color palette demonstration
|
|
80
|
+
--version Show version information
|
|
81
|
+
-h, --help Show help message
|
|
82
|
+
```
|
|
83
|
+
---
|
|
84
|
+
## Examples
|
|
85
|
+
**Full system information (default):**
|
|
86
|
+
```bash
|
|
87
|
+
metafetch
|
|
88
|
+
```
|
|
89
|
+
**Minimal display:**
|
|
90
|
+
```
|
|
91
|
+
metafetch -m
|
|
92
|
+
```
|
|
93
|
+
**Color palette:**
|
|
94
|
+
```bash
|
|
95
|
+
metafetch -c
|
|
96
|
+
```
|
|
97
|
+
---
|
|
98
|
+
## 🎨 Customization
|
|
99
|
+
MetaFetch is highly customizable. You can modify:
|
|
100
|
+
- Colors: Edit the colors dictionary in the `metafetch` class
|
|
101
|
+
- ASCII Art: Modify the `get_ascii_art()` method
|
|
102
|
+
- Information Fields: Add or remove fields in the `collect_info()` method
|
|
103
|
+
- Display Format: Customize the `display()` method
|
|
104
|
+
---
|
|
105
|
+
## 🔧 Supported Systems
|
|
106
|
+
**Operating Systems**
|
|
107
|
+
- Linux: All major distributions (Ubuntu, Debian, Fedora, Arch, etc.)
|
|
108
|
+
- macOS: macOS 10.12+ (Sierra and later)
|
|
109
|
+
- Windows: Windows 10/11
|
|
110
|
+
|
|
111
|
+
**Package Managers**
|
|
112
|
+
- Linux: apt, dnf/yum, pacman, portage, xbps, apk
|
|
113
|
+
- macOS: brew
|
|
114
|
+
- Cross-platform: pip, conda, npm, gem, cargo
|
|
115
|
+
|
|
116
|
+
**Desktop Environments**
|
|
117
|
+
- GNOME, KDE Plasma, XFCE, MATE, Cinnamon
|
|
118
|
+
- Window Managers: i3, bspwm, awesome, dwm, openbox, fluxbox
|
|
119
|
+
---
|
|
120
|
+
<div align="center">
|
|
121
|
+
<sub>Built with ❤️ by <a href="https://github.com/volksgeistt">Ujjawal Singh</a></sub>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: metafetch
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A beautiful, fast, and comprehensive system information tool
|
|
5
|
+
Home-page: https://github.com/volksgeistt/metafetch
|
|
6
|
+
Author: Ujjawal Singh / @volksgeistt
|
|
7
|
+
Author-email: unrealvolksgeist@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Bug Reports, https://github.com/volksgeistt/metafetch/issues
|
|
10
|
+
Project-URL: Source, https://github.com/volksgeistt/metafetch
|
|
11
|
+
Project-URL: Documentation, https://github.com/volksgeistt/metafetch/blob/main/README.md
|
|
12
|
+
Keywords: system information neofetch system-info cli terminal
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.6
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Topic :: System :: Systems Administration
|
|
27
|
+
Classifier: Topic :: Utilities
|
|
28
|
+
Requires-Python: >=3.6
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: psutil>=5.8.0
|
|
32
|
+
Dynamic: author
|
|
33
|
+
Dynamic: author-email
|
|
34
|
+
Dynamic: classifier
|
|
35
|
+
Dynamic: description
|
|
36
|
+
Dynamic: description-content-type
|
|
37
|
+
Dynamic: home-page
|
|
38
|
+
Dynamic: keywords
|
|
39
|
+
Dynamic: license
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
Dynamic: project-url
|
|
42
|
+
Dynamic: requires-dist
|
|
43
|
+
Dynamic: requires-python
|
|
44
|
+
Dynamic: summary
|
|
45
|
+
|
|
46
|
+
# MetaFetch
|
|
47
|
+
A beautiful, fast, and comprehensive system information tool inspired by neofetch, written in Python with enhanced cross-platform support.
|
|
48
|
+
```bash
|
|
49
|
+
- john@desktop
|
|
50
|
+
.o+` -------------
|
|
51
|
+
`ooo/ OS: Ubuntu 22.04.3 LTS
|
|
52
|
+
`+oooo: Kernel: 5.15.0-84-generic
|
|
53
|
+
`+oooooo: Uptime: 2d 14h 32m
|
|
54
|
+
-+oooooo+: Packages: 2847 (apt), 23 (pip)
|
|
55
|
+
`/:-:++oooo+: Shell: bash 5.1.16
|
|
56
|
+
`/++++/+++++++: Desktop: GNOME
|
|
57
|
+
`/++++++++++++++: Terminal: gnome-terminal
|
|
58
|
+
`/+++ooooooooo+/` CPU: Intel i7-9700K (8C)
|
|
59
|
+
./ooosssso++osssssso+` GPU: NVIDIA GeForce RTX 3070
|
|
60
|
+
.oossssso-````/ossssss+` Memory: 8.2GB / 32.0GB (26%)
|
|
61
|
+
-osssssso. :ssssssso. Disk: 245.8GB / 931.5GB (26%)
|
|
62
|
+
:osssssss/ osssso+++. Network: eth0 (192.168.1.100)
|
|
63
|
+
/ossssssss/ +ssssooo/- Resolution: 2560x1440
|
|
64
|
+
`/ossssso+/:- -:/+osssso+-
|
|
65
|
+
`+sso+:-` `.-/+oso: ███████████████████████████
|
|
66
|
+
`++:. `-/+/ ███████████████████████████
|
|
67
|
+
.` `/
|
|
68
|
+
```
|
|
69
|
+
---
|
|
70
|
+
## 🌟 Features
|
|
71
|
+
- Cross-Platform Support: Works seamlessly on Linux, macOS, and Windows
|
|
72
|
+
- Comprehensive System Info: Display detailed information about your system
|
|
73
|
+
- Beautiful ASCII Art: Platform-specific ASCII logos with colorful output
|
|
74
|
+
- Multiple Display Modes: Full, minimal, and color palette display options
|
|
75
|
+
- Package Manager Detection: Supports multiple package managers (apt, dnf, pacman, brew, pip, npm, etc.)
|
|
76
|
+
- Desktop Environment Detection: Automatically detects DE and WM
|
|
77
|
+
- Network Interface Information: Shows active network interfaces
|
|
78
|
+
- Performance Monitoring: Real-time memory, disk, and swap usage
|
|
79
|
+
- Customizable Output: Easy to extend and modify
|
|
80
|
+
---
|
|
81
|
+
## 🚀 Installation
|
|
82
|
+
**Prerequisites**
|
|
83
|
+
- Make sure you have Python 3.6 or higher installed:
|
|
84
|
+
```bash
|
|
85
|
+
python --version
|
|
86
|
+
```
|
|
87
|
+
**Install from Source**
|
|
88
|
+
1. Clone the repository:
|
|
89
|
+
```bash
|
|
90
|
+
git clone https://github.com/volksgeistt/metafetch
|
|
91
|
+
cd metafetch
|
|
92
|
+
```
|
|
93
|
+
2. Install dependencies:
|
|
94
|
+
```bash
|
|
95
|
+
pip install -r requirements.txt
|
|
96
|
+
```
|
|
97
|
+
3. Make it executable (Linux/macOS):
|
|
98
|
+
```bash
|
|
99
|
+
chmod +x metafetch.py
|
|
100
|
+
```
|
|
101
|
+
**System-wide Installation (Optional)**
|
|
102
|
+
Create a link to use `metafetch` from anywhere:
|
|
103
|
+
```bash
|
|
104
|
+
# Linux/macOS
|
|
105
|
+
sudo ln -s $(pwd)/metafetch.py /usr/local/bin/metafetch
|
|
106
|
+
|
|
107
|
+
# Or add to your PATH
|
|
108
|
+
export PATH="$PATH:$(pwd)"
|
|
109
|
+
```
|
|
110
|
+
---
|
|
111
|
+
## 📖 Usage
|
|
112
|
+
**Basic:**
|
|
113
|
+
```bash
|
|
114
|
+
python metafetch.py
|
|
115
|
+
# or if installed globally
|
|
116
|
+
metafetch
|
|
117
|
+
```
|
|
118
|
+
**Command Line Options:**
|
|
119
|
+
```bash
|
|
120
|
+
metafetch [OPTIONS]
|
|
121
|
+
|
|
122
|
+
Options:
|
|
123
|
+
-m, --minimal Display minimal system information
|
|
124
|
+
-c, --colors Show color palette demonstration
|
|
125
|
+
--version Show version information
|
|
126
|
+
-h, --help Show help message
|
|
127
|
+
```
|
|
128
|
+
---
|
|
129
|
+
## Examples
|
|
130
|
+
**Full system information (default):**
|
|
131
|
+
```bash
|
|
132
|
+
metafetch
|
|
133
|
+
```
|
|
134
|
+
**Minimal display:**
|
|
135
|
+
```
|
|
136
|
+
metafetch -m
|
|
137
|
+
```
|
|
138
|
+
**Color palette:**
|
|
139
|
+
```bash
|
|
140
|
+
metafetch -c
|
|
141
|
+
```
|
|
142
|
+
---
|
|
143
|
+
## 🎨 Customization
|
|
144
|
+
MetaFetch is highly customizable. You can modify:
|
|
145
|
+
- Colors: Edit the colors dictionary in the `metafetch` class
|
|
146
|
+
- ASCII Art: Modify the `get_ascii_art()` method
|
|
147
|
+
- Information Fields: Add or remove fields in the `collect_info()` method
|
|
148
|
+
- Display Format: Customize the `display()` method
|
|
149
|
+
---
|
|
150
|
+
## 🔧 Supported Systems
|
|
151
|
+
**Operating Systems**
|
|
152
|
+
- Linux: All major distributions (Ubuntu, Debian, Fedora, Arch, etc.)
|
|
153
|
+
- macOS: macOS 10.12+ (Sierra and later)
|
|
154
|
+
- Windows: Windows 10/11
|
|
155
|
+
|
|
156
|
+
**Package Managers**
|
|
157
|
+
- Linux: apt, dnf/yum, pacman, portage, xbps, apk
|
|
158
|
+
- macOS: brew
|
|
159
|
+
- Cross-platform: pip, conda, npm, gem, cargo
|
|
160
|
+
|
|
161
|
+
**Desktop Environments**
|
|
162
|
+
- GNOME, KDE Plasma, XFCE, MATE, Cinnamon
|
|
163
|
+
- Window Managers: i3, bspwm, awesome, dwm, openbox, fluxbox
|
|
164
|
+
---
|
|
165
|
+
<div align="center">
|
|
166
|
+
<sub>Built with ❤️ by <a href="https://github.com/volksgeistt">Ujjawal Singh</a></sub>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
psutil>=5.8.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
metafetch
|
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import platform
|
|
3
|
+
import subprocess
|
|
4
|
+
import socket
|
|
5
|
+
import psutil
|
|
6
|
+
import getpass
|
|
7
|
+
import time
|
|
8
|
+
import sys
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
class metafetch:
|
|
13
|
+
def __init__(self):
|
|
14
|
+
self.info = {}
|
|
15
|
+
self.colors = {
|
|
16
|
+
'red': '\033[91m',
|
|
17
|
+
'green': '\033[92m',
|
|
18
|
+
'yellow': '\033[93m',
|
|
19
|
+
'blue': '\033[94m',
|
|
20
|
+
'purple': '\033[95m',
|
|
21
|
+
'cyan': '\033[96m',
|
|
22
|
+
'white': '\033[97m',
|
|
23
|
+
'gray': '\033[90m',
|
|
24
|
+
'bold': '\033[1m',
|
|
25
|
+
'end': '\033[0m'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def run_command(self, cmd, timeout=3):
|
|
29
|
+
try:
|
|
30
|
+
if isinstance(cmd, str):
|
|
31
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=timeout)
|
|
32
|
+
else:
|
|
33
|
+
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
|
34
|
+
if result.returncode == 0:
|
|
35
|
+
return result.stdout.strip()
|
|
36
|
+
except:
|
|
37
|
+
pass
|
|
38
|
+
return None
|
|
39
|
+
|
|
40
|
+
def get_os_info(self):
|
|
41
|
+
try:
|
|
42
|
+
system = platform.system()
|
|
43
|
+
|
|
44
|
+
if system == "Linux":
|
|
45
|
+
sources = ['/etc/os-release', '/etc/lsb-release', '/etc/redhat-release']
|
|
46
|
+
for source in sources:
|
|
47
|
+
try:
|
|
48
|
+
with open(source, 'r') as f:
|
|
49
|
+
content = f.read()
|
|
50
|
+
if 'PRETTY_NAME=' in content:
|
|
51
|
+
for line in content.split('\n'):
|
|
52
|
+
if line.startswith('PRETTY_NAME='):
|
|
53
|
+
return line.split('=')[1].strip().strip('"')
|
|
54
|
+
elif source == '/etc/redhat-release':
|
|
55
|
+
return content.strip()
|
|
56
|
+
except:
|
|
57
|
+
continue
|
|
58
|
+
|
|
59
|
+
lsb = self.run_command(['lsb_release', '-d'])
|
|
60
|
+
if lsb:
|
|
61
|
+
return lsb.split('\t')[1] if '\t' in lsb else lsb
|
|
62
|
+
|
|
63
|
+
return f"Linux {platform.release()}"
|
|
64
|
+
|
|
65
|
+
elif system == "Darwin":
|
|
66
|
+
version = self.run_command(['sw_vers', '-productVersion'])
|
|
67
|
+
name = self.run_command(['sw_vers', '-productName'])
|
|
68
|
+
if version and name:
|
|
69
|
+
return f"{name} {version}"
|
|
70
|
+
return f"macOS {platform.release()}"
|
|
71
|
+
|
|
72
|
+
elif system == "Windows":
|
|
73
|
+
try:
|
|
74
|
+
import winreg
|
|
75
|
+
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion")
|
|
76
|
+
product_name = winreg.QueryValueEx(key, "ProductName")[0]
|
|
77
|
+
build = winreg.QueryValueEx(key, "CurrentBuild")[0]
|
|
78
|
+
return f"{product_name} (Build {build})"
|
|
79
|
+
except:
|
|
80
|
+
pass
|
|
81
|
+
return f"Windows {platform.release()}"
|
|
82
|
+
else:
|
|
83
|
+
return f"{system} {platform.release()}"
|
|
84
|
+
except:
|
|
85
|
+
return "Unknown OS"
|
|
86
|
+
|
|
87
|
+
def get_kernel(self):
|
|
88
|
+
try:
|
|
89
|
+
system = platform.system()
|
|
90
|
+
if system == "Linux":
|
|
91
|
+
return platform.release()
|
|
92
|
+
elif system == "Darwin":
|
|
93
|
+
return f"Darwin {platform.release()}"
|
|
94
|
+
elif system == "Windows":
|
|
95
|
+
return f"NT {platform.version()}"
|
|
96
|
+
else:
|
|
97
|
+
return platform.release()
|
|
98
|
+
except:
|
|
99
|
+
return "Unknown"
|
|
100
|
+
|
|
101
|
+
def get_uptime(self):
|
|
102
|
+
try:
|
|
103
|
+
boot_time = psutil.boot_time()
|
|
104
|
+
uptime_seconds = time.time() - boot_time
|
|
105
|
+
uptime = timedelta(seconds=int(uptime_seconds))
|
|
106
|
+
|
|
107
|
+
days = uptime.days
|
|
108
|
+
hours = uptime.seconds // 3600
|
|
109
|
+
minutes = (uptime.seconds % 3600) // 60
|
|
110
|
+
|
|
111
|
+
parts = []
|
|
112
|
+
if days > 0:
|
|
113
|
+
parts.append(f"{days}d")
|
|
114
|
+
if hours > 0:
|
|
115
|
+
parts.append(f"{hours}h")
|
|
116
|
+
if minutes > 0:
|
|
117
|
+
parts.append(f"{minutes}m")
|
|
118
|
+
|
|
119
|
+
return " ".join(parts) if parts else "0m"
|
|
120
|
+
except:
|
|
121
|
+
return "Unknown"
|
|
122
|
+
|
|
123
|
+
def get_packages(self):
|
|
124
|
+
try:
|
|
125
|
+
counts = []
|
|
126
|
+
|
|
127
|
+
managers = [
|
|
128
|
+
('apt', ['dpkg', '--get-selections'], lambda x: len([l for l in x.split('\n') if '\tinstall' in l])),
|
|
129
|
+
('dnf/yum', ['rpm', '-qa'], lambda x: len(x.split('\n'))),
|
|
130
|
+
('pacman', ['pacman', '-Q'], lambda x: len(x.split('\n'))),
|
|
131
|
+
('portage', ['qlist', '-I'], lambda x: len(x.split('\n'))),
|
|
132
|
+
('xbps', ['xbps-query', '-l'], lambda x: len(x.split('\n'))),
|
|
133
|
+
('apk', ['apk', 'info'], lambda x: len(x.split('\n'))),
|
|
134
|
+
('brew', ['brew', 'list'], lambda x: len(x.split('\n'))),
|
|
135
|
+
('pip', ['pip', 'list'], lambda x: len(x.split('\n')) - 2 if len(x.split('\n')) > 2 else 0),
|
|
136
|
+
('conda', ['conda', 'list'], lambda x: len([l for l in x.split('\n') if l and not l.startswith('#')])),
|
|
137
|
+
('npm', ['npm', 'list', '-g', '--depth=0'], lambda x: len([l for l in x.split('\n') if '├──' in l or '└──' in l])),
|
|
138
|
+
('gem', ['gem', 'list'], lambda x: len(x.split('\n'))),
|
|
139
|
+
('cargo', ['cargo', 'install', '--list'], lambda x: len([l for l in x.split('\n') if l and not l.startswith(' ')]))
|
|
140
|
+
]
|
|
141
|
+
|
|
142
|
+
for name, cmd, counter in managers:
|
|
143
|
+
output = self.run_command(cmd)
|
|
144
|
+
if output:
|
|
145
|
+
try:
|
|
146
|
+
count = counter(output)
|
|
147
|
+
if count > 0:
|
|
148
|
+
counts.append(f"{count} ({name})")
|
|
149
|
+
except:
|
|
150
|
+
continue
|
|
151
|
+
|
|
152
|
+
return ", ".join(counts[:3]) if counts else "Unknown"
|
|
153
|
+
except:
|
|
154
|
+
return "Unknown"
|
|
155
|
+
|
|
156
|
+
def get_shell(self):
|
|
157
|
+
try:
|
|
158
|
+
shell_path = os.environ.get('SHELL', '')
|
|
159
|
+
if shell_path:
|
|
160
|
+
shell_name = os.path.basename(shell_path)
|
|
161
|
+
version = self.run_command([shell_name, '--version'])
|
|
162
|
+
if version:
|
|
163
|
+
version_match = re.search(r'(\d+\.\d+(?:\.\d+)?)', version.split('\n')[0])
|
|
164
|
+
if version_match:
|
|
165
|
+
return f"{shell_name} {version_match.group(1)}"
|
|
166
|
+
return shell_name
|
|
167
|
+
else:
|
|
168
|
+
if platform.system() == "Windows":
|
|
169
|
+
return "PowerShell" if "powershell" in os.environ.get('PSModulePath', '').lower() else "cmd"
|
|
170
|
+
return "Unknown"
|
|
171
|
+
except:
|
|
172
|
+
return "Unknown"
|
|
173
|
+
|
|
174
|
+
def get_desktop(self):
|
|
175
|
+
try:
|
|
176
|
+
de_vars = [
|
|
177
|
+
'XDG_CURRENT_DESKTOP',
|
|
178
|
+
'DESKTOP_SESSION',
|
|
179
|
+
'XDG_SESSION_DESKTOP',
|
|
180
|
+
'CURRENT_DESKTOP'
|
|
181
|
+
]
|
|
182
|
+
|
|
183
|
+
for var in de_vars:
|
|
184
|
+
de = os.environ.get(var)
|
|
185
|
+
if de:
|
|
186
|
+
return de
|
|
187
|
+
|
|
188
|
+
if os.environ.get('GNOME_DESKTOP_SESSION_ID'):
|
|
189
|
+
return 'GNOME'
|
|
190
|
+
elif os.environ.get('KDE_FULL_SESSION'):
|
|
191
|
+
return 'KDE'
|
|
192
|
+
elif os.environ.get('MATE_DESKTOP_SESSION_ID'):
|
|
193
|
+
return 'MATE'
|
|
194
|
+
elif os.environ.get('XFCE4_SESSION'):
|
|
195
|
+
return 'XFCE4'
|
|
196
|
+
|
|
197
|
+
try:
|
|
198
|
+
processes = [p.name() for p in psutil.process_iter(['name'])]
|
|
199
|
+
if 'gnome-shell' in processes:
|
|
200
|
+
return 'GNOME'
|
|
201
|
+
elif 'kwin' in processes or 'plasmashell' in processes:
|
|
202
|
+
return 'KDE'
|
|
203
|
+
elif 'xfwm4' in processes:
|
|
204
|
+
return 'XFCE4'
|
|
205
|
+
elif 'marco' in processes:
|
|
206
|
+
return 'MATE'
|
|
207
|
+
elif 'openbox' in processes:
|
|
208
|
+
return 'Openbox'
|
|
209
|
+
except:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
return "Unknown"
|
|
213
|
+
except:
|
|
214
|
+
return "Unknown"
|
|
215
|
+
|
|
216
|
+
def get_window_manager(self):
|
|
217
|
+
try:
|
|
218
|
+
wm = os.environ.get('WINDOW_MANAGER')
|
|
219
|
+
if wm:
|
|
220
|
+
return os.path.basename(wm)
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
wms = ['i3', 'bspwm', 'awesome', 'dwm', 'openbox', 'fluxbox', 'jwm']
|
|
224
|
+
try:
|
|
225
|
+
processes = [p.name() for p in psutil.process_iter(['name'])]
|
|
226
|
+
for wm in wms:
|
|
227
|
+
if wm in processes:
|
|
228
|
+
return wm
|
|
229
|
+
except:
|
|
230
|
+
pass
|
|
231
|
+
|
|
232
|
+
return None
|
|
233
|
+
except:
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
def get_cpu(self):
|
|
237
|
+
try:
|
|
238
|
+
cpu_info = ""
|
|
239
|
+
cpu_count = psutil.cpu_count(logical=False)
|
|
240
|
+
cpu_count_logical = psutil.cpu_count(logical=True)
|
|
241
|
+
|
|
242
|
+
if platform.system() == "Linux":
|
|
243
|
+
try:
|
|
244
|
+
with open('/proc/cpuinfo', 'r') as f:
|
|
245
|
+
for line in f:
|
|
246
|
+
if 'model name' in line:
|
|
247
|
+
cpu_info = line.split(':')[1].strip()
|
|
248
|
+
break
|
|
249
|
+
except:
|
|
250
|
+
pass
|
|
251
|
+
elif platform.system() == "Darwin":
|
|
252
|
+
cpu_info = self.run_command(['sysctl', '-n', 'machdep.cpu.brand_string'])
|
|
253
|
+
elif platform.system() == "Windows":
|
|
254
|
+
cpu_info = self.run_command('wmic cpu get name /value').split('=')[1] if self.run_command('wmic cpu get name /value') else ""
|
|
255
|
+
|
|
256
|
+
if not cpu_info:
|
|
257
|
+
cpu_info = platform.processor()
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
cpu_info = re.sub(r'\s+', ' ', cpu_info)
|
|
261
|
+
cpu_info = cpu_info.replace('(R)', '').replace('(TM)', '').replace('CPU', '').replace('@', '').strip()
|
|
262
|
+
|
|
263
|
+
if cpu_count != cpu_count_logical:
|
|
264
|
+
cpu_info += f" ({cpu_count}C/{cpu_count_logical}T)"
|
|
265
|
+
else:
|
|
266
|
+
cpu_info += f" ({cpu_count}C)"
|
|
267
|
+
|
|
268
|
+
return cpu_info
|
|
269
|
+
except:
|
|
270
|
+
return "Unknown CPU"
|
|
271
|
+
|
|
272
|
+
def get_gpu(self):
|
|
273
|
+
try:
|
|
274
|
+
gpus = []
|
|
275
|
+
|
|
276
|
+
if platform.system() == "Linux":
|
|
277
|
+
lspci = self.run_command(['lspci'])
|
|
278
|
+
if lspci:
|
|
279
|
+
for line in lspci.split('\n'):
|
|
280
|
+
if 'VGA' in line or 'Display' in line or '3D' in line:
|
|
281
|
+
gpu = line.split(': ')[-1]
|
|
282
|
+
gpus.append(gpu)
|
|
283
|
+
|
|
284
|
+
nvidia = self.run_command(['nvidia-smi', '--query-gpu=name', '--format=csv,noheader'])
|
|
285
|
+
if nvidia:
|
|
286
|
+
gpus.extend(nvidia.split('\n'))
|
|
287
|
+
|
|
288
|
+
elif platform.system() == "Windows":
|
|
289
|
+
wmic = self.run_command('wmic path win32_VideoController get name /value')
|
|
290
|
+
if wmic:
|
|
291
|
+
for line in wmic.split('\n'):
|
|
292
|
+
if 'Name=' in line and line.split('=')[1].strip():
|
|
293
|
+
gpus.append(line.split('=')[1].strip())
|
|
294
|
+
|
|
295
|
+
elif platform.system() == "Darwin":
|
|
296
|
+
system_profiler = self.run_command(['system_profiler', 'SPDisplaysDataType'])
|
|
297
|
+
if system_profiler:
|
|
298
|
+
for line in system_profiler.split('\n'):
|
|
299
|
+
if 'Chipset Model:' in line:
|
|
300
|
+
gpu = line.split(':')[1].strip()
|
|
301
|
+
gpus.append(gpu)
|
|
302
|
+
|
|
303
|
+
return gpus[0] if gpus else "Unknown"
|
|
304
|
+
except:
|
|
305
|
+
return "Unknown"
|
|
306
|
+
|
|
307
|
+
def get_memory(self):
|
|
308
|
+
try:
|
|
309
|
+
mem = psutil.virtual_memory()
|
|
310
|
+
used_gb = mem.used / (1024**3)
|
|
311
|
+
total_gb = mem.total / (1024**3)
|
|
312
|
+
return f"{used_gb:.1f}GB / {total_gb:.1f}GB ({mem.percent:.0f}%)"
|
|
313
|
+
except:
|
|
314
|
+
return "Unknown"
|
|
315
|
+
|
|
316
|
+
def get_swap(self):
|
|
317
|
+
try:
|
|
318
|
+
swap = psutil.swap_memory()
|
|
319
|
+
if swap.total > 0:
|
|
320
|
+
used_gb = swap.used / (1024**3)
|
|
321
|
+
total_gb = swap.total / (1024**3)
|
|
322
|
+
percent = (swap.used / swap.total * 100) if swap.total > 0 else 0
|
|
323
|
+
return f"{used_gb:.1f}GB / {total_gb:.1f}GB ({percent:.0f}%)"
|
|
324
|
+
return "Not configured"
|
|
325
|
+
except:
|
|
326
|
+
return "Unknown"
|
|
327
|
+
|
|
328
|
+
def get_disk(self):
|
|
329
|
+
try:
|
|
330
|
+
if platform.system() == "Windows":
|
|
331
|
+
disk = psutil.disk_usage('C:')
|
|
332
|
+
else:
|
|
333
|
+
disk = psutil.disk_usage('/')
|
|
334
|
+
used_gb = disk.used / (1024**3)
|
|
335
|
+
total_gb = disk.total / (1024**3)
|
|
336
|
+
percent = (disk.used / disk.total) * 100
|
|
337
|
+
return f"{used_gb:.1f}GB / {total_gb:.1f}GB ({percent:.0f}%)"
|
|
338
|
+
except:
|
|
339
|
+
return "Unknown"
|
|
340
|
+
|
|
341
|
+
def get_network(self):
|
|
342
|
+
try:
|
|
343
|
+
interfaces = psutil.net_if_addrs()
|
|
344
|
+
active_interfaces = []
|
|
345
|
+
|
|
346
|
+
for interface, addresses in interfaces.items():
|
|
347
|
+
if interface == 'lo' or interface.startswith('docker'):
|
|
348
|
+
continue
|
|
349
|
+
for addr in addresses:
|
|
350
|
+
if addr.family == socket.AF_INET and not addr.address.startswith('127.'):
|
|
351
|
+
active_interfaces.append(f"{interface} ({addr.address})")
|
|
352
|
+
break
|
|
353
|
+
|
|
354
|
+
return ", ".join(active_interfaces[:2]) if active_interfaces else "Unknown"
|
|
355
|
+
except:
|
|
356
|
+
return "Unknown"
|
|
357
|
+
|
|
358
|
+
def get_resolution(self):
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
if platform.system() == "Linux":
|
|
362
|
+
xrandr = self.run_command(['xrandr', '--current'])
|
|
363
|
+
if xrandr:
|
|
364
|
+
resolutions = []
|
|
365
|
+
for line in xrandr.split('\n'):
|
|
366
|
+
if '*' in line and 'x' in line:
|
|
367
|
+
match = re.search(r'(\d+x\d+)', line)
|
|
368
|
+
if match:
|
|
369
|
+
resolutions.append(match.group(1))
|
|
370
|
+
return ", ".join(set(resolutions)) if resolutions else "Unknown"
|
|
371
|
+
|
|
372
|
+
xdpyinfo = self.run_command(['xdpyinfo'])
|
|
373
|
+
if xdpyinfo:
|
|
374
|
+
for line in xdpyinfo.split('\n'):
|
|
375
|
+
if 'dimensions:' in line:
|
|
376
|
+
match = re.search(r'(\d+x\d+)', line)
|
|
377
|
+
if match:
|
|
378
|
+
return match.group(1)
|
|
379
|
+
|
|
380
|
+
elif platform.system() == "Windows":
|
|
381
|
+
wmic = self.run_command('wmic desktopmonitor get screenheight,screenwidth /value')
|
|
382
|
+
if wmic:
|
|
383
|
+
width = height = None
|
|
384
|
+
for line in wmic.split('\n'):
|
|
385
|
+
if 'ScreenWidth=' in line:
|
|
386
|
+
width = line.split('=')[1].strip()
|
|
387
|
+
elif 'ScreenHeight=' in line:
|
|
388
|
+
height = line.split('=')[1].strip()
|
|
389
|
+
if width and height and width != '0':
|
|
390
|
+
return f"{width}x{height}"
|
|
391
|
+
|
|
392
|
+
elif platform.system() == "Darwin":
|
|
393
|
+
system_profiler = self.run_command(['system_profiler', 'SPDisplaysDataType'])
|
|
394
|
+
if system_profiler:
|
|
395
|
+
for line in system_profiler.split('\n'):
|
|
396
|
+
if 'Resolution:' in line:
|
|
397
|
+
match = re.search(r'(\d+\s*x\s*\d+)', line)
|
|
398
|
+
if match:
|
|
399
|
+
return match.group(1).replace(' ', '')
|
|
400
|
+
|
|
401
|
+
return "Unknown"
|
|
402
|
+
except:
|
|
403
|
+
return "Unknown"
|
|
404
|
+
|
|
405
|
+
def get_terminal(self):
|
|
406
|
+
try:
|
|
407
|
+
term_vars = ['TERM_PROGRAM', 'TERMINAL_EMULATOR', 'TERM']
|
|
408
|
+
for var in term_vars:
|
|
409
|
+
term = os.environ.get(var)
|
|
410
|
+
if term and term not in ['xterm', 'xterm-256color', 'screen']:
|
|
411
|
+
return term
|
|
412
|
+
|
|
413
|
+
try:
|
|
414
|
+
ppid = os.getppid()
|
|
415
|
+
parent = psutil.Process(ppid)
|
|
416
|
+
parent_name = parent.name()
|
|
417
|
+
|
|
418
|
+
terminals = ['gnome-terminal', 'konsole', 'xfce4-terminal', 'mate-terminal',
|
|
419
|
+
'terminator', 'tilix', 'alacritty', 'kitty', 'urxvt', 'xterm',
|
|
420
|
+
'iTerm', 'Terminal', 'WindowsTerminal', 'ConEmu']
|
|
421
|
+
|
|
422
|
+
for term in terminals:
|
|
423
|
+
if term.lower() in parent_name.lower():
|
|
424
|
+
return term
|
|
425
|
+
|
|
426
|
+
return parent_name
|
|
427
|
+
except:
|
|
428
|
+
pass
|
|
429
|
+
|
|
430
|
+
return os.environ.get('TERM', 'Unknown')
|
|
431
|
+
except:
|
|
432
|
+
return "Unknown"
|
|
433
|
+
|
|
434
|
+
def get_ascii_art(self):
|
|
435
|
+
system = platform.system().lower()
|
|
436
|
+
|
|
437
|
+
if "linux" in system:
|
|
438
|
+
return [
|
|
439
|
+
f"{self.colors['blue']} -`{self.colors['end']}",
|
|
440
|
+
f"{self.colors['blue']} .o+`{self.colors['end']}",
|
|
441
|
+
f"{self.colors['blue']} `ooo/{self.colors['end']}",
|
|
442
|
+
f"{self.colors['blue']} `+oooo:{self.colors['end']}",
|
|
443
|
+
f"{self.colors['blue']} `+oooooo:{self.colors['end']}",
|
|
444
|
+
f"{self.colors['blue']} -+oooooo+:{self.colors['end']}",
|
|
445
|
+
f"{self.colors['blue']} `/:-:++oooo+:{self.colors['end']}",
|
|
446
|
+
f"{self.colors['blue']} `/++++/+++++++:{self.colors['end']}",
|
|
447
|
+
f"{self.colors['blue']} `/++++++++++++++:{self.colors['end']}",
|
|
448
|
+
f"{self.colors['blue']} `/+++ooooooooo+/`{self.colors['end']}",
|
|
449
|
+
f"{self.colors['blue']} ./ooosssso++osssssso+`{self.colors['end']}",
|
|
450
|
+
f"{self.colors['blue']} .oossssso-````/ossssss+`{self.colors['end']}",
|
|
451
|
+
f"{self.colors['blue']} -osssssso. :ssssssso.{self.colors['end']}",
|
|
452
|
+
f"{self.colors['blue']} :osssssss/ osssso+++.{self.colors['end']}",
|
|
453
|
+
f"{self.colors['blue']} /ossssssss/ +ssssooo/-{self.colors['end']}",
|
|
454
|
+
f"{self.colors['blue']} `/ossssso+/:- -:/+osssso+-{self.colors['end']}",
|
|
455
|
+
f"{self.colors['blue']} `+sso+:-` `.-/+oso:{self.colors['end']}",
|
|
456
|
+
f"{self.colors['blue']} `++:. `-/+/{self.colors['end']}",
|
|
457
|
+
f"{self.colors['blue']} .` `/{self.colors['end']}"
|
|
458
|
+
]
|
|
459
|
+
elif "darwin" in system:
|
|
460
|
+
return [
|
|
461
|
+
f"{self.colors['green']} 'c.{self.colors['end']}",
|
|
462
|
+
f"{self.colors['green']} ,xNMM.{self.colors['end']}",
|
|
463
|
+
f"{self.colors['green']} .OMMMMo{self.colors['end']}",
|
|
464
|
+
f"{self.colors['green']} OMMM0,{self.colors['end']}",
|
|
465
|
+
f"{self.colors['green']} .;loddo:' loolloddol;.{self.colors['end']}",
|
|
466
|
+
f"{self.colors['green']} cKMMMMMMMMMMNWMMMMMMMMMM0:{self.colors['end']}",
|
|
467
|
+
f"{self.colors['yellow']} .KMMMMMMMMMMMMMMMMMMMMMMMWd.{self.colors['end']}",
|
|
468
|
+
f"{self.colors['yellow']} XMMMMMMMMMMMMMMMMMMMMMMMX.{self.colors['end']}",
|
|
469
|
+
f"{self.colors['red']};MMMMMMMMMMMMMMMMMMMMMMMM:{self.colors['end']}",
|
|
470
|
+
f"{self.colors['red']}:MMMMMMMMMMMMMMMMMMMMMMMM:{self.colors['end']}",
|
|
471
|
+
f"{self.colors['red']}.MMMMMMMMMMMMMMMMMMMMMMMMX.{self.colors['end']}",
|
|
472
|
+
f"{self.colors['purple']} kMMMMMMMMMMMMMMMMMMMMMMMMWd.{self.colors['end']}",
|
|
473
|
+
f"{self.colors['purple']} .XMMMMMMMMMMMMMMMMMMMMMMMMMMk{self.colors['end']}",
|
|
474
|
+
f"{self.colors['blue']} .XMMMMMMMMMMMMMMMMMMMMMMMMK.{self.colors['end']}",
|
|
475
|
+
f"{self.colors['blue']} kMMMMMMMMMMMMMMMMMMMMMMd{self.colors['end']}",
|
|
476
|
+
f"{self.colors['cyan']} ;KMMMMMMMWXXWMMMMMMMk.{self.colors['end']}",
|
|
477
|
+
f"{self.colors['cyan']} .cooc,. .,coo:.{self.colors['end']}"
|
|
478
|
+
]
|
|
479
|
+
elif "windows" in system:
|
|
480
|
+
return [
|
|
481
|
+
f"{self.colors['blue']} ,.=:!!t3Z3z.,{self.colors['end']}",
|
|
482
|
+
f"{self.colors['blue']} :tt:::tt333EE3{self.colors['end']}",
|
|
483
|
+
f"{self.colors['blue']} Et:::ztt33EEEL{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
484
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
485
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
486
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
487
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
488
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
489
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
490
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
491
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
492
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
493
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['cyan']} @@@@@@@@@@@@@@@@@@@@{self.colors['end']}",
|
|
494
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['end']}",
|
|
495
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['end']}",
|
|
496
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['end']}",
|
|
497
|
+
f"{self.colors['blue']} Et:::zt333EEE{self.colors['end']}"
|
|
498
|
+
]
|
|
499
|
+
else:
|
|
500
|
+
return [
|
|
501
|
+
f"{self.colors['cyan']} .-\"\"\"\"\"-. {self.colors['end']}",
|
|
502
|
+
f"{self.colors['cyan']} .' '. {self.colors['end']}",
|
|
503
|
+
f"{self.colors['cyan']} / O O \\ {self.colors['end']}",
|
|
504
|
+
f"{self.colors['cyan']} : : {self.colors['end']}",
|
|
505
|
+
f"{self.colors['cyan']} | | {self.colors['end']}",
|
|
506
|
+
f"{self.colors['cyan']} : __ : {self.colors['end']}",
|
|
507
|
+
f"{self.colors['cyan']} \\ .-\"` `\"-. / {self.colors['end']}",
|
|
508
|
+
f"{self.colors['cyan']} '. .' {self.colors['end']}",
|
|
509
|
+
f"{self.colors['cyan']} '-.......-' {self.colors['end']}",
|
|
510
|
+
"",
|
|
511
|
+
f"{self.colors['bold']} Unknown System{self.colors['end']}"
|
|
512
|
+
]
|
|
513
|
+
|
|
514
|
+
def collect_info(self):
|
|
515
|
+
self.info = {
|
|
516
|
+
'user': getpass.getuser(),
|
|
517
|
+
'hostname': socket.gethostname(),
|
|
518
|
+
'os': self.get_os_info(),
|
|
519
|
+
'kernel': self.get_kernel(),
|
|
520
|
+
'uptime': self.get_uptime(),
|
|
521
|
+
'packages': self.get_packages(),
|
|
522
|
+
'shell': self.get_shell(),
|
|
523
|
+
'desktop': self.get_desktop(),
|
|
524
|
+
'wm': self.get_window_manager(),
|
|
525
|
+
'terminal': self.get_terminal(),
|
|
526
|
+
'cpu': self.get_cpu(),
|
|
527
|
+
'gpu': self.get_gpu(),
|
|
528
|
+
'memory': self.get_memory(),
|
|
529
|
+
'swap': self.get_swap(),
|
|
530
|
+
'disk': self.get_disk(),
|
|
531
|
+
'network': self.get_network(),
|
|
532
|
+
'resolution': self.get_resolution()
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
def display(self):
|
|
536
|
+
self.collect_info()
|
|
537
|
+
ascii_art = self.get_ascii_art()
|
|
538
|
+
|
|
539
|
+
user_host = f"{self.colors['bold']}{self.colors['green']}{self.info['user']}{self.colors['red']}@{self.colors['blue']}{self.info['hostname']}{self.colors['end']}"
|
|
540
|
+
separator = f"{self.colors['gray']}{'-' * (len(self.info['user']) + len(self.info['hostname']) + 1)}{self.colors['end']}"
|
|
541
|
+
|
|
542
|
+
info_lines = [
|
|
543
|
+
user_host,
|
|
544
|
+
separator,
|
|
545
|
+
f"{self.colors['bold']}{self.colors['red']}OS{self.colors['end']}: {self.info['os']}",
|
|
546
|
+
f"{self.colors['bold']}{self.colors['yellow']}Kernel{self.colors['end']}: {self.info['kernel']}",
|
|
547
|
+
f"{self.colors['bold']}{self.colors['green']}Uptime{self.colors['end']}: {self.info['uptime']}",
|
|
548
|
+
f"{self.colors['bold']}{self.colors['blue']}Packages{self.colors['end']}: {self.info['packages']}",
|
|
549
|
+
f"{self.colors['bold']}{self.colors['purple']}Shell{self.colors['end']}: {self.info['shell']}",
|
|
550
|
+
f"{self.colors['bold']}{self.colors['cyan']}Desktop{self.colors['end']}: {self.info['desktop']}",
|
|
551
|
+
]
|
|
552
|
+
|
|
553
|
+
if self.info['wm'] and self.info['wm'].lower() not in self.info['desktop'].lower():
|
|
554
|
+
info_lines.append(f"{self.colors['bold']}{self.colors['white']}WM{self.colors['end']}: {self.info['wm']}")
|
|
555
|
+
|
|
556
|
+
info_lines.extend([
|
|
557
|
+
f"{self.colors['bold']}{self.colors['red']}Terminal{self.colors['end']}: {self.info['terminal']}",
|
|
558
|
+
f"{self.colors['bold']}{self.colors['yellow']}CPU{self.colors['end']}: {self.info['cpu']}",
|
|
559
|
+
f"{self.colors['bold']}{self.colors['green']}GPU{self.colors['end']}: {self.info['gpu']}",
|
|
560
|
+
f"{self.colors['bold']}{self.colors['blue']}Memory{self.colors['end']}: {self.info['memory']}"
|
|
561
|
+
])
|
|
562
|
+
|
|
563
|
+
if self.info['swap'] != "Not configured":
|
|
564
|
+
info_lines.append(f"{self.colors['bold']}{self.colors['purple']}Swap{self.colors['end']}: {self.info['swap']}")
|
|
565
|
+
|
|
566
|
+
info_lines.extend([
|
|
567
|
+
f"{self.colors['bold']}{self.colors['cyan']}Disk{self.colors['end']}: {self.info['disk']}",
|
|
568
|
+
f"{self.colors['white']}Network{self.colors['end']}: {self.info['network']}",
|
|
569
|
+
f"{self.colors['bold']}{self.colors['gray']}Resolution{self.colors['end']}: {self.info['resolution']}"
|
|
570
|
+
])
|
|
571
|
+
|
|
572
|
+
info_lines.append("")
|
|
573
|
+
colors_line1 = ""
|
|
574
|
+
colors_line2 = ""
|
|
575
|
+
color_names = ['red', 'green', 'yellow', 'blue', 'purple', 'cyan', 'white', 'gray']
|
|
576
|
+
|
|
577
|
+
for color in color_names:
|
|
578
|
+
colors_line1 += f"{self.colors[color]}███{self.colors['end']}"
|
|
579
|
+
colors_line2 += f"{self.colors[color]}███{self.colors['end']}"
|
|
580
|
+
|
|
581
|
+
info_lines.extend([colors_line1, colors_line2])
|
|
582
|
+
|
|
583
|
+
max_lines = max(len(ascii_art), len(info_lines))
|
|
584
|
+
|
|
585
|
+
for i in range(max_lines):
|
|
586
|
+
ascii_line = ascii_art[i] if i < len(ascii_art) else " " * 40
|
|
587
|
+
info_line = info_lines[i] if i < len(info_lines) else ""
|
|
588
|
+
|
|
589
|
+
clean_info = re.sub(r'\x1b\[[0-9;]*m', '', info_line)
|
|
590
|
+
padding = " " * (3)
|
|
591
|
+
|
|
592
|
+
print(f"{ascii_line}{padding}{info_line}")
|
|
593
|
+
|
|
594
|
+
def get_colors_demo(self):
|
|
595
|
+
print("\nColor Palette:")
|
|
596
|
+
for name, code in self.colors.items():
|
|
597
|
+
if name != 'end':
|
|
598
|
+
print(f"{code}{name.capitalize():10}{self.colors['end']}: {code}████████{self.colors['end']}")
|
|
599
|
+
|
|
600
|
+
def get_minimal_info(self):
|
|
601
|
+
return {
|
|
602
|
+
'user_host': f"{getpass.getuser()}@{socket.gethostname()}",
|
|
603
|
+
'os': platform.system(),
|
|
604
|
+
'uptime': self.get_uptime(),
|
|
605
|
+
'memory': self.get_memory()
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
def minimal_display(self):
|
|
609
|
+
info = self.get_minimal_info()
|
|
610
|
+
print(f"{self.colors['bold']}{self.colors['cyan']}{info['user_host']}{self.colors['end']}")
|
|
611
|
+
print(f"{self.colors['yellow']}OS{self.colors['end']}: {info['os']}")
|
|
612
|
+
print(f"{self.colors['green']}Uptime{self.colors['end']}: {info['uptime']}")
|
|
613
|
+
print(f"{self.colors['blue']}Memory{self.colors['end']}: {info['memory']}")
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
def fetch(minimal=False, colors=False):
|
|
617
|
+
pf = metafetch()
|
|
618
|
+
|
|
619
|
+
if colors:
|
|
620
|
+
pf.get_colors_demo()
|
|
621
|
+
elif minimal:
|
|
622
|
+
pf.minimal_display()
|
|
623
|
+
else:
|
|
624
|
+
pf.display()
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
def main():
|
|
628
|
+
import argparse
|
|
629
|
+
|
|
630
|
+
parser = argparse.ArgumentParser(description='metafetch - Enhanced system information tool')
|
|
631
|
+
parser.add_argument('-m', '--minimal', action='store_true',
|
|
632
|
+
help='Display minimal information')
|
|
633
|
+
parser.add_argument('-c', '--colors', action='store_true',
|
|
634
|
+
help='Display color palette')
|
|
635
|
+
parser.add_argument('--version', action='version', version='metafetch 1.0.0')
|
|
636
|
+
|
|
637
|
+
args = parser.parse_args()
|
|
638
|
+
|
|
639
|
+
try:
|
|
640
|
+
fetch(minimal=args.minimal, colors=args.colors)
|
|
641
|
+
except KeyboardInterrupt:
|
|
642
|
+
print(f"\n{metafetch().colors['red']}Interrupted by user{metafetch().colors['end']}")
|
|
643
|
+
sys.exit(1)
|
|
644
|
+
except Exception as e:
|
|
645
|
+
print(f"{metafetch().colors['red']}Error: {e}{metafetch().colors['end']}")
|
|
646
|
+
sys.exit(1)
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
if __name__ == "__main__":
|
|
650
|
+
main()
|
metafetch-1.0.0/setup.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
from setuptools import setup, find_packages
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
def read_readme():
|
|
6
|
+
with open(os.path.join(os.path.dirname(__file__), 'README.md'), encoding='utf-8') as f:
|
|
7
|
+
return f.read()
|
|
8
|
+
|
|
9
|
+
def read_requirements():
|
|
10
|
+
with open('requirements.txt') as f:
|
|
11
|
+
return [line.strip() for line in f if line.strip() and not line.startswith('#')]
|
|
12
|
+
|
|
13
|
+
setup(
|
|
14
|
+
name='metafetch',
|
|
15
|
+
version='1.0.0',
|
|
16
|
+
description='A beautiful, fast, and comprehensive system information tool',
|
|
17
|
+
long_description=read_readme(),
|
|
18
|
+
long_description_content_type='text/markdown',
|
|
19
|
+
author='Ujjawal Singh / @volksgeistt',
|
|
20
|
+
author_email='unrealvolksgeist@gmail.com',
|
|
21
|
+
url='https://github.com/volksgeistt/metafetch',
|
|
22
|
+
license='MIT',
|
|
23
|
+
py_modules=['metafetch'],
|
|
24
|
+
install_requires=read_requirements(),
|
|
25
|
+
entry_points={
|
|
26
|
+
'console_scripts': [
|
|
27
|
+
'metafetch=metafetch:main',
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
classifiers=[
|
|
31
|
+
'Development Status :: 5 - Production/Stable',
|
|
32
|
+
'Environment :: Console',
|
|
33
|
+
'Intended Audience :: End Users/Desktop',
|
|
34
|
+
'Intended Audience :: System Administrators',
|
|
35
|
+
'License :: OSI Approved :: MIT License',
|
|
36
|
+
'Operating System :: OS Independent',
|
|
37
|
+
'Programming Language :: Python :: 3',
|
|
38
|
+
'Programming Language :: Python :: 3.6',
|
|
39
|
+
'Programming Language :: Python :: 3.7',
|
|
40
|
+
'Programming Language :: Python :: 3.8',
|
|
41
|
+
'Programming Language :: Python :: 3.9',
|
|
42
|
+
'Programming Language :: Python :: 3.10',
|
|
43
|
+
'Programming Language :: Python :: 3.11',
|
|
44
|
+
'Topic :: System :: Systems Administration',
|
|
45
|
+
'Topic :: Utilities',
|
|
46
|
+
],
|
|
47
|
+
keywords='system information neofetch system-info cli terminal',
|
|
48
|
+
python_requires='>=3.6',
|
|
49
|
+
project_urls={
|
|
50
|
+
'Bug Reports': 'https://github.com/volksgeistt/metafetch/issues',
|
|
51
|
+
'Source': 'https://github.com/volksgeistt/metafetch',
|
|
52
|
+
'Documentation': 'https://github.com/volksgeistt/metafetch/blob/main/README.md',
|
|
53
|
+
},
|
|
54
|
+
)
|