Пример #1
0
def update_addons(quiet=True):
	from distutils.version import LooseVersion
	if not quiet: kodi.open_busy_dialog()
	sources = DB.query("SELECT addon_id, source FROM install_history")
	update_count = 0
	for source in sources:
		addon_id = source[0]
		source = json.loads(source[1])
		if kodi.get_condition_visiblity("System.HasAddon(%s)" % addon_id):
			if source['type'] == SOURCES.ZIP:
				url, filename, full_name, version = github.find_zip(source['user'], addon_id)
				current_version = kodi.get_addon(addon_id).getAddonInfo('version')
				if LooseVersion(version) > LooseVersion(current_version):
					GitHub_Installer(addon_id, url, full_name, kodi.vfs.join("special://home", "addons"), False, quiet)
					update_count += 1
			elif source['type'] == SOURCES.REPO:
				full_name = sources['user'] + '/' + sources['repo']
				xml_str = github.find_xml(full_name)
				xml = BeautifulSoup(xml_str)
				addon = xml.find('addon')
				current_version = kodi.get_addon(addon_id).getAddonInfo('version')
				if LooseVersion(addon['version']) > LooseVersion(current_version):
					GitHub_Installer(addon_id, source['url'], full_name, kodi.vfs.join("special://home", "addons"), True, quiet)
					update_count += 1

	if not quiet: kodi.close_busy_dialog()
	if update_count > 0: 
		kodi.notify("Update complete",'Some addons may require restarting kodi.')
	else:
		kodi.notify("Update complete",'No updates found.')
Пример #2
0
    def resolve_url(self, raw_url):
        resolved_url = ''
        host = self.get_domain_from_url(raw_url)
        if host not in self.get_domains(): return ''
        from commoncore.dispatcher import WeightedDispatcher
        dispatcher = WeightedDispatcher()

        @dispatcher.register(kodi.get_setting('premiumize_priority', ADDON_ID),
                             [raw_url])
        def pm_resolver(raw_url):
            if host not in self.premiumize_hosts: return ''
            try:
                response = premiumize.get_download(raw_url)
                return response['result']['location']
            except:
                return ''

        @dispatcher.register(kodi.get_setting('realdebrid_priority', ADDON_ID),
                             [raw_url])
        def rd_resolver(raw_url):
            if host not in self.realdebrid_hosts: return ''
            try:
                return realdebrid.resolve_url(raw_url)
            except:
                return ''

        kodi.open_busy_dialog()
        try:
            resolved_url = dispatcher.run()
        except:
            kodi.close_busy_dialog()
        kodi.close_busy_dialog()
        return resolved_url
Пример #3
0
def update_addons(quiet=True):
	from distutils.version import LooseVersion
	if not quiet: kodi.open_busy_dialog()
	sources = DB.query("SELECT addon_id, source FROM install_history")
	update_count = 0
	for source in sources:
		addon_id = source[0]
		source = json.loads(source[1])
		if kodi.get_condition_visiblity("System.HasAddon(%s)" % addon_id):
			if source['type'] == SOURCES.ZIP:
				url, filename, full_name, version = github.find_zip(source['user'], addon_id)
				current_version = kodi.get_addon(addon_id).getAddonInfo('version')
				if LooseVersion(version) > LooseVersion(current_version):
					GitHub_Installer(addon_id, url, full_name, kodi.vfs.join("special://home", "addons"), False, quiet)
					update_count += 1
			elif source['type'] == SOURCES.REPO:
				full_name = sources['user'] + '/' + sources['repo']
				xml_str = github.find_xml(full_name)
				xml = BeautifulSoup(xml_str)
				addon = xml.find('addon')
				current_version = kodi.get_addon(addon_id).getAddonInfo('version')
				if LooseVersion(addon['version']) > LooseVersion(current_version):
					GitHub_Installer(addon_id, source['url'], full_name, kodi.vfs.join("special://home", "addons"), True, quiet)
					update_count += 1

	if not quiet: kodi.close_busy_dialog()
	if update_count > 0:
		kodi.notify("Update complete",'Some addons may require restarting kodi.')
	else:
		kodi.notify("Update complete",'No updates found.')
Пример #4
0
def download(url, addon_id, destination, unzip=False, quiet=False):
	version = None
	filename = addon_id + '.zip'
	r = requests.get(url, stream=True)
	kodi.log("Download: %s" % url)
	
	
	
	if r.status_code == requests.codes.ok:
		temp_file = kodi.vfs.join(kodi.get_profile(), "downloads")
		if not kodi.vfs.exists(temp_file): kodi.vfs.mkdir(temp_file, recursive=True)
		temp_file = kodi.vfs.join(temp_file, filename)
		try:
			total_bytes = int(r.headers["Content-Length"])
		except:
			total_bytes = 0
		block_size = 1000
		cached_bytes = 0
		if not quiet:
			pb = xbmcgui.DialogProgress()
			pb.create("Downloading",filename,' ', ' ')
		kodi.sleep(150)
		start = time.time()
		with open(temp_file, 'wb') as f:
			for block in r.iter_content(chunk_size=block_size):
				if not block: break
				if not quiet and pb.iscanceled():
					raise downloaderException('Download Aborted')
					return False
				cached_bytes += len(block)
				f.write(block)
				if total_bytes > 0:
					delta = int(time.time() - start)
					if delta:
						bs = int(cached_bytes / (delta))
					else: bs = 0
					if not quiet:
						percent = int(cached_bytes * 100 / total_bytes)
						pb.update(percent, "Downloading",filename, format_status(cached_bytes, total_bytes, bs))
		
		if not quiet: pb.close()
		if unzip:
			zip_ref = zipfile.ZipFile(temp_file, 'r')
			zip_ref.extractall(destination)
			zip_ref.close()
			kodi.vfs.rm(temp_file, quiet=True)
			try:
				xml = kodi.vfs.read_file(kodi.vfs.join(destination, kodi.vfs.join(addon_id, 'addon.xml')), soup=True)
				version = get_version_by_xml(xml)
				if not version:
					version = get_version_by_name(filename)
			except:
				kodi.log("Unable to fine version from addon.xml for addon: %s" % addon_id)
		else:
			kodi.vfs.mv(temp_file, kodi.vfs.join(destination, filename))
	else:
		kodi.close_busy_dialog()
		raise downloaderException(r.status_code)
	return version
Пример #5
0
	def resolve_url(self, raw_url):
		resolved_url = ''
		kodi.open_busy_dialog()
		hash = self.get_hash_from_magnet(raw_url)
		if not hash: hash = self.get_hash_from_url(raw_url)
		if hash:
			kodi.set_property('Playback.Hash', hash)
		else: kodi.clear_property('Playback.Hash')
		attempt = 0
		attempts = 5
		try:
			response = premiumize.create_transfer(raw_url)
			id = response['id']	
		except:
			premiumize.clear_transfers()
			response = premiumize.create_transfer(raw_url)
			id = response['id']
		try:	
			while attempt < attempts:
				folder_id = False
				file_id = False
				target_folder_id = False
				kodi.log("Resolve Attempt %s" % attempt)
				temp = premiumize.list_transfers()

				for t in temp['transfers']:
					if t['id'] == id and t['status'] == 'finished':
						target_folder_id = t['target_folder_id']
						folder_id = t['folder_id']
						file_id = t['file_id']
						break
				if folder_id:
					response = premiumize.list_folder(folder_id)
					resolved_url = premiumize.get_folder_stream(response)
					break
				if target_folder_id:
					response = premiumize.list_folder(target_folder_id)
					resolved_url = premiumize.get_folder_stream(response)
					break

				attempt += 1
				kodi.sleep(150)
		except:
			kodi.close_busy_dialog()

		kodi.close_busy_dialog()
		return resolved_url
Пример #6
0
 def handel_error(self, error, response, request_args, request_kwargs):
     if response.status_code == 401:
         traceback.print_stack()
         kodi.close_busy_dialog()
         raise githubException("Unauthorized: %s" % error)
     elif response.status_code == 403 and 'X-RateLimit-Reset' in response.headers:
         import time
         retry = int(response.headers['X-RateLimit-Reset']) - int(
             time.time())
         for delay in range(retry, 0, -1):
             kodi.notify("API Rate limit exceeded",
                         "Retry in %s seconds(s)" % delay,
                         timeout=1000)
             kodi.sleep(1000)
         return self.request(*request_args, **request_kwargs)
     elif response.status_code == 422 and 'Only the first 1000' in response.text:
         kodi.handel_error('Result count exceeds API limit.',
                           'Try different search or result filter.')
         kodi.close_busy_dialog()
         traceback.print_stack()
     else:
         kodi.close_busy_dialog()
         traceback.print_stack()
         raise githubException("Status %s: %s" %
                               (response.status_code, response.text))
Пример #7
0
	def handel_error(self, error, response, request_args, request_kwargs):
		if response.status_code == 401:
			traceback.print_stack()
			kodi.close_busy_dialog()
			raise githubException("Unauthorized: %s" % error)
		elif response.status_code == 403 and 'X-RateLimit-Reset' in response.headers:
			import time
			retry = int(response.headers['X-RateLimit-Reset']) - int(time.time())
			for delay in range(retry, 0, -1):
				kodi.notify("API Rate limit exceeded", "Retry in %s seconds(s)" % delay, timeout=1000)
				kodi.sleep(1000)
			return self.request(*request_args, **request_kwargs)
		elif response.status_code == 422 and 'Only the first 1000' in response.text:
			kodi.handel_error('Result count exceeds API limit.', 'Try different search or result filter.')
			kodi.close_busy_dialog()
			traceback.print_stack()
		else:
			kodi.close_busy_dialog()
			traceback.print_stack()
			raise githubException("Status %s: %s" % (response.status_code, response.text))
Пример #8
0
    def resolve_url(self, raw_url):
        from commoncore.dispatcher import WeightedDispatcher
        resolved_url = ''
        hash = self.get_hash(raw_url)
        kodi.set_property('Playback.Hash', hash)

        dispatcher = WeightedDispatcher()

        @dispatcher.register(kodi.get_setting('premiumize_priority', ADDON_ID),
                             [raw_url])
        def premiumize_resolver(raw_url):
            resolved_url = ''
            if kodi.get_setting('premiumize_enable', ADDON_ID) != 'true':
                return resolved_url
            attempt = 0
            attempts = 5
            try:
                response = premiumize.create_transfer(raw_url)
                id = response['id']
            except:
                premiumize.clear_transfers()
                response = premiumize.create_transfer(raw_url)
                id = response['id']
            try:
                while attempt < attempts:
                    folder_id = False
                    file_id = False
                    target_folder_id = False
                    kodi.log("Resolve Attempt %s" % attempt)
                    temp = premiumize.list_transfers()
                    for t in temp['transfers']:
                        if t['id'] == id and t['status'] == 'finished':
                            if 'target_folder_id' in t:
                                target_folder_id = t['target_folder_id']
                            if 'folder_id' in t: folder_id = t['folder_id']
                            if 'file_id' in t: file_id = t['file_id']
                            break
                    if file_id:
                        response = premiumize.item_details(file_id)
                        resolved_url = response['stream_link']
                        kodi.set_property('Playback.Resolver', 'premiumize')
                        kodi.set_property('Playback.ID', file_id)
                        return resolved_url
                    if folder_id:
                        response = premiumize.list_folder(folder_id)
                        resolved_url = premiumize.get_folder_stream(response)
                        kodi.set_property('Playback.Resolver', 'premiumize')
                        kodi.set_property('Playback.ID', folder_id)
                        return resolved_url
                    if target_folder_id:
                        response = premiumize.list_folder(target_folder_id)
                        resolved_url = premiumize.get_folder_stream(response)
                        kodi.set_property('Playback.Resolver', 'premiumize')
                        kodi.set_property('Playback.ID', target_folder_id)
                        return resolved_url

                    attempt += 1
                    kodi.sleep(150)
            except:
                pass
            return resolved_url

        @dispatcher.register(kodi.get_setting('realdebrid_priority', ADDON_ID),
                             [raw_url])
        def realdebrid_resolver(raw_url):
            resolved_url = ''
            if kodi.get_setting('realdebrid_enable', ADDON_ID) != 'true':
                return resolved_url
            response = realdebrid.add_torrent(raw_url)
            try:
                torrent_id = response['id']
                info = realdebrid.get_torrent_info(torrent_id)
                file_id = realdebrid.get_stream_file(info['files'])
                if not file_id: return
                realdebrid.select_torrent_files(torrent_id, file_id)
                kodi.sleep(500)
                info = realdebrid.get_torrent_info(torrent_id)
                raw_url = info['links'][0]
                kodi.set_property('Playback.Resolver', 'realdebrid')
                kodi.set_property('Playback.ID', torrent_id)
                resolved_url = realdebrid.resolve_url(raw_url)
            except:
                pass
            return resolved_url

        kodi.open_busy_dialog()
        try:
            resolved_url = dispatcher.run()
        except Exception, e:
            kodi.log(e)
            kodi.close_busy_dialog()
Пример #9
0
class TorrentScraper(BaseScraper):
    valid = (kodi.get_setting('premiumize_enable', ADDON_ID) == 'true'
             and kodi.get_setting('premiumize_username', ADDON_ID) != ''
             ) or kodi.get_setting('realdebrid_enable', ADDON_ID) == 'true'
    torrent = True
    return_cached = True

    def __init__(self):
        self._make_media_object = self.make_media_object

        def make_media_object(obj):
            media = self._make_media_object(obj)
            media['torrent'] = True
            return media

        self.make_media_object = make_media_object

    def get_hash_from_magnet(self, magnet):
        match = re.search("btih:([^&]+)&", magnet, re.IGNORECASE)
        if match:
            return match.group(1)
        else:
            return False

    def get_hash_from_url(self, url):
        match = re.search('([a-fA-F0-9]{40})', url)
        if match:
            return match.group(1)
        else:
            return False

    def get_hash(self, source):
        if source[0:6] == 'magnet':
            return self.get_hash_from_magnet(source)
        else:
            return self.get_hash_from_url(source)

    def check_hashes(self, hashes):
        results = {'realdebrid': {}, "premiumize": {}}
        if kodi.get_setting('realdebrid_enable', ADDON_ID) == 'true':
            results['realdebrid'] = realdebrid.check_hashes(hashes)

        if kodi.get_setting('premiumize_enable', ADDON_ID) == 'true':
            results['premiumize'] = premiumize.check_hashes(hashes)
        return results

    def get_torrent_services(self):
        pass

    def verify_hash(self, hash):
        if kodi.get_setting('realdebrid_enable', ADDON_ID) == 'true':
            try:
                if self.verified_hashes['realdebrid'][hash]['rd'] != []:
                    return True
            except:
                pass
        if kodi.get_setting('premiumize_enable', ADDON_ID) == 'true':
            try:
                if self.verified_hashes['premiumize']['hashes'][hash][
                        'status'] == 'finished':
                    return True
            except:
                pass
        return False

    def verify_results(self, processor, results):
        hashes = [self.get_hash(r['raw_url']) for r in results]
        self.verified_hashes = self.check_hashes(hashes)
        for r in results:
            hash = self.get_hash(r['raw_url'])
            if self.verify_hash(hash):
                self.verify_result([r])
        return (self.name, self.verified_results)

    def resolve_url(self, raw_url):
        from commoncore.dispatcher import WeightedDispatcher
        resolved_url = ''
        hash = self.get_hash(raw_url)
        kodi.set_property('Playback.Hash', hash)

        dispatcher = WeightedDispatcher()

        @dispatcher.register(kodi.get_setting('premiumize_priority', ADDON_ID),
                             [raw_url])
        def premiumize_resolver(raw_url):
            resolved_url = ''
            if kodi.get_setting('premiumize_enable', ADDON_ID) != 'true':
                return resolved_url
            attempt = 0
            attempts = 5
            try:
                response = premiumize.create_transfer(raw_url)
                id = response['id']
            except:
                premiumize.clear_transfers()
                response = premiumize.create_transfer(raw_url)
                id = response['id']
            try:
                while attempt < attempts:
                    folder_id = False
                    file_id = False
                    target_folder_id = False
                    kodi.log("Resolve Attempt %s" % attempt)
                    temp = premiumize.list_transfers()
                    for t in temp['transfers']:
                        if t['id'] == id and t['status'] == 'finished':
                            if 'target_folder_id' in t:
                                target_folder_id = t['target_folder_id']
                            if 'folder_id' in t: folder_id = t['folder_id']
                            if 'file_id' in t: file_id = t['file_id']
                            break
                    if file_id:
                        response = premiumize.item_details(file_id)
                        resolved_url = response['stream_link']
                        kodi.set_property('Playback.Resolver', 'premiumize')
                        kodi.set_property('Playback.ID', file_id)
                        return resolved_url
                    if folder_id:
                        response = premiumize.list_folder(folder_id)
                        resolved_url = premiumize.get_folder_stream(response)
                        kodi.set_property('Playback.Resolver', 'premiumize')
                        kodi.set_property('Playback.ID', folder_id)
                        return resolved_url
                    if target_folder_id:
                        response = premiumize.list_folder(target_folder_id)
                        resolved_url = premiumize.get_folder_stream(response)
                        kodi.set_property('Playback.Resolver', 'premiumize')
                        kodi.set_property('Playback.ID', target_folder_id)
                        return resolved_url

                    attempt += 1
                    kodi.sleep(150)
            except:
                pass
            return resolved_url

        @dispatcher.register(kodi.get_setting('realdebrid_priority', ADDON_ID),
                             [raw_url])
        def realdebrid_resolver(raw_url):
            resolved_url = ''
            if kodi.get_setting('realdebrid_enable', ADDON_ID) != 'true':
                return resolved_url
            response = realdebrid.add_torrent(raw_url)
            try:
                torrent_id = response['id']
                info = realdebrid.get_torrent_info(torrent_id)
                file_id = realdebrid.get_stream_file(info['files'])
                if not file_id: return
                realdebrid.select_torrent_files(torrent_id, file_id)
                kodi.sleep(500)
                info = realdebrid.get_torrent_info(torrent_id)
                raw_url = info['links'][0]
                kodi.set_property('Playback.Resolver', 'realdebrid')
                kodi.set_property('Playback.ID', torrent_id)
                resolved_url = realdebrid.resolve_url(raw_url)
            except:
                pass
            return resolved_url

        kodi.open_busy_dialog()
        try:
            resolved_url = dispatcher.run()
        except Exception, e:
            kodi.log(e)
            kodi.close_busy_dialog()
        kodi.close_busy_dialog()

        return resolved_url
Пример #10
0
	def __init__(self, addon_id, url, full_name, destination, master=False, quiet=False, installed_list=[], batch=False):
		self.installed_list = installed_list
		self.quiet = quiet
		self.batch=batch
		if not self.quiet: kodi.open_busy_dialog()
		v = kodi.get_kodi_version()

		# Grab a list of KNOWN addons from the database. Unfortunately Jarvis requires direct database access for the installed flag
		if v >= 17:
			response = kodi.kodi_json_request("Addons.GetAddons", { "installed": False, "properties": ["path", "dependencies"]})
			for a in response['result']['addons']:
				self.available_addons += [a['addonid']]
				self.source_table[a['addonid']] = a['path']
		else:
			from sqlite3 import dbapi2
			dbf = kodi.vfs.join("special://profile/Database", "Addons20.db")
			with dbapi2.connect(dbf) as dbh:
				dbc = dbh.cursor()
				dbc.execute("SELECT addon.addonID, broken.addonID is Null AS enabled, addon.path FROM addon LEFT JOIN broken on addon.addonID=broken.addonID WHERE enabled=1")
				for a in dbc.fetchall():
					self.available_addons += [a[0]]
					self.source_table[a[0]] = a[2]
			dbh.close()
		self._addon_id = addon_id
		self._url = url
		self._full_name = full_name
		self._user, self.repo = full_name.split("/")
		self._master = master
		self._destination = destination

		# Add the final addon target to the sources list with type of zip
		# Initiate install routine
		self.install_addon(addon_id, url, full_name, master)


		completed = list(reversed(self.completed))
		if not quiet:
			pb = kodi.ProgressBar()
			pb.new('Enabling Addons', len(completed)+1)
			pb.update_subheading('Building Addon List')
		kodi.run_command("XBMC.UpdateLocalAddons()")
		kodi.sleep(500)
		for addon_id in completed:
			if not quiet:
				#percent = 100* (completed.index(addon_id) / len(completed))
				#pb.update(percent, "Enabling Addons", addon_id, '')
				pb.next(addon_id)
				kodi.sleep(100)
			self.enable_addon(addon_id)

		if not quiet: pb.next("Looking for Updates", "")
		kodi.sleep(500)
		kodi.run_command('XBMC.UpdateAddonRepos')

		# Enable installed addons
		if not self.quiet:
			pb.close()
			kodi.close_busy_dialog()
			if self.install_error:
				kodi.notify("Install failed", self._addon_id)
			else:
				kodi.notify("Install complete", self._addon_id)
Пример #11
0
	def build_dependency_list(self, addon_id, url, full_name, master):
		#if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % addon_id) == 1: return True
		if addon_id in self.installed_list:
			kodi.log('Dependency is already installed: %s' % addon_id)
			return True
		user, repo = full_name.split("/")
		kodi.log('Finding dependencies for: %s' % addon_id)
		if master:
			self.sources[addon_id] = {"type": SOURCES.REPO, "url": url, "user": user, "repo": repo, "version": ""}
			xml_str = github.find_xml(full_name)
			self.sources[addon_id]['version'] = github.get_version_by_xml(BeautifulSoup(xml_str))
		else:
			version = downloader.download(url, addon_id, self._destination, True, self.quiet)
			src_file = kodi.vfs.join("special://home/addons", addon_id)
			kodi.vfs.join(src_file, "addon.xml")
			xml = kodi.vfs.read_file(kodi.vfs.join(src_file, "addon.xml"), soup=True)
			self.save_source(addon_id, {"type": SOURCES.ZIP, "url": url, "user": user, "repo": repo, "version": version})

		for dep in xml.findAll('import'):
			test = dep['addon']
			try:
				if dep['optional'].lower() == 'true':
					if kodi.get_setting('install_optional') == 'false':
						continue
					elif kodi.get_setting('prompt_optional') == "true":
						c = kodi.dialog_confirm("Install Optional Dependency", dep['name'], dep['addon'])
						if not c: continue
			except:
				pass
			if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % test) == 1 or test in self.installed_list:
				kodi.log('Dependency is already installed: %s' % test)
				continue
			self.required_addons += [test]
			if test not in self.available_addons:
				self.unmet_addons += [test]
			else:
				self.sources[test] = {"type": SOURCES.DEFAULT, "url": self.source_table[test]}
				kodi.log("%s dependency met in %s" % (test, self.source_table[test]))

		def user_resolver(user, unmet):
			dep_url, dep_filename, dep_full_name, version = github.find_zip(user, unmet)
			if dep_url:
				kodi.log("%s found in %s repo" % (unmet, user))
				self.met_addons.append(unmet)
				user, repo = dep_full_name.split("/")
				self.sources[unmet] = {"type": SOURCES.ZIP, "url": dep_url, "user": user, "repo": repo, "version": ""}
				kodi.log("%s dependency met in %s" % (unmet, dep_url))
				return True
			return False

		def	github_resolver(unmet):
			results = github.web_search(unmet)
			c = kodi.dialog_select("GitHub Search Results for %s" % unmet, [r['full_name'] for r in results['items']])
			if c is not False:
				dep = results['items'][c]
				dep_url = url = "https://github.com/%s/archive/master.zip" % (dep['full_name'])
				self.met_addons.append(unmet)
				dep_filename = "%s.zip" % unmet
				self.sources[unmet] = {"type": SOURCES.REPO, "url": dep_url, "user": user, "repo": repo, "version": ""}
				kodi.log("%s dependency met in %s" % (unmet, dep_url))
				self.install_addon(unmet, dep_url, dep['full_name'], master=True)

				return True
			return False

		for unmet in self.unmet_addons:
			# Now attempt to locate dependencies from available sources
			# The addons that can be found in any enabled repos will be installed at the end.

			# check if this exists in users root repo
			if kodi.get_setting('source_user') == 'true':
				if user_resolver(user, unmet): continue

			# check if this exists in tva root repo
			if kodi.get_setting('source_tva') == 'true':
				if user_resolver(tva_user, unmet): continue

			# check if this exists on github
			if kodi.get_setting('source_github') == 'true':
				if github_resolver(unmet): continue

		self.unmet_addons = list(set(self.unmet_addons) - set(self.met_addons))
		if len(self.unmet_addons):
			self.install_error = True
			if not self.quiet:
				kodi.close_busy_dialog()
				kodi.raise_error("", "Unmet Dependencies:", "See log or install manually", ','.join(self.unmet_addons))
			kodi.log("Unmet Dependencies for addon install: %s" % addon_id)  # % self.addon_id)
			kodi.log(','.join(self.unmet_addons))
			inserts = [(a, ) for a in self.unmet_addons]
			DB.execute_many("INSERT INTO failed_depends(addon_id) VALUES(?)", inserts)
			DB.commit()
		self.completed.append(addon_id)
Пример #12
0
def download(url, addon_id, destination, unzip=False, quiet=False):
    version = None
    filename = addon_id + '.zip'
    r = requests.get(url, stream=True)
    kodi.log("Download: %s" % url)

    if r.status_code == requests.codes.ok:
        temp_file = kodi.vfs.join(kodi.get_profile(), "downloads")
        if not kodi.vfs.exists(temp_file):
            kodi.vfs.mkdir(temp_file, recursive=True)
        temp_file = kodi.vfs.join(temp_file, filename)
        try:
            total_bytes = int(r.headers["Content-Length"])
        except:
            total_bytes = 0
        block_size = 1000
        cached_bytes = 0
        if not quiet:
            pb = xbmcgui.DialogProgress()
            pb.create("Downloading", filename, ' ', ' ')
        kodi.sleep(150)
        start = time.time()
        with open(temp_file, 'wb') as f:
            for block in r.iter_content(chunk_size=block_size):
                if not block: break
                if not quiet and pb.iscanceled():
                    raise downloaderException('Download Aborted')
                    return False
                cached_bytes += len(block)
                f.write(block)
                if total_bytes > 0:
                    delta = int(time.time() - start)
                    if delta:
                        bs = int(cached_bytes / (delta))
                    else:
                        bs = 0
                    if not quiet:
                        percent = int(cached_bytes * 100 / total_bytes)
                        pb.update(percent, "Downloading", filename,
                                  format_status(cached_bytes, total_bytes, bs))

        if not quiet: pb.close()
        if unzip:
            zip_ref = zipfile.ZipFile(temp_file, 'r')
            zip_ref.extractall(destination)
            zip_ref.close()
            kodi.vfs.rm(temp_file, quiet=True)
            try:
                xml = kodi.vfs.read_file(kodi.vfs.join(
                    destination, kodi.vfs.join(addon_id, 'addon.xml')),
                                         soup=True)
                version = get_version_by_xml(xml)
                if not version:
                    version = get_version_by_name(filename)
            except:
                kodi.log(
                    "Unable to fine version from addon.xml for addon: %s" %
                    addon_id)
        else:
            kodi.vfs.mv(temp_file, kodi.vfs.join(destination, filename))
    else:
        kodi.close_busy_dialog()
        raise downloaderException(r.status_code)
    return version
Пример #13
0
def download(url,
             full_name,
             addon_id,
             destination,
             unzip=False,
             quiet=False,
             verify_hash=True):
    version = None
    filename = addon_id + ".zip"
    r = requests.get(url, stream=True)
    kodi.log("Download: %s" % url)

    if r.status_code == requests.codes.ok:
        temp_file = kodi.vfs.join(kodi.get_profile(), "downloads")
        if not kodi.vfs.exists(temp_file):
            kodi.vfs.mkdir(temp_file, recursive=True)
        temp_file = kodi.vfs.join(temp_file, filename)
        try:
            total_bytes = int(r.headers["Content-Length"])
        except:
            total_bytes = 0
        block_size = 1000
        cached_bytes = 0
        if not quiet:
            pb = xbmcgui.DialogProgress()
            pb.create("Downloading", filename, " ", " ")
        kodi.sleep(150)
        start = time.time()
        is_64bit = sys.maxsize > 2**32
        with open(temp_file, "wb") as f:
            for chunk in r.iter_content(chunk_size=block_size):
                if chunk:
                    if not quiet and pb.iscanceled():
                        raise downloaderException("Download Aborted")
                        return False
                    cached_bytes += len(chunk)
                    shutil.copyfileobj(functionIO(chunk), f, 8096)
                    if total_bytes > 0:
                        delta = int(time.time() - start)
                        if delta:
                            bs = int(cached_bytes / (delta))
                        else:
                            bs = 0
                        if not quiet:
                            percent = int(cached_bytes * 100 / total_bytes)
                            pb.update(
                                percent,
                                "Downloading",
                                filename,
                                format_status(cached_bytes, total_bytes, bs),
                            )

        if not quiet:
            pb.close()
        if verify_hash:
            local_sha = hash_func(temp_file, "sha1")
            remote_sha = get_sha(full_name, url)
            if remote_sha != local_sha:
                kodi.close_busy_dialog()
                kodi.handel_error("Download Error", "Checksum mismatch!")

        if unzip:
            if is_64bit:
                zip_ref = zipfile.ZipFile(temp_file, "r")
            else:
                with open(temp_file, "rb") as zip_file:
                    zip_ref = zip_file.ZipFile(functionIO(zip_file.read()))
            zip_ref.extractall(destination)
            zip_ref.close()
            kodi.vfs.rm(temp_file, quiet=True)
            try:
                xml = kodi.vfs.read_file(
                    kodi.vfs.join(destination,
                                  kodi.vfs.join(addon_id, "addon.xml")),
                    soup=True,
                )
                version = get_version_by_xml(xml)
                if not version:
                    version = get_version_by_name(filename)
            except:
                kodi.log(
                    "Unable to fine version from addon.xml for addon: %s" %
                    addon_id)
        else:
            kodi.vfs.mv(temp_file, kodi.vfs.join(destination, filename))
    else:
        kodi.close_busy_dialog()
        raise downloaderException(r.status_code)
    return version
Пример #14
0
	def __init__(self, addon_id, url, full_name, destination, master=False, quiet=False, installed_list=[], batch=False):
		self.installed_list = installed_list
		self.quiet = quiet
		self.batch=batch
		if not self.quiet: kodi.open_busy_dialog()
		v = kodi.get_kodi_version()
		
		# Grab a list of KNOWN addons from the database. Unfortunately Jarvis requires direct database access for the installed flag
		if v >= 17:
			response = kodi.kodi_json_request("Addons.GetAddons", { "installed": False, "properties": ["path", "dependencies"]})
			for a in response['result']['addons']:
				self.available_addons += [a['addonid']]
				self.source_table[a['addonid']] = a['path']
		else:
			from sqlite3 import dbapi2
			dbf = kodi.vfs.join("special://profile/Database", "Addons20.db")
			with dbapi2.connect(dbf) as dbh:
				dbc = dbh.cursor()
				dbc.execute("SELECT addon.addonID, broken.addonID is Null AS enabled, addon.path FROM addon LEFT JOIN broken on addon.addonID=broken.addonID WHERE enabled=1")
				for a in dbc.fetchall():
					self.available_addons += [a[0]]
					self.source_table[a[0]] = a[2]
			dbh.close()
		self._addon_id = addon_id
		self._url = url
		self._full_name = full_name
		self._user, self.repo = full_name.split("/")
		self._master = master
		self._destination = destination
		
		# Add the final addon target to the sources list with type of zip
		# Initiate install routine
		self.install_addon(addon_id, url, full_name, master)

			
		completed = list(reversed(self.completed))
		if not quiet:
			pb = kodi.ProgressBar()
			pb.new('Enabling Addons', len(completed)+1)
			pb.update_subheading('Building Addon List')
		kodi.run_command("XBMC.UpdateLocalAddons()")
		kodi.sleep(500)	
		for addon_id in completed:
			if not quiet:
				#percent = 100* (completed.index(addon_id) / len(completed))
				#pb.update(percent, "Enabling Addons", addon_id, '')
				pb.next(addon_id)
				kodi.sleep(100)
			self.enable_addon(addon_id)
		
		if not quiet: pb.next("Looking for Updates", "")
		kodi.sleep(500)
		kodi.run_command('XBMC.UpdateAddonRepos')
		
		# Enable installed addons	
		if not self.quiet: 
			pb.close()
			kodi.close_busy_dialog()
			if self.install_error:
				kodi.notify("Install failed", self._addon_id)
			else:		
				kodi.notify("Install complete", self._addon_id)
Пример #15
0
	def build_dependency_list(self, addon_id, url, full_name, master):
		#if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % addon_id) == 1: return True
		if addon_id in self.installed_list: 
			kodi.log('Dependency is already installed: %s' % addon_id)
			return True
		user, repo = full_name.split("/")
		kodi.log('Finding dependencies for: %s' % addon_id)
		if master:
			self.sources[addon_id] = {"type": SOURCES.REPO, "url": url, "user": user, "repo": repo, "version": ""}
			xml_str = github.find_xml(full_name)
			self.sources[addon_id]['version'] = github.get_version_by_xml(BeautifulSoup(xml_str))
		else:
			version = downloader.download(url, addon_id, self._destination, True, self.quiet)
			src_file = kodi.vfs.join("special://home/addons", addon_id)
			kodi.vfs.join(src_file, "addon.xml")
			xml = kodi.vfs.read_file(kodi.vfs.join(src_file, "addon.xml"), soup=True)
			self.save_source(addon_id, {"type": SOURCES.ZIP, "url": url, "user": user, "repo": repo, "version": version})
			
		for dep in xml.findAll('import'):
			test = dep['addon']
			try:
				if dep['optional'].lower() == 'true': 
					if kodi.get_setting('install_optional') == 'false': 
						continue
					elif kodi.get_setting('prompt_optional') == "true":
						c = kodi.dialog_confirm("Install Optional Dependency", dep['name'], dep['addon'])
						if not c: continue
			except:
				pass
			if test in ['xbmc.python', 'xbmc.gui'] or kodi.get_condition_visiblity('System.HasAddon(%s)' % test) == 1 or test in self.installed_list:
				kodi.log('Dependency is already installed: %s' % test)
				continue
			self.required_addons += [test]
			if test not in self.available_addons: 
				self.unmet_addons += [test]
			else:
				self.sources[test] = {"type": SOURCES.DEFAULT, "url": self.source_table[test]}
				kodi.log("%s dependency met in %s" % (test, self.source_table[test]))
		
		def user_resolver(user, unmet):
			dep_url, dep_filename, dep_full_name, version = github.find_zip(user, unmet)
			if dep_url:
				kodi.log("%s found in %s repo" % (unmet, user))
				self.met_addons.append(unmet)
				user, repo = dep_full_name.split("/")
				self.sources[unmet] = {"type": SOURCES.ZIP, "url": dep_url, "user": user, "repo": repo, "version": ""}
				kodi.log("%s dependency met in %s" % (unmet, dep_url))
				return True
			return False
		
		def	github_resolver(unmet):
			results = github.web_search(unmet)
			c = kodi.dialog_select("GitHub Search Results for %s" % unmet, [r['full_name'] for r in results['items']])
			if c is not False:
				dep = results['items'][c]
				dep_url = url = "https://github.com/%s/archive/master.zip" % (dep['full_name'])
				self.met_addons.append(unmet)
				dep_filename = "%s.zip" % unmet
				self.sources[unmet] = {"type": SOURCES.REPO, "url": dep_url, "user": user, "repo": repo, "version": ""}
				kodi.log("%s dependency met in %s" % (unmet, dep_url))
				self.install_addon(unmet, dep_url, dep['full_name'], master=True)
				
				return True
			return False	
		
		for unmet in self.unmet_addons:
			# Now attempt to locate dependencies from available sources
			# The addons that can be found in any enabled repos will be installed at the end.
			
			# check if this exists in users root repo
			if kodi.get_setting('source_user') == 'true':
				if user_resolver(user, unmet): continue
			
			# check if this exists in tva root repo
			if kodi.get_setting('source_tva') == 'true':
				if user_resolver(tva_user, unmet): continue
			
			# check if this exists on github
			if kodi.get_setting('source_github') == 'true':
				if github_resolver(unmet): continue
			
		self.unmet_addons = list(set(self.unmet_addons) - set(self.met_addons))
		if len(self.unmet_addons):
			self.install_error = True
			if not self.quiet:
				kodi.close_busy_dialog()
				kodi.raise_error("", "Unmet Dependencies:", "See log or install manually", ','.join(self.unmet_addons))
			kodi.log("Unmet Dependencies for addon install: %s" % addon_id)  # % self.addon_id)
			kodi.log(','.join(self.unmet_addons))
		self.completed.append(addon_id)