diff --git a/osx_installer.py b/osx_installer.py
index 40d5fd91e6..62b6431cd3 100644
--- a/osx_installer.py
+++ b/osx_installer.py
@@ -103,7 +103,7 @@ _check_symlinks_prescript()
else:
debug = 0
return find_modules(
- scripts=scripts['console'] + scripts['gui'],
+ scripts=scripts['console'] + scripts['gui'][1:],
includes=list(self.includes) + main_modules['console'],
packages=self.packages,
excludes=self.excludes,
diff --git a/src/libprs500/devices/errors.py b/src/libprs500/devices/errors.py
index 5e61277f77..b81c8ab5e2 100644
--- a/src/libprs500/devices/errors.py
+++ b/src/libprs500/devices/errors.py
@@ -32,9 +32,10 @@ class TimeoutError(ProtocolError):
class DeviceError(ProtocolError):
""" Raised when device is not found """
- def __init__(self):
- ProtocolError.__init__(self, \
- "Unable to find SONY Reader. Is it connected?")
+ def __init__(self, msg=None):
+ if msg is None:
+ msg = "Unable to find SONY Reader. Is it connected?"
+ ProtocolError.__init__(self, msg)
class DeviceBusy(ProtocolError):
""" Raised when device is busy """
diff --git a/src/libprs500/devices/interface.py b/src/libprs500/devices/interface.py
index 923e864e47..bafac86357 100644
--- a/src/libprs500/devices/interface.py
+++ b/src/libprs500/devices/interface.py
@@ -46,8 +46,18 @@ class Device(object):
raise NotImplementedError()
@classmethod
- def is_connected(cls):
- '''Return True iff the device is physically connected to the computer'''
+ def get_fdi(cls):
+ '''Return the FDI description of this device for HAL on linux.'''
+ return ''
+
+ @classmethod
+ def is_connected(cls, helper=None):
+ '''
+ Return True iff the device is physically connected to the computer
+
+ @param helper: Platform dependent helper object. For e.g. on windows
+ an instantiated WMI interface.
+ '''
raise NotImplementedError()
def set_progress_reporter(self, report_progress):
diff --git a/src/libprs500/devices/prs505/driver.py b/src/libprs500/devices/prs505/driver.py
index d878244a7b..f7a2525649 100644
--- a/src/libprs500/devices/prs505/driver.py
+++ b/src/libprs500/devices/prs505/driver.py
@@ -18,11 +18,18 @@ import shutil
from libprs500.devices.interface import Device
from libprs500.devices.errors import DeviceError, FreeSpaceError
from libprs500.devices.prs500.books import BookList
+from libprs500 import iswindows, islinux, isosx
+if not iswindows:
+ from libprs500.devices.libusb import get_device_by_id
-from libprs500 import islinux, iswindows
import sys, os
+try:
+ import _winreg
+except ImportError:
+ pass
+
class File(object):
def __init__(self, path):
stats = os.stat(path)
@@ -40,43 +47,117 @@ class File(object):
class PRS505(Device):
VENDOR_ID = 0x054c #: SONY Vendor Id
PRODUCT_ID = 0x031e #: Product Id for the PRS-505
- PRODUCT_NAME = 'Sony Portable Reader System'
+ PRODUCT_NAME = 'PRS-505'
+ VENDOR_NAME = 'SONY'
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)
+ MAIN_MEMORY_VOLUME_LABEL = 'Sony Reader Main Memory'
+ STORAGE_CARD_VOLUME_LABEL = 'Sony Reader Storage Card'
+
+ FDI_TEMPLATE = \
+'''
+
+
+
+
+
+ %(main_memory)s
+ %(deviceclass)s
+
+
+
+
+
+
+
+
+
+
+ %(storage_card)s
+ %(deviceclass)s
+
+
+
+
+
+'''
+
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")
+
+ @classmethod
+ def get_fdi(cls):
+ return cls.FDI_TEMPLATE%dict(
+ deviceclass=cls.__name__,
+ vendor_id=hex(cls.VENDOR_ID),
+ product_id=hex(cls.PRODUCT_ID),
+ main_memory=cls.MAIN_MEMORY_VOLUME_LABEL,
+ storage_card=cls.STORAGE_CARD_VOLUME_LABEL,
+ )
- 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
+ @classmethod
+ def is_device(cls, device_id):
+ if 'VEN_'+cls.VENDOR_NAME in device_id.upper() and \
+ 'PROD_'+cls.PRODUCT_NAME in device_id.upper():
+ return True
+ vid, pid = hex(cls.VENDOR_ID)[2:], hex(cls.PRODUCT_ID)[2:]
+ if len(vid) < 4: vid = '0'+vid
+ if len(pid) < 4: pid = '0'+pid
+ if 'VID_'+vid in device_id.upper() and \
+ 'PID_'+pid in device_id.upper():
+ return True
return False
+ @classmethod
+ def is_connected(cls, helper=None):
+ if iswindows:
+ for c in helper.USBControllerDevice():
+ if cls.is_device(c.Dependent.DeviceID):
+ return True
+ return False
+ else:
+ return get_device_by_id(cls.VENDOR_ID, cls.PRODUCT_ID) != None
+
+
+ def open_windows(self):
+ import wmi
+ c = wmi.WMI()
+ for drive in c.Win32_DiskDrive():
+ if self.__class__.is_device(drive.PNPDeviceID):
+ if drive.Partitions == 0:
+ continue
+ try:
+ partition = drive.associators("Win32_DiskDriveToDiskPartition")[0]
+ except IndexError:
+ continue
+ logical_disk = partition.associators('Win32_LogicalDiskToPartition')[0]
+ prefix = logical_disk.DeviceID+os.sep
+ if drive.Index == 1:
+ self._main_prefix = prefix
+ else:
+ self._card_prefix = prefix
+ if self._main_prefix is None:
+ raise DeviceError('Unable to find %s. Is it connected?'%(self.__class__.__name__,))
+
+
def open_linux(self):
+ import dbus
+ bus = dbus.SystemBus()
+ hm = dbus.Interface(self.bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager"), "org.freedesktop.Hal.Manager")
try:
- mm = self.hm.FindDeviceStringMatch('volume.label', 'Sony Reader Main Memory')[0]
+ mm = hm.FindDeviceStringMatch('libprs500.mainvolume', self.__class__.__name__)[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]
+ sc = hm.FindDeviceStringMatch('libprs500.cardvolume', self.__class__.__name__)[0]
except:
sc = None
def conditional_mount(dev):
- mmo = self.bus.get_object("org.freedesktop.Hal", dev)
+ mmo = 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')
@@ -93,8 +174,10 @@ class PRS505(Device):
self._card_prefix = conditional_mount(sc)+os.sep
def open(self):
- if self.hm is not None: # linux
+ if islinux:
self.open_linux()
+ if iswindows:
+ self.open_windows()
def set_progress_reporter(self, pr):
self.report_progress = pr
@@ -105,29 +188,43 @@ class PRS505(Device):
def card_prefix(self, end_session=True):
return self._card_prefix
+ @classmethod
+ def _windows_space(cls, prefix):
+ if prefix is None:
+ return 0, 0
+ import win32file
+ sectors_per_cluster, bytes_per_sector, free_clusters, total_clusters = \
+ win32file.GetDiskFreeSpace(prefix[:-1])
+ mult = sectors_per_cluster * bytes_per_sector
+ return total_clusters * mult, free_clusters * mult
+
def total_space(self, end_session=True):
+ msz = csz = 0
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)
+ else:
+ msz = self._windows_space(self._main_prefix)[0]
+ csz = self._windows_space(self._card_prefix)[0]
return (msz, 0, csz)
def free_space(self, end_session=True):
+ msz = csz = 0
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
+ else:
+ msz = self._windows_space(self._main_prefix)[1]
+ csz = self._windows_space(self._card_prefix)[1]
return (msz, 0, csz)
diff --git a/src/libprs500/gui2/device.py b/src/libprs500/gui2/device.py
index 443623b3c2..bf5a19f975 100644
--- a/src/libprs500/gui2/device.py
+++ b/src/libprs500/gui2/device.py
@@ -12,6 +12,7 @@
## 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.Warning
+from libprs500 import iswindows
import sys, os
from PyQt4.QtCore import QThread, SIGNAL, QObject
@@ -42,10 +43,15 @@ class DeviceDetector(QThread):
QThread.__init__(self)
def run(self):
+ helper = None
+ if iswindows:
+ import wmi, pythoncom
+ pythoncom.CoInitialize()
+ helper = wmi.WMI()
while True:
for device in self.devices:
try:
- connected = device[0].is_connected()
+ connected = device[0].is_connected(helper=helper)
except:
connected = False
if connected and not device[1]:
diff --git a/src/libprs500/gui2/main.py b/src/libprs500/gui2/main.py
index f88cc133f4..874ad663ab 100644
--- a/src/libprs500/gui2/main.py
+++ b/src/libprs500/gui2/main.py
@@ -709,7 +709,7 @@ class Main(MainWindow, Ui_MainWindow):
-def main(args=sys.argv):
+def main(args=sys.argv):
from PyQt4.Qt import QApplication
pid = os.fork() if islinux else -1
if pid <= 0:
diff --git a/src/libprs500/linux.py b/src/libprs500/linux.py
index 697eaac585..1ea128aa0d 100644
--- a/src/libprs500/linux.py
+++ b/src/libprs500/linux.py
@@ -14,9 +14,15 @@
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.Warning
import shutil
''' Post installation script for linux '''
-import sys, os, stat
+import sys, os
+
from subprocess import check_call
-from libprs500 import __version__
+from libprs500 import __version__, __appname__
+
+from libprs500.devices.prs500.driver import PRS500
+from libprs500.devices.prs505.driver import PRS505
+
+DEVICES = (PRS500, PRS505)
def options(option_parser):
parser = option_parser()
@@ -182,36 +188,24 @@ def setup_udev_rules():
'''BUS=="usb", SYSFS{idProduct}=="029b", SYSFS{idVendor}=="054c", MODE="660", GROUP="%s"\n'''%(group,)
)
udev.close()
- open('/usr/share/hal/fdi/policy/20thirdparty/10-libprs500.fdi', 'w').write(
-'''\
-
-
-
+ fdi = open('/usr/share/hal/fdi/policy/20thirdparty/10-libprs500.fdi', 'w')
+ fdi.write('\n\n\n')
+ for cls in DEVICES:
+ fdi.write(\
+'''
-
-
-
-
- Sony Reader Main Memory
-
-
+
+
+ %(cls)s
+ %(prog)s
-
-
-
-
-
- Sony Reader Storage Card
-
-
-
-
-
-
-
-''')
+'''%dict(cls=cls.__name__, vendor_id=cls.VENDOR_ID, product_id=cls.PRODUCT_ID,
+ prog=__appname__))
+ fdi.write('\n'+cls.get_fdi())
+ fdi.write('\n\n')
+ fdi.close()
check_call('/etc/init.d/hald restart', shell=True)
try:
diff --git a/windows_installer.py b/windows_installer.py
index 06759f78c6..0f7216c8f7 100644
--- a/windows_installer.py
+++ b/windows_installer.py
@@ -446,11 +446,14 @@ setup(
options = { 'py2exe' : {'compressed': 1,
'optimize' : 2,
'dist_dir' : PY2EXE_DIR,
- 'includes' : ['sip', 'pkg_resources', 'PyQt4.QtSvg', 'mechanize', 'ClientForm'],
+ 'includes' : ['sip', 'pkg_resources', 'PyQt4.QtSvg',
+ 'mechanize', 'ClientForm', 'wmi',
+ 'win32file', 'pythoncom'],
'packages' : ['PIL'],
'excludes' : ["Tkconstants", "Tkinter", "tcl",
"_imagingtk", "ImageTk", "FixTk",
'pydoc'],
+ 'dll_excludes' : ['mswsock.dll'],
},
},