mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-11-03 19:17:02 -05:00 
			
		
		
		
	Fix 4311
This commit is contained in:
		
							parent
							
								
									57d0a310b2
								
							
						
					
					
						commit
						0b3cf0b19f
					
				@ -24,6 +24,7 @@ isosx     = 'darwin' in sys.platform.lower()
 | 
				
			|||||||
isnewosx = isosx and getattr(sys, 'new_app_bundle', False)
 | 
					isnewosx = isosx and getattr(sys, 'new_app_bundle', False)
 | 
				
			||||||
islinux   = not(iswindows or isosx)
 | 
					islinux   = not(iswindows or isosx)
 | 
				
			||||||
isfrozen  = hasattr(sys, 'frozen')
 | 
					isfrozen  = hasattr(sys, 'frozen')
 | 
				
			||||||
 | 
					isunix = isosx or islinux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    preferred_encoding = locale.getpreferredencoding()
 | 
					    preferred_encoding = locale.getpreferredencoding()
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ Device driver for Bookeen's Cybook Gen 3
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from calibre import islinux
 | 
					from calibre.constants import isunix
 | 
				
			||||||
from calibre.devices.usbms.driver import USBMS
 | 
					from calibre.devices.usbms.driver import USBMS
 | 
				
			||||||
import calibre.devices.cybookg3.t2b as t2b
 | 
					import calibre.devices.cybookg3.t2b as t2b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,7 +55,7 @@ class CYBOOKG3(USBMS):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def can_handle(cls, device_info, debug=False):
 | 
					    def can_handle(cls, device_info, debug=False):
 | 
				
			||||||
        if islinux:
 | 
					        if isunix:
 | 
				
			||||||
            return device_info[3] == 'Bookeen' and device_info[4] == 'Cybook Gen3'
 | 
					            return device_info[3] == 'Bookeen' and device_info[4] == 'Cybook Gen3'
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -87,6 +87,6 @@ class CYBOOK_OPUS(CYBOOKG3):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def can_handle(cls, device_info, debug=False):
 | 
					    def can_handle(cls, device_info, debug=False):
 | 
				
			||||||
        if islinux:
 | 
					        if isunix:
 | 
				
			||||||
            return device_info[3] == 'Bookeen'
 | 
					            return device_info[3] == 'Bookeen'
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
				
			|||||||
@ -104,12 +104,12 @@ class DevicePlugin(Plugin):
 | 
				
			|||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def is_usb_connected(cls, devices_on_system, debug=False):
 | 
					    def is_usb_connected(cls, devices_on_system, debug=False):
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        Return True if a device handled by this plugin is currently connected.
 | 
					        Return True, device_info if a device handled by this plugin is currently connected.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param devices_on_system: List of devices currently connected
 | 
					        :param devices_on_system: List of devices currently connected
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        if iswindows:
 | 
					        if iswindows:
 | 
				
			||||||
            return cls.is_usb_connected_windows(devices_on_system, debug=debug)
 | 
					            return cls.is_usb_connected_windows(devices_on_system, debug=debug), None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        vendors_on_system = set([x[0] for x in devices_on_system])
 | 
					        vendors_on_system = set([x[0] for x in devices_on_system])
 | 
				
			||||||
        vendors = cls.VENDOR_ID if hasattr(cls.VENDOR_ID, '__len__') else [cls.VENDOR_ID]
 | 
					        vendors = cls.VENDOR_ID if hasattr(cls.VENDOR_ID, '__len__') else [cls.VENDOR_ID]
 | 
				
			||||||
@ -134,18 +134,20 @@ class DevicePlugin(Plugin):
 | 
				
			|||||||
                                if debug:
 | 
					                                if debug:
 | 
				
			||||||
                                    cls.print_usb_device_info(dev)
 | 
					                                    cls.print_usb_device_info(dev)
 | 
				
			||||||
                                if cls.can_handle(dev, debug=debug):
 | 
					                                if cls.can_handle(dev, debug=debug):
 | 
				
			||||||
                                    return True
 | 
					                                    return True, dev
 | 
				
			||||||
        return False
 | 
					        return False, None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset(self, key='-1', log_packets=False, report_progress=None) :
 | 
					    def reset(self, key='-1', log_packets=False, report_progress=None,
 | 
				
			||||||
 | 
					            detected_device=None) :
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        @param key: The key to unlock the device
 | 
					        :key: The key to unlock the device
 | 
				
			||||||
        @param log_packets: If true the packet stream to/from the device is logged
 | 
					        :log_packets: If true the packet stream to/from the device is logged
 | 
				
			||||||
        @param report_progress: Function that is called with a % progress
 | 
					        :report_progress: Function that is called with a % progress
 | 
				
			||||||
                                (number between 0 and 100) for various tasks
 | 
					                                (number between 0 and 100) for various tasks
 | 
				
			||||||
                                If it is called with -1 that means that the
 | 
					                                If it is called with -1 that means that the
 | 
				
			||||||
                                task does not have any progress information
 | 
					                                task does not have any progress information
 | 
				
			||||||
 | 
					        :detected_device: Device information from the device scanner
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        raise NotImplementedError()
 | 
					        raise NotImplementedError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -206,9 +206,10 @@ def main():
 | 
				
			|||||||
    scanner.scan()
 | 
					    scanner.scan()
 | 
				
			||||||
    connected_devices = []
 | 
					    connected_devices = []
 | 
				
			||||||
    for d in device_plugins():
 | 
					    for d in device_plugins():
 | 
				
			||||||
        if scanner.is_device_connected(d):
 | 
					        ok, det = scanner.is_device_connected(d)
 | 
				
			||||||
 | 
					        if ok:
 | 
				
			||||||
            dev = d
 | 
					            dev = d
 | 
				
			||||||
            dev.reset(log_packets=options.log_packets)
 | 
					            dev.reset(log_packets=options.log_packets, detected_device=det)
 | 
				
			||||||
            connected_devices.append(dev)
 | 
					            connected_devices.append(dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if dev is None:
 | 
					    if dev is None:
 | 
				
			||||||
 | 
				
			|||||||
@ -194,7 +194,8 @@ class PRS500(DeviceConfig, DevicePlugin):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return run_session
 | 
					        return run_session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset(self, key='-1', log_packets=False, report_progress=None) :
 | 
					    def reset(self, key='-1', log_packets=False, report_progress=None,
 | 
				
			||||||
 | 
					            detected_device=None) :
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        @param key: The key to unlock the device
 | 
					        @param key: The key to unlock the device
 | 
				
			||||||
        @param log_packets: If true the packet stream to/from the device is logged
 | 
					        @param log_packets: If true the packet stream to/from the device is logged
 | 
				
			||||||
 | 
				
			|||||||
@ -22,9 +22,32 @@ from itertools import repeat
 | 
				
			|||||||
from calibre.devices.interface import DevicePlugin
 | 
					from calibre.devices.interface import DevicePlugin
 | 
				
			||||||
from calibre.devices.errors import DeviceError, FreeSpaceError
 | 
					from calibre.devices.errors import DeviceError, FreeSpaceError
 | 
				
			||||||
from calibre.devices.usbms.deviceconfig import DeviceConfig
 | 
					from calibre.devices.usbms.deviceconfig import DeviceConfig
 | 
				
			||||||
from calibre import iswindows, islinux, isosx, __appname__
 | 
					from calibre.constants import iswindows, islinux, isosx, __appname__, plugins
 | 
				
			||||||
from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to
 | 
					from calibre.utils.filenames import ascii_filename as sanitize, shorten_components_to
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if isosx:
 | 
				
			||||||
 | 
					    usbobserver, usbobserver_err = plugins['usbobserver']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class USBDevice:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, dev):
 | 
				
			||||||
 | 
					        self.idVendor = dev[0]
 | 
				
			||||||
 | 
					        self.idProduct = dev[1]
 | 
				
			||||||
 | 
					        self.bcdDevice = dev[2]
 | 
				
			||||||
 | 
					        self.manufacturer = dev[3]
 | 
				
			||||||
 | 
					        self.product = dev[4]
 | 
				
			||||||
 | 
					        self.serial = dev[5]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def match_serial(self, serial):
 | 
				
			||||||
 | 
					        return self.serial and self.serial == serial
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def match_numbers(self, vid, pid, bcd):
 | 
				
			||||||
 | 
					        return self.idVendor == vid and self.idProduct == pid and self.bcdDevice == bcd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def match_strings(self, vid, pid, bcd, man, prod):
 | 
				
			||||||
 | 
					        return self.match_numbers(vid, pid, bcd) and \
 | 
				
			||||||
 | 
					                self.manufacturer == man and self.product == prod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Device(DeviceConfig, DevicePlugin):
 | 
					class Device(DeviceConfig, DevicePlugin):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
@ -108,8 +131,10 @@ class Device(DeviceConfig, DevicePlugin):
 | 
				
			|||||||
    FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
 | 
					    FDI_LUNS = {'lun0':0, 'lun1':1, 'lun2':2}
 | 
				
			||||||
    FDI_BCD_TEMPLATE = '<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">'
 | 
					    FDI_BCD_TEMPLATE = '<match key="@info.parent:@info.parent:@info.parent:@info.parent:usb.device_revision_bcd" int="%(bcd)s">'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset(self, key='-1', log_packets=False, report_progress=None) :
 | 
					    def reset(self, key='-1', log_packets=False, report_progress=None,
 | 
				
			||||||
 | 
					            detected_device=None):
 | 
				
			||||||
        self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
 | 
					        self._main_prefix = self._card_a_prefix = self._card_b_prefix = None
 | 
				
			||||||
 | 
					        self.detected_device = USBDevice(detected_device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_gui_name(cls):
 | 
					    def get_gui_name(cls):
 | 
				
			||||||
@ -391,29 +416,80 @@ class Device(DeviceConfig, DevicePlugin):
 | 
				
			|||||||
                    raise
 | 
					                    raise
 | 
				
			||||||
            time.sleep(2)
 | 
					            time.sleep(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def open_osx(self):
 | 
					    def _osx_bsd_names(self):
 | 
				
			||||||
        mount = self.osx_run_mount()
 | 
					        if usbobserver_err:
 | 
				
			||||||
        names = self.get_osx_mountpoints()
 | 
					            raise RuntimeError('Failed to load usbobserver: '+usbobserver_err)
 | 
				
			||||||
        dev_pat = r'/dev/%s(\w*)\s+on\s+([^\(]+)\s+'
 | 
					        drives = usbobserver.get_usb_drives()
 | 
				
			||||||
        if 'main' not in names.keys():
 | 
					        matches = []
 | 
				
			||||||
            raise DeviceError(_('Unable to detect the %s disk drive. Try rebooting.')%self.__class__.__name__)
 | 
					        d = self.detected_device
 | 
				
			||||||
        main_pat = dev_pat % names['main']
 | 
					        if d.serial:
 | 
				
			||||||
        main_match = re.search(main_pat, mount)
 | 
					            for path, vid, pid, bcd, ven, prod, serial in drives:
 | 
				
			||||||
        if main_match is None:
 | 
					                if d.match_serial(serial):
 | 
				
			||||||
            raise DeviceError(_('Unable to detect the %s mount point. Try rebooting.')%self.__class__.__name__)
 | 
					                    matches.append(path)
 | 
				
			||||||
        self._main_prefix = main_match.group(2) + os.sep
 | 
					        if not matches:
 | 
				
			||||||
        card_a_pat = names['carda'] if 'carda' in names.keys() else None
 | 
					            if d.manufacturer and d.product:
 | 
				
			||||||
        card_b_pat = names['cardb'] if 'cardb' in names.keys() else None
 | 
					                for path, vid, pid, bcd, man, prod, serial in drives:
 | 
				
			||||||
 | 
					                    if d.match_strings(vid, pid, bcd, man, prod):
 | 
				
			||||||
        def get_card_prefix(pat):
 | 
					                        matches.append(path)
 | 
				
			||||||
            if pat is not None:
 | 
					 | 
				
			||||||
                pat = dev_pat % pat
 | 
					 | 
				
			||||||
                return re.search(pat, mount).group(2) + os.sep
 | 
					 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                return None
 | 
					                for path, vid, pid, bcd, man, prod, serial in drives:
 | 
				
			||||||
 | 
					                    if d.match_numbers(vid, pid, bcd):
 | 
				
			||||||
 | 
					                        matches.append(path)
 | 
				
			||||||
 | 
					        if not matches:
 | 
				
			||||||
 | 
					            raise DeviceError(
 | 
				
			||||||
 | 
					             'Could not detect BSD names for %s. Try rebooting.' % self.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._card_a_prefix = get_card_prefix(card_a_pat)
 | 
					        pat = re.compile(r'(?P<m>\d+)([a-z]+(?P<p>\d+)){0,1}')
 | 
				
			||||||
        self._card_b_prefix = get_card_prefix(card_b_pat)
 | 
					        def nums(x):
 | 
				
			||||||
 | 
					            m = pat.search(x)
 | 
				
			||||||
 | 
					            if m is None:
 | 
				
			||||||
 | 
					                return (10000, 0)
 | 
				
			||||||
 | 
					            g = m.groupdict()
 | 
				
			||||||
 | 
					            if g['p'] is None:
 | 
				
			||||||
 | 
					                g['p'] = 0
 | 
				
			||||||
 | 
					            return map(int, (g.get('m'), g.get('p')))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def dcmp(x, y):
 | 
				
			||||||
 | 
					            x = x.rpartition('/')[-1]
 | 
				
			||||||
 | 
					            y = y.rpartition('/')[-1]
 | 
				
			||||||
 | 
					            x, y = nums(x), nums(y)
 | 
				
			||||||
 | 
					            ans = cmp(x[0], y[0])
 | 
				
			||||||
 | 
					            if ans == 0:
 | 
				
			||||||
 | 
					                ans = cmp(x[1], y[1])
 | 
				
			||||||
 | 
					            return ans
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        matches.sort(cmp=dcmp)
 | 
				
			||||||
 | 
					        drives = {'main':matches[0]}
 | 
				
			||||||
 | 
					        if len(matches > 1):
 | 
				
			||||||
 | 
					            drives['carda'] = matches[1]
 | 
				
			||||||
 | 
					        if len(matches > 2):
 | 
				
			||||||
 | 
					            drives['cardb'] = matches[2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return drives
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def osx_bsd_names(self):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            return self._osx_bsd_names()
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            time.sleep(2)
 | 
				
			||||||
 | 
					        return self._osx_bsd_names()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def open_osx(self):
 | 
				
			||||||
 | 
					        drives = self.osx_bsd_names()
 | 
				
			||||||
 | 
					        drives = self.osx_sort_names(drives)
 | 
				
			||||||
 | 
					        mount_map = usbobserver.get_mounted_filesystems()
 | 
				
			||||||
 | 
					        for k, v in drives.items():
 | 
				
			||||||
 | 
					            drives[k] = mount_map.get(k, None)
 | 
				
			||||||
 | 
					        if drives['main'] is None:
 | 
				
			||||||
 | 
					            raise DeviceError(_('Unable to detect the %s mount point. Try rebooting.')%self.__class__.__name__)
 | 
				
			||||||
 | 
					        self._main_prefix = drives['main']+os.sep
 | 
				
			||||||
 | 
					        def get_card_prefix(c):
 | 
				
			||||||
 | 
					            ans = drives.get(c, None)
 | 
				
			||||||
 | 
					            if ans is not None:
 | 
				
			||||||
 | 
					                ans += os.sep
 | 
				
			||||||
 | 
					            return ans
 | 
				
			||||||
 | 
					        self._card_a_prefix = get_card_prefix('carda')
 | 
				
			||||||
 | 
					        self._card_b_prefix = get_card_prefix('cardb')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def find_device_nodes(self):
 | 
					    def find_device_nodes(self):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -33,10 +33,6 @@ class USBMS(CLI, Device):
 | 
				
			|||||||
    FORMATS = []
 | 
					    FORMATS = []
 | 
				
			||||||
    CAN_SET_METADATA = False
 | 
					    CAN_SET_METADATA = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def reset(self, key='-1', log_packets=False, report_progress=None):
 | 
					 | 
				
			||||||
        Device.reset(self, key=key, log_packets=log_packets,
 | 
					 | 
				
			||||||
                        report_progress=report_progress)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def get_device_information(self, end_session=True):
 | 
					    def get_device_information(self, end_session=True):
 | 
				
			||||||
        self.report_progress(1.0, _('Get device information...'))
 | 
					        self.report_progress(1.0, _('Get device information...'))
 | 
				
			||||||
        return (self.__class__.__name__, '', '', '')
 | 
					        return (self.__class__.__name__, '', '', '')
 | 
				
			||||||
 | 
				
			|||||||
@ -268,7 +268,7 @@ usbobserver_get_mounted_filesystems(PyObject *self, PyObject *args) {
 | 
				
			|||||||
    buf = (struct statfs*)calloc(num, sizeof(struct statfs));
 | 
					    buf = (struct statfs*)calloc(num, sizeof(struct statfs));
 | 
				
			||||||
    if (buf == NULL) return PyErr_NoMemory();
 | 
					    if (buf == NULL) return PyErr_NoMemory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    num = getfsstat(buf, num*sizeof(struct statfs), MNT_WAIT);
 | 
					    num = getfsstat(buf, num*sizeof(struct statfs), MNT_NOWAIT);
 | 
				
			||||||
    if (num == -1) {
 | 
					    if (num == -1) {
 | 
				
			||||||
        PyErr_SetString(PyExc_RuntimeError, "Call to getfsstat failed");
 | 
					        PyErr_SetString(PyExc_RuntimeError, "Call to getfsstat failed");
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
				
			|||||||
@ -94,8 +94,8 @@ class DeviceManager(Thread):
 | 
				
			|||||||
            import pythoncom
 | 
					            import pythoncom
 | 
				
			||||||
            pythoncom.CoInitialize()
 | 
					            pythoncom.CoInitialize()
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            for dev in connected_devices:
 | 
					            for dev, detected_device in connected_devices:
 | 
				
			||||||
                dev.reset()
 | 
					                dev.reset(detected_device=detected_device)
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    dev.open()
 | 
					                    dev.open()
 | 
				
			||||||
                except:
 | 
					                except:
 | 
				
			||||||
@ -116,10 +116,10 @@ class DeviceManager(Thread):
 | 
				
			|||||||
        self.scanner.scan()
 | 
					        self.scanner.scan()
 | 
				
			||||||
        connected_devices = []
 | 
					        connected_devices = []
 | 
				
			||||||
        for device in self.devices:
 | 
					        for device in self.devices:
 | 
				
			||||||
            connected = self.scanner.is_device_connected(device[0])
 | 
					            connected, detected_device = self.scanner.is_device_connected(device[0])
 | 
				
			||||||
            if connected and not device[1] and not device[2]:
 | 
					            if connected and not device[1] and not device[2]:
 | 
				
			||||||
                # If connected and not showing in GUI and not ejected
 | 
					                # If connected and not showing in GUI and not ejected
 | 
				
			||||||
                connected_devices.append(device[0])
 | 
					                connected_devices.append((device[0], detected_device))
 | 
				
			||||||
                device[1] = True
 | 
					                device[1] = True
 | 
				
			||||||
            elif not connected and device[1]:
 | 
					            elif not connected and device[1]:
 | 
				
			||||||
                # Disconnected but showing in GUI
 | 
					                # Disconnected but showing in GUI
 | 
				
			||||||
 | 
				
			|||||||
@ -190,10 +190,14 @@ class RecursiveFetcher(object):
 | 
				
			|||||||
            time.sleep(delta)
 | 
					            time.sleep(delta)
 | 
				
			||||||
        if isinstance(url, unicode):
 | 
					        if isinstance(url, unicode):
 | 
				
			||||||
            url = url.encode('utf-8')
 | 
					            url = url.encode('utf-8')
 | 
				
			||||||
        purl = list(urlparse.urlparse(url))
 | 
					        # Not sure is this is really needed as I think mechanize
 | 
				
			||||||
        for i in range(2, 6):
 | 
					        # handles quoting automatically, but leaving it in
 | 
				
			||||||
            purl[i] = quote(purl[i])
 | 
					        # in case it breaks something
 | 
				
			||||||
        url = urlparse.urlunparse(purl)
 | 
					        if re.search(r'\s+|,', url) is not None:
 | 
				
			||||||
 | 
					            purl = list(urlparse.urlparse(url))
 | 
				
			||||||
 | 
					            for i in range(2, 6):
 | 
				
			||||||
 | 
					                purl[i] = quote(purl[i])
 | 
				
			||||||
 | 
					            url = urlparse.urlunparse(purl)
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            open_func = getattr(self.browser, 'open_novisit', self.browser.open)
 | 
					            open_func = getattr(self.browser, 'open_novisit', self.browser.open)
 | 
				
			||||||
            with closing(open_func(url, timeout=self.timeout)) as f:
 | 
					            with closing(open_func(url, timeout=self.timeout)) as f:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user