2009-01-22 14 views
34

मैं लिनक्स में अमरोक के लिए पाइथन लिपि लिखना चाहता हूं ताकि मैं अपने प्लेयर को स्टैक ओवरफ्लो पॉडकास्ट को स्वचालित रूप से कॉपी कर सकूं। जब मैं प्लेयर में प्लग करता हूं, तो यह ड्राइव को आरोहित करेगा, किसी भी लंबित पॉडकास्ट की प्रतिलिपि बनाएँ, और प्लेयर को बाहर निकाल देगा। मैं "प्लग इन" घटना के लिए कैसे सुन सकता हूं? मैंने हल्का देखा है लेकिन एक अच्छा उदाहरण नहीं मिला।मैं पाइथन में लिनक्स में 'यूएसबी डिवाइस डालने' घटनाओं को कैसे सुन सकता हूं?

उत्तर

50

अद्यतन: जैसा कि टिप्पणी में कहा, हैल नए वितरणों में समर्थित नहीं है, मानक अब है udev, यहाँ एक छोटा सा उदाहरण है कि चिकना पाश और udev का उपयोग करता है, मैं ऐतिहासिक लिए हैल वर्शन को बनाए रखने कारणों।

यह मूलतः example in the pyudev documentation है, पुराने संस्करणों के साथ काम करने के लिए अनुकूलित, और चिकना पाश के साथ, ध्यान दें कि फिल्टर अपने विशिष्ट आवश्यकता होगी, के लिए अनुकूलित किया जाना चाहिए:

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() 

हैल और घ के साथ पुराना संस्करण -bus:

आप डी-बस बाइंडिंग का उपयोग और DeviceAdded और DeviceRemoved संकेतों सुन सकते हैं। आपको केवल स्टोरेज डिवाइस का चयन करने के लिए जोड़े गए डिवाइस की क्षमताओं की जांच करनी होगी।

यहां एक छोटा सा उदाहरण है, आप टिप्पणियां हटा सकते हैं और इसे आजमा सकते हैं।

import dbus 
import gobject 

class DeviceAddedListener: 
    def __init__(self): 

आपको सिस्टम बस का उपयोग करके हैल मैनेजर से कनेक्ट करने की आवश्यकता है।

 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 पर कॉल करेगा यदि आप अपनी आवश्यकताओं के लिए अधिक उपयुक्त क्वेरी ढूंढने के लिए हैल दस्तावेज़ों को पढ़ सकते हैं, या हैल उपकरणों के गुणों के बारे में अधिक जानकारी प्राप्त कर सकते हैं।

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() 
+1

मैं इस कोड के साथ एक त्रुटि हो रही है: dbus.exception.DBusException: org.freedesktop.DBus.Error.ServiceUnknown: नाम org.freedesktop.Hal किसी भी .service फ़ाइलों द्वारा प्रदान नहीं किया गया था। क्या आपको लगता है कि आप मेरी मदद कर सकते हैं? –

+0

@ एटियेन लेपेज-लेपिट्रे हैल अब बहिष्कृत है, आम तौर पर यह समाधान अब और काम नहीं करेगा :( – Andy

+1

udev का उपयोग करके समाधान जोड़ा गया। –

7

मैं इस तरह का कार्यक्रम अपने आप को लिखने के प्रयास नहीं किया है, हालांकि मैं अभी (धन्यवाद गूगल!) है, जो मैं मदद की हो जाएगा लगता है कि निम्नलिखित दो लिंक देखा है:

  • dbus-python tutorial (जो बात करती है के बारे में कैसे डी-बस) तक पहुँचने के लिए अजगर का उपयोग करने के
  • HAL 0.5.10 Specification (जो कैसे एचएएल डी-बस के लिए घटनाओं को प्रकाशित करता है)

विशेष रूप से, org.freedesktop.Hal.Manager इंटरफ़ेस के बारे में पढ़ा है, और इसके DeviceAdded औरके बारे में बातघटनाक्रम। :-)

आशा है कि इससे मदद मिलती है!

4

मुझे लगता है कि डी-बस क्रिस के रूप में काम करेगा, लेकिन यदि आप केडीई 4 का उपयोग कर रहे हैं, तो आप केडीई 4 "न्यू डिवाइस नोटिफ़ायर" एप्लेट के समान ठोस फ्रेमवर्क का उपयोग कर सकते हैं।

उस एप्लेट के लिए सी ++ स्रोत here है, जो दिखाता है कि नए उपकरणों का पता लगाने के लिए सॉलिड का उपयोग कैसे करें। here दिखाए गए अनुसार, इन पुस्तकालयों में पाइथन बाइंडिंग के लिए PyKDE4 का उपयोग करें।

2

यहाँ 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 

pyudev==0.21.0 साथ अजगर 3.5 पर परीक्षण किया गया प्रिंट होगा।

संबंधित मुद्दे