source: lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/loadStore.py @ 7080

Last change on this file since 7080 was 7080, checked in by Juanma, 2 years ago

Load external appimages from file

File size: 7.7 KB
Line 
1import os
2import gi
3from gi.repository import Gio
4gi.require_version('AppStreamGlib', '1.0')
5from gi.repository import AppStreamGlib as appstream
6import subprocess
7import json
8import re
9import urllib
10import random
11import threading
12import time
13import datetime
14import gettext
15from bs4 import BeautifulSoup
16
17class loadstore:
18        def __init__(self):
19                self.dbg=False
20                self.plugin_actions={'load':'*'}
21                self.store=''
22                self.progress=0
23                self.error=0
24                self.zmd_store_dir='/var/lib/lliurexstore/zmds'
25                self.result={}
26                self.result['data']={}
27                self.result['status']={}
28        #def __init__
29
30        def set_debug(self,dbg=True):
31                self.dbg=dbg
32                self._debug ("Debug enabled")
33        #def set_debug
34
35        def _debug(self,msg=''):
36                if self.dbg:
37                        print ('DEBUG Load: %s'%msg)
38        #def _debug
39
40        def register(self):
41                return(self.plugin_actions)
42        #def register
43
44        def execute_action(self,action,store=None,loadBundles=False):
45                self.progress=0
46                if store:
47                        self.store=store
48                else:
49                        self.store=appstream.Store()
50                if action=='load':
51                        self._load_store(self.store)
52                if action=='load_bundles':
53                        self._load_store(self.store,loadBundles=True)
54                self.result['data']=self.store
55                self.progress=100
56                return(self.result)
57        #def execute_action
58
59        def get_error(self):
60                return (self.error)
61        #def get_error
62
63        def _load_store(self,store,loadBundles=False):
64                icon_dir='/usr/share/icons/hicolor/128x128'
65                flags=[appstream.StoreLoadFlags.APP_INFO_SYSTEM,appstream.StoreLoadFlags.APP_INSTALL,appstream.StoreLoadFlags.APP_INFO_USER,appstream.StoreLoadFlags.DESKTOP,appstream.StoreLoadFlags.APPDATA,appstream.StoreLoadFlags.ALLOW_VETO]
66                for flag in flags:
67                        try:
68                                self._debug("Loading "+str(flag))
69                                store.load(flag)
70                        except:
71                                print ("Failed to load"+str(flag))
72                                pass
73                store=self.load_zmds_catalog(store)
74                store=self._sanitize_store(store)
75                self.store=store
76                return(store)
77        #def load_store
78
79        def load_zmds_catalog(self,store):
80                if os.path.exists(self.zmd_store_dir):
81                        store=self._generic_file_load(self.zmd_store_dir,store)
82                return(store)
83        #def load_zmds_catalog(self)
84
85        def _generic_file_load(self,target_dir,store):
86                icon_dir='/usr/share/icons/hicolor/128x128'
87                files=os.listdir(target_dir)
88                for target_file in os.listdir(target_dir):
89                        if target_file.endswith('appdata.xml'):
90                                store_file=Gio.File.new_for_path(target_dir+'/'+target_file)
91                                self._debug("Adding file %s/%s"%(target_dir,target_file))
92                                try:
93                                        store.from_file(store_file,icon_dir,None)
94                                except Exception as e:
95                                        self._debug("Couldn't add file %s to store"%target_file)
96                                        self._debug("Reason: %s"%e)
97                return(store)
98       
99        def _parse_desktop(self,store): #DEPRECATED. Loads the apps from the available desktop files
100                desktop_dir='/usr/share/applications'
101                applist=[]
102                for desktop_file in os.listdir(desktop_dir):
103                        if desktop_file.endswith('desktop'):
104                                a=appstream.App()
105                                try:
106                                        a.parse_file(desktop_dir+'/'+desktop_file,16)
107                                        a.set_priority(0)
108                                        for veto in a.get_vetos():
109                                                a.remove_veto(veto)
110                                        store.add_app(a)
111                                        self._debug("Adding app from desktop %s"%desktop_file)
112                                except:
113                                        pass
114                return(store)
115        #def _parse_desktop
116
117        def _sanitize_store(self,store):
118                applist=store.get_apps()
119                tmp_store_apps={}
120                lliurex_apps={}
121                zmd_apps=[]
122                for app in applist:
123                        #Zomandos get max priority
124                        if app.has_category('Zomando'):
125                                self._debug("Prioritize zmd %s"%app.get_id())
126                                app.set_priority(400)
127                                lliurex_apps.update({app.get_id_filename():app})
128                                id_app=str(app.get_id_filename()).replace('zero-lliurex-','')
129                                zmd_apps.append(id_app)
130                        #Prioritize Lliurex apps
131                        elif app.has_category('Lliurex'):
132                                self._debug("Prioritize app %s"%app.get_id())
133                                app.set_priority(200)
134                                lliurex_apps.update({app.get_id_filename():app})
135                        elif str(app.get_origin()).find('lliurex')>=0:
136                                self._debug("Prioritize app %s"%app.get_id())
137                                app.set_priority(100)
138                                lliurex_apps.update({app.get_id_filename():app})
139                        else:
140                                app.set_priority(0)
141                                if app.get_id_filename() in lliurex_apps.keys():
142                                        self._debug("Mergin app %s as is in LliureX"%app.get_id())
143                                        lliurex_apps[app.get_id_filename()].subsume_full(app,appstream.AppSubsumeFlags.BOTH_WAYS)
144                                        store.remove_app(app)
145                        #Remove apps whitout pkgname
146                        if not app.get_pkgnames():
147                                store.remove_app(app)
148                        #Remove add-on apps (as are included in the main packages)
149                        if app.get_kind()==appstream.AppKind.ADDON:
150                                self._debug("Removed addon %s"%app.get_pkgnames())
151                                store.remove_app(app)
152                        #Remove duplicated apps
153                        #Unlike gnome-store we'll try to compare the info of the package in order of discard only the "part-of" packages
154                        pkg=app.get_pkgname_default()
155                        if pkg in tmp_store_apps.keys():
156                                fn=app.get_id_no_prefix()
157                                self._debug("Comparing %s with %s"%(fn,tmp_store_apps[pkg]['fn']))
158                                if fn != tmp_store_apps[pkg]['fn']:
159                                        if fn != pkg and ".desktop" not in fn:
160                                                self._debug("Removed duplicated %s"%app.get_id())
161                                                store.remove_app(app)
162                                        else:
163                                                self._debug("Removed duplicated %s"%tmp_store_apps[pkg]['app'].get_id())
164                                                store.remove_app(tmp_store_apps[pkg]['app'])
165                                                tmp_store_apps.update({pkg:{'fn':app.get_id_no_prefix(),'app':app}})
166                        elif pkg:
167#                               self._debug("Adding "+app.get_id_filename()+" to uniq dict")
168                                tmp_store_apps.update({pkg:{'fn':app.get_id_filename(),'app':app}})
169                #Delete zomando-related debs
170                store=self._purge_zomandos(zmd_apps,store)
171                #Check the blacklist
172                store=self._apply_blacklist(store)
173                return (store)
174        #def _sanitize_store
175
176        def _purge_zomandos(self,zmd_apps,store):
177                for zmd_id in zmd_apps:
178                        self._debug("Searching debs related to %s"%zmd_id)
179                        purge_list=store.get_apps_by_id(zmd_id)
180                        purge_list.extend(store.get_apps_by_id(zmd_id+".desktop"))
181                        for purge_app in purge_list:
182                                if purge_app:
183                                        if not purge_app.has_category('Zomando'):
184                                                self._debug("Removed related zomando app %s"%purge_app.get_id())
185                                                store.remove_app(purge_app)
186                return(store)
187        #def _purge_zomandos
188
189        def _apply_blacklist(self,store):
190                try:
191                        flavour=subprocess.check_output(["lliurex-version","-f"]).rstrip()
192                        flavour=flavour.decode("utf-8")
193                        if flavour=='None':
194                                self._debug("Unknown flavour. Switching to desktop")
195                                flavour='desktop'
196                except (subprocess.CalledProcessError,FileNotFoundError) as e:
197                                self._debug("Running on a non Lliurex host")
198                                flavour='desktop'
199                try:
200                        if os.path.isfile('/usr/share/lliurex-store/files/blacklist.json'):
201                                blFile=open('/usr/share/lliurex-store/files/blacklist.json').read()
202                                blacklist=json.loads(blFile)
203                                blacklist_apps=[]
204                                if flavour in blacklist:
205                                        blacklist_apps=blacklist[flavour]
206                                if "all" in blacklist:
207                                        blacklist_apps.extend(blacklist["all"])
208                                blacklist_re=[]
209                                for blacklist_app in blacklist_apps:
210                                        self._debug("Blacklisted app: "+blacklist_app)
211                                        re_result=re.search('([^a-zA-Z0-9_-])',blacklist_app)
212                                        if re_result:
213                                                if blacklist_app[0]=='*':
214                                                        blacklist_app='.'+blacklist_app
215                                                blacklist_re.append("("+blacklist_app+")")
216                                        else:
217                                                app=store.get_app_by_pkgname(blacklist_app)
218                                                if app:
219                                                        self._debug("Removed "+str(app))
220                                                        store.remove_app(app)
221                                                else:
222                                                        self._debug("App %s from blacklist not found in store. Assigned to RE blacklist"%blacklist_app)
223                                                        blacklist_re.append("("+blacklist_app+")")
224                                if blacklist_re:
225                                        self._debug("Attempting to remove apps by RE match")
226                                        for app in store.get_apps():
227                                                for blacklist_app in blacklist_re:
228                                                        re_result=re.search(blacklist_app,app.get_id())
229                                                        if re_result:
230                                                                store.remove_app(app)
231                                                                self._debug("Removed %s as matches with %s"%(app.get_id(),blacklist_app))
232                        else:
233                                self._debug('No blacklist to check')
234                except Exception as e:
235                        self._debug("Error processing blacklist: %s"%e)
236                finally:
237                        return(store)
238        #def _apply_blacklist
239
Note: See TracBrowser for help on using the repository browser.