我想在Linux中为Amarok编写一个Python脚本,以自动将stackoverflow播客复制到我的播放器.当我插入播放器时,它会挂载驱动器,复制任何待处理的播客,然后弹出播放器.我该如何收听"插入"事件?我已经查看过了,但找不到一个好的例子.
更新:正如评论中所述,Hal在最近的发行版中不受支持,标准现在是udev,这是一个利用glib循环和udev的小例子,我保留了Hal版本的历史原因.
这基本上是pyudev文档中的示例,适用于旧版本,并且对于glib循环,请注意应根据您的特定需求自定义过滤器:
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()
Hal和d-bus的旧版本:
您可以使用D-Bus绑定并收听DeviceAdded
和DeviceRemoved
发送信号.您必须检查已添加设备的功能才能仅选择存储设备.
这是一个小例子,你可以删除评论并试一试.
import dbus import gobject class DeviceAddedListener: def __init__(self):
您需要使用系统总线连接到Hal Manager.
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")
在这种情况下,您需要将侦听器连接到您感兴趣的信号DeviceAdded
.
self.hal_manager.connect_to_signal("DeviceAdded", self._filter)
我正在使用基于功能的过滤器.它将接受任何volume
并且将调用do_something
if,您可以阅读Hal文档以找到更适合您需求的查询,或者有关Hal设备属性的更多信息.
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)
显示有关卷的一些信息的示例函数:
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()
我自己没有尝试过编写这样的程序,但是我只看了以下两个链接(感谢Google!),我认为这会有所帮助:
dbus-python教程(讲述如何使用Python访问D-Bus)
HAL 0.5.10规范(讨论HAL如何将事件发布到D-Bus)
特别是,阅读有关org.freedesktop.Hal.Manager
接口及其DeviceAdded
和DeviceRemoved
事件的信息.:-)
希望这可以帮助!
这是5行解决方案。
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.
将其保存到文件中usb_monitor.py
,然后运行python monitor.py
。插入任何USB,它将打印设备详细信息
? 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
已在Python 3.5上使用进行了测试pyudev==0.21.0
。