zrzeczenie się odpowiedzialności: Jestem autorem tego wskaźnika i jest on napisany dla tego konkretnego pytania
Aktualizacja 23 października 2018 r
Wskaźnik obsługuje teraz wyświetlanie udziałów sieciowych . Dzięki mihaigalos
Aktualizacja 29 października 2016 r
Wskaźnik ma teraz funkcję odmontowywania, a aliasy zostały uczynione unikalnymi poprzez odniesienie do UUID każdej partycji zamiast nazwy urządzenia blokowego, takiego jak sda1
. Zobacz powiązany raport o błędzie
Aktualizacja, 8 października 2016 r
Wskaźnik jest teraz w wersji 2.0, dodał kilka funkcji i ma własny PPA.
Aby zainstalować z PPA, wykonaj następujące kroki w terminalu:
sudo apt-add-repository ppa:udisks-indicator-team/ppa
sudo bash -c 'apt-get update && apt-get install udisks-indicator'
Jak wspomniano w uwagach do wydania, funkcje obejmują:
- Ikony pozycji menu: do każdej partycji / urządzenia dołączona jest odpowiednia ikona. Jeśli urządzeniem jest dysk USB, używana jest ikona nośnika wymiennego, jeśli jest to obraz iso - używana jest ikona dysku optycznego, a oczywiście partycje dysku twardego / SSD mają ikony napędu.
- Użycie jest teraz wyświetlane w wartościach procentowych i czytelnych dla człowieka (moc 1024).
- Graficzne przedstawienie użycia za pomocą paska użycia (wielkie podziękowania dla Mateo Salta za pomysł)
- Okno dialogowe preferencji: użytkownicy mogą wyłączyć niektóre pola, których nie chcą widzieć w każdej pozycji menu. Pozwala to utrzymać menu wskaźnika w czystości, jeśli dołączona jest duża liczba partycji. (Dzięki prośbie Zacharee)
- Odstępy między tekstami: w przypadku domyślnych czcionek Ubuntu i Monospace wpisy tekstowe są ładnie rozmieszczone, aby uzyskać bardziej przejrzysty wygląd i poprawić czytelność informacji.
- Pęcherzyki powiadomień w przypadku niemożności zamontowania partycji
Poniżej znajduje się zrzut ekranu z domyślnym motywem ikony Ubuntu:
Motyw ikony Ubuntu Kylin
Przy wyłączonych wszystkich opcjonalnych polach
Zaprojektuj opcje i dodatkowe przemyślenia:
Przy tworzeniu tego wskaźnika miałem nadzieję uzyskać narzędzie, które byłoby odpowiednie zarówno dla zaawansowanych, jak i zwykłych użytkowników. Próbowałem rozwiązać niektóre problemy, które zauważyłem, że nowi użytkownicy mogą mieć problemy z obsługą narzędzi wiersza poleceń. Ponadto narzędzie stara się być uniwersalne.
Okno dialogowe Preferencje pozwala uczynić wskaźnik tak złożonym i / lub tak prostym, jak chce użytkownik. Decyzja o unikaniu umieszczenia etykiety na górnym panelu była również specyficzną decyzją projektową, aby nie zajmowała zbyt dużo miejsca na górnym panelu użytkownika. Ponadto ten wskaźnik stara się być narzędziem wielofunkcyjnym, które umożliwia montowanie partycji, a także otwieranie odpowiednich katalogów. Może to służyć nie tylko jako narzędzie do użycia dysku, ale także jako narzędzie do nawigacji do szybkiego otwierania katalogów.
Wygodne jest również, aby użytkownicy wiedzieli, która partycja zamieszkuje dany dysk, unikając w ten sposób częstych nieporozumień podczas montowania za pomocą narzędzi wiersza poleceń, takich jak mount
. Zamiast tego wykorzystuje udisksctl
do tego celu (a także uzyskiwanie informacji od UDisks2
demona, stąd nazewnictwo). Jedynym zadaniem, którego nie wykonuje, jest odmontowanie lub z tego powodu Open Disks Utility
pozycja menu jest uwzględniona.
Podczas gdy pierwotnie starałem się uczynić go podobnym do menuletu iStat, projekt odszedł od tego celu - wskaźnik jest wyjątkowy pod względem projektu i celu. Mam nadzieję, że okaże się przydatny dla wielu użytkowników i sprawi, że korzystanie z Ubuntu będzie znacznie przyjemniejsze.
wskaźnik udisks (oryginalna odpowiedź)
Wskaźnik Ubuntu z pulpitem Unity, aby pokazać użycie dysku
Przegląd
Ten wskaźnik dla Ubuntu z Unity pozwala łatwo przeglądać informacje o zamontowanych partycjach. Stara się być wizualnie podobny do menuletu iStat Menu 3 z OS X.
Wpisy są organizowane w kolejności:
- Przegroda
- Alias (jeśli ustawiony przez użytkownika)
- Dysk twardy, do którego należy partycja
- Punkt montowania partycji (katalog)
- % Stosowanie
Kliknięcie każdego wpisu partycji otworzy punkt montowania partycji w domyślnym menedżerze plików
Menu „Unmounted Partitions” zawiera listę wszystkich partycji, które nie są obecnie montowane przez system. Kliknięcie dowolnego wpisu w tym podmenu spowoduje automatyczne zamontowanie partycji, zwykle do /media/username/drive-id
folderu
Wskaźnik używa domyślnych ikon dostarczonych z systemem, więc ikona powinna się zmieniać wraz ze zmianą motywu ikony za pomocą narzędzia Unity Tweak Tool lub innych metod
UWAGA : jeśli chcesz dodać wiele aliasów jednocześnie, zamiast jeden po drugim za pomocą opcji „Utwórz alias”, możesz to zrobić poprzez edycję ~/.partition_aliases.json
pliku konfiguracyjnego. Format jest następujący:
{
"sda1": "Alias 1",
"sda2": "Alias 2",
"sdb1": "Alias 3"
}
Instalacja
PPA do łatwej instalacji już wkrótce. . .
Tymczasem oto alternatywne kroki:
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
Wszystkie te kroki można umieścić w ładnym skrypcie instalacyjnym:
#!/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
Kod źródłowy
Oryginalny kod źródłowy (wersja v1.0) z podstawową funkcjonalnością tego wskaźnika można znaleźć poniżej. Aby uzyskać najnowsze funkcje, sprawdź repozytorium GitHub dla tego projektu . Proszę zgłaszać wszelkie żądania funkcji, a także błędy w GitHub.
/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()
The /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
Dodatkowe informacje:
Test Ubuntu Mate 16.04:
Użytkownicy GNOME potrzebują rozszerzenia (obsługa KStatusNotifierItem / AppIndicator), aby wskaźnik działał poprawnie:
/dev/sdb1
i jego użycie tuż obok niego? W procentach lub w rzeczywistych gigabajtach?