mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Linux device mounting: Use udisks, if it is available, to mount devices, so that I no longer have to hear bug reports from users using distro packages that have crippled calibre-mount-helper. You can turn off udisks by setting the environment variable CALIBRE_DISABLE_UDISKS=1
This commit is contained in:
parent
c5ebc3e5a3
commit
1022ddd101
88
src/calibre/devices/udisks.py
Normal file
88
src/calibre/devices/udisks.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
|
||||||
|
__license__ = 'GPL v3'
|
||||||
|
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
import dbus
|
||||||
|
import os
|
||||||
|
|
||||||
|
def node_mountpoint(node):
|
||||||
|
|
||||||
|
def de_mangle(raw):
|
||||||
|
return raw.replace('\\040', ' ').replace('\\011', '\t').replace('\\012',
|
||||||
|
'\n').replace('\\0134', '\\')
|
||||||
|
|
||||||
|
for line in open('/proc/mounts').readlines():
|
||||||
|
line = line.split()
|
||||||
|
if line[0] == node:
|
||||||
|
return de_mangle(line[1])
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class UDisks(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
if os.environ.get('CALIBRE_DISABLE_UDISKS', False):
|
||||||
|
raise Exception('User has aborted use of UDISKS')
|
||||||
|
self.bus = dbus.SystemBus()
|
||||||
|
self.main = dbus.Interface(self.bus.get_object('org.freedesktop.UDisks',
|
||||||
|
'/org/freedesktop/UDisks'), 'org.freedesktop.UDisks')
|
||||||
|
|
||||||
|
def device(self, device_node_path):
|
||||||
|
devpath = self.main.FindDeviceByDeviceFile(device_node_path)
|
||||||
|
return dbus.Interface(self.bus.get_object('org.freedesktop.UDisks',
|
||||||
|
devpath), 'org.freedesktop.UDisks.Device')
|
||||||
|
|
||||||
|
def mount(self, device_node_path):
|
||||||
|
d = self.device(device_node_path)
|
||||||
|
try:
|
||||||
|
return unicode(d.FilesystemMount('',
|
||||||
|
['auth_no_user_interaction', 'rw', 'noexec', 'nosuid',
|
||||||
|
'sync', 'nodev', 'uid=1000', 'gid=1000']))
|
||||||
|
except:
|
||||||
|
# May be already mounted, check
|
||||||
|
mp = node_mountpoint(str(device_node_path))
|
||||||
|
if mp is None:
|
||||||
|
raise
|
||||||
|
return mp
|
||||||
|
|
||||||
|
def unmount(self, device_node_path):
|
||||||
|
d = self.device(device_node_path)
|
||||||
|
d.FilesystemUnmount(['force'])
|
||||||
|
|
||||||
|
def eject(self, device_node_path):
|
||||||
|
parent = device_node_path
|
||||||
|
while parent[-1] in '0123456789':
|
||||||
|
parent = parent[:-1]
|
||||||
|
devices = [str(x) for x in self.main.EnumerateDeviceFiles()]
|
||||||
|
for d in devices:
|
||||||
|
if d.startswith(parent) and d != parent:
|
||||||
|
try:
|
||||||
|
self.unmount(d)
|
||||||
|
except:
|
||||||
|
import traceback
|
||||||
|
print 'Failed to unmount:', d
|
||||||
|
traceback.print_exc()
|
||||||
|
d = self.device(parent)
|
||||||
|
d.DriveEject([])
|
||||||
|
|
||||||
|
def mount(node_path):
|
||||||
|
u = UDisks()
|
||||||
|
u.mount(node_path)
|
||||||
|
|
||||||
|
def eject(node_path):
|
||||||
|
u = UDisks()
|
||||||
|
u.eject(node_path)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
dev = sys.argv[1]
|
||||||
|
print 'Testing with node', dev
|
||||||
|
u = UDisks()
|
||||||
|
print 'Mounted at:', u.mount(dev)
|
||||||
|
print 'Ejecting'
|
||||||
|
u.eject(dev)
|
||||||
|
|
||||||
|
|
@ -530,16 +530,8 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
return drives
|
return drives
|
||||||
|
|
||||||
def node_mountpoint(self, node):
|
def node_mountpoint(self, node):
|
||||||
|
from calibre.devices.udisks import node_mountpoint
|
||||||
def de_mangle(raw):
|
return node_mountpoint(node)
|
||||||
return raw.replace('\\040', ' ').replace('\\011', '\t').replace('\\012',
|
|
||||||
'\n').replace('\\0134', '\\')
|
|
||||||
|
|
||||||
for line in open('/proc/mounts').readlines():
|
|
||||||
line = line.split()
|
|
||||||
if line[0] == node:
|
|
||||||
return de_mangle(line[1])
|
|
||||||
return None
|
|
||||||
|
|
||||||
def find_largest_partition(self, path):
|
def find_largest_partition(self, path):
|
||||||
node = path.split('/')[-1]
|
node = path.split('/')[-1]
|
||||||
@ -585,6 +577,13 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
label += ' (%d)'%extra
|
label += ' (%d)'%extra
|
||||||
|
|
||||||
def do_mount(node, label):
|
def do_mount(node, label):
|
||||||
|
try:
|
||||||
|
from calibre.devices.udisks import mount
|
||||||
|
mount(node)
|
||||||
|
return 0
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
cmd = 'calibre-mount-helper'
|
cmd = 'calibre-mount-helper'
|
||||||
if getattr(sys, 'frozen_path', False):
|
if getattr(sys, 'frozen_path', False):
|
||||||
cmd = os.path.join(sys.frozen_path, cmd)
|
cmd = os.path.join(sys.frozen_path, cmd)
|
||||||
@ -617,6 +616,7 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
if not mp.endswith('/'): mp += '/'
|
if not mp.endswith('/'): mp += '/'
|
||||||
self._linux_mount_map[main] = mp
|
self._linux_mount_map[main] = mp
|
||||||
self._main_prefix = mp
|
self._main_prefix = mp
|
||||||
|
self._linux_main_device_node = main
|
||||||
cards = [(carda, '_card_a_prefix', 'carda'),
|
cards = [(carda, '_card_a_prefix', 'carda'),
|
||||||
(cardb, '_card_b_prefix', 'cardb')]
|
(cardb, '_card_b_prefix', 'cardb')]
|
||||||
for card, prefix, typ in cards:
|
for card, prefix, typ in cards:
|
||||||
@ -732,6 +732,11 @@ class Device(DeviceConfig, DevicePlugin):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def eject_linux(self):
|
def eject_linux(self):
|
||||||
|
try:
|
||||||
|
from calibre.devices.udisks import eject
|
||||||
|
return eject(self._linux_main_device_node)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
drives = self.find_device_nodes()
|
drives = self.find_device_nodes()
|
||||||
for drive in drives:
|
for drive in drives:
|
||||||
if drive:
|
if drive:
|
||||||
|
@ -24,6 +24,7 @@ Environment variables
|
|||||||
* ``CALIBRE_OVERRIDE_DATABASE_PATH`` - allows you to specify the full path to metadata.db. Using this variable you can have metadata.db be in a location other than the library folder. Useful if your library folder is on a networked drive that does not support file locking.
|
* ``CALIBRE_OVERRIDE_DATABASE_PATH`` - allows you to specify the full path to metadata.db. Using this variable you can have metadata.db be in a location other than the library folder. Useful if your library folder is on a networked drive that does not support file locking.
|
||||||
* ``CALIBRE_DEVELOP_FROM`` - Used to run from a calibre development environment. See :ref:`develop`.
|
* ``CALIBRE_DEVELOP_FROM`` - Used to run from a calibre development environment. See :ref:`develop`.
|
||||||
* ``CALIBRE_OVERRIDE_LANG`` - Used to force the language used by the interface (ISO 639 language code)
|
* ``CALIBRE_OVERRIDE_LANG`` - Used to force the language used by the interface (ISO 639 language code)
|
||||||
|
* ``CALIBRE_DISABLE_UDISKS`` - Used to disable the use of udisks for mounting/ejecting. Set it to 1 to use calibre-mount-helper instead.
|
||||||
* ``SYSFS_PATH`` - Use if sysfs is mounted somewhere other than /sys
|
* ``SYSFS_PATH`` - Use if sysfs is mounted somewhere other than /sys
|
||||||
* ``http_proxy`` - Used on linux to specify an HTTP proxy
|
* ``http_proxy`` - Used on linux to specify an HTTP proxy
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user