Appunti di Programmazione

Creative Commons License

InfoPanel: un pannello di informazioni per OpenBox

InfoPanel

InfoPanel è un piccolo script realizzato in Python, il cui scopo è quello di riunire in un'unica schermata alcune informazioni che mi sono utili quando uso il mio portatile Mac con Debian+OpenBox installati: ora, data, stato della batteria, SSID, stato delle due reti WiFi e Ethernet e relativi indirizzi IP, Stato Bluetooth e Server Apache2 e infine presenza di aggiornamenti disponibili.

Lo script è contenuto in una cartella nominata 'InfoPanel', all'interno della quale si trovano il programma vero e proprio, 'InfoPanel.py', le immagini necessarie all'applicazione e una directory di nome 'digital_display' che contiene il font necessario alla rappresentazione delle cifre dell'orologio.

Per utilizzare il programma è sufficiente salvare la directory dell'applicazione all'interno della propria 'home' senza modificare in alcun modo il nome della cartella stessa e dei file in essa contenuti.
Entrate nella directory dove avete scaricato InfoPanel e impartite il seguente comando:

$ mv InfoPanel ~/InfoPanel

Poi copiate la cartella che contiene il font in '/usr/share/fonts/opentype' in questo modo:

$ cd InfoPanel

quindi

$ cp -r digital_display /usr/share/fonts/opentype/digital_display

Adesso è necessario cambiare i permessi di 'sudo' per l'utente:

$ sudo visudo
[sudo] password di gandalfrank:

Qualora un messaggio vi comunichi che il file non è stato trovato scrivete questa istruzione:

$ sudo /usr/sbin/visudo
[sudo] password di gandalfrank:

Appare l'editor 'Nano' con il file '/etc/sudoers.tmp' pronto per essere modificato. Bisogna aggiungere alla fine del file la seguente linea:

gandalfrank ALL=(ALL) NOPASSWD:ALL

la cui funzione è quella di comunicare al sistema che l'utente 'gandalfrank' può utilizzare l'istruzione 'sudo' senza inserire la password. Ovviamente al posto del mio nickname dovete inserire il vostro.

Sudoers aggiornato

Per avviare il programma digitare la seguente istruzione nel terminale o come comando in un lanciatore:

python3 ~/InfoPanel/InfoPanel.py

Di seguito il codice sorgente dello script e il link per il download.

# 10/08/2023 Fiaschi Francesco
import tkinter as tk
import tkinter.ttk as ttk
import subprocess
import time as ti

root=tk.Tk()
root.geometry("250x540")
root.resizable(width=False, height=False)
root.title("InfoPanel")

img_On=tk.PhotoImage(file='~/InfoPanel/On.png')
img_Off=tk.PhotoImage(file='~/InfoPanel/Off.png')
img_100=tk.PhotoImage(file='~/InfoPanel/Batteria_100.png')
img_80=tk.PhotoImage(file='~/InfoPanel/Batteria_80.png')
img_60=tk.PhotoImage(file='~/InfoPanel/Batteria_60.png')
img_40=tk.PhotoImage(file='~/InfoPanel/Batteria_40.png')
img_20=tk.PhotoImage(file='~/InfoPanel/Batteria_20.png')
img_PC_Aggiornato=tk.PhotoImage(file="~/InfoPanel/PC_Aggiornato.png")
img_PC_Aggiornabile=tk.PhotoImage(file="~/InfoPanel/PC_Aggiornabile.png")
img_Errore_Aggiornamenti=tk.PhotoImage(file="~/InfoPanel/Errore_Aggiornamenti.png")

# Recupera il nome delle reti WiFi ed Ethernet
risposta=str(subprocess.run(["ip a"], shell=True, capture_output=True, text=True))
global rete_E
global rete_W

valore=""
n=1
while valore!="fine":
    i=risposta.find(str(n)+": ")
    if i!=-1:
        j=i+1
        c=""
        while c!="<":
            if risposta[j]=="<":
                break
            c=risposta[j]
            j+=1
        valore=(risposta[i+2:j]).strip()
        valore=valore[:-1]
    else:
        valore="fine"
    n+=1
    if valore[0].lower()=="e":
        rete_E=valore
    elif valore[0].lower()=="w":
        rete_W=valore

def Rileva_IP(testo_IP):

    indice_1=testo_IP.find("inet ")
    if indice_1==-1:
        valore_IP="- - - - - - - - - -"
    else:
        indice_2=indice_1+5
        while (testo_IP[indice_2]!="/" and testo_IP[indice_2]!=" "):
            indice_2+=1
        valore_IP=(testo_IP[indice_1+4:indice_2]).strip()
    return valore_IP

def Controlla():

    # Orologio
    string=ti.strftime('%H:%M:%S')
    lbl_Orologio.config(text=string, width=9)
    lbl_Orologio.after(1000,Controlla)

    # Batteria
    risposta_Batteria=subprocess.run(["sudo upower -i /org/freedesktop/UPower/devices/battery_BAT0"], shell=True, capture_output=True, text=True)
    testo_Batteria=str(risposta_Batteria)
    indice=testo_Batteria.find("percentage")
    if indice==-1:
        valore=0
        lbl_Batteria.config(text="NO Batteria", fg="black")
    else:
        indice+=11
        indice_2=indice
        while testo_Batteria[indice_2]!="%":
            indice_2+=1
        valore=(testo_Batteria[indice:indice_2]).strip()
        valore=valore.replace(",", ".")
        valore=float(valore)
        valore=int(valore)
        
        if valore>=80:
            cnv_Livello_Batteria.create_image(1,1,image=img_100, anchor="nw")
        elif valore>=60 and valore<80:
            cnv_Livello_Batteria.create_image(1,1,image=img_80, anchor="nw")
        elif valore>=40 and valore<60:
            cnv_Livello_Batteria.create_image(1,1,image=img_60, anchor="nw")
        elif valore>=20 and valore<40:
            cnv_Livello_Batteria.create_image(1,1,image=img_40, anchor="nw")
        elif valore<20:
            cnv_Livello_Batteria.create_image(1,1,image=img_20, anchor="nw")
        lbl_Batteria.config(text="Batteria: "+str(valore)+"%")
        cnv_Livello_Batteria.create_rectangle(valore+2,3,102,18, fill="#273236")

    # SSID
    risposta_SSID=subprocess.run(["sudo iw dev"], shell=True, capture_output=True, text=True)
    testo_SSID=str(risposta_SSID)
    indice_1=testo_SSID.find("ssid")
    indice_2=testo_SSID.find("type managed")
    if indice_1==-1:
        valore_SSID="- - - - - - - - - -"
    else:
        valore_SSID=(testo_SSID[indice_1+5:indice_2-6])
    lbl_Stato_SSID.config(text=valore_SSID)

    # WiFi e IP WiFi
    risposta_WiFi=subprocess.run(["sudo ip addr show "+rete_W], shell=True, capture_output=True, text=True)
    testo_IP_WiFi=str(risposta_WiFi)
    valore_IP_WiFi=Rileva_IP(testo_IP_WiFi)
    if "state UP" in risposta_WiFi.stdout:
        lbl_Stato_WiFi.config(text="Attivo", fg="green")
        btn_WiFi.config(image=img_On)
        lbl_Stato_IP_WiFi.config(text=valore_IP_WiFi)
    else:
        lbl_Stato_WiFi.config(text="Non Attivo", fg="red")
        btn_WiFi.config(image=img_Off)
        lbl_Stato_IP_WiFi.config(text="- - - - - - - - - -")
        
    # Ethernet e IP Ethernet
    risposta_Ethernet=subprocess.run(["sudo ip addr show "+rete_E], shell=True, capture_output=True, text=True)
    testo_IP_Ethernet=str(risposta_Ethernet)
    valore_IP_Ethernet=Rileva_IP(testo_IP_Ethernet)
    if "state UP" in risposta_Ethernet.stdout:
        lbl_Stato_Ethernet.config(text="Attivo", fg="green")
        lbl_Stato_IP_Ethernet.config(text=valore_IP_Ethernet)
    else:
        lbl_Stato_Ethernet.config(text="Non Attivo", fg="red")
        lbl_Stato_IP_Ethernet.config(text="- - - - - - - - - -")

    # Bluetooth
    risposta_Bluetooth = subprocess.run(["sudo systemctl status bluetooth"], shell=True, capture_output=True, text=True)
    if "Active: active" in risposta_Bluetooth.stdout:
        lbl_Stato_Bluetooth.config(text="Attivo", fg="green")
        btn_Bluetooth.config(image=img_On)
    else:
        lbl_Stato_Bluetooth.config(text="Non Attivo", fg="red")
        btn_Bluetooth.config(image=img_Off)

    # Apache2
    risposta_Apache2 = subprocess.run(["sudo systemctl status apache2"], shell=True, capture_output=True, text=True)
    if "Active: active" in risposta_Apache2.stdout:
        lbl_Stato_Apache2.config(text="Attivo", fg="green")
        btn_Apache2.config(image=img_On)
    else:
        lbl_Stato_Apache2.config(text="Non Attivo", fg="red")
        btn_Apache2.config(image=img_Off)

def On_Off_WiFi():
    if lbl_Stato_WiFi["text"]=="Attivo":
        subprocess.run(["sudo ip link set "+rete_W+" down"], shell=True)
        btn_WiFi.config(image=img_Off)
    else:
        subprocess.run(["sudo ip link set "+rete_W+" up"], shell=True)
        btn_WiFi.config(image=img_On)

def On_Off_Bluetooth():
    if lbl_Stato_Bluetooth["text"]=="Attivo":
        subprocess.run(["sudo systemctl stop bluetooth"], shell=True)
        btn_Bluetooth.config(image=img_Off)
    else:
        subprocess.run(["sudo systemctl start bluetooth"], shell=True)
        btn_Bluetooth.config(image=img_On)

def On_Off_Apache2():
    if lbl_Stato_Apache2["text"]=="Attivo":
        subprocess.run(["sudo systemctl stop apache2"], shell=True)
        btn_Apache2.config(image=img_Off)
    else:
        subprocess.run(["sudo systemctl start apache2"], shell=True)
        btn_Apache2.config(image=img_On)

# Orologio
lbl_Orologio=tk.Label(root, font=("Digital Display",30), fg="gray30")
lbl_Orologio.pack(anchor='center')

# Data
lbl_Data=tk.Label(root, font=("DejaVu Sans",10), text=ti.strftime('%A %d / %m / %Y'))
lbl_Data.pack(anchor='center')

# Separatore
separator_1 = ttk.Separator(root, orient='horizontal')
separator_1.place(x=10, y=70, width=230)

# Batteria
lbl_Batteria=tk.Label(root, font=("DejaVu Sans",10), text="Batteria: ")
lbl_Batteria.place(x=15, y=90)

cnv_Livello_Batteria=tk.Canvas(root, width=104, height=20)
cnv_Livello_Batteria.place(x=130, y=90)

# Separatore
separator_2 = ttk.Separator(root, orient='horizontal')
separator_2.place(x=10, y=130, width=230)

# SSID
lbl_SSID=tk.Label(root, font=("DejaVu Sans",10), text="SSID: ")
lbl_SSID.place(x=15, y=150)

lbl_Stato_SSID=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_SSID.place(x=105, y=150)

# Separatore
separator_3 = ttk.Separator(root, orient='horizontal')
separator_3.place(x=10, y=190, width=230)

# WiFi
lbl_WiFi=tk.Label(root, font=("DejaVu Sans",10), text="WiFi: ")
lbl_WiFi.place(x=15, y=210)

lbl_Stato_WiFi=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_WiFi.place(x=105, y=210)

btn_WiFi=tk.Button(root, image=img_On, command=On_Off_WiFi)
btn_WiFi.place(x=215, y=212)

# IP WiFi
lbl_IP_WiFi=tk.Label(root, font=("DejaVu Sans",10), text="IP: ")
lbl_IP_WiFi.place(x=15, y=230)

lbl_Stato_IP_WiFi=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_IP_WiFi.place(x=105, y=230)

# Separatore
separator_4 = ttk.Separator(root, orient='horizontal')
separator_4.place(x=10, y=270, width=230)

# Ethernet
lbl_Ethernet=tk.Label(root, font=("DejaVu Sans",10), text="Ethernet: ")
lbl_Ethernet.place(x=15, y=290)

lbl_Stato_Ethernet=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_Ethernet.place(x=105, y=290)

# IP Ethernet
lbl_IP_Ethernet=tk.Label(root, font=("DejaVu Sans",10), text="IP: ")
lbl_IP_Ethernet.place(x=15, y=310)

lbl_Stato_IP_Ethernet=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_IP_Ethernet.place(x=105, y=310)

# Separatore
separator_5 = ttk.Separator(root, orient='horizontal')
separator_5.place(x=10, y=350, width=230)

# Bluetooth
lbl_Bluetooth=tk.Label(root, font=("DejaVu Sans",10), text="Bluetooth: ")
lbl_Bluetooth.place(x=15, y=370)

lbl_Stato_Bluetooth=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_Bluetooth.place(x=105, y=370)

btn_Bluetooth=tk.Button(root, image=img_On, command=On_Off_Bluetooth)
btn_Bluetooth.place(x=215, y=362)

# Separatore
separator_6 = ttk.Separator(root, orient='horizontal')
separator_6.place(x=10, y=410, width=230) 

# Server Apache2
lbl_Apache2=tk.Label(root, font=("DejaVu Sans",10), text="Apache 2: ")
lbl_Apache2.place(x=15, y=430)

lbl_Stato_Apache2=tk.Label(root, font=("DejaVu Sans",10))
lbl_Stato_Apache2.place(x=105, y=430)

btn_Apache2=tk.Button(root, image=img_On, command=On_Off_Apache2)
btn_Apache2.place(x=215, y=422)

# Separatore
separator_7 = ttk.Separator(root, orient='horizontal')
separator_7.place(x=10, y=470, width=230) 

# Aggiornamenti
lbl_Aggiornamenti=tk.Label(root)
lbl_Icona_Aggiornamenti=tk.Label(root)

risposta_Aggiornamenti = subprocess.run(["sudo apt update"], shell=True, capture_output=True, text=True)
if "Tutti i pacchetti sono aggiornati." in risposta_Aggiornamenti.stdout:
    lbl_Aggiornamenti.config(text="Sistema aggiornato")
    lbl_Icona_Aggiornamenti.config(image=img_PC_Aggiornato)
elif ': eseguire "apt list --upgradable"' in risposta_Aggiornamenti.stdout:
    lbl_Aggiornamenti.config(text="Aggiornare il sistema", fg="red")
    lbl_Icona_Aggiornamenti.config(image=img_PC_Aggiornabile)
else:
    lbl_Aggiornamenti.config(text="Controllare il sistema", fg="red")
    lbl_Icona_Aggiornamenti.config(image=img_Errore_Aggiornamenti)

lbl_Aggiornamenti.place(x=15, y=490)
lbl_Icona_Aggiornamenti.place(x=205, y=480)

Controlla()
root.mainloop()

Download InfoPanel ( 54 KB )