mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Command line interface to 505 for linux implemented.
This commit is contained in:
parent
bb2f9c36c1
commit
1353492be4
@ -75,9 +75,9 @@ class Device(object):
|
|||||||
def total_space(self, end_session=True):
|
def total_space(self, end_session=True):
|
||||||
"""
|
"""
|
||||||
Get total space available on the mountpoints:
|
Get total space available on the mountpoints:
|
||||||
1. Main memory
|
1. Main memory
|
||||||
2. Memory Stick
|
2. Memory Stick
|
||||||
3. SD Card
|
3. SD Card
|
||||||
|
|
||||||
@return: A 3 element list with total space in bytes of (1, 2, 3). If a
|
@return: A 3 element list with total space in bytes of (1, 2, 3). If a
|
||||||
particular device doesn't have any of these locations it should return 0.
|
particular device doesn't have any of these locations it should return 0.
|
||||||
@ -99,9 +99,9 @@ class Device(object):
|
|||||||
def books(self, oncard=False, end_session=True):
|
def books(self, oncard=False, end_session=True):
|
||||||
"""
|
"""
|
||||||
Return a list of ebooks on the device.
|
Return a list of ebooks on the device.
|
||||||
@param oncard: If True return a list of ebooks on the storage card,
|
@param oncard: If True return a list of ebooks on the storage card,
|
||||||
otherwise return list of ebooks in main memory of device.
|
otherwise return list of ebooks in main memory of device.
|
||||||
If True and no books on card return empty list.
|
If True and no books on card return empty list.
|
||||||
@return: A BookList.
|
@return: A BookList.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## You should have received a copy of the GNU General Public License along
|
||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from libprs500.devices.prs505.driver import PRS505
|
||||||
"""
|
"""
|
||||||
Provides a command-line and optional graphical interface to the SONY Reader PRS-500.
|
Provides a command-line and optional graphical interface to the SONY Reader PRS-500.
|
||||||
|
|
||||||
@ -136,7 +137,7 @@ def ls(dev, path, term, recurse=False, color=False, human_readable_size=False, l
|
|||||||
return rowwidths
|
return rowwidths
|
||||||
|
|
||||||
output = StringIO.StringIO()
|
output = StringIO.StringIO()
|
||||||
if path.endswith("/"): path = path[:-1]
|
if path.endswith("/") and len(path) > 1: path = path[:-1]
|
||||||
dirs = dev.list(path, recurse)
|
dirs = dev.list(path, recurse)
|
||||||
for dir in dirs:
|
for dir in dirs:
|
||||||
if recurse: print >>output, dir[0] + ":"
|
if recurse: print >>output, dir[0] + ":"
|
||||||
@ -197,8 +198,6 @@ def main():
|
|||||||
parser.add_option("--log-packets", help="print out packet stream to stdout. "+\
|
parser.add_option("--log-packets", help="print out packet stream to stdout. "+\
|
||||||
"The numbers in the left column are byte offsets that allow the packet size to be read off easily.",
|
"The numbers in the left column are byte offsets that allow the packet size to be read off easily.",
|
||||||
dest="log_packets", action="store_true", default=False)
|
dest="log_packets", action="store_true", default=False)
|
||||||
parser.add_option("--unlock", help="Unlock device with KEY. For e.g. --unlock=1234", \
|
|
||||||
dest='key', default='-1')
|
|
||||||
parser.remove_option("-h")
|
parser.remove_option("-h")
|
||||||
parser.disable_interspersed_args() # Allow unrecognized options
|
parser.disable_interspersed_args() # Allow unrecognized options
|
||||||
options, args = parser.parse_args()
|
options, args = parser.parse_args()
|
||||||
@ -209,8 +208,12 @@ def main():
|
|||||||
|
|
||||||
command = args[0]
|
command = args[0]
|
||||||
args = args[1:]
|
args = args[1:]
|
||||||
dev = PRS500(key=options.key, log_packets=options.log_packets)
|
dev = PRS500(log_packets=options.log_packets)
|
||||||
|
if not dev.is_connected():
|
||||||
|
dev = PRS505()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
dev.open()
|
||||||
if command == "df":
|
if command == "df":
|
||||||
total = dev.total_space(end_session=False)
|
total = dev.total_space(end_session=False)
|
||||||
free = dev.free_space()
|
free = dev.free_space()
|
||||||
@ -226,13 +229,13 @@ def main():
|
|||||||
print "\nBooks on storage card:"
|
print "\nBooks on storage card:"
|
||||||
for book in dev.books(oncard=True): print book
|
for book in dev.books(oncard=True): print book
|
||||||
elif command == "mkdir":
|
elif command == "mkdir":
|
||||||
parser = OptionParser(usage="usage: %prog mkdir [options] path\nCreate a directory on the device\n\npath must begin with /,a:/ or b:/")
|
parser = OptionParser(usage="usage: %prog mkdir [options] path\nCreate a directory on the device\n\npath must begin with / or card:/")
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
dev.mkdir(args[0])
|
dev.mkdir(args[0])
|
||||||
elif command == "ls":
|
elif command == "ls":
|
||||||
parser = OptionParser(usage="usage: %prog ls [options] path\nList files on the device\n\npath must begin with /,a:/ or b:/")
|
parser = OptionParser(usage="usage: %prog ls [options] path\nList files on the device\n\npath must begin with / or card:/")
|
||||||
parser.add_option("--color", help="show ls output in color", dest="color", action="store_true", default=False)
|
parser.add_option("--color", help="show ls output in color", dest="color", action="store_true", default=False)
|
||||||
parser.add_option("-l", help="In addition to the name of each file, print the file type, permissions, and timestamp (the modification time, in the local timezone). Times are local.", dest="ll", action="store_true", default=False)
|
parser.add_option("-l", help="In addition to the name of each file, print the file type, permissions, and timestamp (the modification time, in the local timezone). Times are local.", dest="ll", action="store_true", default=False)
|
||||||
parser.add_option("-R", help="Recursively list subdirectories encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False)
|
parser.add_option("-R", help="Recursively list subdirectories encountered. /dev and /proc are omitted", dest="recurse", action="store_true", default=False)
|
||||||
@ -249,7 +252,7 @@ def main():
|
|||||||
usage="usage: %prog cp [options] source destination\nCopy files to/from the device\n\n"+\
|
usage="usage: %prog cp [options] source destination\nCopy files to/from the device\n\n"+\
|
||||||
"One of source or destination must be a path on the device. \n\nDevice paths have the form\n"+\
|
"One of source or destination must be a path on the device. \n\nDevice paths have the form\n"+\
|
||||||
"prs500:mountpoint/my/path\n"+\
|
"prs500:mountpoint/my/path\n"+\
|
||||||
"where mountpoint is one of /, a: or b:\n\n"+\
|
"where mountpoint is one of / or card:/\n\n"+\
|
||||||
"source must point to a file for which you have read permissions\n"+\
|
"source must point to a file for which you have read permissions\n"+\
|
||||||
"destination must point to a file or directory for which you have write permissions"
|
"destination must point to a file or directory for which you have write permissions"
|
||||||
parser = OptionParser(usage=usage)
|
parser = OptionParser(usage=usage)
|
||||||
@ -305,7 +308,7 @@ def main():
|
|||||||
dev.get_file(path, outfile)
|
dev.get_file(path, outfile)
|
||||||
elif command == "rm":
|
elif command == "rm":
|
||||||
parser = OptionParser(usage="usage: %prog rm path\nDelete files from the device\n\npath should point to a file or empty directory on the device "+\
|
parser = OptionParser(usage="usage: %prog rm path\nDelete files from the device\n\npath should point to a file or empty directory on the device "+\
|
||||||
"and must begin with /,a:/ or b:/\n\n"+\
|
"and must begin with / or card:/\n\n"+\
|
||||||
"rm will DELETE the file. Be very CAREFUL")
|
"rm will DELETE the file. Be very CAREFUL")
|
||||||
options, args = parser.parse_args(args)
|
options, args = parser.parse_args(args)
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## You should have received a copy of the GNU General Public License along
|
||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
from StringIO import StringIO
|
|
||||||
|
|
||||||
### End point description for PRS-500 procductId=667
|
### End point description for PRS-500 procductId=667
|
||||||
### Endpoint Descriptor:
|
### Endpoint Descriptor:
|
||||||
@ -51,6 +50,7 @@ import sys, os
|
|||||||
from tempfile import TemporaryFile
|
from tempfile import TemporaryFile
|
||||||
from array import array
|
from array import array
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
from libprs500.devices.interface import Device
|
from libprs500.devices.interface import Device
|
||||||
from libprs500.devices.libusb import Error as USBError
|
from libprs500.devices.libusb import Error as USBError
|
||||||
@ -58,7 +58,7 @@ from libprs500.devices.libusb import get_device_by_id
|
|||||||
from libprs500.devices.prs500.prstypes import *
|
from libprs500.devices.prs500.prstypes import *
|
||||||
from libprs500.devices.errors import *
|
from libprs500.devices.errors import *
|
||||||
from libprs500.devices.prs500.books import BookList, fix_ids
|
from libprs500.devices.prs500.books import BookList, fix_ids
|
||||||
from libprs500 import __author__, __appname__
|
from libprs500 import __author__
|
||||||
|
|
||||||
# Protocol versions libprs500 has been tested with
|
# Protocol versions libprs500 has been tested with
|
||||||
KNOWN_USB_PROTOCOL_VERSIONS = [0x3030303030303130L]
|
KNOWN_USB_PROTOCOL_VERSIONS = [0x3030303030303130L]
|
||||||
@ -459,6 +459,7 @@ class PRS500(Device):
|
|||||||
"""
|
"""
|
||||||
if path.endswith("/"):
|
if path.endswith("/"):
|
||||||
path = path[:-1] # We only copy files
|
path = path[:-1] # We only copy files
|
||||||
|
path = path.replace('card:/', self.card_prefix(False))
|
||||||
_file = self.path_properties(path, end_session=False)
|
_file = self.path_properties(path, end_session=False)
|
||||||
if _file.is_dir:
|
if _file.is_dir:
|
||||||
raise PathError("Cannot read as " + path + " is a directory")
|
raise PathError("Cannot read as " + path + " is a directory")
|
||||||
@ -520,6 +521,7 @@ class PRS500(Device):
|
|||||||
""" Do a non recursive listsing of path """
|
""" Do a non recursive listsing of path """
|
||||||
if not path.endswith("/"):
|
if not path.endswith("/"):
|
||||||
path += "/" # Initially assume path is a directory
|
path += "/" # Initially assume path is a directory
|
||||||
|
path = path.replace('card:/', self.card_prefix(False))
|
||||||
files = []
|
files = []
|
||||||
candidate = self.path_properties(path, end_session=False)
|
candidate = self.path_properties(path, end_session=False)
|
||||||
if not candidate.is_dir:
|
if not candidate.is_dir:
|
||||||
@ -643,6 +645,7 @@ class PRS500(Device):
|
|||||||
@todo: Update file modification time if it exists.
|
@todo: Update file modification time if it exists.
|
||||||
Opening the file in write mode and then closing it doesn't work.
|
Opening the file in write mode and then closing it doesn't work.
|
||||||
"""
|
"""
|
||||||
|
path = path.replace('card:/', self.card_prefix(False))
|
||||||
if path.endswith("/") and len(path) > 1:
|
if path.endswith("/") and len(path) > 1:
|
||||||
path = path[:-1]
|
path = path[:-1]
|
||||||
exists, _file = self._exists(path)
|
exists, _file = self._exists(path)
|
||||||
@ -669,6 +672,7 @@ class PRS500(Device):
|
|||||||
bytes = infile.tell() - pos
|
bytes = infile.tell() - pos
|
||||||
start_pos = pos
|
start_pos = pos
|
||||||
infile.seek(pos)
|
infile.seek(pos)
|
||||||
|
path = path.replace('card:/', self.card_prefix(False))
|
||||||
exists, dest = self._exists(path)
|
exists, dest = self._exists(path)
|
||||||
if exists:
|
if exists:
|
||||||
if dest.is_dir:
|
if dest.is_dir:
|
||||||
@ -737,6 +741,8 @@ class PRS500(Device):
|
|||||||
@safe
|
@safe
|
||||||
def mkdir(self, path, end_session=True):
|
def mkdir(self, path, end_session=True):
|
||||||
""" Make directory """
|
""" Make directory """
|
||||||
|
if path.startswith('card:/'):
|
||||||
|
path = path.replace('card:/', self.card_prefix(False))
|
||||||
if not path.endswith("/"):
|
if not path.endswith("/"):
|
||||||
path += "/"
|
path += "/"
|
||||||
error_prefix = "Cannot create directory " + path
|
error_prefix = "Cannot create directory " + path
|
||||||
@ -754,6 +760,7 @@ class PRS500(Device):
|
|||||||
@safe
|
@safe
|
||||||
def rm(self, path, end_session=True):
|
def rm(self, path, end_session=True):
|
||||||
""" Delete path from device if it is a file or an empty directory """
|
""" Delete path from device if it is a file or an empty directory """
|
||||||
|
path = path.replace('card:/', self.card_prefix(False))
|
||||||
dir = self.path_properties(path, end_session=False)
|
dir = self.path_properties(path, end_session=False)
|
||||||
if not dir.is_dir:
|
if not dir.is_dir:
|
||||||
self.del_file(path, end_session=False)
|
self.del_file(path, end_session=False)
|
||||||
@ -945,4 +952,3 @@ class PRS500(Device):
|
|||||||
f.seek(0)
|
f.seek(0)
|
||||||
self.put_file(f, path, replace_file=True, end_session=False)
|
self.put_file(f, path, replace_file=True, end_session=False)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
14
src/libprs500/devices/prs505/__init__.py
Normal file
14
src/libprs500/devices/prs505/__init__.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
## Copyright (C) 2007 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License along
|
||||||
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
195
src/libprs500/devices/prs505/driver.py
Normal file
195
src/libprs500/devices/prs505/driver.py
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
## Copyright (C) 2007 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License along
|
||||||
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
from libprs500.devices.prs500.books import BookList
|
||||||
|
import shutil
|
||||||
|
''''''
|
||||||
|
|
||||||
|
from libprs500.devices.interface import Device
|
||||||
|
from libprs500.devices.errors import DeviceError
|
||||||
|
|
||||||
|
from libprs500 import islinux, iswindows
|
||||||
|
|
||||||
|
import sys, os
|
||||||
|
|
||||||
|
class File(object):
|
||||||
|
def __init__(self, path):
|
||||||
|
stats = os.stat(path)
|
||||||
|
self.is_dir = os.path.isdir(path)
|
||||||
|
self.is_readonly = not os.access(path, os.W_OK)
|
||||||
|
self.ctime = stats.st_ctime
|
||||||
|
self.wtime = stats.st_mtime
|
||||||
|
self.size = stats.st_size
|
||||||
|
if path.endswith(os.sep):
|
||||||
|
path = path[:-1]
|
||||||
|
self.path = path
|
||||||
|
self.name = os.path.basename(path)
|
||||||
|
|
||||||
|
|
||||||
|
class PRS505(Device):
|
||||||
|
VENDOR_ID = 0x054c #: SONY Vendor Id
|
||||||
|
PRODUCT_ID = 0x031e #: Product Id for the PRS-505
|
||||||
|
PRODUCT_NAME = 'Sony Portable Reader System'
|
||||||
|
|
||||||
|
MEDIA_XML = 'database/cache/media.xml'
|
||||||
|
CACHE_XML = 'Sony Reader/database/cache.xml'
|
||||||
|
|
||||||
|
LINUX_DEVICE_NODE = 'sony_prs_505'
|
||||||
|
LINUX_DEVICE_PATH = os.path.join('/dev', LINUX_DEVICE_NODE)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._main_prefix = self._card_prefix = None
|
||||||
|
self.hm = None
|
||||||
|
if islinux:
|
||||||
|
import dbus
|
||||||
|
self.bus = dbus.SystemBus()
|
||||||
|
self.hm = dbus.Interface(self.bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager"), "org.freedesktop.Hal.Manager")
|
||||||
|
|
||||||
|
def is_connected(self):
|
||||||
|
if self.hm is not None: # linux
|
||||||
|
devs = self.hm.FindDeviceStringMatch('info.product', 'Sony Portable Reader System')
|
||||||
|
for dev in devs:
|
||||||
|
obj = self.bus.get_object("org.freedesktop.Hal", dev)
|
||||||
|
if obj.GetPropertyInteger('usb_device.product_id', dbus_interface='org.freedesktop.Hal.Device') == self.__class__.PRODUCT_ID:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def open_linux(self):
|
||||||
|
try:
|
||||||
|
mm = self.hm.FindDeviceStringMatch('volume.label', 'Sony Reader Main Memory')[0]
|
||||||
|
except:
|
||||||
|
raise DeviceError('Unable to find %s. Is it connected?'%(self.__class__.__name__,))
|
||||||
|
try:
|
||||||
|
sc = self.hm.FindDeviceStringMatch('volume.label', 'Sony Reader Storage Card')[0]
|
||||||
|
except:
|
||||||
|
sc = None
|
||||||
|
|
||||||
|
def conditional_mount(dev):
|
||||||
|
mmo = self.bus.get_object("org.freedesktop.Hal", dev)
|
||||||
|
label = mmo.GetPropertyString('volume.label', dbus_interface='org.freedesktop.Hal.Device')
|
||||||
|
is_mounted = mmo.GetPropertyString('volume.is_mounted', dbus_interface='org.freedesktop.Hal.Device')
|
||||||
|
mount_point = mmo.GetPropertyString('volume.mount_point', dbus_interface='org.freedesktop.Hal.Device')
|
||||||
|
fstype = mmo.GetPropertyString('volume.fstype', dbus_interface='org.freedesktop.Hal.Device')
|
||||||
|
if is_mounted:
|
||||||
|
return str(mount_point)
|
||||||
|
mmo.Mount(label, fstype, ['umask=077', 'uid='+str(os.getuid())],# 'gid='+str(os.getgid())],
|
||||||
|
dbus_interface='org.freedesktop.Hal.Device.Volume')
|
||||||
|
return label+os.sep
|
||||||
|
|
||||||
|
self._main_prefix = conditional_mount(mm)+os.sep
|
||||||
|
self._card_prefix = None
|
||||||
|
if sc is not None:
|
||||||
|
self._card_prefix = conditional_mount(sc)+os.sep
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
if self.hm is not None: # linux
|
||||||
|
self.open_linux()
|
||||||
|
|
||||||
|
def set_progress_reporter(self, pr):
|
||||||
|
self.report_progress = pr
|
||||||
|
|
||||||
|
def get_device_information(self, end_session=True):
|
||||||
|
return ('PRS-505', '', '', '')
|
||||||
|
|
||||||
|
def card_prefix(self, end_session=True):
|
||||||
|
return self._card_prefix
|
||||||
|
|
||||||
|
def total_space(self, end_session=True):
|
||||||
|
if not iswindows:
|
||||||
|
msz = 0
|
||||||
|
if self._main_prefix is not None:
|
||||||
|
stats = os.statvfs(self._main_prefix)
|
||||||
|
msz = stats.f_frsize * (stats.f_blocks + stats.f_bavail - stats.f_bfree)
|
||||||
|
csz = 0
|
||||||
|
if self._card_prefix is not None:
|
||||||
|
stats = os.statvfs(self._card_prefix)
|
||||||
|
csz = stats.f_frsize * (stats.f_blocks + stats.f_bavail - stats.f_bfree)
|
||||||
|
|
||||||
|
return (msz, 0, csz)
|
||||||
|
|
||||||
|
def free_space(self, end_session=True):
|
||||||
|
if not iswindows:
|
||||||
|
msz = 0
|
||||||
|
if self._main_prefix is not None:
|
||||||
|
stats = os.statvfs(self._main_prefix)
|
||||||
|
msz = stats.f_bsize * stats.f_bavail
|
||||||
|
csz = 0
|
||||||
|
if self._card_prefix is not None:
|
||||||
|
stats = os.statvfs(self._card_prefix)
|
||||||
|
csz = stats.f_bsize * stats.f_bavail
|
||||||
|
|
||||||
|
return (msz, 0, csz)
|
||||||
|
|
||||||
|
def books(self, oncard=False, end_session=True):
|
||||||
|
db = self.__class__.CACHE_XML if oncard else self.__class__.MEDIA_XML
|
||||||
|
prefix = self._card_prefix if oncard else self._main_prefix
|
||||||
|
f = open(prefix + db, 'rb')
|
||||||
|
bl = BookList(root='', sfile=f)
|
||||||
|
paths = bl.purge_corrupted_files()
|
||||||
|
for path in paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
os.unlink(path)
|
||||||
|
return bl
|
||||||
|
|
||||||
|
def munge_path(self, path):
|
||||||
|
if path.startswith('/') and not path.startswith(self._main_prefix):
|
||||||
|
path = self._main_prefix + path[1:]
|
||||||
|
elif path.startswith('card:/'):
|
||||||
|
path = path.replace('card:/', self._card_prefix)
|
||||||
|
return path
|
||||||
|
|
||||||
|
def mkdir(self, path, end_session=True):
|
||||||
|
""" Make directory """
|
||||||
|
path = self.munge_path(path)
|
||||||
|
os.mkdir(path)
|
||||||
|
|
||||||
|
def list(self, path, recurse=False, end_session=True):
|
||||||
|
path = self.munge_path(path)
|
||||||
|
if os.path.isfile(path):
|
||||||
|
return [(os.path.dirname(path), [File(path)])]
|
||||||
|
entries = [File(os.path.join(path, f)) for f in os.listdir(path)]
|
||||||
|
dirs = [(path, entries)]
|
||||||
|
for _file in entries:
|
||||||
|
if recurse and _file.is_dir:
|
||||||
|
dirs[len(dirs):] = self.list(_file.path, recurse=True, end_session=False)
|
||||||
|
return dirs
|
||||||
|
|
||||||
|
def get_file(self, path, outfile, end_session=True):
|
||||||
|
path = self.munge_path(path)
|
||||||
|
src = open(path, 'rb')
|
||||||
|
shutil.copyfileobj(src, outfile, 10*1024*1024)
|
||||||
|
|
||||||
|
def put_file(self, infile, path, end_session=True):
|
||||||
|
path = self.munge_path(path)
|
||||||
|
if os.path.isdir(path):
|
||||||
|
path = os.path.join(path, infile.name)
|
||||||
|
dest = open(path, 'wb')
|
||||||
|
shutil.copyfileobj(infile, dest, 10*1024*1024)
|
||||||
|
|
||||||
|
def rm(self, path, end_session=True):
|
||||||
|
path = self.munge_path(path)
|
||||||
|
os.unlink(path)
|
||||||
|
|
||||||
|
def touch(self, path, end_session=True):
|
||||||
|
path = self.munge_path(path)
|
||||||
|
if not os.path.exists(path):
|
||||||
|
open(path, 'w').close()
|
||||||
|
if not os.path.isdir(path):
|
||||||
|
os.utime(path, None)
|
||||||
|
|
||||||
|
def main(args=sys.argv):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
@ -14,7 +14,7 @@
|
|||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
|
||||||
import shutil
|
import shutil
|
||||||
''' Post installation script for linux '''
|
''' Post installation script for linux '''
|
||||||
import sys, os
|
import sys, os, stat
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
from libprs500 import __version__
|
from libprs500 import __version__
|
||||||
|
|
||||||
@ -178,14 +178,44 @@ def setup_udev_rules():
|
|||||||
groups = open('/etc/group', 'rb').read()
|
groups = open('/etc/group', 'rb').read()
|
||||||
group = 'plugdev' if 'plugdev' in groups else 'usb'
|
group = 'plugdev' if 'plugdev' in groups else 'usb'
|
||||||
udev = open('/etc/udev/rules.d/95-libprs500.rules', 'w')
|
udev = open('/etc/udev/rules.d/95-libprs500.rules', 'w')
|
||||||
udev.write(('''# Sony Reader PRS-500\n'''
|
udev.write('''# Sony Reader PRS-500\n'''
|
||||||
'''BUS=="usb", SYSFS{idProduct}=="029b", SYSFS{idVendor}=="054c", MODE="660", GROUP="%(group)s"\n'''
|
'''BUS=="usb", SYSFS{idProduct}=="029b", SYSFS{idVendor}=="054c", MODE="660", GROUP="%s"\n'''%(group,)
|
||||||
'''# Sony Reader PRS-505\n'''
|
|
||||||
'''BUS=="usb", SYSFS{idProduct}=="031e", SYSFS{idVendor}=="054c", MODE="660", GROUP="%(group)s"\n''')%dict(group=group,)
|
|
||||||
)
|
)
|
||||||
udev.close()
|
udev.close()
|
||||||
|
open('/usr/share/hal/fdi/policy/20thirdparty/10-libprs500.fdi', 'w').write(
|
||||||
|
'''\
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<deviceinfo version="0.2">
|
||||||
|
<device>
|
||||||
|
<match key="info.category" string="volume">
|
||||||
|
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.vendor_id" int="0x054c">
|
||||||
|
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.product_id" int="0x031e">
|
||||||
|
<match key="volume.is_partition" bool="false">
|
||||||
|
<merge key="volume.label" type="string">Sony Reader Main Memory</merge>
|
||||||
|
</match>
|
||||||
|
</match>
|
||||||
|
</match>
|
||||||
|
</match>
|
||||||
|
</device>
|
||||||
|
<device>
|
||||||
|
<match key="info.category" string="volume">
|
||||||
|
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.vendor_id" int="0x054c">
|
||||||
|
<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.product_id" int="0x031e">
|
||||||
|
<match key="volume.is_partition" bool="true">
|
||||||
|
<merge key="volume.label" type="string">Sony Reader Storage Card</merge>
|
||||||
|
</match>
|
||||||
|
</match>
|
||||||
|
</match>
|
||||||
|
</match>
|
||||||
|
</device>
|
||||||
|
|
||||||
|
</deviceinfo>
|
||||||
|
''')
|
||||||
|
check_call('/etc/init.d/hald restart', shell=True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
check_call('udevstart', shell=True)
|
check_call('udevcontrol reload_rules', shell=True)
|
||||||
except:
|
except:
|
||||||
try:
|
try:
|
||||||
check_call('/etc/init.d/udev reload', shell=True)
|
check_call('/etc/init.d/udev reload', shell=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user