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

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

Added snap support. Minor changes

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