mirror of
https://github.com/HorlogeSkynet/archey4
synced 2025-04-16 16:00:13 +02:00
962 lines
39 KiB
Python
Executable File
962 lines
39 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
|
|
import json
|
|
import os
|
|
import re
|
|
import sys
|
|
from enum import Enum
|
|
from glob import glob
|
|
from math import floor
|
|
from os import getenv, getuid
|
|
from subprocess import CalledProcessError, DEVNULL, PIPE, Popen, \
|
|
TimeoutExpired, check_output
|
|
|
|
|
|
# -------------- Enumerations -------------- #
|
|
|
|
class Distributions(Enum):
|
|
ARCH_LINUX = 'Arch.*'
|
|
BUNSENLABS = 'BunsenLabs'
|
|
CRUNCHBANG = 'CrunchBang'
|
|
DEBIAN = '(Rasp|De)bian'
|
|
FEDORA = 'Fedora'
|
|
GENTOO = 'Gentoo'
|
|
KALI_LINUX = 'Kali'
|
|
MANJARO_LINUX = 'ManjaroLinux'
|
|
LINUX = 'Linux'
|
|
LINUX_MINT = 'LinuxMint'
|
|
OPENSUSE = 'openSUSE'
|
|
RED_HAT = 'Red Hat'
|
|
UBUNTU = 'Ubuntu'
|
|
WINDOWS = 'Windows'
|
|
|
|
|
|
# -------------- Dictionaries -------------- #
|
|
|
|
colorDict = {
|
|
Distributions.ARCH_LINUX: ['\x1b[0;34m', '\x1b[1;34m'],
|
|
Distributions.BUNSENLABS: ['\x1b[1;37m', '\x1b[1;33m', '\x1b[0;33m'],
|
|
Distributions.CRUNCHBANG: ['\x1b[1;37m', '\x1b[1;37m'],
|
|
Distributions.DEBIAN: ['\x1b[0;31m', '\x1b[1;31m'],
|
|
Distributions.FEDORA: ['\x1b[1;37m', '\x1b[0;34m'],
|
|
Distributions.GENTOO: ['\x1b[1;37m', '\x1b[1;35m'],
|
|
Distributions.KALI_LINUX: ['\x1b[1;37m', '\x1b[1;34m'],
|
|
Distributions.MANJARO_LINUX: ['\x1b[0;32m', '\x1b[1;32m'],
|
|
Distributions.LINUX: ['\x1b[1;33m', '\x1b[1;37m'],
|
|
Distributions.LINUX_MINT: ['\x1b[1;37m', '\x1b[1;32m'],
|
|
Distributions.OPENSUSE: ['\x1b[1;37m', '\x1b[1;32m'],
|
|
Distributions.RED_HAT: ['\x1b[1;37m', '\x1b[1;31m', '\x1b[0;31m'],
|
|
Distributions.UBUNTU: ['\x1b[0;31m', '\x1b[1;31m', '\x1b[0;33m'],
|
|
Distributions.WINDOWS: ['\x1b[1;31m', '\x1b[1;34m',
|
|
'\x1b[1;32m', '\x1b[0;33m'],
|
|
'sensors': ['\x1b[0;32m', '\x1b[0;33m', '\x1b[0;31m'],
|
|
'clear': '\x1b[0m'
|
|
}
|
|
|
|
deDict = {
|
|
'cinnamon': 'Cinnamon',
|
|
'gnome-session': 'GNOME',
|
|
'gnome-shell': 'GNOME',
|
|
'mate-session': 'MATE',
|
|
'ksmserver': 'KDE',
|
|
'xfce4-session': 'Xfce',
|
|
'fur-box-session': 'Fur Box',
|
|
'lxsession': 'LXDE',
|
|
'lxqt-session': 'LXQt'
|
|
}
|
|
|
|
wmDict = {
|
|
'awesome': 'Awesome',
|
|
'beryl': 'Beryl',
|
|
'blackbox': 'Blackbox',
|
|
'bspwm': 'bspwm',
|
|
'cinnamon': 'Cinnamon',
|
|
'compiz': 'Compiz',
|
|
'dwm': 'DWM',
|
|
'enlightenment': 'Enlightenment',
|
|
'herbstluftwm': 'herbstluftwm',
|
|
'fluxbox': 'Fluxbox',
|
|
'fvwm': 'FVWM',
|
|
'i3': 'i3',
|
|
'icewm': 'IceWM',
|
|
'kwin_x11': 'KWin',
|
|
'metacity': 'Metacity',
|
|
'musca': 'Musca',
|
|
'openbox': 'Openbox',
|
|
'pekwm': 'PekWM',
|
|
'qtile': 'QTile',
|
|
'ratpoison': 'ratpoison',
|
|
'scrotwm': 'ScrotWM',
|
|
'stumpwm': 'StumpWM',
|
|
'subtle': 'Subtle',
|
|
'monsterwm': 'MonsterWM',
|
|
'wingo': 'Wingo',
|
|
'wmaker': 'Window Maker',
|
|
'wmfs': 'Wmfs',
|
|
'wmii': 'wmii',
|
|
'xfwm4': 'Xfwm',
|
|
'xmonad': 'xmonad'
|
|
}
|
|
|
|
logosDict = {
|
|
Distributions.ARCH_LINUX: """
|
|
{c[1]} + {r[0]}
|
|
{c[1]} # {r[1]}
|
|
{c[1]} ### {r[2]}
|
|
{c[1]} ##### {r[3]}
|
|
{c[1]} ###### {r[4]}
|
|
{c[1]} ; #####; {r[5]}
|
|
{c[1]} +##.##### {r[6]}
|
|
{c[1]} +########## {r[7]}
|
|
{c[1]} ######{c[0]}#####{c[1]}##; {r[8]}
|
|
{c[1]} ###{c[0]}############{c[1]}+ {r[9]}
|
|
{c[1]} #{c[0]}###### #######{c[1]} {r[10]}
|
|
{c[1]} {c[0]}.######; ;###;`\".{c[1]} {r[11]}
|
|
{c[1]} {c[0]}.#######; ;#####.{c[1]} {r[12]}
|
|
{c[1]} {c[0]}#########. .########`{c[1]} {r[13]}
|
|
{c[1]} {c[0]}######' '######{c[1]} {r[14]}
|
|
{c[1]} {c[0]};#### ####;{c[1]} {r[15]}
|
|
{c[1]} {c[0]}##' '##{c[1]} {r[16]}
|
|
{c[1]} {c[0]}#' `#{c[1]} {r[17]}\n""",
|
|
Distributions.BUNSENLABS: """
|
|
{c[0]} .{c[1]}..{c[0]}+hhy+-` \0
|
|
{c[0]} `+hd{c[1]}-{c[0]}+dddd{c[2]}hyso{c[0]}+//: \0
|
|
{c[0]} `+dddd{c[1]}:-{c[0]}sdh/. {r[0]}
|
|
{c[0]} -hdddddh{c[1]}-.{c[2]}/:{c[0]} {r[1]}
|
|
{c[0]} /ddddddddd{c[1]}:```{c[0]} {r[2]}
|
|
{c[0]} :ddddddddddd/ {r[3]}
|
|
{c[0]} `hdddddddddddd+ {r[4]}
|
|
{c[0]} /dddddddddddddd: {r[5]}
|
|
{c[0]} odddds..sddddddh {r[6]}
|
|
{c[0]} oddd/ /dddddd: {r[7]}
|
|
{c[0]} +dd+ +ddddd+ {r[8]}
|
|
{c[0]} .dd` `ddddd+ {r[9]}
|
|
{c[0]} oh ydddd: {r[10]}
|
|
{c[0]} `o sdddh` {r[11]}
|
|
{c[0]} yddd: {r[12]}
|
|
{c[0]} `dddo {r[13]}
|
|
{c[0]} :s :dds {r[14]}
|
|
{c[0]} yd/ yd+ {r[15]}
|
|
{c[0]} `sddy :h- {r[16]}
|
|
{c[0]} `sddys` :` {r[17]}
|
|
{c[0]} -hdy+`y+yo./+/:- \0
|
|
{c[0]} ... .o++oso+/ \n""",
|
|
Distributions.CRUNCHBANG: """
|
|
{c[0]} ___ ___ _ {r[0]}
|
|
{c[0]} / / / / | | {r[1]}
|
|
{c[0]} / / / / | | {r[2]}
|
|
{c[0]} / / / / | | {r[3]}
|
|
{c[0]} _______/ /______/ /______ | | {r[4]}
|
|
{c[0]} /______ _______ _______/ | | {r[5]}
|
|
{c[0]} / / / / | | {r[6]}
|
|
{c[0]} / / / / | | {r[7]}
|
|
{c[0]} / / / / | | {r[8]}
|
|
{c[0]} ______/ /______/ /______ | | {r[9]}
|
|
{c[0]} /_____ _______ _______/ | | {r[10]}
|
|
{c[0]} / / / / | | {r[11]}
|
|
{c[0]} / / / / |_| {r[12]}
|
|
{c[0]} / / / / _ {r[13]}
|
|
{c[0]} / / / / | | {r[14]}
|
|
{c[0]} /__/ /__/ |_| {r[15]}
|
|
{c[0]} {r[16]}
|
|
{c[0]} {r[17]}\n""",
|
|
Distributions.DEBIAN: """
|
|
{c[1]} {r[0]}
|
|
{c[1]} _sudZUZ#Z#XZo=_ {r[1]}
|
|
{c[1]} _jmZZ2!!~---~!!X##wx {r[2]}
|
|
{c[1]} .<wdP~~ -!YZL, {r[3]}
|
|
{c[1]} .mX2' _xaaa__ XZ[. {r[4]}
|
|
{c[1]} oZ[ _jdXY!~?S#wa ]Xb; {r[5]}
|
|
{c[1]} _#e' .]X2( ~Xw| )XXc {r[6]}
|
|
{c[1]} .2Z` ]X[. xY| ]oZ( {r[7]}
|
|
{c[1]} .2#; )3k; _s!~ jXf` {r[8]}
|
|
{c[1]} {c[0]}1Z>{c[1]} {c[0]}-]Xb/{c[1]} {c[0]}~{c[1]} {c[0]}__#2({c[1]} {r[9]}
|
|
{c[1]} {c[0]}-Zo;{c[1]} {c[0]}+!4ZwerfgnZZXY'{c[1]} {r[10]}
|
|
{c[1]} {c[0]}*#[,{c[1]} {c[0]}~-?!!!!!!-~{c[1]} {r[11]}
|
|
{c[1]} {c[0]}XUb;.{c[1]} {r[12]}
|
|
{c[1]} {c[0]})YXL,,{c[1]} {r[13]}
|
|
{c[1]} {c[0]}+3#bc,{c[1]} {r[14]}
|
|
{c[1]} {c[0]}-)SSL,,{c[1]} {r[15]}
|
|
{c[1]} {c[0]}~~~~~{c[1]} {r[16]}
|
|
{c[1]} {r[17]}\n""",
|
|
Distributions.FEDORA: """
|
|
{c[1]} :/------------:// {r[0]}
|
|
{c[1]} :------------------:// {r[1]}
|
|
{c[1]} :-----------{c[0]}/shhdhyo/{c[1]}-:// {r[2]}
|
|
{c[1]} /-----------{c[0]}omMMMNNNMMMd/{c[1]}-:/ {r[3]}
|
|
{c[1]} :-----------{c[0]}sMMMdo:/{c[1]} -:/ {r[4]}
|
|
{c[1]} :-----------{c[0]}:MMMd{c[1]}------- --:/ {r[5]}
|
|
{c[1]} /-----------{c[0]}:MMMy{c[1]}------- ---/ {r[6]}
|
|
{c[1]} :------ --{c[0]}/+MMMh/{c[1]}-- ---: {r[7]}
|
|
{c[1]} :--- {c[0]}oNMMMMMMMMMNho{c[1]} -----: {r[8]}
|
|
{c[1]} :-- {c[0]}+shhhMMMmhhy++{c[1]} ------: {r[9]}
|
|
{c[1]} :- -----{c[0]}:MMMy{c[1]}--------------/ {r[10]}
|
|
{c[1]} :- ------{c[0]}/MMMy{c[1]}-------------: {r[11]}
|
|
{c[1]} :- ----{c[0]}/hMMM+{c[1]}------------: {r[12]}
|
|
{c[1]} :--{c[0]}:dMMNdhhdNMMNo{c[1]}-----------: {r[13]}
|
|
{c[1]} :---{c[0]}:sdNMMMMNds:{c[1]}----------: {r[14]}
|
|
{c[1]} :------{c[0]}:://:{c[1]}-----------:// {r[15]}
|
|
{c[1]} :--------------------:// {r[16]}
|
|
{c[1]} {r[17]}\n""",
|
|
Distributions.GENTOO: """
|
|
{c[1]} -/oyddmdhs+:. {r[0]}
|
|
{c[1]} -o{c[0]}dNMMMMMMMMNNmhy+{c[1]}-` {r[1]}
|
|
{c[1]} -y{c[0]}NMMMMMMMMMMMNNNmmdhy{c[1]}+- {r[2]}
|
|
{c[1]} `o{c[0]}mMMMMMMMMMMMMNmdmmmmddhhy{c[1]}/` {r[3]}
|
|
{c[1]} om{c[0]}MMMMMMMMMMMN{c[1]}hhyyyo{c[0]}hmdddhhhd{c[1]}o` {r[4]}
|
|
{c[1]} .y{c[0]}dMMMMMMMMMMd{c[1]}hs++so/s{c[0]}mdddhhhhdm{c[1]}+` {r[5]}
|
|
{c[1]} oy{c[0]}hdmNMMMMMMMN{c[1]}dyooy{c[0]}dmddddhhhhyhN{c[1]}d. {r[6]}
|
|
{c[1]} :o{c[0]}yhhdNNMMMMMMMNNNmmdddhhhhhyym{c[1]}Mh {r[7]}
|
|
{c[1]} .:{c[0]}+sydNMMMMMNNNmmmdddhhhhhhmM{c[1]}my {r[8]}
|
|
{c[1]} /m{c[0]}MMMMMMNNNmmmdddhhhhhmMNh{c[1]}s: {r[9]}
|
|
{c[1]} `o{c[0]}NMMMMMMMNNNmmmddddhhdmMNhs{c[1]}+` {r[10]}
|
|
{c[1]} `s{c[0]}NMMMMMMMMNNNmmmdddddmNMmhs{c[1]}/. {r[11]}
|
|
{c[1]} /N{c[0]}MMMMMMMMNNNNmmmdddmNMNdso{c[1]}:` {r[12]}
|
|
{c[1]} +M{c[0]}MMMMMMNNNNNmmmmdmNMNdso{c[1]}/- {r[13]}
|
|
{c[1]} yM{c[0]}MNNNNNNNmmmmmNNMmhs+/{c[1]}-` {r[14]}
|
|
{c[1]} /h{c[0]}MMNNNNNNNNMNdhs++/{c[1]}-` {r[15]}
|
|
{c[1]} `/{c[0]}ohdmmddhys+++/:{c[1]}.` {r[16]}
|
|
{c[1]} `-//////:--. {r[17]}\n""",
|
|
Distributions.KALI_LINUX: """
|
|
{c[0]} ,..... \0
|
|
{c[0]} ----` `..,;:ccc,. \0
|
|
{c[0]} ......''';lxO. {r[0]}
|
|
{c[0]} .....''''..........,:ld; {r[1]}
|
|
{c[0]} .';;;:::;,,.x, {r[2]}
|
|
{c[0]} ..'''. 0Xxoc:,. ... {r[3]}
|
|
{c[0]} .... ,ONkc;,;cokOdc',. {r[4]}
|
|
{c[0]} . OMo ':{c[1]}d{c[0]}o. {r[5]}
|
|
{c[0]} dMc :OO; {r[6]}
|
|
{c[0]} 0M. .:o. {r[7]}
|
|
{c[0]} ;Wd {r[8]}
|
|
{c[0]} ;XO, {r[9]}
|
|
{c[0]} ,d0Odlc;,.. {r[10]}
|
|
{c[0]} ..',;:cdOOd::,. {r[11]}
|
|
{c[0]} .:d;.':;. {r[12]}
|
|
{c[0]} 'd, .' {r[13]}
|
|
{c[0]} ;l .. {r[14]}
|
|
{c[0]} .o {r[15]}
|
|
{c[0]} c {r[16]}
|
|
{c[0]} .' {r[17]}
|
|
{c[0]} . \n""",
|
|
Distributions.MANJARO_LINUX: """
|
|
{c[0]} $$$$$$$$$$$$$$$$ $$$$$$$ {r[0]}
|
|
{c[0]} M77777777777777M M77777M {r[1]}
|
|
{c[0]} M77777777777777M M77777M {r[2]}
|
|
{c[0]} M77777MMMMMMMMMM M77777M {r[3]}
|
|
{c[0]} M77777M M77777M {r[4]}
|
|
{c[0]} M77777M $$$$$$$ M77777M {r[5]}
|
|
{c[0]} MMMMMMM M77777M M77777M {r[6]}
|
|
{c[0]} M77777M M77777M {r[7]}
|
|
{c[0]} $$$$$$$ M77777M M77777M {r[8]}
|
|
{c[0]} M77777M M77777M M77777M {r[9]}
|
|
{c[0]} M77777M M77777M M77777M {r[10]}
|
|
{c[0]} M77777M M77777M M77777M {r[11]}
|
|
{c[0]} M77777M M77777M M77777M {r[12]}
|
|
{c[0]} M77777M M77777M M77777M {r[13]}
|
|
{c[0]} M77777M M77777M M77777M {r[14]}
|
|
{c[0]} M77777M M77777M M77777M {r[15]}
|
|
{c[0]} M77777M M77777M M77777M {r[16]}
|
|
{c[0]} MMMMMMM MMMMMMM MMMMMMM {r[17]}\n""",
|
|
Distributions.LINUX: """
|
|
{c[1]} {r[0]}
|
|
{c[1]} a8888b. {r[1]}
|
|
{c[1]} d888888b. {r[2]}
|
|
{c[1]} 8P"YP"Y88 {r[3]}
|
|
{c[1]} 8|o||o|88 {r[4]}
|
|
{c[1]} 8{c[0]}\\vvvv/{c[1]}88 {r[5]}
|
|
{c[1]} 8{c[0]} \\vv/ {c[1]}Y8. {r[6]}
|
|
{c[1]} d/ {c[0]}`'{c[1]} \8b. {r[7]}
|
|
{c[1]} .dP . Y8b. {r[8]}
|
|
{c[1]} d8:' " `::88b. {r[9]}
|
|
{c[1]} d8" `Y88b {r[10]}
|
|
{c[1]} :8P ' :888 {r[11]}
|
|
{c[1]} 8a. : _a88P {r[12]}
|
|
{c[1]} {c[0]}._/"{c[1]}Yaa_ : .{c[0]}| {c[1]}88P{c[0]}|{c[1]} {r[13]}
|
|
{c[1]} {c[0]}\++++{c[1]}YP" `{c[0]}| {c[1]}8P{c[0]}++\.{c[1]} {r[14]}
|
|
{c[1]} {c[0]}/+++++\.{c[1]}_____.d{c[0]}|+++++/{c[1]} {r[15]}
|
|
{c[1]} {c[0]}\++++++){c[1]}888888P{c[0]}\+++/{c[1]} {r[16]}
|
|
{c[1]} {r[17]}\n""",
|
|
Distributions.LINUX_MINT: """
|
|
{c[1]} {r[0]}
|
|
{c[1]} MMMMMMMMMMMMMMMMMMMMMMMMMmds+. {r[1]}
|
|
{c[1]} MMm----::-://////////////oymNMd+` {r[2]}
|
|
{c[1]} MMd {c[0]}/++{c[1]} -sNMd: {r[3]}
|
|
{c[1]} MMNso/` {c[0]}dMM{c[1]} {c[0]}`.::-. .-::.`{c[1]} .hMN: {r[4]}
|
|
{c[1]} ddddMMh {c[0]}dMM{c[1]} {c[0]}:hNMNMNhNMNMNh:`{c[1]} NMm {r[5]}
|
|
{c[1]} NMm {c[0]}dMM{c[1]} {c[0]}.NMN/-+MMM+-/NMN`{c[1]} dMM {r[6]}
|
|
{c[1]} NMm {c[0]}dMM{c[1]} {c[0]}-MMm{c[1]} {c[0]}`MMM{c[1]} {c[0]}dMM.{c[1]} dMM {r[7]}
|
|
{c[1]} NMm {c[0]}dMM{c[1]} {c[0]}-MMm{c[1]} {c[0]}`MMM{c[1]} {c[0]}dMM.{c[1]} dMM {r[8]}
|
|
{c[1]} NMm {c[0]}dMM{c[1]} {c[0]}.mmd{c[1]} {c[0]}`mmm{c[1]} {c[0]}yMM.{c[1]} dMM {r[9]}
|
|
{c[1]} NMm {c[0]}dMM`{c[1]} {c[0]}..`{c[1]} {c[0]}`...{c[1]} {c[0]}ydm.{c[1]} dMM {r[10]}
|
|
{c[1]} hMM- {c[0]}+MMd/-------...-:sdds{c[1]} MMM {r[11]}
|
|
{c[1]} -NMm- {c[0]}:hNMNNNmdddddddddy/`{c[1]} dMM {r[12]}
|
|
{c[1]} -dMNs-``{c[0]}-::::-------.``{c[1]} dMM {r[13]}
|
|
{c[1]} `/dMNmy+/:-------------:/yMMM {r[14]}
|
|
{c[1]} ./ydNMMMMMMMMMMMMMMMMMMMMM {r[15]}
|
|
{c[1]} {r[16]}
|
|
{c[1]} {r[17]}\n""",
|
|
Distributions.OPENSUSE: """
|
|
{c[0]} .;ldkO0000Okdl;. {r[0]}
|
|
{c[0]} .;d00xl:^''''''^:ok00d;. {r[1]}
|
|
{c[0]} .d00l' 'o00d. {r[2]}
|
|
{c[0]} .d0Kd' {c[1]}Okxol:;,.{c[0]} :O0d. {r[3]}
|
|
{c[0]} .OK{c[1]}KKK0kOKKKKKKKKKKOxo:,{c[0]} lKO. {r[4]}
|
|
{c[0]} ,0K{c[1]}KKKKKKKKKKKKKKK0P^{c[0]},,,{c[1]}^dx:{c[0]} ;00, {r[5]}
|
|
{c[0]} .OK{c[1]}KKKKKKKKKKKKKKKk'{c[0]}.oOPPb.{c[1]}'0k.{c[0]} cKO. {r[6]}
|
|
{c[0]} :KK{c[1]}KKKKKKKKKKKKKKK: {c[0]}kKx..dd{c[1]} lKd{c[0]} 'OK: {r[7]}
|
|
{c[0]} dKK{c[1]}KKKKKKKKKOx0KKKd {c[0]}^0KKKO'{c[1]} kKKc{c[0]} dKd {r[8]}
|
|
{c[0]} dKK{c[1]}KKKKKKKKKK;.;oOKx,..{c[0]}^{c[1]}..;kKKK0.{c[0]} dKd {r[9]}
|
|
{c[0]} :KK{c[1]}KKKKKKKKKK0o;...^cdxxOK0O/^^'{c[0]} .0K: {r[10]}
|
|
{c[0]} kKK{c[1]}KKKKKKKKKKKKK0x;,,......,;od{c[0]} lKk {r[11]}
|
|
{c[0]} '0K{c[1]}KKKKKKKKKKKKKKKKKKKK00KKOo^{c[0]} c00' {r[12]}
|
|
{c[0]} 'kK{c[1]}KKOxddxkOO00000Okxoc;''{c[0]} .dKk' {r[13]}
|
|
{c[0]} l0Ko. .c00l' {r[14]}
|
|
{c[0]} 'l0Kk:. .;xK0l' {r[15]}
|
|
{c[0]} 'lkK0xl:;,,,,;:ldO0kl' {r[16]}
|
|
{c[0]} '^:ldxkkkkxdl:^' {r[17]}\n""",
|
|
Distributions.RED_HAT: """
|
|
{c[1]} {r[0]}
|
|
{c[1]} {c[2]}\`.-..........\`{c[1]} {r[1]}
|
|
{c[1]} {c[2]}\`////////::.\`-/.{c[1]} {r[2]}
|
|
{c[1]} {c[2]}-: ....-////////.{c[1]} {r[3]}
|
|
{c[1]} {c[2]}//:-::///////////\`{c[1]} {r[4]}
|
|
{c[1]} {c[2]}\`--::: \`-://////////////:{c[1]} {r[5]}
|
|
{c[1]} {c[2]}//////- \`\`.-://///////{c[1]} .\` {r[6]}
|
|
{c[1]} {c[2]}\`://////:-.\` :///////::///:\`{c[1]} {r[7]}
|
|
{c[1]} {c[2]}.-/////////:---/////////////:{c[1]} {r[8]}
|
|
{c[1]} {c[2]}.-://////////////////////.{c[1]} {r[9]}
|
|
{c[1]} {c[0]}yMN+\`.-${c[2]}::///////////////-\`{c[1]} {r[10]}
|
|
{c[1]} {c[0]}.-\`:NMMNMs\` \`..-------..\`{c[1]} {r[11]}
|
|
{c[1]} {c[0]}MN+/mMMMMMhoooyysshsss{c[1]} {r[12]}
|
|
{c[1]} {c[0]}MMM MMMMMMMMMMMMMMyyddMMM+{c[1]} {r[13]}
|
|
{c[1]} {c[0]}MMMM MMMMMMMMMMMMMNdyNMMh\` hyhMMM{c[1]} {r[14]}
|
|
{c[1]} {c[0]}MMMMMMMMMMMMMMMMyoNNNMMM+. MMMMMMMM{c[1]} {r[15]}
|
|
{c[1]} {c[0]}MMNMMMNNMMMMMNM+ mhsMNyyyyMNMMMMsMM{c[1]} {r[16]}
|
|
{c[1]} {r[17]}\n""",
|
|
Distributions.UBUNTU: """
|
|
{c[1]} {c[0]}.oyhhs:{c[1]} {r[0]}
|
|
{c[1]} ..--.., {c[0]}shhhhhh-{c[1]} {r[1]}
|
|
{c[1]} -+++++++++`:{c[0]}yyhhyo`{c[1]} {r[2]}
|
|
{c[1]} {c[2]}.--{c[1]} -++++++++/-.-{c[0]}::-`{c[1]} {r[3]}
|
|
{c[1]} {c[2]}.::::-{c[1]} :-----:/+++/++/. {r[4]}
|
|
{c[1]} {c[2]}-:::::-.{c[1]} .:++++++: {r[5]}
|
|
{c[1]} ,,, {c[2]}.:::::-`{c[1]} .++++++- {r[6]}
|
|
{c[1]} ./+++/-{c[2]}`-::-{c[1]} ./////: {r[7]}
|
|
{c[1]} +++++++ {c[2]}.::-{c[1]} {r[8]}
|
|
{c[1]} ./+++/-`{c[2]}-::-{c[1]} {c[0]}:yyyyyo{c[1]} {r[9]}
|
|
{c[1]} ``` `{c[2]}-::::-`{c[1]} {c[0]}:yhhhhh:{c[1]} {r[10]}
|
|
{c[1]} {c[2]}-:::::-.{c[1]} {c[0]}`-ohhhhhh+{c[1]} {r[11]}
|
|
{c[1]} {c[2]}.::::-`{c[1]} {c[0]}-o+///+oyhhyyyhy:{c[1]} {r[12]}
|
|
{c[1]} {c[2]}`.--{c[1]} {c[0]}/yhhhhhhhy+{c[2]},....{c[1]} {r[13]}
|
|
{c[1]} {c[0]}/hhhhhhhhh{c[2]}-.-:::;{c[1]} {r[14]}
|
|
{c[1]} {c[0]}`.:://::- {c[2]}-:::::;{c[1]} {r[15]}
|
|
{c[1]} {c[2]}`.-:-'{c[1]} {r[16]}
|
|
{c[1]} {r[17]}\n""",
|
|
Distributions.WINDOWS: """
|
|
{c[1]} {r[0]}
|
|
{c[1]} {c[0]},.=:^!^!t3Z3z.,{c[1]} {r[1]}
|
|
{c[1]} {c[0]}:tt:::tt333EE3{c[1]} {r[2]}
|
|
{c[1]} {c[0]}Et:::ztt33EEE{c[1]} {c[2]}@Ee.,{c[1]} {c[2]}..,{c[1]} {r[3]}
|
|
{c[1]} {c[0]};tt:::tt333EE7{c[1]} {c[2]};EEEEEEttttt33#{c[1]} {r[4]}
|
|
{c[1]} {c[0]}:Et:::zt333EEQ.{c[1]} {c[2]}SEEEEEttttt33QL{c[1]} {r[5]}
|
|
{c[1]} {c[0]}it::::tt333EEF{c[1]} {c[2]}@EEEEEEttttt33F{c[1]} {r[6]}
|
|
{c[1]} {c[0]};3=*^```'*4EEV{c[1]} {c[2]}:EEEEEEttttt33@.{c[1]} {r[7]}
|
|
{c[1]} ,.=::::it=.,{c[0]} `{c[1]} {c[2]}@EEEEEEtttz33QF{c[1]} {r[8]}
|
|
{c[1]} ;::::::::zt33){c[1]} {c[2]}'4EEEtttji3P*{c[1]} {r[9]}
|
|
{c[1]} :t::::::::tt33.{c[3]}:Z3z..{c[2]} `` {c[3]},..g.{c[1]} {r[10]}
|
|
{c[1]} i::::::::zt33F{c[1]} {c[3]}AEEEtttt::::ztF{c[1]} {r[11]}
|
|
{c[1]} ;:::::::::t33V{c[1]} {c[3]};EEEttttt::::t3{c[1]} {r[12]}
|
|
{c[1]} E::::::::zt33L{c[1]} {c[3]}@EEEtttt::::z3F{c[1]} {r[13]}
|
|
{c[1]} {{3=*^```'*4E3){c[1]} {c[3]};EEEtttt:::::tZ`{c[1]} {r[14]}
|
|
{c[1]} `{c[1]} {c[3]}:EEEEtttt::::z7{c[1]} {r[15]}
|
|
{c[1]} {c[3]}'VEzjt:;;z>*`{c[1]} {r[16]}
|
|
{c[1]} {r[17]}\n"""
|
|
}
|
|
|
|
|
|
# ----------- Configuration ----------- #
|
|
|
|
class Configuration():
|
|
def __init__(self):
|
|
"""
|
|
Represents the default configuration which will be used by Archey.
|
|
Values present in the dictionary below are needed.
|
|
New optional values may be added with `updateRecursive()` method.
|
|
"""
|
|
self.config = {
|
|
'colors_palette': {
|
|
'use_unicode': False
|
|
},
|
|
'default_strings': {
|
|
'no_address': 'No Address',
|
|
'not_detected': 'Not detected'
|
|
},
|
|
'ip_settings': {
|
|
'lan_ip_max_count': 2,
|
|
'wan_ip_v6_support': True
|
|
},
|
|
'temperature': {
|
|
'char_before_unit': ' ',
|
|
'use_fahrenheit': False
|
|
},
|
|
'timeout': {
|
|
'ipv4_detection': 1,
|
|
'ipv6_detection': 1
|
|
}
|
|
}
|
|
|
|
def get(self, key, default=None):
|
|
"""
|
|
A binding method to imitate the `dict.get()` behavior.
|
|
"""
|
|
return self.config.get(key, default)
|
|
|
|
def loadConfiguration(self, path):
|
|
# If a previous configuration file has denied overriding...
|
|
if not self.config.get('allow_overriding', True):
|
|
# ... don't load this one.
|
|
return
|
|
|
|
if not path.endswith('/'):
|
|
path += '/'
|
|
|
|
path += 'config.json'
|
|
|
|
try:
|
|
with open(path) as file:
|
|
self.updateRecursive(self.config, json.load(file))
|
|
|
|
except FileNotFoundError:
|
|
pass
|
|
|
|
# For backward compatibility with Python versions prior to 3.5.0
|
|
# we use `ValueError` instead of `json.JSONDecodeError`.
|
|
except ValueError as e:
|
|
print('Warning: {0} ({1})'.format(e, path), file=sys.stderr)
|
|
|
|
def updateRecursive(self, oldDict, newDict):
|
|
"""
|
|
A method for recursively merging dictionaries as...
|
|
... `dict.update()` is not able to do this.
|
|
Original snippet taken from here :
|
|
https://gist.github.com/angstwad/bf22d1822c38a92ec0a9
|
|
"""
|
|
for key, value in newDict.items():
|
|
if key in oldDict and isinstance(oldDict[key], dict) \
|
|
and isinstance(value, dict):
|
|
self.updateRecursive(oldDict[key], value)
|
|
|
|
else:
|
|
oldDict[key] = value
|
|
|
|
|
|
# ---------- Global variables --------- #
|
|
|
|
# We create a global instance of our `Configuration` Class
|
|
config = Configuration()
|
|
|
|
# We'll list the running processes only one time
|
|
try:
|
|
PROCESSES = check_output([
|
|
'ps',
|
|
'-u' + str(getuid()) if getuid() != 0 else '-ax',
|
|
'-o', 'comm', '--no-headers'
|
|
]).decode().split('\n')
|
|
|
|
except FileNotFoundError:
|
|
print('Please, install first `procps` on your distribution.',
|
|
file=sys.stderr)
|
|
exit()
|
|
|
|
|
|
# -------------- Classes -------------- #
|
|
|
|
class Output:
|
|
def __init__(self):
|
|
self.results = []
|
|
try:
|
|
lsbOutput = check_output([
|
|
'lsb_release', '-i', '-s'
|
|
]).decode().rstrip()
|
|
|
|
except FileNotFoundError:
|
|
print('Please, install first `lsb-release` on your distribution.',
|
|
file=sys.stderr)
|
|
exit()
|
|
|
|
if re.search('Microsoft',
|
|
check_output(['uname', '-r']).decode().rstrip()):
|
|
self.distribution = Distributions.WINDOWS
|
|
|
|
else:
|
|
for distribution in Distributions:
|
|
if re.fullmatch(distribution.value, lsbOutput):
|
|
self.distribution = distribution
|
|
break
|
|
|
|
else:
|
|
self.distribution = Distributions.LINUX
|
|
|
|
def append(self, key, value):
|
|
self.results.append('{0}{1}:{2} {3}'.format(
|
|
colorDict[self.distribution][1], key, colorDict['clear'], value))
|
|
|
|
def output(self):
|
|
results = []
|
|
results.extend([''] * floor((18 - len(self.results)) / 2))
|
|
results.extend(self.results[:])
|
|
|
|
if len(results) < 18:
|
|
results.extend([''] * (18 - len(results)))
|
|
|
|
print(logosDict[self.distribution].format(
|
|
c=colorDict[self.distribution], r=results) + colorDict['clear'])
|
|
|
|
|
|
class User:
|
|
def __init__(self):
|
|
self.value = getenv('USER',
|
|
config.get('default_strings')['not_detected'])
|
|
|
|
|
|
class Hostname:
|
|
def __init__(self):
|
|
self.value = check_output(['uname', '-n']).decode().rstrip()
|
|
|
|
|
|
class Model:
|
|
def __init__(self):
|
|
try:
|
|
with open('/sys/devices/virtual/dmi/id/product_name') as file:
|
|
model = file.read().rstrip()
|
|
|
|
except FileNotFoundError:
|
|
# The file above does not exist, is this device a Raspberry Pi ?
|
|
# Let's retrieve the Hardware and Revision IDs with `/proc/cpuinfo`
|
|
with open('/proc/cpuinfo') as file:
|
|
output = file.read()
|
|
|
|
hardware = re.search('(?<=Hardware\t: ).*', output)
|
|
revision = re.search('(?<=Revision\t: ).*', output)
|
|
|
|
# If the output contains 'Hardware' and 'Revision'...
|
|
if hardware and revision:
|
|
# ... let's set a pretty info string with these data
|
|
model = 'Raspberry Pi ' + hardware.group(0) + \
|
|
' (Rev. ' + revision.group(0) + ')'
|
|
|
|
else:
|
|
# A tricky way to retrieve some details about hypervisor...
|
|
# ... within virtualized contexts.
|
|
# `archey` needs to be run as root although.
|
|
try:
|
|
virtWhat = ', '.join(check_output([
|
|
'virt-what'
|
|
],
|
|
stderr=DEVNULL)
|
|
.decode().split())
|
|
|
|
if virtWhat:
|
|
try:
|
|
# Sometimes we may gather info added by...
|
|
# ... hosting service provider this way
|
|
model = check_output([
|
|
'dmidecode',
|
|
'-s',
|
|
'system-product-name'
|
|
], stderr=DEVNULL
|
|
).decode().rstrip()
|
|
|
|
except (FileNotFoundError, CalledProcessError):
|
|
model = 'Virtualized environment'
|
|
|
|
model += ' (' + virtWhat + ')'
|
|
|
|
else:
|
|
model = 'Bare-metal environment'
|
|
|
|
except (FileNotFoundError, CalledProcessError):
|
|
model = config.get('default_strings')['not_detected']
|
|
|
|
self.value = model
|
|
|
|
|
|
class Distro:
|
|
def __init__(self):
|
|
self.value = check_output(['lsb_release', '-d', '-s']
|
|
).decode().rstrip() + \
|
|
' ' + check_output(['uname', '-m']).decode().rstrip()
|
|
|
|
|
|
class Kernel:
|
|
def __init__(self):
|
|
self.value = check_output(['uname', '-r']).decode().rstrip()
|
|
|
|
|
|
class Uptime:
|
|
def __init__(self):
|
|
with open('/proc/uptime') as file:
|
|
fuptime = int(file.read().split('.')[0])
|
|
|
|
day, fuptime = divmod(fuptime, 86400)
|
|
hour, fuptime = divmod(fuptime, 3600)
|
|
minute = fuptime // 60
|
|
|
|
uptime = ''
|
|
uptime += ((str(day) + ' day' + ('s' if day > 1 else '') + ('' if minute == 0 and hour == 0 else (' and ' if (minute != 0 and hour == 0) or (minute == 0 and hour != 0) else ', '))) if day >= 1 else '')
|
|
uptime += ((str(hour) + ' hour' + ('s' if hour > 1 else '') + (' and ' if minute != 0 else '')) if hour >= 1 else '')
|
|
uptime += ((str(minute) + ' minute' + ('s' if minute > 1 else '')) if minute >= 1 else ('< 1 minute' if day == 0 and hour == 0 else ''))
|
|
|
|
self.value = uptime
|
|
|
|
|
|
class WindowManager:
|
|
def __init__(self):
|
|
try:
|
|
wm = re.search('(?<=Name: ).*',
|
|
check_output(['wmctrl', '-m'],
|
|
stderr=DEVNULL).decode()).group(0)
|
|
|
|
except (FileNotFoundError, CalledProcessError):
|
|
for key in wmDict.keys():
|
|
if key in PROCESSES:
|
|
wm = wmDict[key]
|
|
break
|
|
|
|
else:
|
|
wm = config.get('default_strings')['not_detected']
|
|
|
|
self.value = wm
|
|
|
|
|
|
class DesktopEnvironment:
|
|
def __init__(self):
|
|
for key in deDict.keys():
|
|
if key in PROCESSES:
|
|
de = deDict[key]
|
|
break
|
|
|
|
else:
|
|
# Let's rely on an environment var if the loop above didn't `break`
|
|
de = getenv('XDG_CURRENT_DESKTOP',
|
|
config.get('default_strings')['not_detected'])
|
|
|
|
self.value = de
|
|
|
|
|
|
class Shell:
|
|
def __init__(self):
|
|
self.value = getenv('SHELL',
|
|
config.get('default_strings')['not_detected'])
|
|
|
|
|
|
class Terminal:
|
|
def __init__(self):
|
|
terminal = getenv('TERM',
|
|
config.get('default_strings')['not_detected'])
|
|
|
|
# On systems with non-Unicode locales, we imitate '\u2588' character
|
|
# ... with '#' to display the terminal colors palette.
|
|
# This is the default option for backward compatibility.
|
|
colors = ' '.join([
|
|
'\x1b[0;3{0}m{1}\x1b[1;3{0}m{1}{2}'.format(
|
|
i,
|
|
'\u2588' if config.get('colors_palette')['use_unicode']
|
|
else '#',
|
|
colorDict['clear']
|
|
) for i in range(7, 0, -1)])
|
|
|
|
self.value = terminal + ' ' + colors
|
|
|
|
|
|
class Temperature:
|
|
def __init__(self):
|
|
temps = []
|
|
|
|
try:
|
|
# Let's try to retrieve a value from 'Broadcom' chip on Raspberry
|
|
temp = float(re.findall(
|
|
'\d+\.\d+',
|
|
check_output(['/opt/vc/bin/vcgencmd', 'measure_temp'],
|
|
stderr=DEVNULL).decode())[0])
|
|
temps.append(
|
|
self.convertToFahrenheit(temp)
|
|
if config.get('temperature')['use_fahrenheit'] else temp)
|
|
|
|
except (FileNotFoundError, CalledProcessError):
|
|
pass
|
|
|
|
# Now we just check for values within files present in the path below
|
|
for thermalFile in glob('/sys/class/thermal/thermal_zone*/temp'):
|
|
with open(thermalFile) as file:
|
|
temp = float(file.read().strip()) / 1000
|
|
if temp != 0.0:
|
|
temps.append(
|
|
self.convertToFahrenheit(temp)
|
|
if config.get('temperature')['use_fahrenheit']
|
|
else temp)
|
|
|
|
if temps:
|
|
self.value = '{0}{3}{2} (Max. {1}{3}{2})'.format(
|
|
str(round(sum(temps) / len(temps), 1)),
|
|
str(round(max(temps), 1)),
|
|
'F' if config.get('temperature')['use_fahrenheit'] else 'C',
|
|
config.get('temperature')['char_before_unit'])
|
|
|
|
else:
|
|
self.value = config.get('default_strings')['not_detected']
|
|
|
|
"""
|
|
Simple Celsius to Fahrenheit conversion method
|
|
"""
|
|
def convertToFahrenheit(self, temp):
|
|
return temp * (9 / 5) + 32
|
|
|
|
|
|
class Packages:
|
|
def __init__(self):
|
|
for packagesTool in [['pacman', '-Q'],
|
|
['dnf', 'list', 'installed'],
|
|
['dpkg', '--get-selections'],
|
|
['zypper', 'search', '--installed-only'],
|
|
['emerge', '-ep', 'world'],
|
|
['rpm', '-qa']]:
|
|
try:
|
|
results = check_output(packagesTool, stderr=DEVNULL).decode()
|
|
packages = results.count('\n')
|
|
|
|
if 'dpkg' in packagesTool:
|
|
packages -= results.count('deinstall')
|
|
|
|
break
|
|
|
|
except (FileNotFoundError, CalledProcessError):
|
|
pass
|
|
|
|
else:
|
|
packages = config.get('default_strings')['not_detected']
|
|
|
|
self.value = packages
|
|
|
|
|
|
class CPU:
|
|
def __init__(self):
|
|
with open('/proc/cpuinfo') as file:
|
|
self.value = re.sub('\s+', ' ',
|
|
re.search('(?<=model name\t: ).*',
|
|
file.read()).group(0))
|
|
|
|
|
|
class GPU:
|
|
def __init__(self):
|
|
try:
|
|
gpuinfo = check_output(['grep', '-E', '3D|VGA|Display'],
|
|
stdin=Popen(['lspci'],
|
|
stdout=PIPE,
|
|
stderr=DEVNULL).stdout
|
|
).decode().split(': ')[1].rstrip()
|
|
|
|
# If the line got too long, let's truncate it and add some dots...
|
|
if len(gpuinfo) > 48:
|
|
gpuinfo = re.findall('.{1,45}(?:\W|$)',
|
|
gpuinfo)[0].strip() + '...'
|
|
|
|
except (FileNotFoundError, CalledProcessError):
|
|
gpuinfo = config.get('default_strings')['not_detected']
|
|
|
|
self.value = gpuinfo
|
|
|
|
|
|
class RAM:
|
|
def __init__(self):
|
|
try:
|
|
ram = ''.join(filter(re.compile('M').search,
|
|
Popen(['free', '-m'], stdout=PIPE, env={'LANG': 'C'}
|
|
).communicate()[0].decode().split('\n'))
|
|
).split()
|
|
used = float(ram[2])
|
|
total = float(ram[1])
|
|
|
|
except (IndexError, FileNotFoundError):
|
|
# An in-digest one-liner to retrieve memory info into a dictionary
|
|
with open('/proc/meminfo') as file:
|
|
ram = {
|
|
i.split(':')[0]: float(i.split(':')[1].strip(' kB')) / 1024
|
|
for i in filter(None, file.read().split('\n'))
|
|
}
|
|
|
|
total = ram['MemTotal']
|
|
# Here, let's imitate the `free` command behavior
|
|
# (https://gitlab.com/procps-ng/procps/blob/master/proc/sysinfo.c#L787)
|
|
used = total - (ram['MemFree'] + ram['Cached'] + ram['Buffers'])
|
|
if used < 0:
|
|
used += ram['Cached'] + ram['Buffers']
|
|
|
|
self.value = '{0}{1} MB{2} / {3} MB'.format(
|
|
colorDict['sensors'][
|
|
int(((used / total) * 100) // 33.34)
|
|
],
|
|
int(used), colorDict['clear'], int(total))
|
|
|
|
|
|
class Disk:
|
|
def __init__(self):
|
|
total = re.sub(',', '.',
|
|
check_output([
|
|
'df', '-Tlh', '-B', 'GB', '--total',
|
|
'-t', 'ext4', '-t', 'ext3', '-t', 'ext2',
|
|
'-t', 'reiserfs', '-t', 'jfs', '-t', 'zfs',
|
|
'-t', 'ntfs', '-t', 'fat32', '-t', 'btrfs',
|
|
'-t', 'fuseblk', '-t', 'xfs',
|
|
'-t', 'simfs', '-t', 'tmpfs'
|
|
]).decode().splitlines()[-1]).split()
|
|
|
|
self.value = '{0}{1}{2} / {3}'.format(
|
|
colorDict['sensors'][
|
|
int(float(total[5][:-1]) // 33.34)
|
|
],
|
|
re.sub('GB', ' GB', total[3]), colorDict['clear'],
|
|
re.sub('GB', ' GB', total[2]))
|
|
|
|
|
|
class LAN_IP:
|
|
def __init__(self):
|
|
try:
|
|
addresses = check_output(['hostname', '-I'], stderr=DEVNULL
|
|
).decode().split()
|
|
|
|
except (CalledProcessError, FileNotFoundError):
|
|
# Slow manual workaround for old `inetutils` versions, with `ip`
|
|
addresses = check_output(
|
|
['cut', '-d', ' ', '-f', '4'],
|
|
stdin=Popen(['cut', '-d', '/', '-f', '1'],
|
|
stdout=PIPE,
|
|
stdin=Popen(['tr', '-s', ' '],
|
|
stdout=PIPE,
|
|
stdin=Popen(['grep', '-E',
|
|
'scope (global|site)'
|
|
], stdout=PIPE,
|
|
stdin=Popen(['ip',
|
|
'-o',
|
|
'addr',
|
|
'show',
|
|
'up'],
|
|
stdout=PIPE
|
|
).stdout
|
|
).stdout
|
|
).stdout
|
|
).stdout
|
|
).decode().split()
|
|
|
|
# Use list slice to save only `lan_ip_max_count` addresses.
|
|
# If set to `False`, don't modify the list.
|
|
# This option is still optional.
|
|
self.value = ', '.join(addresses[:(
|
|
config.get('ip_settings')['lan_ip_max_count']
|
|
if config.get('ip_settings')['lan_ip_max_count'] is not False
|
|
else len(addresses)
|
|
)]) or config.get('default_strings')['no_address']
|
|
|
|
|
|
class WAN_IP:
|
|
def __init__(self):
|
|
# IPv6 address retrieval (unless the user doesn't want it).
|
|
if config.get('ip_settings')['wan_ip_v6_support']:
|
|
try:
|
|
ipv6_value = check_output([
|
|
'dig', '+short', '-6', 'aaaa', 'myip.opendns.com',
|
|
'@resolver1.ipv6-sandbox.opendns.com'
|
|
], timeout=config.get('timeout')['ipv6_detection'],
|
|
stderr=DEVNULL).decode().rstrip()
|
|
|
|
except (FileNotFoundError, TimeoutExpired, CalledProcessError):
|
|
try:
|
|
ipv6_value = check_output([
|
|
'wget', '-qO-', 'https://v6.ident.me/'
|
|
], timeout=config.get('timeout')['ipv6_detection']
|
|
).decode()
|
|
|
|
except (CalledProcessError, TimeoutExpired):
|
|
# It looks like this user doesn't have any IPv6 address...
|
|
# ... or is not connected to Internet.
|
|
ipv6_value = None
|
|
|
|
except FileNotFoundError:
|
|
ipv6_value = None
|
|
print('Warning: `wget` has not been found on your system.',
|
|
file=sys.stderr)
|
|
|
|
else:
|
|
ipv6_value = None
|
|
|
|
# IPv4 addresses retrieval (anyway).
|
|
try:
|
|
ipv4_value = check_output([
|
|
'dig', '+short', 'myip.opendns.com', '@resolver1.opendns.com'
|
|
], timeout=config.get('timeout')['ipv4_detection'],
|
|
stderr=DEVNULL).decode().rstrip()
|
|
|
|
except (FileNotFoundError, TimeoutExpired, CalledProcessError):
|
|
try:
|
|
ipv4_value = check_output([
|
|
'wget', '-qO-', 'https://v4.ident.me/'
|
|
], timeout=config.get('timeout')['ipv4_detection']
|
|
).decode()
|
|
|
|
except (CalledProcessError, TimeoutExpired):
|
|
# This user looks not connected to Internet...
|
|
ipv4_value = None
|
|
|
|
except FileNotFoundError:
|
|
ipv4_value = None
|
|
# If statement so as to not print the same message twice.
|
|
if not config.get('ip_settings')['wan_ip_v6_support']:
|
|
print('Warning: `wget` has not been found on your system.',
|
|
file=sys.stderr)
|
|
|
|
self.value = ', '.join(
|
|
'{0}\n{1}'.format(ipv4_value or '', ipv6_value or '').split()
|
|
) or config.get('default_strings')['no_address']
|
|
|
|
|
|
# -------------- Classes' Enumeration -------------- #
|
|
|
|
class Classes(Enum):
|
|
User = User
|
|
Hostname = Hostname
|
|
Model = Model
|
|
Distro = Distro
|
|
Kernel = Kernel
|
|
Uptime = Uptime
|
|
WindowManager = WindowManager
|
|
DesktopEnvironment = DesktopEnvironment
|
|
Shell = Shell
|
|
Terminal = Terminal
|
|
Packages = Packages
|
|
Temperature = Temperature
|
|
CPU = CPU
|
|
GPU = GPU
|
|
RAM = RAM
|
|
Disk = Disk
|
|
LAN_IP = LAN_IP
|
|
WAN_IP = WAN_IP
|
|
|
|
|
|
# -------------- Main -------------- #
|
|
|
|
if __name__ == '__main__':
|
|
|
|
# Load global and local configurations in a "regular" order (all optional)
|
|
config.loadConfiguration('/etc/archey4/')
|
|
config.loadConfiguration(os.path.expanduser('~') + '/.config/archey4/')
|
|
config.loadConfiguration(os.path.dirname(os.path.realpath(__file__)))
|
|
|
|
output = Output()
|
|
for key in Classes:
|
|
if config.get('entries', {}).get(key.name, True):
|
|
output.append(key.name, key.value().value)
|
|
|
|
output.output()
|