Example #1
0
    def update_description(self):
        # I have become GTK - Destroyer Of Children
        for child in self.description_box.get_children():
            child.destroy()

        id = self.item.get_id()
        fallback = self.item.get_description()
        store = self.item.get_store()
        desc = self.context.appsystem.get_description(id, fallback, store)

        plain = As.markup_convert(desc, As.MarkupConvertFormat.MARKDOWN)
        lines = []
        try:
            self.parser.consume(plain)
            lines = self.parser.emit()
        except Exception as e:
            print("Parsing error: {}".format(e))
            plain = As.markup_convert_simple(desc)
            lines = plain.split("\n")

        for line in lines:
            lab = Gtk.Label(line)
            lab.set_use_markup(True)
            lab.set_halign(Gtk.Align.START)
            lab.set_line_wrap(True)
            lab.set_property("xalign", 0.0)
            lab.set_property("margin", 2)
            lab.set_margin_bottom(4)
            self.description_box.pack_start(lab, False, False, 0)
            lab.show_all()
Example #2
0
    def update_description(self):
        # I have become GTK - Destroyer Of Children
        for child in self.description_box.get_children():
            child.destroy()

        id = self.item.get_id()
        fallback = self.item.get_description()
        desc = self.context.appsystem.get_description(id, fallback)

        plain = As.markup_convert(desc, As.MarkupConvertFormat.MARKDOWN)
        lines = []
        try:
            self.parser.consume(plain)
            lines = self.parser.emit()
        except Exception as e:
            print("Parsing error: {}".format(e))
            plain = As.markup_convert_simple(desc)
            lines = plain.split("\n")

        for line in lines:
            lab = Gtk.Label(line)
            lab.set_use_markup(True)
            lab.set_halign(Gtk.Align.START)
            lab.set_line_wrap(True)
            lab.set_property("xalign", 0.0)
            lab.set_property("margin", 2)
            lab.set_margin_bottom(4)
            self.description_box.pack_start(lab, False, False, 0)
            lab.show_all()
Example #3
0
    def update_app(self, app, content_app_id=''):
        app_id = content_app_id or app.get_id()
        metadata = self._get_app_metadata(app_id)

        if not metadata:
            app_id = app_id.rsplit('.desktop', 1)[0]
            metadata = self._get_app_metadata(app_id)

            if not metadata:
                raise NoMetadataException(app_id)

        app.set_name('C', metadata['title'])
        app.set_comment('C', metadata['subtitle'])
        description = metadata['description']
        app.set_description('C', description)

        categories = metadata.get('category')
        for category in categories.split(';'):
            app.add_category(category)

        # Screenshots in the metadata are arranged as 'language' -> ['image', ...]
        # but we need to group the same images in the same screenshot (with a
        # different language each), so we invert the arrangement as:
        # 'image' -> ['language', ...]
        #
        # Use an OrderedDict so we maintain the order of the screenshots as found
        # in the metadata which can be important.
        screenshots = collections.OrderedDict()
        for locale, images in metadata.get('screenshots', {}).items():
            for image in images:
                screenshots.setdefault(image, []).append(locale)

        for image, locales in screenshots.items():
            screenshot = AppStreamGlib.Screenshot()
            for locale in locales:
                as_img = AppStreamGlib.Image()
                # We need to add the screenshots as source, otherwise, without a
                # caption and other elements, AppStreamGlib discards the screenshots
                # as duplicates...
                as_img.set_kind(AppStreamGlib.ImageKind.SOURCE)
                as_img.set_url(self._get_screenshot_url(app_id, locale, image))
                if locale != 'C':
                    as_img.set_locale(locale)
                screenshot.add_image(as_img)
            app.add_screenshot(screenshot)

        self._translate_app(app)
        # We only format the description now otherwise it would not
        # match the translations
        app.set_description('C',
                            self._add_paragraph_tags_if_needed(description))
Example #4
0
    def __init__(self):
        self.store = As.Store()
        self.store.load(As.StoreLoadFlags.APP_INFO_SYSTEM)

        itheme = Gtk.IconTheme.get_default()
        try:
            self.default_pixbuf = self.scaled_icon(itheme.load_icon(
                "package-x-generic",
                64,
                Gtk.IconLookupFlags.GENERIC_FALLBACK))
            self.security_pixbuf = self.scaled_icon(itheme.load_icon(
                "network-vpn",
                64,
                Gtk.IconLookupFlags.GENERIC_FALLBACK))
            self.mandatory_pixbuf = self.scaled_icon(itheme.load_icon(
                "computer",
                64,
                Gtk.IconLookupFlags.GENERIC_FALLBACK))
            self.other_pixbuf = self.scaled_icon(itheme.load_icon(
                "folder-download",
                64,
                Gtk.IconLookupFlags.GENERIC_FALLBACK))
            self.addon_pixbuf = self.scaled_icon(itheme.load_icon(
                "application-x-addon",
                64,
                Gtk.IconLookupFlags.GENERIC_FALLBACK))
        except Exception as e:
            print(e)
Example #5
0
 def matches(self, value):
     if self.compare == 'eq':
         return value == self.value
     if self.compare == 'lt':
         return AppStreamGlib.utils_vercmp(value, self.value) < 0
     if self.compare == 'le':
         return AppStreamGlib.utils_vercmp(value, self.value) <= 0
     if self.compare == 'gt':
         return AppStreamGlib.utils_vercmp(value, self.value) > 0
     if self.compare == 'ge':
         return AppStreamGlib.utils_vercmp(value, self.value) >= 0
     if self.compare == 'glob':
         return fnmatch.fnmatch(value, self.value)
     if self.compare == 'regex':
         return re.search(self.value, value)
     return False
Example #6
0
	def execute_action(self,action,applist=None,store=None,results=0):
		if store:
			self.store=store
		else:
			self.store=appstream.Store()
		self.progress=0
		self.result['status']={'status':-1,'msg':''}
		self.result['data']=''
		
		if self.disabled==True:
			self._set_status(9)
			self.result['data']=self.store
		else:
			self._check_dirs()
			dataList=[]
			if action=='load':
				self.result['data']=self._loadStore(self.store)
			else:
				for app_info in applist:
					self.partial_progress=0
					if action=='install':
						dataList.append(self._install(app_info))
					if action=='remove':
						dataList.append(self._remove(app_info))
					if action=='pkginfo':
						dataList.append(self._get_info(app_info))
						#dataList.append((app_info))
					self.progress+=round(self.partial_progress/len(applist),1)
					if self.progress>98:
						self.progress=98
				self.result['data']=list(dataList)
		self.progress=100
		return(self.result)
Example #7
0
 def render_plain(self, input_string):
     """ Render a plain version of the description, no markdown """
     plain = As.markup_convert_simple(input_string)
     plain = plain.replace("&quot;",
                           "\"").replace("&apos;",
                                         "'").replace("&amp;", "&")
     return plain
Example #8
0
def _load_appstream_pool(pools, remote):
    pool = AppStreamGlib.Store()
    path = remote.get_appstream_dir().get_path()

    with open(os.path.join(path, "appstream.xml")) as f:
        pool.from_xml(f.read(), path)

    pools[remote.get_name()] = pool
Example #9
0
	def _searchPackage(self,package):
		self._debug("Searching %s"%package)
		pklist=None
		package=package.replace("_","-")
		apps=appstream.Store()
		searchStore=[]
		for app in self.store.get_apps():
			if app.search_matches(package)>90:
				apps.add_app(app)
		searchResults=rebostHelper.appstream_to_rebost(apps)
		return(searchResults)
Example #10
0
def _user_agent_safe_for_requirement(user_agent):

    # very early versions of fwupd used 'fwupdmgr' as the user agent
    if user_agent == 'fwupdmgr':
        return False

    # gnome-software/3.26.5 (Linux x86_64 4.14.0) fwupd/1.0.4
    sections = user_agent.split(' ')
    for chunk in sections:
        toks = chunk.split('/')
        if len(toks) == 2 and toks[0] == 'fwupd':
            return AppStreamGlib.utils_vercmp(toks[1], '0.8.0') >= 0

    # this is a heuristic; the logic is that it's unlikely that a distro would
    # ship a very new gnome-software and a very old fwupd
    for chunk in sections:
        toks = chunk.split('/')
        if len(toks) == 2 and toks[0] == 'gnome-software':
            return AppStreamGlib.utils_vercmp(toks[1], '3.26.0') >= 0

    # is is probably okay
    return True
Example #11
0
def firmware_modify(firmware_id):
    """ Modifies the update urgency and release notes for the update """

    if request.method != 'POST':
        return redirect(url_for('.firmware'))

    # find firmware
    fw = db.session.query(Firmware).filter(
        Firmware.firmware_id == firmware_id).first()
    if not fw:
        return _error_internal("No firmware %s" % firmware_id)

    # security check
    for md in fw.mds:
        if not md.check_acl('@modify-updateinfo'):
            return _error_permission_denied(
                'Insufficient permissions to modify firmware')

    # set new metadata values
    for md in fw.mds:
        if 'urgency' in request.form:
            md.release_urgency = request.form['urgency']
        if 'description' in request.form:
            txt = request.form['description']
            if txt:
                if txt.find('<p>') == -1:
                    txt = AppStreamGlib.markup_import(
                        txt, AppStreamGlib.MarkupConvertFormat.SIMPLE)
                try:
                    AppStreamGlib.markup_validate(txt)
                except GLib.Error as e:  # pylint: disable=catching-non-exception
                    return _error_internal("Failed to parse %s: %s" %
                                           (txt, str(e)))
            md.release_description = unicode(txt)

    # modify
    db.session.commit()
    flash('Update text updated', 'info')
    return redirect(url_for('.firmware_show', firmware_id=firmware_id))
Example #12
0
    def cache_icons(self):
        for release in self.active_fedora_releases:
            fname = 'fedora-%s.xml.gz' % release
            target = join(self.icons_path, 'tmp', str(release), fname)
            if not os.path.exists(target):
                return

            metadata = AppStreamGlib.Store()

            with gzip.open(target, 'rb') as f:
                metadata.from_xml(f.read(), '')

            for app in metadata.get_apps():
                # Other types are 'stock' and 'unknown'
                icons = app.get_icons()
                pkgname = app.get_pkgnames()[0]

                # Pick the biggest one..
                icon = None
                for candidate in icons:
                    if not icon:
                        if candidate.get_kind().value_nick == 'cached':
                            icon = candidate
                        continue
                    if int(icon.get_width()) < int(candidate.get_width()):
                        icon = candidate

                if not icon:
                    continue

                # Move the file out of the temp dir and into place
                s = join(self.icons_path, 'tmp', str(release),
                         '{width}x{height}', '{value}')
                d = join(self.icons_path, '{value}')
                source = s.format(width=icon.get_width(), height=icon.get_height(),
                                  value=icon.get_name())
                destination = d.format(value=icon.get_name())

                try:
                    shutil.copy(source, destination)

                    # And hang the name in the dict for other code to find it
                    # ... but only if we succeeded at placing the icon file.
                    self.icon_cache[pkgname] = icon.get_name()
                except IOError as e:
                    log.warning("appstream metadata lied: %s %r" % (source, e))
                except OSError as e:
                    log.warning("fail %r->%r.  %r" % (source, destination, e))

        shutil.rmtree(join(self.icons_path, 'tmp'))
Example #13
0
 def execute_action(self, action, applist=None, store=None):
     if store:
         self.store = store
     else:
         self.store = appstream.Store()
     self.appimage_store = appstream.Store()
     self.progress = 0
     self.result['status'] = {'status': -1, 'msg': ''}
     self.result['data'] = []
     self.threads = []
     dataList = []
     if self.disabled:
         self._set_status(9)
         self.result['data'] = self.store
     else:
         self._chk_installDir()
         if action == 'load':
             self._load_appimage_store(self.store)
             self._debug("Ending threads...")
             while not self.apps_for_store.empty():
                 app = self.apps_for_store.get()
                 self.store.add_app(app)
             self.result['data'] = self.store
         else:
             for app_info in applist:
                 self.partial_progress = 0
                 if action == 'install':
                     dataList.append(self._install_appimage(app_info))
                 if action == 'remove':
                     dataList.append(self._remove_appimage(app_info))
                 if action == 'pkginfo':
                     dataList.append(self._get_info(app_info))
                 self.progress += int(
                     self.partial_progress / len(applist)) - 1
             self.result['data'] = list(dataList)
     self.progress = 100
     return (self.result)
Example #14
0
	def _th_load_store(self,store,pkg,semaphore):
		semaphore.acquire()
		app=self.store.get_app_by_pkgname(pkg.get_name())
		if not app:
			#self._debug("Searching for %s"%pkg.get_name())
			app=self.store.get_app_by_id(pkg.get_name().lower()+".desktop")
			if app:
				bundle=appstream.Bundle()
				bundle.set_kind(bundle.kind_from_string('SNAP'))
				bundle.set_id(pkg.get_name()+'.snap')
				app.add_bundle(bundle)
				app.add_category("Snap")
				store.put(self._generate_appstream_app_from_snap(pkg))
			else:
				store.put(self._generate_appstream_app_from_snap(pkg))
		semaphore.release()
Example #15
0
    def __init__(self):
        #  /usr/share/gir-1.0/AppStreamGlib-1.0.gir
        try:
            if not USE_APPSTREAM:
                raise ValueError
            import gi
            gi.require_version('AppStreamGlib', '1.0')
            from gi.repository import AppStreamGlib
            app_store = AppStreamGlib.Store()
            app_store.load(flags=AppStreamGlib.StoreLoadFlags.APP_INFO_SYSTEM);
            app_store.set_search_match(AppStreamGlib.AppSearchMatch.PKGNAME | AppStreamGlib.AppSearchMatch.NAME |  AppStreamGlib.AppSearchMatch.KEYWORD);
        except ValueError:
            app_store = None

        def _app_store_ico(tofind):
            """ find app in store
            It's very slow ...
            """
            default = "package"
            for app in app_store.get_apps():
                if app.get_kind() != AppStreamGlib.AppKind.DESKTOP:
                    continue
                if app.get_pkgname_default() == tofind:
                    #print(f"-- AppStream trouvé -- {tofind}")
                    # FIX entries errors
                    iname = app.get_icon_default().get_name()
                    if not ".png" in iname:
                        iname = f"{app.get_pkgname_default()}_{iname}.png"
                    icon = f"{app.get_icon_path()}/64x64/{iname}"
                    if not Path(icon).exists():
                        print(f"  bad ico ? {icon} {app.get_icon_default().get_name()}")
                        icon = default
                    return icon
            return default

        #self.handle = Handle('/', '/var/lib/pacman')
        self.handle = config.init_with_config("/etc/pacman.conf")
        self.pkgs = []
        for i, pkg in enumerate(self.handle.get_localdb().pkgcache):
            pkg_repo = self._find(pkg.name)
            afile = AlpmFile(pkg, i, pkg_repo)
            if app_store:
                afile.ico = _app_store_ico(pkg.name)
            self.pkgs.append(afile)
        print(f"end scan {len(self.pkgs)} packages")
Example #16
0
    def execute_action(self,
                       appstreamStore,
                       action,
                       tokens,
                       exact_match_for_search=False,
                       max_results=0):
        self._debug("Executing action %s" % action)
        self._debug("Tokens: %s" % tokens)
        self.progress = 0
        if type(tokens) == type([]):
            tokens = ' '.join(tokens)
        if type(tokens) is str:
            tokens = tokens.lower()
        else:
            tokens = ''
        if len(tokens.split(' ')) > 1:
            if action == 'search':
                #self._debug("Tokenizing search items")
                tokens = appstream.utils_search_tokenize(tokens)
            else:
                tokens = tokens.split(' ')
        else:
            if len(tokens) >= 1:
                tokens = [tokens]
            else:
                tokens = []

        self.store = appstreamStore
        self.result['status'] = {'status': -1, 'msg': ''}
        self.result['data'] = []
        if self.store:
            if action == 'list':
                self._list_category(tokens, max_results)
            if action == 'list_sections':
                self._list_sections()
            if (action == 'search' or action == 'info'):
                self._search_app(tokens, exact_match_for_search)
        else:
            #self._debug("Search needs a store")
            pass
        self.progress = 100
        return (self.result)
Example #17
0
	def execute_action(self,action,applist=None,store=None,results=0):
		if store:
			self.store=store
		else:
			self.store=appstream.Store()
		self.progress=0
		self.result['status']={'status':-1,'msg':''}
		self.result['data']=''
		
		self.snap_client=Snapd.Client()
		try:
			self.snap_client.connect_sync(None)
		except Exception as e:
			self.disabled=True
			#self._debug("Disabling snap %s"%e)

		if self.disabled==True:
			self._set_status(9)
			self.result['data']=self.store
		else:
			self._check_dirs()
			dataList=[]
			if action=='load':
				self.result['data']=self._load_snap_store(self.store)
			else:
				for app_info in applist:
					self.partial_progress=0
					if action=='install':
						dataList.append(self._install_snap(app_info))
					if action=='remove':
						dataList.append(self._remove_snap(app_info))
					if action=='pkginfo':
						dataList.append(self._get_info(app_info))
					self.progress+=round(self.partial_progress/len(applist),1)
					if self.progress>98:
						self.progress=98
				self.result['data']=list(dataList)
		self.progress=100
		return(self.result)
Example #18
0
    def update_appdata_from_file(self, file_path, content_app_id=''):
        app = load_as_app_from_appdata(file_path)
        self.update_app(app, content_app_id)

        # Add a special metadata item in order to easily check if this app-data
        # file has been merged by eos-shell-content
        app.add_metadata('Endless::EosShellContent::Merged', 'true')

        store = AppStreamGlib.Store()
        store.add_app(app)
        xml_str = store.to_xml(AppStreamGlib.NodeToXmlFlags.NONE).str
        root = ET.fromstring(xml_str)
        if root.tag == 'components':
            root = root.find('component')

        # We do not want to display screenshots from 3rd parties when we have
        # provided some from the Shell Content, so we need to remove them.
        # The removal should be done in the app object but this cannot be
        # accomplished until there is API to do it in libappstream-glib.
        self._remove_unneeded_screenshots(root)

        node = xml.dom.minidom.parseString(ET.tostring(root, encoding='utf-8'))
        return node.toprettyxml(indent='  ')
Example #19
0
#!/usr/bin/env python2.7
import gi.repository
gi.require_version('AppStreamGlib', '1.0')
from gi.repository import AppStreamGlib as AS

store = AS.Store()

store.load(AS.StoreLoadFlags.APP_INFO_SYSTEM)


def test_markup(desc):
    m = AS.markup_convert(desc, -1, AS.MarkupConvertFormat.SIMPLE)
    return m


app = store.get_app_by_pkgname("pitivi")

desc = app.get_description("C")
print test_markup(desc)
Example #20
0
	def _generate_appstream_app_from_snap(self,pkg):
		bundle=appstream.Bundle()
		app=appstream.App()
		icon=appstream.Icon()
		screenshot=appstream.Screenshot()
#		bundle.set_kind(appstream.BundleKind.SNAP)
		bundle.set_kind(bundle.kind_from_string('SNAP'))
		bundle.set_id(pkg.get_name()+'.snap')
		app.add_bundle(bundle)
		app.set_name("C",pkg.get_name()+'.snap')
		app.add_pkgname(pkg.get_name()+'.snap')
		app.add_category("Snap")
		release=appstream.Release()
		release.set_version(pkg.get_version())
		app.add_release(release)
		app.set_id("io.snapcraft.%s"%pkg.get_name()+'.snap')
		app.set_id_kind=appstream.IdKind.DESKTOP
		app.set_metadata_license("CC0-1.0")
		description="" #This is an Snap bundle. It hasn't been tested by our developers and comes from a 3rd party dev team. Please use it carefully."
		pkg_description=pkg.get_description()
		pkg_description=html.escape(pkg_description,quote=True)
		pkg_description=pkg_description.replace("<","&gt;")
		app.set_description("C","<p>%s</p><p>%s</p>"%(description,pkg_description))
		app.set_comment("C",pkg.get_summary().rstrip('.'))

		app.add_keyword("C",pkg.get_name())
		for word in pkg.get_summary().split(' '):
			if len(word)>3:
				app.add_keyword("C",word)

		if pkg.get_icon():
			if self.icon_cache_enabled:
				icon.set_kind(appstream.IconKind.LOCAL)
				icon.set_filename(self._download_file(pkg.get_icon(),pkg.get_name(),self.icons_folder))
			else:
				icon.set_kind(appstream.IconKind.REMOTE)
				icon.set_name(pkg.get_icon())
				icon.set_url(pkg.get_icon())
			app.add_icon(icon)

		if pkg.get_license():
			app.set_project_license(pkg.get_license())

		if pkg.get_screenshots():
			for snap_screen in pkg.get_screenshots():
				img=appstream.Image()
				img.set_kind(appstream.ImageKind.SOURCE)
				img.set_url(snap_screen.get_url())
				break
			screenshot.add_image(img)
			app.add_screenshot(screenshot)

		if not os.path.isfile(self.cache_xmls+'/'+app.get_id_filename()):
			xml_path='%s/%s.xml'%(self.cache_xmls,app.get_id_filename())
			gioFile=Gio.File.new_for_path(xml_path)
			app.to_file(gioFile)
			#Fix some things in app_file...
			with open(xml_path,'r',encoding='utf-8') as f:
				xml_data=f.readlines()
			#self._debug("fixing %s"%xml_path)
			try:
				xml_data[0]=xml_data[0]+"<components>\n"
				xml_data[-1]=xml_data[-1]+"\n"+"</components>"
			except:
				pass
			with open(xml_path,'w') as f:
				f.writelines(xml_data)
		return(app)
Example #21
0
def _generate_metadata_kind(filename, fws, firmware_baseuri=''):
    """ Generates AppStream metadata of a specific kind """
    store = AppStreamGlib.Store.new()
    store.set_origin('lvfs')
    store.set_api_version(0.9)
    for fw in fws:

        # add each component
        for md in fw.mds:
            component = AppStreamGlib.App.new()
            component.set_id(md.appstream_id)
            component.set_kind(AppStreamGlib.AppKind.FIRMWARE)
            component.set_name(None, md.name)
            component.set_comment(None, md.summary)
            component.set_description(None, md.description)
            if md.url_homepage:
                component.add_url(AppStreamGlib.UrlKind.HOMEPAGE, md.url_homepage)
            component.set_metadata_license(md.metadata_license)
            component.set_project_license(md.project_license)
            component.set_developer_name(None, md.developer_name)

            # add provide
            for guid in md.guids:
                prov = AppStreamGlib.Provide.new()
                prov.set_kind(AppStreamGlib.ProvideKind.FIRMWARE_FLASHED)
                prov.set_value(guid.value)
                component.add_provide(prov)

            # add release
            if md.version:
                rel = AppStreamGlib.Release.new()
                rel.set_version(md.version)
                if md.release_description:
                    rel.set_description(None, md.release_description)
                if md.release_timestamp:
                    rel.set_timestamp(md.release_timestamp)
                rel.checksums = []
                rel.add_location(firmware_baseuri + fw.filename)
                rel.set_size(AppStreamGlib.SizeKind.INSTALLED, md.release_installed_size)
                rel.set_size(AppStreamGlib.SizeKind.DOWNLOAD, md.release_download_size)
                if md.release_urgency:
                    rel.set_urgency(AppStreamGlib.urgency_kind_from_string(md.release_urgency))
                component.add_release(rel)

                # add container checksum
                if fw.checksum_signed:
                    csum = AppStreamGlib.Checksum.new()
                    csum.set_kind(GLib.ChecksumType.SHA1)
                    csum.set_target(AppStreamGlib.ChecksumTarget.CONTAINER)
                    csum.set_value(fw.checksum_signed)
                    csum.set_filename(fw.filename)
                    rel.add_checksum(csum)

                # add content checksum
                if md.checksum_contents:
                    csum = AppStreamGlib.Checksum.new()
                    csum.set_kind(GLib.ChecksumType.SHA1)
                    csum.set_target(AppStreamGlib.ChecksumTarget.CONTENT)
                    csum.set_value(md.checksum_contents)
                    csum.set_filename(md.filename_contents)
                    rel.add_checksum(csum)

            # add screenshot
            if md.screenshot_caption:
                ss = AppStreamGlib.Screenshot.new()
                ss.set_caption(None, md.screenshot_caption)
                if md.screenshot_url:
                    im = AppStreamGlib.Image.new()
                    im.set_url(md.screenshot_url)
                    ss.add_image(im)
                component.add_screenshot(ss)

            # add requires for each allowed vendor_ids
            vendor = db.session.query(Vendor).filter(Vendor.vendor_id == fw.vendor_id).first()
            if vendor and vendor.restrictions:
                vendor_ids = []
                for res in vendor.restrictions:
                    vendor_ids.append(res.value)
                req = AppStreamGlib.Require.new()
                req.set_kind(AppStreamGlib.RequireKind.FIRMWARE)
                req.set_value('vendor-id')
                if len(vendor_ids) == 1:
                    req.set_compare(AppStreamGlib.RequireCompare.EQ)
                else:
                    req.set_compare(AppStreamGlib.RequireCompare.REGEX)
                req.set_version('|'.join(vendor_ids))
                component.add_require(req)

            # add manual firmware or fwupd version requires
            for rq in md.requirements:
                if rq.kind == 'hardware':
                    continue
                req = AppStreamGlib.Require.new()
                req.set_kind(AppStreamGlib.Require.kind_from_string(rq.kind))
                if rq.value:
                    req.set_value(rq.value)
                if rq.compare:
                    req.set_compare(AppStreamGlib.Require.compare_from_string(rq.compare))
                if rq.version:
                    req.set_version(rq.version)
                component.add_require(req)

            # add hardware requirements
            rq_hws = []
            for rq in md.requirements:
                if rq.kind == 'hardware':
                    rq_hws.append(rq.value)
            if rq_hws:
                req = AppStreamGlib.Require.new()
                req.set_kind(AppStreamGlib.RequireKind.HARDWARE)
                req.set_value('|'.join(rq_hws))
                component.add_require(req)

            # add any shared metadata
            if md.inhibit_download:
                component.add_metadata('LVFS::InhibitDownload')
            if md.version_format:
                component.add_metadata('LVFS::VersionFormat', md.version_format)

            # add component
            store.add_app(component)

    # dump to file
    store.to_file(Gio.file_new_for_path(filename),
                  AppStreamGlib.NodeToXmlFlags.ADD_HEADER |
                  AppStreamGlib.NodeToXmlFlags.FORMAT_INDENT |
                  AppStreamGlib.NodeToXmlFlags.FORMAT_MULTILINE)
Example #22
0
 def __init__(self):
     self.store = As.Store()
     self.store.load(As.StoreLoadFlags.APP_INFO_SYSTEM)
Example #23
0
def _create_fw_from_uploaded_file(ufile):

    # create empty firmware
    fw = Firmware()
    fw.filename = ufile.filename_new
    fw.checksum_upload = ufile.checksum_upload
    if ufile.version_display:
        fw.version_display = ufile.version_display

    # create child metadata object for the components
    for component in ufile.get_components():
        md = Component()
        md.appstream_id = component.get_id()
        md.name = unicode(component.get_name())
        md.summary = unicode(component.get_comment())
        md.developer_name = unicode(component.get_developer_name())
        md.metadata_license = component.get_metadata_license()
        md.project_license = component.get_project_license()
        md.url_homepage = unicode(
            component.get_url_item(AppStreamGlib.UrlKind.HOMEPAGE))
        md.description = unicode(component.get_description())

        # fix up the vendor
        if md.developer_name == 'LenovoLtd.':
            md.developer_name = u'Lenovo Ltd.'

        # add manually added keywords
        for keyword in component.get_keywords():
            md.add_keywords_from_string(unicode(keyword), priority=5)

        # add from the provided free text
        if md.developer_name:
            md.add_keywords_from_string(md.developer_name, priority=10)
        if md.name:
            md.add_keywords_from_string(md.name, priority=3)
        if md.summary:
            md.add_keywords_from_string(md.summary, priority=1)

        # from the provide
        for prov in component.get_provides():
            if prov.get_kind() != AppStreamGlib.ProvideKind.FIRMWARE_FLASHED:
                continue
            md.guids.append(Guid(md.component_id, prov.get_value()))

        # from the release
        rel = component.get_release_default()
        md.version = rel.get_version()
        md.release_description = unicode(rel.get_description())
        md.release_timestamp = rel.get_timestamp()
        md.release_installed_size = rel.get_size(
            AppStreamGlib.SizeKind.INSTALLED)
        md.release_download_size = rel.get_size(
            AppStreamGlib.SizeKind.DOWNLOAD)
        md.release_urgency = AppStreamGlib.urgency_kind_to_string(
            rel.get_urgency())

        # from requires
        for req in component.get_requires():
            rq = Requirement(
                md.component_id,
                AppStreamGlib.Require.kind_to_string(req.get_kind()),
                req.get_value(),
                AppStreamGlib.Require.compare_to_string(req.get_compare()),
                req.get_version())
            md.requirements.append(rq)

        # from the first screenshot
        if len(component.get_screenshots()) > 0:
            ss = component.get_screenshots()[0]
            md.screenshot_caption = ss.get_caption(None)
            if len(ss.get_images()) > 0:
                im = ss.get_images()[0]
                md.screenshot_url = unicode(im.get_url())

        # from the content checksum
        csum = rel.get_checksum_by_target(AppStreamGlib.ChecksumTarget.CONTENT)
        md.checksum_contents = csum.get_value()
        md.filename_contents = csum.get_filename()

        # allows OEM to hide the direct download link on the LVFS
        metadata = component.get_metadata()
        if 'LVFS::InhibitDownload' in metadata:
            md.inhibit_download = True

        # allows OEM to change the triplet (AA.BB.CCDD) to quad (AA.BB.CC.DD)
        if 'LVFS::VersionFormat' in metadata:
            md.version_format = metadata['LVFS::VersionFormat']

        fw.mds.append(md)

    return fw
Example #24
0
    def _add_appimage(self, appinfo):
        #Search in local store for the app
        sw_new = True
        app = appstream.App()
        app_orig = self.store.get_app_by_pkgname(appinfo['name'].lower())
        if not app_orig:
            app_orig = self.store.get_app_by_id(appinfo['name'].lower() +
                                                ".desktop")
        if app_orig:
            self._debug("Extending app %s" % appinfo['package'])
            if appinfo['icon']:
                #self._debug("Icon: %s"%appinfo['icon'])
                app = self._copy_app_from_appstream(app_orig,
                                                    app,
                                                    copy_icon=False)
            else:
                app = self._copy_app_from_appstream(app_orig,
                                                    app,
                                                    copy_icon=True)
            sw_new = False
        else:
            self._debug("Generating new %s" % appinfo['package'])
            pass
        if appinfo['name'].lower().endswith('.appimage'):
            app.set_id("appimagehub.%s" % appinfo['name'].lower())
            app.set_name("C", appinfo['name'])
        else:
            app.set_id("appimagehub.%s" % appinfo['name'].lower() +
                       '.appimage')
            app.set_name("C", appinfo['name'] + ".appimage")
        if appinfo['package'].lower().endswith('.appimage'):
            app.add_pkgname(appinfo['package'].lower())
        else:
            app.add_pkgname(appinfo['package'].lower() + ".appimage")
        app.set_id_kind = appstream.IdKind.DESKTOP

        if appinfo['license']:
            app.set_project_license(appinfo['license'])
        bundle = appstream.Bundle()
        bundle.set_kind(bundle.kind_from_string('APPIMAGE'))
        if appinfo['package'].endswith('.appimage'):
            bundle.set_id(appinfo['package'])
        else:
            bundle.set_id(appinfo['package'] + '.appimage')
        app.add_bundle(bundle)
        if 'keywords' in appinfo.keys():
            for keyword in appinfo['keywords']:
                app.add_keyword("C", keyword)
            if 'appimage' not in appinfo['keywords']:
                app.add_keyword("C", "appimage")
        else:
            app.add_keyword("C", "appimage")
        app.add_url(appstream.UrlKind.UNKNOWN, appinfo['installerUrl'])
        app.add_url(appstream.UrlKind.HOMEPAGE, appinfo['homepage'])
        if sw_new:
            app.add_keyword("C", appinfo['package'])
            if not appinfo['name'].endswith('.appimage'):
                app.set_name("C", appinfo['name'] + ".appimage")
            desc_header = ""  #This is an AppImage bundle. It hasn't been tested by our developers and comes from a 3rd party dev team. Please use it carefully."
            if appinfo['description']:
                for lang, desc in appinfo['description'].items():
                    desc = desc.replace('&', '&amp;')
                    description = "<p>%s</p><p>%s</p>" % (desc_header, desc)
                    summary = ' '.join(list(desc.split(' ')[:10]))
                    app.set_description(lang, description)
                    app.set_comment(lang, summary)
            else:
                description = "<p>%s</p>" % (desc_header)
                summary = ' '.join(list(desc_header.split(' ')[:8]))
                app.set_description("C", description)
                app.set_comment("C", summary)

            if 'categories' in appinfo.keys():
                for category in appinfo['categories']:
                    if category:
                        app.add_category(category)
                if 'appimage' not in appinfo['categories']:
                    app.add_category("appimage")
            else:
                app.add_category("appimage")
        if appinfo['icon']:
            icon = appstream.Icon()
            if self.icon_cache_enabled:
                icon.set_kind(appstream.IconKind.LOCAL)
                icon_fn = self._download_file(appinfo['icon'], appinfo['name'],
                                              self.icons_dir)
                icon.set_filename(icon_fn)
            else:
                icon.set_kind(appstream.IconKind.REMOTE)
                icon.set_name(pkg.get_icon())
                icon.set_url(pkg.get_icon())
            app.add_icon(icon)
        if appinfo['thumbnails']:
            screenshot = appstream.Screenshot()
            img = appstream.Image()
            if not appinfo['thumbnails'][0].startswith('http'):
                appinfo['screenshot'] = appinfo['thumbnails'][0]
                appinfo[
                    'screenshot'] = "https://appimage.github.io/database/%s" % appinfo[
                        'screenshot']
            img.set_kind(appstream.ImageKind.SOURCE)
            img.set_url(appinfo['screenshot'])
            screenshot.add_image(img)
            app.add_screenshot(screenshot)
        #Adds the app to the store
        self.apps_for_store.put(app)
        xml_path = '%s/%s.xml' % (self.cache_xmls, app.get_id_filename())
        gioFile = Gio.File.new_for_path(xml_path)
        app.to_file(gioFile)
        #Fix some things in app_file...
        xml_file = open(xml_path, 'r', encoding='utf-8')
        xml_data = xml_file.readlines()
        xml_file.close()
        self._debug("fixing %s" % xml_path)
        try:
            xml_data[0] = xml_data[
                0] + "<components origin=\"%s\">\n" % app.get_origin()
            xml_data[-1] = xml_data[-1] + "\n" + "</components>"
        except:
            pass
        xml_file = open(xml_path, 'w')
        xml_file.writelines(xml_data)
        xml_file.close()
Example #25
0
	def _get_flatpak_catalogue(self):
		action="load"
		rebostPkgList=[]
		sections=[]
		progress=0
		inc=0
		flInst=''
		store=appstream.Store()
		store2=appstream.Store()
		#metadata=appstream.Metadata()
		try:
			#Get all the remotes, copy appstream to wrkdir
			flInst=Flatpak.get_system_installations()
			for installer in flInst:
				flRemote=installer.list_remotes()
				for remote in flRemote:
					srcDir=remote.get_appstream_dir().get_path()
					installer.update_appstream_sync(remote.get_name())
			#sections=self.snap_client.get_sections_sync()
		except Exception as e:
			print(e)
			#self._on_error("load",e)

		try:
			store.from_file(Gio.File.parse_name(os.path.join(srcDir,"appstream.xml")))
		except Exception as e:
			print(e)
			pass
		added=[]
		for pkg in store.get_apps():
			idx=pkg.get_id()
			idxList=idx.split(".")
			if len(idxList)>2:
				idxList[0]="org"
				idxList[1]="flathub"
				newId=".".join(idxList).lower()
			else:
				newId="org.flathub.{}".format(idx[-1])
			#pkg.set_id(newId)
			state="available"
			for installer in flInst:
				installed=False
				try:
					installed=installer.get_installed_ref(0,pkg.get_name())
				except:
					try:
						installed=installer.get_installed_ref(1,pkg.get_name())
					except:
						pass
				if installed:
					state="installed"
					break
			#flatpak has his own cache dir for icons so if present use it
			iconPath=''
			icon64=os.path.join(srcDir,"icons/64x64")
			icon128=os.path.join(srcDir,"icons/128x128")
			idx=idx.replace(".desktop","")
			if os.path.isfile(os.path.join(icon128,"{}.png".format(idx))):
				iconPath=os.path.join(icon128,"{}.png".format(idx))
			elif os.path.isfile(os.path.join(icon64,"{}.png".format(idx))):
				iconPath=os.path.join(icon64,"{}.png".format(idx))
			if iconPath!='':
				icon=appstream.Icon()
				icon.set_kind(appstream.IconKind.LOCAL)
				icon.set_filename(iconPath)
				pkg.add_icon(icon)
			add=False
			if not pkg.get_bundles():
				bundle=appstream.Bundle()
				bundle.set_id("{};amd64;{}".format(pkg.get_id(),state))
				bundle.set_kind(appstream.BundleKind.FLATPAK)
				pkg.add_bundle(bundle)
				add=True
			else:
				for bundle in pkg.get_bundles():
					bundle.set_id("{};amd64;{}".format(pkg.get_id(),state))
					bundle.set_kind(appstream.BundleKind.FLATPAK)
					add=True
			if add and pkg.get_id() not in added:
				try:
						#	if not (app.validate()):
					pkg.set_name("C",pkg.get_name().lower().replace(" ","_")+'.flatpak')
					pkg.add_pkgname(pkg.get_name())
					store2.add_app(pkg)
				#	else:
				#		pass
				#		print(app.validate())
				except:
					pass
				added.append(pkg.get_id())
		self._debug("Loaded flatpak metadata")
		return(store2)
Example #26
0
def render_plain(input_string):
    """ Render a plain version of the description, no markdown """
    plain = As.markup_convert_simple(input_string)
    plain = plain.replace("&quot;", "\"").replace("&apos;", "'").replace("&amp;", "&")
    return plain
Example #27
0
def load_as_app_from_appdata(appdata_file):
    app = AppStreamGlib.App()
    app.parse_file(appdata_file, AppStreamGlib.AppParseFlags.NONE)
    return app
Example #28
0
def test_markup(desc):
    m = AS.markup_convert_simple(desc)
    return m
Example #29
0
def test_markup(desc):
    m = AS.markup_convert(desc, -1, AS.MarkupConvertFormat.SIMPLE)
    return m
Example #30
0
def test_markup(desc):
    m = AS.markup_convert(desc, -1, AS.MarkupConvertFormat.SIMPLE)
    return m
Example #31
0
 def render_plain(self, input_string):
     """ Render a plain version of the description, no markdown """
     plain = As.markup_convert(input_string, -1,
                               As.MarkupConvertFormat.SIMPLE)
     plain = plain.replace("&quot;", "\"").replace("&apos;", "'")
     return plain
Example #32
0
 def render_plain(self, input_string):
     """ Render a plain version of the description, no markdown """
     plain = As.markup_convert(input_string, -1,
                               As.MarkupConvertFormat.SIMPLE)
     plain = plain.replace("&quot;", "\"")
     return plain