Changeset 7432
- Timestamp:
- Jun 13, 2018, 1:42:39 PM (18 months ago)
- Location:
- lliurex-store/trunk/fuentes
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
lliurex-store/trunk/fuentes/debian/changelog
r7383 r7432 1 lliurex-store (0.5.4.6) xenial; urgency=medium 2 3 * Fix wrong update 4 5 -- Juanma Navarro Mañez <juanma1980@gmail.com> Wed, 13 Jun 2018 13:41:28 +0200 6 1 7 lliurex-store (0.5.4.5) xenial; urgency=high 2 8 -
lliurex-store/trunk/fuentes/lliurex-store-gui/usr/share/lliurex-store/lliurex-store-gui/DetailsBox.py
r7096 r7432 515 515 516 516 def open_clicked(self,widget): 517 if self.core.main_window.current_pkg[" bundle"]=='snap':518 snap=self.core.main_window.current_pkg["name"] 517 if self.core.main_window.current_pkg["name"].endswith('.snap'): 518 snap=self.core.main_window.current_pkg["name"].replace('.snap','') 519 519 if os.path.exists("/snap/bin/%s"%snap): 520 520 os.system("/snap/bin/%s"%snap) 521 elif self.core.main_window.current_pkg["bundle"]=='appimage': 522 appimg=self.core.main_window.current_pkg["package"] 523 if os.path.exists(os.getenv("HOME")+"/.lliurex-store/appimg/%s"%appimg): 524 os.system(os.getenv("HOME")+"/.lliurex-store/appimg/%s"%appimg) 521 elif self.core.main_window.current_pkg["name"].endswith('.appimage'): 522 appimg=self.core.main_window.current_pkg["name"].lower() 523 if os.path.exists(os.getenv("HOME")+"/.local/bin/%s"%appimg): 524 os.system(os.getenv("HOME")+"/.local/bin/%s"%appimg) 525 elif 'Zomando' in self.core.main_window.current_pkg["categories"]: 526 zmd=self.core.main_window.current_pkg["id"]+".zmd" 527 if os.path.exists("/usr/share/zero-center/zmds/%s"%zmd): 528 os.system("pe /usr/share/zero-center/zmds/%s"%zmd) 525 529 else: 526 530 desktop=self.core.main_window.current_pkg["id"] -
lliurex-store/trunk/fuentes/lliurex-store-gui/usr/share/lliurex-store/lliurex-store-gui/ResourcesManager.py
r7092 r7432 5 5 import time 6 6 import json 7 7 import re 8 8 import gi 9 9 gi.require_version('Gtk', '3.0') … … 43 43 if os.path.isfile(icon): 44 44 return(icon) 45 46 if icon.startswith("http"): 47 cache_dir=os.getenv("HOME")+"/.cache/lliurex-store/icons" 48 icon_name=icon.split("/")[-1] 49 if not os.path.exists(cache_dir): 50 os.makedirs(cache_dir) 51 if os.path.isfile(cache_dir+"/"+icon_name): 52 return(cache_dir+"/"+icon_name) 53 icon_file=cache_dir+"/"+icon_name 54 url=icon 55 try: 56 req=urllib2.Request(url,headers=HEADER) 57 res=urllib2.urlopen(req) 58 x=open(icon_file,"wb") 59 x.write(res.read()) 60 x.close() 61 except Exception as e: 62 icon_file='' 63 finally: 64 return(icon_file) 65 45 66 46 67 component=pkg_info["component"] … … 55 76 for dist in ["xenial-updates","xenial-security","xenial"]: 56 77 # "64x64/" is included in pkg_info["icon"] 57 if "64x64/" not in icon: 78 # if "64x64/" not in icon: 79 if not re.match("[0-9]*x[0-9]*\/",icon): 58 80 icon="64x64/" + icon 59 81 if debian_name+"_"+debian_name not in icon: 60 82 icon=icon.replace(debian_name,debian_name+"_"+debian_name) 83 if not icon.endswith(".png"): 84 icon=icon+'.png' 61 85 if "pyromaths" in icon: 62 86 icon="64x64/pyromaths_pyromaths.png" … … 64 88 ret_icon=self.icons_path+"%s/%s"%(component,icon) 65 89 if os.path.exists(ret_icon): 66 67 90 return ret_icon 91 else: 92 ret_icon=ret_icon.replace("64x64","128x128") 93 if os.path.exists(ret_icon): 94 return ret_icon 95 icon="64x64/" + pkg_info['icon'] 96 ret_icon=self.icons_path+"%s/%s"%(component,icon) 97 if os.path.exists(ret_icon): 98 return ret_icon 99 else: 100 #Last attempt 101 pkg_id=pkg_info['id'].split('.')[-2] 102 icon="64x64/%s_%s.png"%(debian_name,pkg_id) 103 ret_icon=self.icons_path+"%s/%s"%(component,icon) 104 if os.path.exists(ret_icon): 105 return ret_icon 106 else: 107 #Unaccurate icon search... 108 for icon_file in os.listdir(self.icons_path+"/"+component+"/64x64/"): 109 if re.search("^.*"+pkg_info['icon']+".*\.png",icon_file): 110 ret_icon=self.icons_path+"%s/64x64/%s"%(component,icon_file) 111 return ret_icon 112 68 113 69 114 ret_icon=self.package_icon -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/appImageManager.py
r7143 r7432 1 1 #The name of the main class must match the file name in lowercase 2 import re 2 3 import urllib 3 4 from urllib.request import Request … … 6 7 import json 7 8 import os 8 from subprocess import call9 9 import sys 10 10 import threading 11 from bs4 import BeautifulSoup 11 import queue 12 import time 12 13 import random 13 import time14 14 import gi 15 15 from gi.repository import Gio 16 16 gi.require_version('AppStreamGlib', '1.0') 17 17 from gi.repository import AppStreamGlib as appstream 18 from bs4 import BeautifulSoup 19 #from subprocess import call 18 20 19 21 class appimagemanager: 20 22 def __init__(self): 21 self.dbg= False23 self.dbg=True 22 24 self.progress=0 23 25 self.partial_progress=0 … … 26 28 self.result['data']={} 27 29 self.result['status']={} 28 self.conf_dir=os.getenv("HOME")+"/.cache/lliurex-store" 29 self.bundles_dir=self.conf_dir+"/bundles" 30 self.cache_dir=os.getenv("HOME")+"/.cache/lliurex-store" 31 self.icons_dir=self.cache_dir+"/icons" 32 self.bundles_dir=self.cache_dir+"/xmls/appimage" 30 33 self.bundle_types=['appimg'] 31 self.appimage_dir=os.getenv("HOME")+"/.local/bin/" 34 # self.appimage_dir=os.getenv("HOME")+"/.lliurex-store/appimg" 35 self.appimage_dir=os.getenv("HOME")+"/.local/bin" 32 36 #To get the description of an app we must go to a specific url defined in url_info. 33 37 #$(appname) we'll be replaced with the appname so the url matches the right one. 34 38 #If other site has other url naming convention it'll be mandatory to define it with the appropiate replacements 35 self.repos={' probono':{'url':'https://dl.bintray.com/probono/AppImages', 'url_info':'https://bintray.com/probono/AppImages/$(appname)'}}36 #Appimges not stored in a repo must be listed here, providing the download url and the info url (if there's any)39 self.repos={'appimagehub':{'type':'json','url':'https://appimage.github.io/feed.json','url_info':''}} 40 #Appimges not stored in a repo must be listed in this file, providing the download url and the info url (if there's any) 37 41 self.external_appimages="/usr/share/lliurex-store/files/external_appimages.json" 42 self.locale=['ca_ES@valencia','ca@valencia','qcv','ca','ca_ES','es_ES','es','en_US','en_GB','en','C'] 38 43 self.disabled=False 39 self.count=0 44 self.icon_cache_enabled=True 45 self.image_cache_enabled=True 46 self.apps_for_store=queue.Queue() 40 47 #def __init__ 41 48 … … 61 68 else: 62 69 self.store=appstream.Store() 70 self.appimage_store=appstream.Store() 63 71 self.progress=0 64 72 self.result['status']={'status':-1,'msg':''} 65 self.result['data']='' 73 self.result['data']=[] 74 self.threads=[] 66 75 dataList=[] 67 76 if self.disabled: … … 71 80 self._chk_installDir() 72 81 if action=='load': 73 self.result['data']=self._load_appimage_store(self.store) 82 self._load_appimage_store() 83 # self.result['data']=self._load_appimage_store() 84 #wait till threads end (if any) 85 self._debug("Ending threads...") 86 # for app in self.apps_for_store: 87 for th in threading.enumerate(): 88 if th.is_alive(): 89 try: 90 th.join(5) 91 except: 92 pass 93 while not self.apps_for_store.empty(): 94 app=self.apps_for_store.get() 95 self.store.add_app(app) 96 self.result['data']=self.store 74 97 else: 75 98 for app_info in applist: … … 81 104 if action=='pkginfo': 82 105 dataList.append(self._get_info(app_info)) 83 self.progress+=int(self.partial_progress/len(applist)) 106 self.progress+=int(self.partial_progress/len(applist))-1 84 107 self.result['data']=list(dataList) 85 108 self.progress=100 … … 118 141 self._set_status(4) 119 142 else: 120 # appimage_url=self.repository_url+'/'+app_info['package']121 appimage_url=app_info[' homepage']+'/'+app_info['package']143 # appimage_url=app_info['installerUrl']+'/'+app_info['package'] 144 appimage_url=app_info['channel_releases']['appimage'][0] 122 145 self._debug("Downloading "+appimage_url) 123 146 dest_path=self.appimage_dir+'/'+app_info['package'] … … 163 186 #def _remove_appimage 164 187 165 def _get_info(self,app_info): 166 app_info['state']='available' 167 if os.path.isfile(self.appimage_dir+'/'+app_info['package']): 168 app_info['state']='installed' 169 #Get size 170 appimage_url=app_info['homepage']+'/'+app_info['package'] 171 dest_path=self.appimage_dir+'/'+app_info['package'] 172 if appimage_url: 173 try: 174 with urllib.request.urlopen(appimage_url) as response: 175 app_info['size']=(response.info()['Content-Length']) 176 except: 177 app_info['size']=0 178 self._set_status(0) 179 self.partial_progress=100 180 return(app_info) 181 #def _get_info 182 183 def _load_appimage_store(self,store): 184 self._download_bundles_catalogue() 188 def _load_appimage_store(self,store=None): 189 self._get_bundles_catalogue() 185 190 if os.path.exists(self.bundles_dir): 186 191 for bundle_type in self.bundle_types: … … 207 212 #def _generic_file_load 208 213 209 def _download_bundles_catalogue(self): 210 CURSOR_UP='\033[F' 211 ERASE_LINE='\033[K' 212 content='' 214 def _get_bundles_catalogue(self): 213 215 applist=[] 214 progress_bar="#" 215 self.descriptions_dict={} 216 appdict={} 216 217 all_apps=[] 217 218 outdir=self.bundles_dir+'/appimg/' 218 219 #Load repos 219 220 for repo_name,repo_info in self.repos.items(): 220 if self._chk_bundle_dir(outdir): 221 self._debug("Fetching repo %s"%repo_info['url']) 222 ## print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r") 223 ## progress_bar=progress_bar+"#" 224 ## print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r") 225 applist=self._generate_applist(self._fetch_repo(repo_info['url']),repo_name) 226 ## progress_bar=progress_bar+"##" 227 ## print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r") 228 self._debug("Processing info...") 229 self._th_generate_xml_catalog(applist,outdir,repo_info['url_info'],repo_info['url'],repo_name,progress_bar) 230 self._debug("Fetched repo "+repo_info['url']) 231 all_apps.extend(applist) 232 else: 221 if not os.path.isdir(self.bundles_dir): 222 try: 223 os.makedirs(self.bundles_dir) 224 except: 233 225 self._debug("appImage catalogue could not be fetched: Permission denied") 226 self._debug("Fetching repo %s"%repo_info['url']) 227 if repo_info['type']=='json': 228 applist=self._process_appimage_json(self._fetch_repo(repo_info['url']),repo_name) 229 230 self._debug("Fetched repo "+repo_info['url']) 231 self._th_generate_xml_catalog(applist,outdir,repo_info['url_info'],repo_info['url'],repo_name) 232 all_apps.extend(applist) 234 233 #Load external apps 235 234 for app_name,app_info in self._get_external_appimages().items(): 236 if self._chk_bundle_dir(outdir): 237 appimage=app_info['url'].split('/')[-1] 238 appimage_url='/'.join(app_info['url'].split('/')[0:-1]) 235 if os.path.isdir(self.bundles_dir): 236 appinfo=self._init_appinfo() 237 appinfo['name']=app_info['url'].split('/')[-1] 238 appinfo['package']=app_info['url'].split('/')[-1] 239 appinfo['homepage']='/'.join(app_info['url'].split('/')[0:-1]) 239 240 self._debug("Fetching external appimage %s"%app_info['url']) 240 app list=[appimage]241 self._debug("Processing info...")242 self._th_generate_xml_catalog(applist,outdir,app_info['url_info'],app image_url,app_name,progress_bar)241 appinfo['bundle']='appimage' 242 applist=[appinfo] 243 self._th_generate_xml_catalog(applist,outdir,app_info['url_info'],app_info['url'],app_name) 243 244 self._debug("Fetched appimage "+app_info['url']) 244 245 all_apps.extend(applist) 245 246 else: 246 247 self._debug("External appImage could not be fetched: Permission denied") 247 248 249 ## print (("Removing old entries...")) 250 self._clean_bundle_catalogue(all_apps,outdir) 248 self._debug("Removing old entries...") 249 # self._clean_bundle_catalogue(all_apps,outdir) 251 250 return(True) 252 #def _download_bundles_catalogue 253 251 #def _get_bundles_catalogue 252 253 def _fetch_repo(self,repo): 254 req=Request(repo, headers={'User-Agent':'Mozilla/5.0'}) 255 with urllib.request.urlopen(req) as f: 256 content=(f.read().decode('utf-8')) 257 258 return(content) 259 #def _fetch_repo 260 254 261 def _get_external_appimages(self): 255 262 external_appimages={} … … 262 269 self._debug(external_appimages) 263 270 return external_appimages 264 271 #def _get_external_appimages 272 273 def _process_appimage_json(self,data,repo_name): 274 applist=[] 275 json_data=json.loads(data) 276 if 'items' in json_data.keys(): 277 for appimage in json_data['items']: 278 appinfo=self._th_process_appimage(appimage) 279 if appinfo: 280 applist.append(appinfo) 281 return (applist) 282 #_process_appimage_json 283 284 def _th_process_appimage(self,appimage): 285 appinfo=None 286 releases=[] 287 if 'links' in appimage.keys(): 288 if appimage['links']: 289 appinfo=self.load_json_appinfo(appimage) 290 #Deprecated. appImage releases will be load on the info stage 291 # releases=self._get_releases_from_json(appimage) 292 # if releases: 293 # appinfo['releases']=releases 294 # for release in releases: 295 # #Release has the direct download url 296 # tmp_release=release.split('/') 297 # tmp_appinfo=appinfo.copy() 298 # rel_number=tmp_release[-2] 299 # rel_name=tmp_release[-1].lower().replace('.appimage','') 300 # self._debug("Release: %s"%release) 301 # tmp_appinfo['name']=rel_name 302 # tmp_appinfo['package']=tmp_release[-1] 303 # tmp_appinfo['homepage']='/'.join(tmp_release[0:-1]) 304 # self.queue.put(tmp_appinfo) 305 return(appinfo) 306 #def _th_process_appimage 307 308 def load_json_appinfo(self,appimage): 309 appinfo=self._init_appinfo() 310 appinfo['name']=appimage['name'] 311 appinfo['package']=appimage['name'] 312 if 'license' in appimage.keys(): 313 appinfo['license']=appimage['license'] 314 appinfo['summary']='' 315 if 'description' in appimage.keys(): 316 appinfo['description']=appimage['description'] 317 if 'categories' in appimage.keys(): 318 appinfo['categories']=appimage['categories'] 319 if 'icon' in appimage.keys(): 320 appinfo['icon']=appimage['icon'] 321 if 'icons' in appimage.keys(): 322 self._debug("Loading icon %s"%appimage['icons']) 323 if appimage['icons']: 324 self._debug("Loading icon %s"%appimage['icons'][0]) 325 appinfo['icon']=appimage['icons'][0] 326 if 'screenshots' in appimage.keys(): 327 appinfo['thumbnails']=appimage['screenshots'] 328 if 'links' in appimage.keys(): 329 if appimage['links']: 330 for link in appimage['links']: 331 if 'url' in link.keys() and link['type']=='Download': 332 appinfo['installerUrl']=link['url'] 333 if 'authors' in appimage.keys(): 334 if appimage['authors']: 335 for author in appimage['authors']: 336 if 'url' in author.keys(): 337 self._debug("Author: %s"%author['url']) 338 appinfo['homepage']=author['url'] 339 else: 340 appinfo['homepage']='/'.join(appinfo['installerUrl'].split('/')[0:-1]) 341 appinfo['bundle']=['appimage'] 342 return appinfo 343 #def load_json_appinfo 344 345 def _th_generate_xml_catalog(self,applist,outdir,info_url,repo,repo_name): 346 maxconnections = 2 347 threads=[] 348 semaphore = threading.BoundedSemaphore(value=maxconnections) 349 random_applist = list(applist) 350 random.shuffle(random_applist) 351 for app in applist: 352 th=threading.Thread(target=self._th_write_xml, args = (app,outdir,info_url,repo,repo_name,semaphore)) 353 threads.append(th) 354 th.start() 355 #def _th_generate_xml_catalog 356 357 def _th_write_xml(self,appinfo,outdir,info_url,repo,repo_name,semaphore): 358 semaphore.acquire() 359 self._add_appimage(appinfo) 360 semaphore.release() 361 #def _th_write_xml 362 363 # def _add_appimage(self,appinfo,repo_info): 364 def _add_appimage(self,appinfo): 365 #Search in local store for the app 366 sw_new=False 367 app=appstream.App() 368 app_orig=self.store.get_app_by_pkgname(appinfo['package'].lower()) 369 if not app_orig: 370 app_orig=self.store.get_app_by_id(appinfo['package'].lower()+".desktop") 371 if app_orig: 372 self._debug("Extending app %s"%appinfo['package']) 373 app=self._copy_app_from_appstream(app_orig,app) 374 else: 375 self._debug("Generating new %s"%appinfo['package']) 376 app.set_id("appimagehub.%s"%appinfo['name'].lower()+'.appimage') 377 app.set_id_kind=appstream.IdKind.DESKTOP 378 sw_new=True 379 380 icon=appstream.Icon() 381 screenshot=appstream.Screenshot() 382 app.set_name("C",appinfo['name']+".appimage") 383 app.add_pkgname(appinfo['package'].lower()+".appimage") 384 if appinfo['license']: 385 app.set_project_license(appinfo['license']) 386 bundle=appstream.Bundle() 387 bundle.set_kind(bundle.kind_from_string('APPIMAGE')) 388 bundle.set_id(appinfo['package']+'.appimage') 389 # if app_orig: 390 # app_orig.add_bundle(bundle) 391 app.add_bundle(bundle) 392 app.add_keyword("C","appimage") 393 app.add_category("appimage") 394 app.add_url(appstream.UrlKind.UNKNOWN,appinfo['installerUrl']) 395 app.add_url(appstream.UrlKind.HOMEPAGE,appinfo['homepage']) 396 if sw_new: 397 app.add_keyword("C",appinfo['package']) 398 app.set_name("C",appinfo['name']+".appimage") 399 description="This is an AppImage bundle of app %s. It hasn't been tested by our developers and comes from a 3rd party dev team. Please use it carefully.\n%s"%(appinfo['name'],appinfo['description']) 400 summary=' '.join(list(description.split(' ')[:8])) 401 if len(description.split(' '))>8: 402 summary+="... " 403 app.set_description("C",description) 404 app.set_comment("C",summary) 405 for category in appinfo['categories']: 406 app.add_category(category) 407 if appinfo['icon']: 408 if self.icon_cache_enabled: 409 icon.set_kind(appstream.IconKind.LOCAL) 410 icon.set_name(self._download_file(appinfo['icon'],appinfo['name'],self.icons_dir)) 411 else: 412 icon.set_kind(appstream.IconKind.REMOTE) 413 icon.set_name(pkg.get_icon()) 414 icon.set_url(pkg.get_icon()) 415 app.add_icon(icon) 416 if appinfo['thumbnails']: 417 img=appstream.Image() 418 if not appinfo['thumbnails'][0].startswith('http'): 419 appinfo['screenshot']=appinfo['thumbnails'][0] 420 appinfo['screenshot']="https://appimage.github.io/database/%s"%appinfo['screenshot'] 421 img.set_kind(appstream.ImageKind.SOURCE) 422 img.set_url(appinfo['screenshot']) 423 screenshot.add_image(img) 424 app.add_screenshot(screenshot) 425 #Adds the app to the store 426 # self._debug("Adding %s"%appinfo['package']) 427 self.apps_for_store.put(app) 428 if not os.path.isfile(self.bundles_dir+'/'+app.get_id_filename()): 429 gioFile=Gio.File.new_for_path('%s/%s.xml'%(self.bundles_dir,app.get_id_filename())) 430 app.to_file(gioFile) 431 #def _add_appimage 432 433 def _copy_app_from_appstream(self,app_orig,app): 434 app.set_id("appimage."+app_orig.get_id()) 435 for category in app_orig.get_categories(): 436 app.add_category(category) 437 for screenshot in app_orig.get_screenshots(): 438 app.add_screenshot(screenshot) 439 for icon in app_orig.get_icons(): 440 app.add_icon(icon) 441 for localeItem in self.locale: 442 if app_orig.get_name(localeItem): 443 app.set_name(localeItem,app_orig.get_name(localeItem)+".appimage") 444 if app_orig.get_description(localeItem): 445 app.set_description(localeItem,app_orig.get_description(localeItem)) 446 if app_orig.get_comment(localeItem): 447 app.set_comment(localeItem,app_orig.get_comment(localeItem)) 448 app.set_origin(app_orig.get_origin()) 449 return app 450 451 def _clean_bundle_catalogue(self,applist,outdir): 452 xml_files_list=[] 453 applist=[item.lower() for item in applist] 454 for xml_file in os.listdir(outdir): 455 if xml_file.endswith('appdata.xml'): 456 xml_files_list.append(xml_file.lower().replace('appdata.xml','appimage')) 457 458 if xml_files_list: 459 xml_discard_list=list(set(xml_files_list).difference(applist)) 460 for discarded_file in xml_discard_list: 461 os.remove(outdir+'/'+discarded_file.replace('appimage','appdata.xml')) 462 #def _clean_bunlde_catalogue 463 464 def _download_file(self,url,app_name,dest_dir): 465 # target_file=self.icons_folder+'/'+app_name+".png" 466 target_file=dest_dir+'/'+app_name+".png" 467 if not url.startswith('http'): 468 url="https://appimage.github.io/database/%s"%url 469 if not os.path.isfile(target_file): 470 # shutil.copy("/usr/share/icons/hicolor/128x128/apps/lliurex-store.png",target_file) 471 # if not os.fork(): 472 if not os.path.isfile(target_file): 473 self._debug("Downloading %s to %s"%(url,target_file)) 474 try: 475 with urllib.request.urlopen(url) as response, open(target_file, 'wb') as out_file: 476 bf=16*1024 477 acumbf=0 478 file_size=int(response.info()['Content-Length']) 479 while True: 480 if acumbf>=file_size: 481 break 482 shutil.copyfileobj(response, out_file,bf) 483 acumbf=acumbf+bf 484 st = os.stat(target_file) 485 except Exception as e: 486 self._debug("Unable to download %s"%url) 487 self._debug("Reason: %s"%e) 488 target_file='' 489 # os._exit(0) 490 return(target_file) 491 #def _download_file 492 265 493 def _chk_bundle_dir(self,outdir): 266 494 msg_status=True … … 273 501 return(os.access(outdir,os.W_OK|os.R_OK|os.X_OK|os.F_OK)) 274 502 #def _chk_bundle_dir 275 276 def _fetch_repo(self,repo): 277 req=Request(repo, headers={'User-Agent':'Mozilla/5.0'}) 278 with urllib.request.urlopen(req) as f: 279 content=(f.read().decode('utf-8')) 280 281 return(content) 282 #def _fetch_repo 283 284 def _generate_applist(self,content,repo_name): 285 garbage_list=[] 286 applist=[] 287 #webscrapping for probono repo 288 if repo_name=='probono': 289 garbage_list=content.split(' ') 290 for garbage_line in garbage_list: 291 if garbage_line.endswith('AppImage"'): 292 app=garbage_line.replace('href=":','') 293 applist.append(app.replace('"','')) 294 #Example of a webscrapping from another site 295 # if repo_name='other_repo_name': 296 # for garbage_line in garbage_list: 297 # if garbage_line.startswith('file="'): 298 # if 'appimage' in garbage_line: 299 # app=garbage_line.replace('file="','') 300 # app=app.replace('\n','') 301 # self._debug("Add %s"%app) 302 # applist.append(app.replace('"','')) 303 304 return(applist) 305 #def _generate_applist 306 307 def _th_generate_xml_catalog(self,applist,outdir,info_url,repo,repo_name,progress_bar=''): 308 CURSOR_UP='\033[F' 309 ERASE_LINE='\033[K' 310 maxconnections = 10 311 semaphore = threading.BoundedSemaphore(value=maxconnections) 312 random_applist = list(applist) 313 random.shuffle(random_applist) 314 len_applist=len(random_applist) 315 inc=30/len_applist 316 # print (CURSOR_UP) 317 for app in random_applist: 318 th=threading.Thread(target=self._th_write_xml, args = (app,outdir,info_url,repo,repo_name,semaphore,inc)) 319 th.start() 320 # os.system('setterm -cursor off') 321 # while threading.active_count()>2: #Discard both main and own threads 322 # for i in range(len(progress_bar),int(self.progress)): 323 # progress_bar='#'+progress_bar 324 # print (CURSOR_UP) 325 # print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r") 326 # os.system('setterm -cursor on') 327 #def _th_generate_xml_catalog 328 329 def _th_write_xml(self,app,outdir,info_url,repo,repo_name,semaphore,inc): 330 semaphore.acquire() 331 lock=threading.Lock() 332 name_splitted=app.split('-') 333 name=name_splitted[0] 334 version=name_splitted[1] 335 arch=name_splitted[2] 336 filename=outdir+app.lower().replace('appimage',"appdata.xml") 337 self._debug("checking if we need to download "+filename) 338 if not os.path.isfile(filename): 339 self._write_xml_file(filename,app,name,version,info_url,repo,repo_name,lock) 340 with lock: 341 self.progress=self.progress+inc 342 semaphore.release() 343 #def _th_write_xml 344 345 def _write_xml_file(self,filename,app,name,version,info_url,repo,repo_name,lock): 346 self._debug("Generating "+app+" xml") 347 f=open(filename,'w') 348 f.write('<?xml version="1.0" encoding="UTF-8"?>'+"\n") 349 f.write("<components version=\"0.10\">\n") 350 f.write("<component type=\"desktop-application\">\n") 351 f.write(" <id>"+app.lower()+"</id>\n") 352 f.write(" <pkgname>"+app+"</pkgname>\n") 353 f.write(" <name>"+name+"</name>\n") 354 f.write(" <metadata_license>CC0-1.0</metadata_license>\n") 355 f.write(" <provides><binary>"+app+"</binary></provides>\n") 356 f.write(" <releases>\n") 357 f.write(" <release version=\""+version+"\" timestamp=\"1408573857\"></release>\n") 358 f.write(" </releases>\n") 359 f.write(" <launchable type=\"desktop-id\">"+name+".desktop</launchable>\n") 360 with lock: 361 try: 362 if name in self.descriptions_dict.keys(): 363 description=self.descriptions_dict[name] 503 504 def _init_appinfo(self): 505 appInfo={'appstream_id':'',\ 506 'id':'',\ 507 'name':'',\ 508 'version':'',\ 509 'channel_releases':{},\ 510 'component':'',\ 511 'package':'',\ 512 'license':'',\ 513 'summary':'',\ 514 'description':'',\ 515 'categories':[],\ 516 'icon':'',\ 517 'screenshot':'',\ 518 'thumbnails':[],\ 519 'video':'',\ 520 'homepage':'',\ 521 'installerUrl':'',\ 522 'state':'',\ 523 'depends':'',\ 524 'kudos':'',\ 525 'suggests':'',\ 526 'extraInfo':'',\ 527 'size':'',\ 528 'bundle':'',\ 529 'updatable':'',\ 530 } 531 return(appInfo) 532 #def _init_appinfo 533 534 def _get_info(self,app_info): 535 if app_info['installerUrl']: 536 app_info['channel_releases']={'appimage':[]} 537 app_info['channel_releases']['appimage']=self._get_releases(app_info) 538 app_info['state']='available' 539 if os.path.isfile(self.appimage_dir+'/'+app_info['package']): 540 app_info['state']='installed' 541 #Get size 542 if 'appimage' in app_info['channel_releases'].keys(): 543 if app_info['channel_releases']['appimage'][0]: 544 appimage_url=app_info['channel_releases']['appimage'][0] 545 dest_path=self.appimage_dir+'/'+app_info['package'] 546 if appimage_url: 547 try: 548 with urllib.request.urlopen(appimage_url) as response: 549 app_info['size']=(response.info()['Content-Length']) 550 except: 551 app_info['size']=0 552 else: 553 app_info['size']=0 554 #Version (unaccurate aprox) 555 app_info['version']=app_info['channel_releases']['appimage'][0].split('/')[-2] 556 # try: 557 # app_info['version']="%s.%s"%(version.split('.')[1],version.split('.')[2]) 558 # except: 559 # app_info['version']="%s"%version.split('_')[-1] 560 561 self._set_status(0) 562 self.partial_progress=100 563 return(app_info) 564 #def _get_info 565 566 def _get_releases(self,app_info): 567 releases=[] 568 releases_page='' 569 self._debug("Info url: %s"%app_info['installerUrl']) 570 url_source="" 571 try: 572 if 'github' in app_info['installerUrl']: 573 releases_page="https://github.com" 574 if 'gitlab' in app_info['installerUrl']: 575 releases_page="https://gitlab.com" 576 if 'opensuse' in app_info['installerUrl'].lower(): 577 releases_page="" 578 url_source="opensuse" 579 # app_info['installerUrl']=app_info['installerUrl']+"/download" 580 581 with urllib.request.urlopen(app_info['installerUrl']) as f: 582 content=(f.read().decode('utf-8')) 583 soup=BeautifulSoup(content,"html.parser") 584 package_a=soup.findAll('a', attrs={ "href" : re.compile(r'.*\.[aA]pp[iI]mage$')}) 585 586 for package_data in package_a: 587 if url_source=="opensuse": 588 package_name=package_data.findAll('a', attrs={"class" : "mirrorbrain-btn"}) 364 589 else: 365 description=self._get_description(name,info_url,repo_name) 366 self.descriptions_dict.update({name:description}) 367 except: 368 description='' 369 summary=' '.join(list(description.split(' ')[:8])) 370 description="This is an AppImage bundle of app "+name+". It hasn't been tested by our developers and comes from a 3rd party dev team. Please use it carefully.\n"+description 371 if not summary: 372 summary=' '.join(list(description.split(' ')[:8])) 373 f.write(" <description><p></p><p>"+description+"</p></description>\n") 374 f.write(" <summary>"+summary+"...</summary>\n") 375 f.write(' <url type="homepage">'+repo+'</url>\n') 376 f.write(" <bundle type=\"appimage\">"+app+"</bundle>\n") 377 f.write(" <keywords>\n") 378 f.write(" <keyword>"+name+"</keyword>\n") 379 f.write(" <keyword>appimage</keyword>\n") 380 f.write(" </keywords>\n") 381 f.write(" <categories>\n") 382 f.write(" <category>AppImage</category>\n") 383 # f.write(" <category>GTK</category>\n") 384 f.write(" </categories>\n") 385 f.write("<icon type=\"cached\">"+name+"_"+name+".png</icon>\n") 386 f.write("</component>\n") 387 f.write("</components>\n") 388 f.close() 389 #def _write_xml_file 390 391 def _get_description(self,app_name,info_url,repo_name): 392 desc='' 393 if '$(appname)' in info_url: 394 info_url=info_url.replace('$(appname)',app_name) 395 if info_url: 396 self._debug("Getting description from repo/app %s - %s "%(repo_name,info_url)) 397 try: 398 with urllib.request.urlopen(info_url) as f: 399 if repo_name=='probono': 400 content=(f.read().decode('utf-8')) 401 soup=BeautifulSoup(content,"html.parser") 402 description_div=soup.findAll('div', attrs={ "class" : "description-text"}) 403 if len(description_div)>0: 404 desc=description_div[0].text 405 desc=desc.replace(':','.') 406 desc=desc.replace('&','&') 407 except Exception as e: 408 print("Can't get description from "+info_url) 409 print(str(e)) 410 pass 411 return(desc) 412 #def _get_description 413 414 def _clean_bundle_catalogue(self,applist,outdir): 415 xml_files_list=[] 416 applist=[item.lower() for item in applist] 417 for xml_file in os.listdir(outdir): 418 if xml_file.endswith('appdata.xml'): 419 xml_files_list.append(xml_file.lower().replace('appdata.xml','appimage')) 420 421 if xml_files_list: 422 xml_discard_list=list(set(xml_files_list).difference(applist)) 423 for discarded_file in xml_discard_list: 424 os.remove(outdir+'/'+discarded_file.replace('appimage','appdata.xml')) 425 #def _clean_bunlde_catalogue 426 590 package_name=package_data.findAll('strong', attrs={ "class" : "pl-1"}) 591 package_link=package_data['href'] 592 if releases_page or url_source: 593 package_link=releases_page+package_link 594 releases.append(package_link) 595 self._debug("Link: %s"%package_link) 596 except Exception as e: 597 print(e) 598 return releases 599 #def _get_releases 600 -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/debManager.py
r7080 r7432 6 6 def __init__(self): 7 7 self.installer='' 8 self.dbg= False8 self.dbg=True 9 9 self.result=[] 10 10 self.progress=0 -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/example.py
r6645 r7432 8 8 self.progress=0 9 9 #This dict defines wich package_type relies on what action 10 #actions are defined in storeManager.10 #actions could be defined in storeManager or per-plugin 11 11 #Non contempled actions must declare its related functions on storeManager (threads dict) and define relationships with other actions in relatedActions. 12 #action=example 13 #package='*' (in this case all package_types. It could be "deb", "zmd" or whatever package type) 12 #package='*' (in this case action 'example' is related to all package_types. It could be "deb", "zmd" or whatever package type) 14 13 self.plugin_actions={'example':'*'} 15 #This switch enables cli_mode for the plugin, just in case some function difers from the gui mode 14 #This switch enables cli_mode for the plugin, just in case some function difers from the gui mode (take a look at snapManager) 16 15 self.cli_mode=False 17 16 #This one controls if the plugin is enabled or not … … 19 18 # - storeManager having a parameter with name=package_type (simply add it to the arg list passed when invoking storeManager) 20 19 # - Internal failure controls (see zmdManager for an example) 20 #If there'll be no parameter for enable/disable then the plugin manages it's own state and self.disabled must be None 21 21 #This example plugin is disabled by default 22 22 self.disabled=True -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/infoManager.py
r7143 r7432 3 3 class infomanager: 4 4 def __init__(self): 5 self.dbg= False5 self.dbg=True 6 6 self.plugin_actions={'get_info':'*'} 7 7 self.result={} … … 60 60 appInfo=self._init_appInfo() 61 61 # self._debug("Gathering package info for "+app.get_id()) 62 appInfo['appstream_id']=app 62 #Earlier versions stored the appstream_id as the memory dir of the metadata 63 #Changes in python3.6 and pickle module forces us to disable this feature... 64 # appInfo['appstream_id']=app 63 65 if app.get_id(): 64 66 appInfo['id']=app.get_id() … … 75 77 if app.get_pkgname_default(): 76 78 appInfo['package']=app.get_pkgname_default() 79 if len(app.get_pkgnames())>1: 80 appInfo['packages']=app.get_pkgnames() 77 81 if app.get_project_license(): 78 82 appInfo['license']=app.get_project_license() … … 94 98 appInfo['categories']=app.get_categories() 95 99 if app.get_icon_default(): 96 appInfo['icon']=app.get_icon_default().get_name() 100 if app.get_icon_default().get_filename(): 101 appInfo['icon']=app.get_icon_default().get_filename() 102 else: 103 appInfo['icon']=app.get_icon_default().get_name() 97 104 if appInfo['icon']==None: 98 105 icons=app.get_icons() … … 103 110 else: 104 111 appInfo['icon']='' 105 112 if appInfo['icon']==None: 113 appInfo['icon']='' 106 114 if app.get_screenshots(): 107 115 thumbnails_list=[] … … 134 142 appInfo["screenshots"]=screenshots_list 135 143 #The values are the values of appstream.UrlKind. 1=HOMEPAGE, 0=UNKNOWN 144 # self._debug(app.get_url_item(0)) 136 145 if app.get_url_item(1): 137 146 appInfo['homepage']=app.get_url_item(1).strip() … … 153 162 if 'embed' not in appInfo['video']: 154 163 appInfo['video']=appInfo['video'].replace('watch?v=','embed/') 155 # F***g appstreamreturns unknown for all the possible kinds164 #This appstream version returns unknown for all the possible kinds 156 165 # if app.get_bundle_default(): 157 166 # appInfo['bundle']=app.get_bundle_default().get_kind() 158 # Fix F***g appstreamreturns unknown for all the possible kinds167 #This appstream version returns unknown for all the possible kinds 159 168 #ID must contain bundle type as last field 160 169 for bundle in app.get_bundles(): 161 170 if bundle.get_kind()==0: 162 171 kind=bundle.get_id().split('.')[-1] 163 appInfo['bundle'] =kind.lower()172 appInfo['bundle'].append(kind.lower()) 164 173 if kind.lower=='sh': 165 174 appInfo['installerUrl']=bundle.get_id() … … 192 201 'extraInfo':'',\ 193 202 'size':'',\ 194 'bundle': '',\203 'bundle':[],\ 195 204 'updatable':'',\ 205 'component':'',\ 206 'channel_releases':{} 196 207 } 197 208 return(appInfo) -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/loadStore.py
r7080 r7432 22 22 self.progress=0 23 23 self.error=0 24 self.zmd_store_dir='/var/lib/lliurexstore/zmds' 24 # self.zmd_store_dir='/var/lib/lliurexstore/zmds' #DEPRECATED 25 25 self.result={} 26 26 self.result['data']={} … … 71 71 print ("Failed to load"+str(flag)) 72 72 pass 73 store=self.load_zmds_catalog(store) 73 #Zomandos are now available from appstream 74 # store=self.load_zmds_catalog(store) 74 75 store=self._sanitize_store(store) 75 76 self.store=store … … 77 78 #def load_store 78 79 79 def load_zmds_catalog(self,store): 80 def load_zmds_catalog(self,store): #DEPRECATED 80 81 if os.path.exists(self.zmd_store_dir): 81 82 store=self._generic_file_load(self.zmd_store_dir,store) … … 142 143 self._debug("Mergin app %s as is in LliureX"%app.get_id()) 143 144 lliurex_apps[app.get_id_filename()].subsume_full(app,appstream.AppSubsumeFlags.BOTH_WAYS) 144 store.remove_app(app)145 # store.add_app(lliurex_apps[app.get_id_filename()]) 145 146 #Remove apps whitout pkgname 146 147 if not app.get_pkgnames(): -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/searchManager.py
r7143 r7432 7 7 def __init__(self): 8 8 self.locale=locale.getlocale()[0] 9 self.dbg= False9 self.dbg=True 10 10 self.store='' 11 11 self.plugin_actions={'search':'*','list':'*','list_sections':'*','info':'*'} … … 66 66 if (action=='search' or action=='info'): 67 67 self._search_app(tokens,exact_match_for_search) 68 else: 69 self._debug("Search needs a store") 68 70 self.progress=100 69 71 return(self.result) … … 83 85 app=self._app_exists(tokens[0]) 84 86 if app: 85 applist.append(app) 86 self._debug("App direct match found: "+app.get_id()) 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()) 87 92 if not exact_match: 88 93 applist.extend(self._get_apps_by_match(tokens,applist)) … … 171 176 def _app_exists(self,app_name): 172 177 self._debug("Trying direct match for "+app_name) 178 #id_matches defines how to search for an app 179 # %s -> app_name; zero-lliurex-%s -> app_name with zero-lliurex- prefix and so on... 180 id_matches=['%s','zero-lliurex-%s','%s.desktop'] 173 181 app=None 182 for id_string in id_matches: 183 # app=self.store.get_app_by_id_ignore_prefix(id_string%app_name) 184 app=self.store.get_apps_by_id(id_string%app_name) 185 if app: 186 break 187 188 174 189 #1.- Try exact match 175 app=self.store.get_app_by_id(app_name)176 if not app:177 #2.- Try exact match with zero-lliurex- for the zomandos178 app=self.store.get_app_by_id("zero-lliurex-"+app_name)179 if not app:180 #3.- Try exact match with .desktop181 app=self.store.get_app_by_id(app_name+".desktop")190 # app=self.store.get_apps_by_id(app_name) 191 # if not app: 192 # #2.- Try exact match with zero-lliurex- for the zomandos 193 # app=self.store.get_app_by_id("zero-lliurex-"+app_name) 194 # if not app: 195 # #3.- Try exact match with .desktop 196 # app=self.store.get_apps_by_id(app_name+".desktop") 182 197 if not app: 183 198 #4.- Try exact match by pkgname 184 199 app=self.store.get_app_by_pkgname(app_name) 200 # if not app: 201 # app=self.store.get_app_by_id_ignore_prefix(app_name) 185 202 self._debug("App found %s"%app) 186 203 return(app) 187 204 188 205 def _get_apps_by_match(self,tokens,applist=[]): 189 #Add items wit ch match >= self.precision206 #Add items with match >= self.precision 190 207 self._debug("Searching app by fuzzy match") 191 208 if not applist: -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/snapManager.py
r7143 r7432 10 10 from gi.repository import AppStreamGlib as appstream 11 11 import time 12 import html 12 13 #Needed for async find method, perhaps only on xenial 13 14 wrap=Gio.SimpleAsyncResult() … … 15 16 16 17 def __init__(self): 17 self.dbg= False18 self.dbg=True 18 19 self.progress=0 19 20 self.partial_progress=0 20 21 self.plugin_actions={'install':'snap','remove':'snap','pkginfo':'snap','load':'snap'} 21 22 self.cache_dir=os.getenv("HOME")+"/.cache/lliurex-store" 23 self.cache_xmls=self.cache_dir+'/xmls/snap' 24 self.cache_last_update=self.cache_xmls+'/.snap.lu' 22 25 self.icons_folder=self.cache_dir+"/icons" 23 26 self.images_folder=self.cache_dir+"/images" … … 73 76 self.result['data']=self.store 74 77 else: 78 self._check_dirs() 75 79 self.snap_client=Snapd.Client() 76 80 self.snap_client.connect_sync(None) … … 108 112 #def _callback 109 113 114 def _check_dirs(self): 115 if not os.path.isdir(self.cache_xmls): 116 os.makedirs(self.cache_xmls) 117 110 118 def _load_snap_store(self,store): 111 119 pkgs=[] 120 #Look if cache is up-to-date 121 if os.path.isfile(self.cache_last_update): 122 epoch_time=time.time() 123 fcache=open(self.cache_last_update,'r') 124 fcache_update=fcache.read() 125 if not fcache_update: 126 fcache_update=0 127 if int(epoch_time)-int(fcache_update)<86400: 128 if not os.listdir(os.path.dirname(self.cache_xmls)): 129 self._debug("Loading snap from cache") 130 store=self._load_from_cache(store) 131 return store 132 133 fcache=open(self.cache_last_update,'w') 134 fcache.write(str(int(time.time()))) 112 135 if self.cli_mode: 113 136 pkgs=self._search_snap("*") … … 116 139 self._set_status(1) 117 140 for pkg in pkgs: 118 store.add_app(self._generate_appstream_app(pkg)) 141 app=self.store.get_app_by_pkgname(pkg.get_name()) 142 if not app: 143 self._debug("Searching for %s"%pkg.get_name()) 144 app=self.store.get_app_by_id(pkg.get_name().lower()+".desktop") 145 if app: 146 bundle=appstream.Bundle() 147 bundle.set_kind(bundle.kind_from_string('SNAP')) 148 bundle.set_id(pkg.get_name()+'.snap') 149 app.add_bundle(bundle) 150 app.add_category("Snap") 151 store.add_app(self._generate_appstream_app_from_snap(pkg)) 152 else: 153 store.add_app(self._generate_appstream_app_from_snap(pkg)) 119 154 return(store) 120 155 121 def _generate_appstream_app(self,pkg): 156 def _load_from_cache(self,store): 157 for target_file in os.listdir(self.cache_xmls): 158 if target_file.endswith('.xml'): 159 store_file=Gio.File.new_for_path(self.cache_xmls+'/'+target_file) 160 self._debug("Adding file %s/%s"%(self.cache_xmls,target_file)) 161 try: 162 store.from_file(store_file,None,None) 163 except Exception as e: 164 self._debug("Couldn't add file %s to store"%target_file) 165 self._debug("Reason: %s"%e) 166 return store 167 168 def _generate_appstream_app_from_snap(self,pkg): 122 169 bundle=appstream.Bundle() 123 170 app=appstream.App() 124 171 icon=appstream.Icon() 125 172 screenshot=appstream.Screenshot() 126 #F*****g appstream have kinds undefined but kind_from_string works... wtf?127 173 # bundle.set_kind(appstream.BundleKind.SNAP) 128 174 bundle.set_kind(bundle.kind_from_string('SNAP')) 129 175 bundle.set_id(pkg.get_name()+'.snap') 130 176 app.add_bundle(bundle) 131 app.set_name("C",pkg.get_name() )177 app.set_name("C",pkg.get_name()+'.snap') 132 178 app.add_pkgname(pkg.get_name()+'.snap') 133 179 app.add_category("Snap") … … 135 181 release.set_version(pkg.get_version()) 136 182 app.add_release(release) 137 sw_id=False 138 for snap_app in pkg.get_apps(): 139 if snap_app.get_desktop_file(): 140 app.set_id("%s"%snap_app.get_desktop_file()) 141 sw_id=True 142 break 143 if sw_id==False: 144 app.set_id("%s_%s.desktop"%(pkg.get_name(),pkg.get_name())) 145 # app.set_id(pkg.get_name()+'.snap') 183 app.set_id("io.snapcraft.%s"%pkg.get_name()+'.snap') 146 184 app.set_id_kind=appstream.IdKind.DESKTOP 147 description=("This is an Snap bundle of app %s. It hasn't been tested by our developers and comes from a 3rd party dev team. Please use it carefully."%pkg.get_name()) 148 app.set_description("C",description+'<br>'+pkg.get_description()) 149 app.set_comment("C",pkg.get_summary()) 185 app.set_metadata_license("CC0-1.0") 186 description="This is an Snap bundle. It hasn't been tested by our developers and comes from a 3rd party dev team. Please use it carefully." 187 pkg_description=pkg.get_description() 188 pkg_description=html.escape(pkg_description,quote=True) 189 pkg_description=pkg_description.replace("<",">") 190 app.set_description("C","<p>%s</p><p>%s</p>"%(description,pkg_description)) 191 app.set_comment("C",pkg.get_summary().rstrip('.')) 192 150 193 app.add_keyword("C",pkg.get_name()) 151 194 for word in pkg.get_summary().split(' '): 152 app.add_keyword("C",word) 195 if len(word)>3: 196 app.add_keyword("C",word) 153 197 154 198 if pkg.get_icon(): … … 159 203 icon.set_kind(appstream.IconKind.REMOTE) 160 204 icon.set_name(pkg.get_icon()) 205 icon.set_url(pkg.get_icon()) 161 206 app.add_icon(icon) 162 207 … … 167 212 for snap_screen in pkg.get_screenshots(): 168 213 img=appstream.Image() 169 # img.load_filename(self._download_file(snap_screen.get_url(),pkg.get_name(),self.images_folder))170 214 img.set_kind(appstream.ImageKind.SOURCE) 171 215 img.set_url(snap_screen.get_url()) … … 173 217 screenshot.add_image(img) 174 218 app.add_screenshot(screenshot) 219 220 if not os.path.isfile(self.cache_xmls+'/'+app.get_id_filename()): 221 xml_path='%s/%s.xml'%(self.cache_xmls,app.get_id_filename()) 222 gioFile=Gio.File.new_for_path(xml_path) 223 app.to_file(gioFile) 224 #Fix some things in app_file... 225 xml_file=open(xml_path,'r') 226 xml_data=xml_file.readlines() 227 xml_file.close() 228 count=0 229 xml_data[0]=xml_data[0]+"<components>\n" 230 xml_data[-1]=xml_data[-1]+"\n"+"</components>" 231 xml_file=open(xml_path,'w') 232 xml_file.writelines(xml_data) 233 xml_file.close() 175 234 return(app) 176 235 … … 189 248 while 'Snapd' not in str(type(wrap)): 190 249 time.sleep(0.1) 250 # snaps,curr=self.snap_client.find_finish(wrap) 191 251 snaps=self.snap_client.find_finish(wrap) 192 252 if type(snaps)!=type([]): … … 205 265 pkgs=None 206 266 try: 207 pkgs=self.snap_client.find_sync(Snapd.FindFlags.MATCH_NAME,tokens,None,None) 267 # pkgs,curr=self.snap_client.find_sync(Snapd.FindFlags.MATCH_NAME,tokens,None) 268 pkgs=self.snap_client.find_sync(Snapd.FindFlags.MATCH_NAME,tokens,None) 208 269 except Exception as e: 209 print( e)270 print("ERR: %s"%e) 210 271 self._set_status(1) 211 272 stable_pkgs=[] … … 241 302 self._debug("Unable to download %s"%url) 242 303 self._debug("Reason: %s"%e) 304 target_file='' 243 305 # os._exit(0) 244 306 return(target_file) … … 252 314 pkg=None 253 315 try: 254 pkg=self.snap_client.list_one_sync(app_info[' name'])316 pkg=self.snap_client.list_one_sync(app_info['package'].replace('.snap','')) 255 317 app_info['state']='installed' 256 318 pkgs=[pkg] … … 258 320 app_info['state']='available' 259 321 if self.cli_mode: 260 pkgs=self._search_snap(app_info[' name'])261 else: 262 pkgs=self._search_snap_async(app_info[' name'])322 pkgs=self._search_snap(app_info['package'].replace('.snap','')) 323 else: 324 pkgs=self._search_snap_async(app_info['package'].replace('.snap','')) 263 325 self._debug("Getting extended info for %s %s"%(app_info['name'],pkgs)) 264 326 if type(pkgs)==type([]): … … 283 345 else: 284 346 try: 285 self.snap_client.install_sync(app_info['name'] ,347 self.snap_client.install_sync(app_info['name'].replace('.snap',''), 286 348 None, # channel 287 349 self._callback, (None,), … … 302 364 else: 303 365 try: 304 self.snap_client.remove_sync(app_info['name'] ,366 self.snap_client.remove_sync(app_info['name'].replace('.snap',''), 305 367 self._callback, (None,), 306 368 None) # cancellable -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/zmdManager.py
r7169 r7432 20 20 if hasattr(sys,'last_value') or not (os.path.exists(self.zmd_folder)): 21 21 #If there's an error at this point it only could be an importError caused by xmlrpc 22 print("ERROR!!!!") 22 23 self.disabled=True 23 24 self.plugin_actions={'install':'zmd','pkginfo':'zmd','remove':'zmd'} … … 66 67 except: 67 68 self.disabled=True 69 print("ERROR2!!!!") 68 70 self._set_status(10) 69 71 self.progress=100 -
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/storeManager.py
r7170 r7432 17 17 class StoreManager(): 18 18 def __init__(self,*args,**kwargs): 19 self.dbg=False20 19 if 'dbg' in kwargs.keys(): 21 20 self.dbg=kwargs['dbg'] 21 self.dbg=True 22 22 self._propagate_dbg=False 23 23 self.store=None 24 self.stores={} 24 25 self.related_actions={ 25 26 'load':['load'], … … 79 80 continue 80 81 if target_class.disabled==None: 81 self._debug("Plugin %s will manage its state"%plugin_name) 82 #Time to check if plugin is disabled or enabled by parm 83 #Values for the plugins_registered dict must be the same as the parm name that enables the plugin 82 self._debug("Plugin %s will set its status"%plugin_name) 84 83 else: 84 #Time to check if plugin is disabled or enabled by parm 85 #Values for the plugins_registered dict must be the same as the parm name that enables the plugin 85 86 for key,value in class_actions.items(): 86 87 val=value … … 264 265 self._debug("Joining action: %s"%action) 265 266 try: 267 print("T: %s"%self.running_threads[action]) 266 268 self.running_threads[action].join() 267 269 except Exception as e: … … 394 396 def _load_Store(self): 395 397 action='load' 398 #Load appstream metada first 399 package_type='*' 400 load_function=self._execute_class_method(action,package_type,launchedby=None) 401 self.store=load_function.execute_action(action=action,store=self.store)['data'] 402 #Once appstream is loaded load the appstream plugins for other package types (snap, appimage...) 396 403 for package_type in self.plugins_registered[action]: 397 load_function=self._execute_class_method(action,package_type,launchedby=None) 398 self.store=load_function.execute_action(action=action,store=self.store)['data'] 404 if package_type!='*': 405 load_function=self._execute_class_method(action,package_type,launchedby=None) 406 self.store=load_function.execute_action(action=action,store=self.store)['data'] 399 407 #def _load_Store 400 408 … … 420 428 # - Dict with the related info 421 429 #### 422 def _get_Extended_App_Info(self,info_applist,launchedby=None,fullsearch=True ):430 def _get_Extended_App_Info(self,info_applist,launchedby=None,fullsearch=True,channel=''): 423 431 #Check if there's any plugin for the distinct type of packages 424 432 action='pkginfo' … … 427 435 result['data']=[] 428 436 result['status']={'status':0,'msg':''} 437 processed=[] 429 438 for app_info in info_applist: 430 package_type=self._check_package_type(app_info) 431 if package_type in types_dict: 432 types_dict[package_type].append(app_info) 439 if channel: 440 types_dict[channel]=[app_info] 433 441 else: 434 types_dict[package_type]=[app_info] 442 available_channels=self._check_package_type(app_info) 443 for package_type in available_channels: 444 if app_info['component']!='': 445 if app_info['id'] in processed: 446 self._debug("App %s processed"%app_info['id']) 447 continue 448 449 if package_type in types_dict: 450 types_dict[package_type].append(app_info) 451 else: 452 types_dict[package_type]=[app_info] 453 processed.append(app_info['id']) 435 454 for package_type in types_dict: 436 455 self._debug("Checking plugin for %s %s"%(action,package_type)) 437 456 if package_type in self.plugins_registered[action]: 438 #Only sea rch full info if it's required457 #Only seach full info if it's required 439 458 if (fullsearch==False and package_type=='deb'): 440 459 result['data'].extend(types_dict[package_type]) … … 476 495 def _search_Store(self,*args,**kwargs): 477 496 search_item=args[0] 497 return_msg=False 478 498 action='search' 479 499 if 'action' in kwargs.keys(): … … 500 520 if (launchedby=='search'): 501 521 exact_match=False 522 target_channel='' 523 if '=' in search_item: 524 target_channel=search_item.split('=')[-1] 525 search_item=search_item.split('=')[0] 502 526 for package_type in self.plugins_registered[action]: 527 self._debug("Searching package type %s"%package_type) 503 528 search_function=self._execute_class_method(action,'*',launchedby=launchedby) 504 529 result.update(search_function.execute_action(self.store,action,search_item,exact_match,max_results)) … … 513 538 self._debug("Add result for %s"%subordinate_action) 514 539 self.result[subordinate_action]=result 515 #2.- Get rest of metadata (slower) 516 subordinate_action='pkginfo' 517 result=self._get_Extended_App_Info(result['data'],launchedby,fullsearch) 518 if launchedby: 519 realAction=launchedby 520 self._debug("Assigned results of %s to %s"%(action,realAction)) 521 if (result['status']['status']==0) or (result['status']['status']==9): 522 return_msg=True 523 if fullsearch: 524 result['status']['status']=0 525 else: 526 return_msg=False 540 if fullsearch: 541 #2.- Get rest of metadata (slower) 542 subordinate_action='pkginfo' 543 self._debug("Target channel: %s"%target_channel) 544 result=self._get_Extended_App_Info(result['data'],launchedby,fullsearch,target_channel) 545 if launchedby: 546 realAction=launchedby 547 self._debug("Assigned results of %s to %s"%(action,realAction)) 548 if (result['status']['status']==0) or (result['status']['status']==9): 549 return_msg=True 550 if fullsearch: 551 result['status']['status']=0 552 else: 553 return_msg=False 527 554 else: 528 555 return_msg=False … … 563 590 types_dict={} 564 591 break 565 566 package_type=self._check_package_type(app_info) 567 if package_type in types_dict: 568 types_dict[package_type].append(app_info) 569 else: 570 types_dict[package_type]=[app_info] 592 processed=[] 593 available_channels=self._check_package_type(app_info) 594 for package_type in available_channels: 595 if app_info['component']!='': 596 if app_info['id'] in processed: 597 self._debug("App %s processed"%app_info['id']) 598 continue 599 600 if package_type in types_dict: 601 types_dict[package_type].append(app_info) 602 else: 603 types_dict[package_type]=[app_info] 604 processed.append(app_info['id']) 571 605 572 606 for package_type in types_dict: … … 591 625 result=install_function.execute_action(action,types_dict[package_type]) 592 626 self.result[action]=result 593 if result['status']['status']==0: 627 #Deprecated. Earlier versions stored the "app" object so here the app could get marked as installed/removed without neeed of import or query anything 628 #Python>=3.6 don't let us to store the app object in a queue (needed for the GUI) so this code becames deprecated. 629 # if result['status']['status']==0: 594 630 #Mark the apps as installed or available 595 for app in types_dict[package_type]:596 if action=='install':597 app['appstream_id'].set_state(1)598 self._debug("App state changed to installed")599 else:600 app['appstream_id'].set_state(2)601 self._debug("App state changed to available")631 # for app in types_dict[package_type]: 632 # if action=='install': 633 # app['appstream_id'].set_state(1) 634 # self._debug("App state changed to installed") 635 # else: 636 # app['appstream_id'].set_state(2) 637 # self._debug("App state changed to available") 602 638 return_msg=True 603 639 self._log("Result %s: %s"%(action,self.result[action])) … … 616 652 #Zomandos must have the subcategory "Zomando" 617 653 self._debug("Checking package type for app "+app_info['name']) 618 if "Zomando" in app_info['categories']: 619 return_msg="zmd" 620 else: 654 return_msg=[] 655 if app_info['bundle']: 656 return_msg.extend(app_info['bundle']) 657 else: 658 if "Zomando" in app_info['categories']: 659 return_msg.append("zmd") 660 if 'component' in app_info.keys(): 661 if app_info['component']!='': 662 return_msg.append('deb') 621 663 #Standalone installers must have an installerUrl field loaded from a bundle type=script description 622 if app_info['bundle']!='': 623 return_msg=app_info['bundle'] 624 elif app_info['installerUrl']!='': 625 return_msg="sh" 626 else: 627 return_msg="deb" 664 if app_info['installerUrl']!='': 665 return_msg.append("sh") 628 666 return(return_msg) 629 667 #def _check_package_type
Note: See TracChangeset
for help on using the changeset viewer.