Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
233 lines (187 sloc) 7.4 KB
#!/usr/bin/env python
Arista Input Device Discovery
A set of tools to discover DVD-capable devices and Video4Linux devices that
emit signals when disks that contain video are inserted or webcames / tuner
cards are plugged in using udev.
Copyright 2008 - 2011 Daniel G. Taylor <>
This file is part of Arista.
Arista is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 2.1 of
the License, or (at your option) any later version.
Arista is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with Arista. If not, see
import gettext
import gobject
import gudev
_ = gettext.gettext
class InputSource(object):
A simple object representing an input source.
def __init__(self, device):
Create a new input device.
@type device: gudev.Device
@param device: The device that we are using as an input source
self.device = device
def nice_label(self):
Get a nice label for this device.
@rtype: str
@return: The label, in this case the product name
return self.path
def path(self):
Get the device block in the filesystem for this device.
@rtype: string
@return: The device block, such as "/dev/cdrom".
return self.device.get_device_file()
class DVDDevice(InputSource):
A simple object representing a DVD-capable device.
def media(self):
Check whether media is in the device.
@rtype: bool
@return: True if media is present in the device.
return self.device.has_property("ID_FS_TYPE")
def nice_label(self):
if self.device.has_property("ID_FS_LABEL"):
label = self.device.get_property("ID_FS_LABEL")
return " ".join([word.capitalize() for word in label.split("_")])
return self.device.get_property("ID_MODEL")
class V4LDevice(InputSource):
A simple object representing a Video 4 Linux device.
def nice_label(self):
return self.device.get_sysfs_attr("name")
def version(self):
Get the video4linux version of this device.
if self.device.has_property("ID_V4L_VERSION"):
return self.device.get_property("ID_V4L_VERSION")
# Default to version 2
return "2"
class InputFinder(gobject.GObject):
An object that will find and monitor DVD-capable devices on your
machine and emit signals when video disks are inserted / removed.
- disc-found(InputFinder, DVDDevice, label)
- disc-lost(InputFinder, DVDDevice, label)
- v4l-capture-found(InputFinder, V4LDevice)
- v4l-capture-lost(InputFinder, V4LDevice)
__gsignals__ = {
"disc-found": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
"disc-lost": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
(gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT)),
"v4l-capture-found": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
"v4l-capture-lost": (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
def __init__(self):
Create a new DVDFinder and attach to the udev system to listen for
self.client = gudev.Client(["video4linux", "block"])
self.drives = {}
self.capture_devices = {}
for device in self.client.query_by_subsystem("video4linux"):
block = device.get_device_file()
self.capture_devices[block] = V4LDevice(device)
for device in self.client.query_by_subsystem("block"):
if device.has_property("ID_CDROM"):
block = device.get_device_file()
self.drives[block] = DVDDevice(device)
self.client.connect("uevent", self.event)
def event(self, client, action, device):
Handle a udev event.
return {
"add": self.device_added,
"change": self.device_changed,
"remove": self.device_removed,
}.get(action, lambda x,y: None)(device, device.get_subsystem())
def device_added(self, device, subsystem):
Called when a device has been added to the system.
print device, subsystem
if subsystem == "video4linux":
block = device.get_device_file()
self.capture_devices[block] = V4LDevice(device)
self.emit("v4l-capture-found", self.capture_devices[block])
def device_changed(self, device, subsystem):
Called when a device has changed. If the change represents a disc
being inserted or removed, fire the disc-found or disc-lost signals
if subsystem == "block" and device.has_property("ID_CDROM"):
block = device.get_device_file()
dvd_device = self.drives[block]
media_changed = != device.has_property("ID_FS_TYPE")
dvd_device.device = device
if media_changed:
self.emit("disc-found", dvd_device, dvd_device.nice_label)
self.emit("disc-lost", dvd_device, dvd_device.nice_label)
def device_removed(self, device, subsystem):
Called when a device has been removed from the system.
if __name__ == "__main__":
# Run a test to print out DVD-capable devices and whether or not they
# have video disks in them at the moment.
import gobject
def found(finder, device, label):
print device.path + ": " + label
def lost(finder, device, label):
print device.path + ": " + _("Not mounted.")
finder = InputFinder()
finder.connect("disc-found", found)
finder.connect("disc-lost", lost)
for device, drive in finder.drives.items():
print drive.nice_label + ": " + device
for device, capture in finder.capture_devices.items():
print capture.nice_label + " V4Lv" + str(capture.version) + ": " + device
loop = gobject.MainLoop()