import os import zipfile import sublime from .console_write import console_write from .open_compat import open_compat, read_compat from .unicode import unicode_from_os from .file_not_found_error import FileNotFoundError def read_package_file(package, relative_path, binary=False, debug=False): package_dir = _get_package_dir(package) file_path = os.path.join(package_dir, relative_path) if os.path.exists(package_dir): result = _read_regular_file(package, relative_path, binary, debug) if result != False: return result if int(sublime.version()) >= 3000: result = _read_zip_file(package, relative_path, binary, debug) if result != False: return result if debug: console_write(u"Unable to find file %s in the package %s" % (relative_path, package), True) return False def package_file_exists(package, relative_path): package_dir = _get_package_dir(package) file_path = os.path.join(package_dir, relative_path) if os.path.exists(package_dir): result = _regular_file_exists(package, relative_path) if result: return result if int(sublime.version()) >= 3000: return _zip_file_exists(package, relative_path) return False def _get_package_dir(package): """:return: The full filesystem path to the package directory""" return os.path.join(sublime.packages_path(), package) def _read_regular_file(package, relative_path, binary=False, debug=False): package_dir = _get_package_dir(package) file_path = os.path.join(package_dir, relative_path) try: with open_compat(file_path, ('rb' if binary else 'r')) as f: return read_compat(f) except (FileNotFoundError) as e: if debug: console_write(u"Unable to find file %s in the package folder for %s" % (relative_path, package), True) return False def _read_zip_file(package, relative_path, binary=False, debug=False): zip_path = os.path.join(sublime.installed_packages_path(), package + '.sublime-package') if not os.path.exists(zip_path): if debug: console_write(u"Unable to find a sublime-package file for %s" % package, True) return False try: package_zip = zipfile.ZipFile(zip_path, 'r') except (zipfile.BadZipfile): console_write(u'An error occurred while trying to unzip the sublime-package file for %s.' % package, True) return False try: contents = package_zip.read(relative_path) if not binary: contents = contents.decode('utf-8') return contents except (KeyError) as e: if debug: console_write(u"Unable to find file %s in the sublime-package file for %s" % (relative_path, package), True) except (IOError) as e: message = unicode_from_os(e) console_write(u'Unable to read file from sublime-package file for %s due to an invalid filename' % package, True) except (UnicodeDecodeError): console_write(u'Unable to read file from sublime-package file for %s due to an invalid filename or character encoding issue' % package, True) return False def _regular_file_exists(package, relative_path): package_dir = _get_package_dir(package) file_path = os.path.join(package_dir, relative_path) return os.path.exists(file_path) def _zip_file_exists(package, relative_path): zip_path = os.path.join(sublime.installed_packages_path(), package + '.sublime-package') if not os.path.exists(zip_path): return False try: package_zip = zipfile.ZipFile(zip_path, 'r') except (zipfile.BadZipfile): console_write(u'An error occurred while trying to unzip the sublime-package file for %s.' % package_name, True) return False try: package_zip.getinfo(relative_path) return True except (KeyError) as e: return False