disclaimer: sono autore di questo indicatore ed è scritto per questa domanda specifica
Aggiornamento ottobre 23,2018
L'indicatore ora supporta l' elenco delle condivisioni di rete . Grazie a mihaigalos
Aggiornamento 29 ottobre 2016
L'indicatore ora ha funzionalità di smontaggio e gli alias sono stati resi unici facendo riferimento all'UUID di ciascuna partizione anziché al nome del dispositivo a blocchi come sda1
. Vedi la relativa segnalazione di bug
Aggiornamento, ottobre 8,2016
L'indicatore è ora nella versione 2.0, ha aggiunto alcune funzionalità e ha il proprio PPA.
Per installare da PPA, attenersi alla seguente procedura nel terminale:
sudo apt-add-repository ppa:udisks-indicator-team/ppa
sudo bash -c 'apt-get update && apt-get install udisks-indicator'
Come menzionato nelle note di rilascio, le funzionalità includono:
- Icone per le voci di menu: a ogni partizione / dispositivo è associata un'icona appropriata. Se il dispositivo è un disco USB, viene utilizzata l'icona del supporto rimovibile, se è un'immagine iso - viene utilizzata l'icona del disco ottico e ovviamente le partizioni del disco rigido / SSD hanno icone dell'unità.
- L'utilizzo è ora mostrato in percentuale e valori leggibili dall'uomo (potenze di 1024).
- Rappresentazione grafica dell'utilizzo tramite barra di utilizzo (grande grazie a Mateo Salta per l'idea)
- Finestra di dialogo Preferenze: gli utenti possono disattivare determinati campi che non desiderano visualizzare per ciascuna voce di menu. Ciò consente di mantenere pulito il menu degli indicatori se è presente una grande quantità di partizioni collegate. (Grazie alla richiesta di Zacharee)
- Spaziatura del testo: con i caratteri Ubuntu e Monospace predefiniti, le voci di testo sono ben distanziate per avere un aspetto più pulito e migliorare la leggibilità delle informazioni.
- Bolle di notifica nel caso in cui non sia possibile montare la partizione
Di seguito è riportato lo screenshot con il tema dell'icona di Ubuntu predefinito:
Tema dell'icona di Ubuntu Kylin
Con tutti i campi opzionali disattivati
Scelte di design e pensieri aggiuntivi:
Nel realizzare questo indicatore, speravo di ottenere un'utilità adatta sia agli utenti esperti che a quelli occasionali. Ho provato ad affrontare alcuni dei problemi che ho notato che i nuovi utenti potrebbero avere con la gestione degli strumenti da riga di comando. Inoltre, l'utilità si sforza di essere multiuso.
La finestra di dialogo Preferenze consente di rendere l'indicatore complesso e / o semplice quanto l'utente desidera. È stata anche una decisione di progettazione specifica per evitare di avere un'etichetta nel pannello superiore in modo da non occupare troppo spazio sul pannello superiore dell'utente. Inoltre, questo indicatore si sforza di essere un'utilità multiuso che consente il montaggio di partizioni e l'apertura delle rispettive directory. Questo può essere usato non solo come utility di utilizzo del disco, ma anche come utility di navigazione per una rapida apertura delle directory.
È anche conveniente per gli utenti sapere quale partizione risiede in quale disco, evitando così frequenti confusioni con il montaggio tramite utility da riga di comando come mount
. Invece impiega udisksctl
a tale scopo (oltre a ottenere le informazioni dal UDisks2
demone, da cui la denominazione). L'unica attività che non esegue è lo smontaggio e per questo motivo Open Disks Utility
è inclusa la voce di menu.
Mentre originariamente mi sono sforzato di renderlo simile al menu iStat, il progetto si è discostato da questo obiettivo: l'indicatore è unico nel suo design e scopo. Spero che possa essere utile per molti utenti e rendere la loro esperienza Ubuntu molto più piacevole.
indicatore udisks (risposta originale)
Indicatore per Ubuntu con desktop Unity per mostrare l'utilizzo del disco
Panoramica
Questo indicatore per Ubuntu con Unity consente di visualizzare facilmente le informazioni sulle partizioni montate. Si sforza di essere visivamente simile al menu iStat Menu 3 di OS X.
Le voci sono organizzate in ordine:
- Partizione
- Alias (se impostato dall'utente)
- Unità disco a cui appartiene la partizione
- Punto di mount della partizione (directory)
- % Di utilizzo
Facendo clic su ciascuna voce della partizione si aprirà il mountpoint della partizione nel file manager predefinito
Il menu "Partizioni non montate" elenca tutte le partizioni non attualmente montate dal sistema. Facendo clic su una voce in quel sottomenu, la partizione verrà montata automaticamente, in genere sulla /media/username/drive-id
cartella
L'indicatore utilizza le icone predefinite fornite con il sistema, quindi l'icona dovrebbe cambiare quando si cambia il tema dell'icona utilizzando lo strumento Unity Tweak o altri metodi
NOTA : se si desidera aggiungere più alias contemporaneamente, anziché uno ad uno tramite l'opzione "Crea alias", è possibile farlo modificando il ~/.partition_aliases.json
file di configurazione. Il formato è il seguente:
{
"sda1": "Alias 1",
"sda2": "Alias 2",
"sdb1": "Alias 3"
}
Installazione
PPA per una facile installazione è in arrivo. . .
Nel frattempo, ecco alcuni passaggi alternativi:
cd /tmp
wget https://github.com/SergKolo/udisks-indicator/archive/master.zip
unzip master.zip
sudo install udisks-indicator-master/udisks-indicator /usr/bin/udisks-indicator
sudo install udisks-indicator-master/udisks-indicator.desktop /usr/share/applications/udisks-indicator.desktop
Tutti questi passaggi possono essere inseriti in un piccolo script di installazione:
#!/bin/bash
cd /tmp
rm master.zip*
wget https://github.com/SergKolo/udisks-indicator/archive/master.zip
unzip master.zip
install udisks-indicator-master/udisks-indicator /usr/bin/udisks-indicator
install udisks-indicator-master/udisks-indicator.desktop /usr/share/applications/udisks-indicator.desktop
Codice sorgente
Di seguito è riportato il codice sorgente originale (Versione v1.0) con funzionalità di base di questo indicatore. Per le funzionalità più recenti, controlla il repository GitHub per questo progetto . Si prega di segnalare eventuali richieste di funzionalità, nonché errori su GitHub.
Il /usr/bin/udisks-indicator
:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Author: Serg Kolo , contact: 1047481448@qq.com
# Date: September 27 , 2016
# Purpose: appindicator for displaying mounted filesystem usage
# Tested on: Ubuntu 16.04 LTS
#
#
# Licensed under The MIT License (MIT).
# See included LICENSE file or the notice below.
#
# Copyright © 2016 Sergiy Kolodyazhnyy
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import gi
gi.require_version('AppIndicator3', '0.1')
from gi.repository import GLib as glib
from gi.repository import AppIndicator3 as appindicator
from gi.repository import Gtk as gtk
from os import statvfs
#from collections import OrderedDict
import subprocess
import shutil
import dbus
import json
import os
class UdisksIndicator(object):
def __init__(self):
self.app = appindicator.Indicator.new(
'udisks-indicator', "drive-harddisk-symbolic.svg",
appindicator.IndicatorCategory.HARDWARE
)
if not self.app.get_icon():
self.app.set_icon("drive-harddisk-symbolic")
self.app.set_status(appindicator.IndicatorStatus.ACTIVE)
filename = '.partition_aliases.json'
user_home = os.path.expanduser('~')
self.config_file = os.path.join(user_home,filename)
self.cache = self.get_partitions()
self.make_menu()
self.update()
def update(self):
timeout = 5
glib.timeout_add_seconds(timeout,self.callback)
def callback(self):
if self.cache != self.get_partitions():
self.make_menu()
self.update()
def make_menu(self,*args):
""" generates entries in the indicator"""
if hasattr(self, 'app_menu'):
for item in self.app_menu.get_children():
self.app_menu.remove(item)
self.app_menu = gtk.Menu()
partitions = self.get_partitions()
for i in partitions:
part = "Partition: " + i[0]
alias = self.find_alias(i[0])
drive = "\nDrive: " + i[1]
mount = "\nMountPoint: " + i[2]
usage = "\n%Usage: " + i[3]
item = part + drive + mount + usage
if alias:
alias = "\nAlias: " + alias
item = part + alias + drive + mount + usage
self.menu_item = gtk.MenuItem(item)
self.menu_item.connect('activate',self.open_mountpoint,i[2])
self.app_menu.append(self.menu_item)
self.menu_item.show()
self.separator = gtk.SeparatorMenuItem()
self.app_menu.append(self.separator)
self.separator.show()
self.unmounted = gtk.MenuItem('Unmounted Partitions')
self.unmounted_submenu = gtk.Menu()
self.unmounted.set_submenu(self.unmounted_submenu)
for i in self.get_unmounted_partitions():
# TODO: add type checking, prevent swap
part = "Partition: " + i[0]
alias = self.find_alias(i[0])
drive = "\nDrive: " + i[1]
label = part + drive
if alias:
alias = "\nAlias: " + alias
label = part + alias + drive
self.menu_item = gtk.MenuItem(label)
self.menu_item.connect('activate',self.mount_partition,i[0])
self.unmounted_submenu.append(self.menu_item)
self.menu_item.show()
self.separator = gtk.SeparatorMenuItem()
self.unmounted_submenu.append(self.separator)
self.separator.show()
self.app_menu.append(self.unmounted)
self.unmounted.show()
self.separator = gtk.SeparatorMenuItem()
self.app_menu.append(self.separator)
self.separator.show()
self.make_part_alias = gtk.MenuItem('Make Alias')
self.make_part_alias.connect('activate',self.make_alias)
self.app_menu.append(self.make_part_alias)
self.make_part_alias.show()
user_home = os.path.expanduser('~')
desktop_file = '.config/autostart/udisks-indicator.desktop'
full_path = os.path.join(user_home,desktop_file)
label = 'Start Automatically'
if os.path.exists(full_path):
label = label + ' \u2714'
self.autostart = gtk.MenuItem(label)
self.autostart.connect('activate',self.toggle_auto_startup)
self.app_menu.append(self.autostart)
self.autostart.show()
self.open_gnome_disks = gtk.MenuItem('Open Disks Utility')
self.open_gnome_disks.connect('activate',self.open_disks_utility)
self.app_menu.append(self.open_gnome_disks)
self.open_gnome_disks.show()
self.quit_app = gtk.MenuItem('Quit')
self.quit_app.connect('activate', self.quit)
self.app_menu.append(self.quit_app)
self.quit_app.show()
self.app.set_menu(self.app_menu)
def mount_partition(self,*args):
# TODO: implement error checking for mounting
return self.run_cmd(['udisksctl','mount','-b','/dev/' + args[-1]])
def get_mountpoint_usage(self,mountpoint):
fs = statvfs(mountpoint)
usage = 100*(float(fs.f_blocks)-float(fs.f_bfree))/float(fs.f_blocks)
return str("{0:.2f}".format(usage))
def get_partitions(self):
objects = self.get_dbus('system',
'org.freedesktop.UDisks2',
'/org/freedesktop/UDisks2',
'org.freedesktop.DBus.ObjectManager',
'GetManagedObjects',
None)
partitions = []
for item in objects:
try:
if 'block_devices' in str(item):
drive = self.get_dbus_property('system',
'org.freedesktop.UDisks2',
item,
'org.freedesktop.UDisks2.Block',
'Drive')
if drive == '/': continue
mountpoint = self.get_mountpoint(item)
if not mountpoint: continue
mountpoint = mountpoint.replace('\x00','')
drive = str(drive).split('/')[-1]
usage = self.get_mountpoint_usage(mountpoint)
part = str(item.split('/')[-1])
partitions.append((part,drive,mountpoint,usage))
except Exception as e:
#print(e)
pass
# returning list of tuples
partitions.sort()
return partitions
def get_mountpoint(self,dev_path):
try:
data = self.get_dbus_property(
'system',
'org.freedesktop.UDisks2',
dev_path,
'org.freedesktop.UDisks2.Filesystem',
'MountPoints')[0]
except Exception as e:
#print(e)
return None
else:
if len(data) > 0:
return ''.join([ chr(byte) for byte in data])
def get_unmounted_partitions(self):
objects = self.get_dbus('system',
'org.freedesktop.UDisks2',
'/org/freedesktop/UDisks2',
'org.freedesktop.DBus.ObjectManager',
'GetManagedObjects',
None)
partitions = []
for item in objects:
try:
if 'block_devices' in str(item):
drive = self.get_dbus_property('system',
'org.freedesktop.UDisks2',
item,
'org.freedesktop.UDisks2.Block',
'Drive')
if drive == '/': continue
mountpoint = self.get_mountpoint(item)
if mountpoint: continue
drive = str(drive).split('/')[-1]
part = str(item.split('/')[-1])
if not part[-1].isdigit(): continue
partitions.append((part,drive))
#print(partitions)
except Exception as e:
#print(e)
pass
partitions.sort()
return partitions
def get_dbus(self,bus_type,obj,path,interface,method,arg):
if bus_type == "session":
bus = dbus.SessionBus()
if bus_type == "system":
bus = dbus.SystemBus()
proxy = bus.get_object(obj,path)
method = proxy.get_dbus_method(method,interface)
if arg:
return method(arg)
else:
return method()
def get_dbus_property(self,bus_type,obj,path,iface,prop):
if bus_type == "session":
bus = dbus.SessionBus()
if bus_type == "system":
bus = dbus.SystemBus()
proxy = bus.get_object(obj,path)
aux = 'org.freedesktop.DBus.Properties'
props_iface = dbus.Interface(proxy,aux)
props = props_iface.Get(iface,prop)
return props
def make_alias(self,*args):
partitions = [ i[0] for i in self.get_partitions() ]
combo_values = '|'.join(partitions)
#print(combo_values)
command=[ 'zenity','--forms','--title','Make Alias',
'--add-combo','Partition','--combo-values',
combo_values,'--add-entry','Alias' ]
user_input = self.run_cmd(command)
if not user_input: return
alias = user_input.decode().strip().split('|')
existing_values = None
if os.path.isfile(self.config_file):
with open(self.config_file) as conf_file:
try:
existing_values = json.load(conf_file)
except ValueError:
pass
with open(self.config_file,'w') as conf_file:
if existing_values:
existing_values[alias[0]] = alias[1]
else:
existing_values = {alias[0]:alias[1]}
#print(existing_values)
json.dump(existing_values,conf_file,indent=4,sort_keys=True)
def find_alias(self,part):
if os.path.isfile(self.config_file):
with open(self.config_file) as conf_file:
try:
aliases = json.load(conf_file)
except ValueError:
pass
else:
if part in aliases:
return aliases[part]
else:
return None
def toggle_auto_startup(self,*args):
user_home = os.path.expanduser('~')
desktop_file = '.config/autostart/udisks-indicator.desktop'
full_path = os.path.join(user_home,desktop_file)
if os.path.exists(full_path):
os.unlink(full_path)
else:
original = '/usr/share/applications/udisks-indicator.desktop'
if os.path.exists(original):
shutil.copyfile(original,full_path)
self.make_menu()
def open_mountpoint(self,*args):
pid = subprocess.Popen(['xdg-open',args[-1]]).pid
def open_disks_utility(self,*args):
pid = subprocess.Popen(['gnome-disks']).pid
def run_cmd(self, cmdlist):
""" Reusable function for running external commands """
new_env = dict(os.environ)
new_env['LC_ALL'] = 'C'
try:
stdout = subprocess.check_output(cmdlist, env=new_env)
except subprocess.CalledProcessError:
pass
else:
if stdout:
return stdout
def run(self):
""" Launches the indicator """
try:
gtk.main()
except KeyboardInterrupt:
pass
def quit(self, data=None):
""" closes indicator """
gtk.main_quit()
def main():
""" defines program entry point """
indicator = UdisksIndicator()
indicator.run()
if __name__ == '__main__':
main()
Il /usr/share/applications/udisks-indicator.desktop
[Desktop Entry]
Version=1.0
Name=Udisks Indicator
Comment=Indicator for reporting partition information
Exec=udisks-indicator
Type=Application
Icon=drive-harddisk-symbolic.svg
Terminal=false
Informazioni addizionali:
Test di Ubuntu Mate 16.04:
Gli utenti di Gnome hanno bisogno di un'estensione (KStatusNotifierItem / AppIndicator Support) per far funzionare correttamente l'indicatore:
/dev/sdb1
e il suo utilizzo proprio accanto ad esso? In percentuale o gigabyte effettivi?