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

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

Implemented cache

File size: 6.6 KB
Line 
1import locale
2import gi
3gi.require_version('AppStreamGlib', '1.0')
4from gi.repository import AppStreamGlib as appstream
5
6class searchmanager:
7        def __init__(self):
8                self.locale=locale.getlocale()[0]
9                self.dbg=False
10                self.store=''
11                self.plugin_actions={'search':'*','list':'*','list_sections':'*','info':'*'}
12                self.precision=1
13                self.applist=[]
14                self.progress=0
15                self.result={}
16                self.result['data']={}
17                self.result['status']={}
18        #def __init__
19
20        def __call__(self):
21                return (self.applist)
22        #def __call__
23
24        def set_debug(self,dbg=True):
25                self.dbg=dbg
26                #self._debug ("Debug enabled")
27        #def set__debug
28
29        def _debug(self,msg=''):
30                if self.dbg:
31                        print ('DEBUG Search: %s'%msg)
32        #def _debug
33
34        def register(self):
35                return(self.plugin_actions)
36        #def register
37
38        def execute_action(self,appstreamStore,action,tokens,exact_match_for_search=False,max_results=0):
39                #self._debug("Executing action %s"%action)
40                #self._debug("Tokens: %s"%tokens)
41                self.progress=0
42                if type(tokens)==type([]):
43                        tokens=' '.join(tokens)
44                if type(tokens) is str:
45                        tokens=tokens.lower()
46                else:
47                        tokens=''
48                if len(tokens.split(' '))>1:
49                        if action=='search':
50                                #self._debug("Tokenizing search items")
51                                tokens=appstream.utils_search_tokenize(tokens)
52                        else:
53                                tokens=tokens.split(' ')
54                else:
55                        if len(tokens)>=1:
56                                tokens=[tokens]
57                        else:
58                                tokens=[]
59       
60                self.store=appstreamStore
61                self.result['status']={'status':-1,'msg':''}
62                self.result['data']=[]
63                if self.store:
64                        if action=='list':
65                                self._list_category(tokens,max_results)
66                        if action=='list_sections':
67                                self._list_sections()
68                        if (action=='search' or action=='info'):
69                                self._search_app(tokens,exact_match_for_search)
70                else:
71                        #self._debug("Search needs a store")
72                        pass
73                self.progress=100
74                return(self.result)
75        #def execute_action
76
77        def _set_status(self,status,msg=''):
78                self.result['status']={'status':status,'msg':msg}
79        #def _set_status
80
81        def set_precision(self,precision):
82                self.precision=precision
83        #def set_precision
84
85        def _search_app(self,tokens,exact_match):
86                #self._debug("Searching app "+str(tokens)+ " with exact_match="+str(exact_match))
87                applist=[]
88                app=None
89                if exact_match:
90                        app=self._app_exists(tokens[0])
91                if app:
92                        if type(app)==type([]):
93                                applist.extend(app)
94                        else:
95                                applist.append(app)
96#                       #self._debug("App direct match found: "+app.get_id())
97                if not exact_match:
98                        applist.extend(self._get_apps_by_match(tokens,applist))
99                        applist.extend(self._get_app_by_pkgname(tokens,applist))
100                applist=set(applist)
101                if len(applist):
102                        self._set_status(0)
103                else:
104                        self._set_status(1)
105                self.result['data']=applist
106                return(applist)
107        #def _search_app
108
109        def _list_sections(self):
110                applist=[]
111                categories={}
112                for app in self.store.get_apps():
113                        for cat in app.get_categories():
114                                if cat not in categories.keys():
115                                        categories[cat]=1
116                                else:
117                                        categories[cat]=categories[cat]+1
118                for section in categories:
119                        applist.append({str(section):categories[section]})
120                self.result['data']=applist
121                if len(applist):
122                        self._set_status(0)
123                else:
124                        self._set_status(1)
125                return(applist)
126        #def _list_sections
127
128        def _list_category(self,tokens=[],max_results=0):
129                applist=[]
130                #self._debug("tokens: "+str(tokens))
131                #self._debug("Max results: %s"%max_results)
132                if len(tokens)>=1:
133                        #self._debug("Searching category "+str(tokens))
134                        categories_set=set(tokens)
135                        apps_in_store=self.store.get_apps()
136                        count_apps=len(apps_in_store)
137                        self.progress=0
138                        inc=100/count_apps
139                        for app in apps_in_store:
140                                self.progress=self.progress+inc
141                                if 'categories_set' in locals():
142                                        try:
143                                                app_categories=[cat.lower() for cat in app.get_categories()]
144                                        except:
145                                                pass
146                                        app_categories_set=set(app_categories)
147                                        if categories_set.issubset(app_categories_set):
148                                                #self._debug("Found "+app.get_id())
149                                                applist.append(app)
150                                                if max_results and len(applist)==max_results:
151                                                        break
152                else:
153                        #self._debug("Loading all apps in store")
154                        applist=self.store.get_apps()
155                        categories_set=set(['snap','appimage'])
156                        applist_2=[]
157                        for app in applist:
158                                if 'categories_set' in locals():
159                                        try:
160                                                app_categories=[cat.lower() for cat in app.get_categories()]
161                                        except:
162                                                pass
163                                        app_categories_set=set(app_categories)
164                                        if not categories_set.issubset(app_categories_set):
165                                                applist_2.append(app)
166                                        else:
167                                                print("Removing %s"%app.get_pkgname())
168                        applist=applist_2
169                        if max_results:
170                                applist=applist[0:max_results]
171                #List only valid categories
172
173                self.result['data']=applist
174                if len(applist):
175                        self._set_status(0)
176                else:
177                        self._set_status(1)
178                return(applist)
179        #def _list_category
180
181        def _app_exists(self,app_name):
182                #self._debug("Trying direct match for "+app_name)
183                #id_matches defines how to search for an app
184                # %s -> app_name; zero-lliurex-%s -> app_name with zero-lliurex- prefix and so on...
185                id_matches=['%s','zero-lliurex-%s','%s.desktop']
186                app=None
187                for id_string in id_matches:
188                                #                       app=self.store.get_app_by_id_ignore_prefix(id_string%app_name)
189                        app=self.store.get_apps_by_id(id_string%app_name)
190                        if app:
191                                break
192                if not app:
193                #2.- Try exact match by pkgname
194                        app=self.store.get_app_by_pkgname(app_name)
195                #self._debug("App found %s"%app)
196                return(app)
197        #def _app_exists
198
199        def _get_apps_by_match(self,tokens,applist=[]):
200                #Add items with match >= self.precision
201                #self._debug("Searching app by fuzzy match")
202                if not applist:
203                        position=1
204                else:
205                        position=len(applist)+1
206                apps_in_store=self.store.get_apps()
207                if apps_in_store:
208                        tmp_app_dict={}
209                        count_apps=len(apps_in_store)
210                        self.progress=0
211                        inc=100.0/count_apps
212                        for app in apps_in_store:
213                                self.progress=self.progress+inc
214                                if app not in self.applist:
215                                        for token in tokens:
216                                                score=app.search_matches(token)
217                                                if score>=self.precision:
218                                                        if score in tmp_app_dict:
219                                                                tmp_app_dict[score].append(app)
220                                                        else:
221                                                                tmp_app_dict[score]=[app]
222                        fake_app=[]
223                        for match in sorted(tmp_app_dict.keys()):
224                                for app in tmp_app_dict[match]:
225                                        if app not in applist:
226                                                #self._debug("Adding app "+app.get_id() + " with score: "+str(match))
227                                                applist.insert(0,app)
228                return(applist)
229        #def _get_apps_by_match
230
231        def _get_app_by_pkgname(self,tokens,applist=[]):
232                if not applist:
233                        position=1
234                else:
235                        position=len(applist)+1
236                apps_in_store=self.store.get_apps()
237                if apps_in_store:
238                        count_apps=len(apps_in_store)
239                        self.progress=0
240                        inc=100.0/count_apps
241                        for app in apps_in_store:
242                                self.progress=self.progress+inc
243                                if app not in self.applist:
244                                        for token in tokens:
245                                                if app.get_pkgname_default()==token:
246                                                        applist.insert(1,app)
247
248                return(applist)
249        #def _get_app_by_pkgname
Note: See TracBrowser for help on using the repository browser.