2009-01-22 3 views
34

Ich möchte unter Linux ein Python-Skript für Amarok schreiben, um den stackoverflow-Podcast automatisch auf meinen Player zu kopieren. Wenn ich den Player einstecke, würde es das Laufwerk mounten, alle ausstehenden Podcasts kopieren und den Player auswerfen. Wie kann ich auf das "Plug-in" -Event hören? Ich habe durch das Feld geschaut, konnte aber kein gutes Beispiel finden.Wie kann ich in Linux, in Python für 'USB-Gerät eingefügt' Ereignisse hören?

Antwort

50

aktualisieren: Wie in den Kommentaren gesagt, wird Hal nicht in der letzten Distributionen unterstützt wird, jetzt die Standard-udev ist, hier ein kleines Beispiel ist die Verwendung von glib Schleife und udev macht, halte ich die Hal-Version für historische Gründe dafür.

Dies ist im Grunde die example in the pyudev documentation, angepasst mit älteren Versionen zu arbeiten und mit der glib Schleife, feststellen, dass die Filter nach Ihrem spezifischen benötigt angepasst werden:

import glib 

from pyudev import Context, Monitor 

try: 
    from pyudev.glib import MonitorObserver 

    def device_event(observer, device): 
     print 'event {0} on device {1}'.format(device.action, device) 
except: 
    from pyudev.glib import GUDevMonitorObserver as MonitorObserver 

    def device_event(observer, action, device): 
     print 'event {0} on device {1}'.format(action, device) 

context = Context() 
monitor = Monitor.from_netlink(context) 

monitor.filter_by(subsystem='usb') 
observer = MonitorObserver(monitor) 

observer.connect('device-event', device_event) 
monitor.start() 

glib.MainLoop().run() 

Alter Version mit Hal und d -Bus:

Sie können D-Bus-Bindungen und hören DeviceAdded und DeviceRemoved Signale verwenden. Sie müssen die Funktionen des hinzugefügten Geräts überprüfen, um nur die Speichergeräte auszuwählen.

Hier ist ein kleines Beispiel, Sie können die Kommentare entfernen und es versuchen.

import dbus 
import gobject 

class DeviceAddedListener: 
    def __init__(self): 

Sie müssen eine Verbindung zum Hal Manager über den Systembus herstellen.

 self.bus = dbus.SystemBus() 
     self.hal_manager_obj = self.bus.get_object(
               "org.freedesktop.Hal", 
               "/org/freedesktop/Hal/Manager") 
     self.hal_manager = dbus.Interface(self.hal_manager_obj, 
              "org.freedesktop.Hal.Manager") 

Und Sie brauchen einen Zuhörer auf die Signale verbinden Sie interessiert sind, in diesem Fall DeviceAdded.

 self.hal_manager.connect_to_signal("DeviceAdded", self._filter) 

Ich verwende einen Filter basierend auf Fähigkeiten.Es akzeptiert alle volume und ruft do_something mit, wenn, können Sie Hal Dokumentation zu finden, die passendere Abfragen für Ihre Bedürfnisse oder weitere Informationen über die Eigenschaften der Hal-Geräte.

def _filter(self, udi): 
     device_obj = self.bus.get_object ("org.freedesktop.Hal", udi) 
     device = dbus.Interface(device_obj, "org.freedesktop.Hal.Device") 

     if device.QueryCapability("volume"): 
      return self.do_something(device) 

Beispiel Funktion, die einige Informationen über das Volumen zeigt:

 def do_something(self, volume): 
     device_file = volume.GetProperty("block.device") 
     label = volume.GetProperty("volume.label") 
     fstype = volume.GetProperty("volume.fstype") 
     mounted = volume.GetProperty("volume.is_mounted") 
     mount_point = volume.GetProperty("volume.mount_point") 
     try: 
      size = volume.GetProperty("volume.size") 
     except: 
      size = 0 

     print "New storage device detectec:" 
     print " device_file: %s" % device_file 
     print " label: %s" % label 
     print " fstype: %s" % fstype 
     if mounted: 
      print " mount_point: %s" % mount_point 
     else: 
      print " not mounted" 
     print " size: %s (%.2fGB)" % (size, float(size)/1024**3) 

if __name__ == '__main__': 
    from dbus.mainloop.glib import DBusGMainLoop 
    DBusGMainLoop(set_as_default=True) 
    loop = gobject.MainLoop() 
    DeviceAddedListener() 
    loop.run() 
+1

ich einen Fehler mit diesem Code erhalten: dbus.exception.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: Der org.freedesktop.Hal Name von irgendwelchen .service Dateien nicht zur Verfügung gestellt wurde. Denkst du, du könntest mir helfen? –

+0

@ EtienneLepage-Lepitre Hal ist jetzt veraltet, in der Regel wird diese Lösung nicht mehr funktionieren :( – Andy

+1

Lösung mit udev hinzugefügt. –

7

Ich habe nicht versucht, ein solches Programm selbst schreiben, aber ich habe gerade auf den beiden folgenden Links angesehen (dank Google!), Die ich denke, wird eine Hilfe sein:

insbesondere Ereignisse zu D-Bus) veröffentlicht, lesen Sie über die org.freedesktop.Hal.Manager Schnittstelle und seine DeviceAdded und DeviceRemoved Ereignisse. :-)

Hoffe, das hilft!

4

Ich denke, D-Bus würde funktionieren, wie Chris erwähnt, aber wenn Sie KDE4 verwenden, könnten Sie das Solid Framework ähnlich wie das KDE4 Applet "New Device Notifier" verwenden.

Die C++ - Quelle für dieses Applet ist here, die zeigt, wie Solid verwendet wird, um neue Geräte zu erkennen. Verwenden Sie PyKDE4 für Python-Bindungen zu diesen Bibliotheken (siehe Abbildung here).

2

Hier ist eine Lösung in 5 Zeilen.

import pyudev 

context = pyudev.Context() 
monitor = pyudev.Monitor.from_netlink(context) 
monitor.filter_by(subsystem='usb') 

for device in iter(monitor.poll, None): 
    if device.action == 'add': 
     print('{} connected'.format(device)) 
     # do something very interesting here. 

speichern in eine Datei sagen usb_monitor.py, laufen python monitor.py. Schließen Sie eine beliebige USB und es wird Gerätedetails

→ python usb_monitor.py 
Device('/sys/devices/pci0000:00/0000:00:14.0/usb1/1-6/1-6:1.0') connected 
Device('/sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1:1.0') connected 

Getestet auf Python 3.5 mit pyudev==0.21.0 drucken.

Verwandte Themen