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

Last change on this file was 8223, checked in by Juanma, 13 months ago

Implemented cache

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' #DEPRECATED
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._sanitize_store(store)
74                self.store=store
75                return(store)
76        #def load_store
77
78        def load_zmds_catalog(self,store): #DEPRECATED
79                if os.path.exists(self.zmd_store_dir):
80                        store=self._generic_file_load(self.zmd_store_dir,store)
81                return(store)
82        #def load_zmds_catalog(self)
83
84        def _generic_file_load(self,target_dir,store):
85                icon_dir='/usr/share/icons/hicolor/128x128'
86                files=os.listdir(target_dir)
87                for target_file in os.listdir(target_dir):
88                        if target_file.endswith('appdata.xml'):
89                                store_file=Gio.File.new_for_path(target_dir+'/'+target_file)
90                                #self._debug("Adding file %s/%s"%(target_dir,target_file))
91                                try:
92                                        store.from_file(store_file,icon_dir,None)
93                                except Exception as e:
94                                        #self._debug("Couldn't add file %s to store"%target_file)
95                                        #self._debug("Reason: %s"%e)
96                                        pass
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.add_app(lliurex_apps[app.get_id_filename()])
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                                pass
235                except Exception as e:
236                        #self._debug("Error processing blacklist: %s"%e)
237                        pass
238                finally:
239                        return(store)
240        #def _apply_blacklist
241
Note: See TracBrowser for help on using the repository browser.