isenção de responsabilidade: sou autor deste indicador e está escrito para esta pergunta específica
Atualização Oct 23,2018
O indicador agora suporta a listagem de compartilhamentos de rede . Graças a mihaigalos
Atualização 29 de outubro de 2016
O indicador agora tem funcionalidade de desmontagem e os aliases foram diferenciados ao se referir ao UUID de cada partição, em vez do nome do dispositivo do bloco, como sda1
. Veja o relatório de bug relacionado
Atualização, 8 de outubro de 2016
O indicador está agora na versão 2.0, adicionou alguns recursos e possui seu próprio PPA.
Para instalar a partir do PPA, siga as seguintes etapas no terminal:
sudo apt-add-repository ppa:udisks-indicator-team/ppa
sudo bash -c 'apt-get update && apt-get install udisks-indicator'
Conforme mencionado nas notas de versão, os recursos incluem:
- Ícones para entradas do menu: cada partição / dispositivo possui um ícone apropriado anexado. Se o dispositivo for um disco USB, é usado o ícone de mídia removível, se for uma imagem iso - o ícone do disco óptico é usado e, obviamente, as partições do disco rígido / SSD têm ícones de unidade.
- O uso agora é mostrado em porcentagem e valores legíveis por humanos (potências de 1024).
- Representação gráfica do uso via barra de uso (muito obrigado a Mateo Salta pela ideia)
- Caixa de diálogo Preferências: os usuários podem desativar determinados campos que não desejam ver em cada entrada do menu. Isso permite manter o menu do indicador limpo se houver uma grande quantidade de partições conectadas. (Graças ao pedido de Zacharee)
- Espaçamento de texto: com a fonte Ubuntu padrão e as fontes Monospace, as entradas de texto são bem espaçadas para ter uma aparência mais limpa e melhorar a legibilidade das informações.
- Bolhas de notificação caso a partição não possa ser montada
Abaixo está a captura de tela com o tema padrão do ícone Ubuntu:
Tema de ícone do Ubuntu Kylin
Com todos os campos opcionais desativados
Opções de design e pensamentos adicionais:
Na elaboração desse indicador, esperava obter um utilitário adequado para usuários avançados e casuais. Tentei resolver alguns dos problemas que percebi que os novos usuários podem ter ao lidar com ferramentas de linha de comando. Além disso, o utilitário procura ser multiuso.
A caixa de diálogo Preferências permite tornar o indicador tão complexo e / ou simples quanto o usuário desejar. Também foi uma decisão de design específica evitar rótulos no painel superior para não ocupar muito espaço no painel superior do usuário. Além disso, este indicador se esforça para ser um utilitário multiuso que permite montar partições e abrir seus respectivos diretórios. Isso pode ser usado não apenas como utilitário de uso do disco, mas também como utilitário de navegação para abrir rapidamente os diretórios.
Também é conveniente para os usuários saberem qual partição habita em qual disco, evitando assim confusão frequente com a montagem por meio de utilitários de linha de comando como mount
. Em vez disso, emprega udisksctl
para esse fim (além de obter as informações do UDisks2
daemon, daí a nomeação). A única tarefa que ele não executa é desmontar e / ou é por isso que a Open Disks Utility
entrada do menu está incluída.
Embora originalmente eu tenha me esforçado para torná-lo semelhante ao menulet iStat, o projeto divergiu desse objetivo - o indicador é único em seu design e propósito. Espero que seja útil para muitos usuários e torne a experiência do Ubuntu muito mais agradável.
indicador de udiscos (resposta original)
Indicador para o Ubuntu com área de trabalho do Unity para mostrar o uso do disco
Visão geral
Este indicador para o Ubuntu com Unity permite visualizar facilmente informações sobre suas partições montadas. Ele se esforça para ser visualmente semelhante ao menu iStat Menu 3 do OS X.
As entradas são organizadas em ordem:
- Partição
- Alias (se definido pelo usuário)
- Unidade de disco à qual a partição pertence
- Ponto de montagem da partição (diretório)
- % De uso
Clicar em cada entrada da partição abrirá o ponto de montagem da partição no gerenciador de arquivos padrão
O menu "Partições desmontadas" lista todas as partições atualmente não montadas pelo sistema. Ao clicar em qualquer entrada desse submenu, a partição será montada automaticamente, normalmente na /media/username/drive-id
pasta
O indicador usa ícones padrão fornecidos com o sistema; portanto, o ícone deve mudar conforme você altera o tema do ícone usando a Unity Tweak Tool ou outros métodos
NOTA : se você deseja adicionar vários aliases ao mesmo tempo, em vez de um por um através da opção "Criar alias", pode fazê-lo editando o ~/.partition_aliases.json
arquivo de configuração. O formato é o seguinte:
{
"sda1": "Alias 1",
"sda2": "Alias 2",
"sdb1": "Alias 3"
}
Instalação
O PPA para facilitar a instalação está disponível em breve. . .
Enquanto isso, aqui estão as etapas alternativas:
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
Todas estas etapas podem ser colocadas em um pequeno e agradável script de instalação:
#!/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
Código fonte
O código fonte original (versão v1.0) com a funcionalidade básica deste indicador pode ser encontrado abaixo. Para novos recursos, consulte o repositório GitHub para este projeto . Por favor, relate quaisquer solicitações de recursos, bem como erros no GitHub.
O /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()
o /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
Informação adicional:
Teste do Ubuntu Mate 16.04:
Os usuários do Gnome precisam de uma extensão (suporte do KStatusNotifierItem / AppIndicator) para fazer o indicador se comportar corretamente:
/dev/sdb1
e seu uso ao lado dele? Em porcentagem ou gigabytes reais?