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

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

cli improvements

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