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

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

Added snap support. Minor changes

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