Ignore:
Timestamp:
Jan 18, 2018, 1:34:53 PM (3 years ago)
Author:
Juanma
Message:

Added snap support. Minor changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/loadStore.py

    r6547 r6645  
    1717class loadstore:
    1818        def __init__(self):
    19                 self.dbg=0
    20                 self.pluginInfo={'load':'*','load_bundles':'*'}
     19                self.dbg=False
     20                self.plugin_actions={'load':'*'}
    2121                self.store=''
    2222                self.progress=0
    2323                self.error=0
    24                 self.bundleDir="/var/lib/lliurexstore/bundles"
    25                 self.bundleTypes=['appimg']
    26                 self.zmdCatalogueDir='/var/lib/lliurexstore/zmds'
     24                self.zmd_store_dir='/var/lib/lliurexstore/zmds'
     25                self.result={}
     26                self.result['data']={}
     27                self.result['status']={}
    2728        #def __init__
    2829
    29         def set_debug(self,dbg='1'):
    30                 self.dbg=int(dbg)
     30        def set_debug(self,dbg=True):
     31                self.dbg=dbg
    3132                self._debug ("Debug enabled")
    3233        #def set_debug
    3334
    3435        def _debug(self,msg=''):
    35                 if self.dbg==1:
     36                if self.dbg:
    3637                        print ('DEBUG Load: '+str(msg))
    3738        #def _debug
    3839
    3940        def register(self):
    40                 return(self.pluginInfo)
     41                return(self.plugin_actions)
    4142        #def register
    4243
     
    5152                if action=='load_bundles':
    5253                        self._load_store(self.store,loadBundles=True)
     54#               self.progress=100
     55                self.result['data']=self.store
    5356                self.progress=100
    54                 return (self.store)
     57                return(self.result)
     58#               return (self.store)
    5559        #def execute_action
    5660
     
    6064
    6165        def _load_store(self,store,loadBundles=False):
    62                 iconPath='/usr/share/icons/hicolor/128x128'
     66                icon_dir='/usr/share/icons/hicolor/128x128'
    6367                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]
    6468                for flag in flags:
     
    7175                store=self.load_zmds_catalog(store)
    7276                store=self._sanitize_store(store)
    73                 if loadBundles:
    74                         if self._download_bundles_catalogue():
    75                                 store=self.load_bundles_catalog(store)
    7677                self.store=store
    7778                return(store)
    7879        #def load_store
    7980
    80         def load_bundles_catalog(self,store):
    81                 if os.path.exists(self.bundleDir):
    82                         for bundleType in self.bundleTypes:
    83                                 store=self._generic_file_load(self.bundleDir+'/'+bundleType,store)
    84                 return(store)
    85         #def load_bundles_catalog(self)
    86 
    8781        def load_zmds_catalog(self,store):
    88                 if os.path.exists(self.zmdCatalogueDir):
    89                         store=self._generic_file_load(self.zmdCatalogueDir,store)
     82                if os.path.exists(self.zmd_store_dir):
     83                        store=self._generic_file_load(self.zmd_store_dir,store)
    9084                return(store)
    9185        #def load_zmds_catalog(self)
    9286
    93         def _generic_file_load(self,filesDir,store):
    94                 iconPath='/usr/share/icons/hicolor/128x128'
    95                 files=os.listdir(filesDir)
    96                 for appFile in os.listdir(filesDir):
    97                         if appFile.endswith('appdata.xml'):
    98                                 storePath=Gio.File.new_for_path(filesDir+'/'+appFile)
    99                                 self._debug("Adding file "+filesDir+'/'+appFile)
     87        def _generic_file_load(self,target_dir,store):
     88                icon_dir='/usr/share/icons/hicolor/128x128'
     89                files=os.listdir(target_dir)
     90                for target_file in os.listdir(target_dir):
     91                        if target_file.endswith('appdata.xml'):
     92                                store_file=Gio.File.new_for_path(target_dir+'/'+target_file)
     93                                self._debug("Adding file "+target_dir+'/'+target_file)
    10094                                try:
    101                                         store.from_file(storePath,iconPath,None)
     95                                        store.from_file(store_file,icon_dir,None)
    10296                                except Exception as e:
    103                                         self._debug("Couldn't add file "+appFile+" to store")
     97                                        self._debug("Couldn't add file "+target_file+" to store")
    10498                                        self._debug("Reason: "+str(e))
    10599                return(store)
    106100       
    107101        def _parse_desktop(self,store): #DEPRECATED. Loads the apps from the available desktop files
    108                 desktopDir='/usr/share/applications'
     102                desktop_dir='/usr/share/applications'
    109103                applist=[]
    110                 for desktopFile in os.listdir(desktopDir):
    111                         if desktopFile.endswith('desktop'):
     104                for desktop_file in os.listdir(desktop_dir):
     105                        if desktop_file.endswith('desktop'):
    112106                                a=appstream.App()
    113107                                try:
    114                                         a.parse_file(desktopDir+'/'+desktopFile,16)
     108                                        a.parse_file(desktop_dir+'/'+desktop_file,16)
    115109                                        a.set_priority(0)
    116110                                        for veto in a.get_vetos():
    117111                                                a.remove_veto(veto)
    118112                                        store.add_app(a)
    119                                         self._debug("Adding app from desktop "+desktopFile)
     113                                        self._debug("Adding app from desktop "+desktop_file)
    120114                                except:
    121115                                        pass
     
    125119        def _sanitize_store(self,store):
    126120                applist=store.get_apps()
    127                 uniqDict={}
    128                 lliurexApps={}
    129                 zmdList=[]
     121                tmp_store_apps={}
     122                lliurex_apps={}
     123                zmd_apps=[]
    130124                for app in applist:
    131125                        #Zomandos get max priority
     
    133127                                self._debug("Prioritize zmd "+str(app.get_id()))
    134128                                app.set_priority(400)
    135                                 lliurexApps.update({app.get_id_filename():app})
    136                                 id=str(app.get_id_filename()).replace('zero-lliurex-','')
    137                                 zmdList.append(id)
     129                                lliurex_apps.update({app.get_id_filename():app})
     130                                id_app=str(app.get_id_filename()).replace('zero-lliurex-','')
     131                                zmd_apps.append(id_app)
    138132                        #Prioritize Lliurex apps
    139133                        elif app.has_category('Lliurex'):
    140134                                self._debug("Prioritize app "+str(app.get_id()))
    141135                                app.set_priority(200)
    142                                 lliurexApps.update({app.get_id_filename():app})
     136                                lliurex_apps.update({app.get_id_filename():app})
    143137                        elif str(app.get_origin()).find('lliurex')>=0:
    144138                                self._debug("Prioritize app "+app.get_id())
    145139                                app.set_priority(100)
    146                                 lliurexApps.update({app.get_id_filename():app})
     140                                lliurex_apps.update({app.get_id_filename():app})
    147141                        else:
    148142                                app.set_priority(0)
    149                                 if app.get_id_filename() in lliurexApps.keys():
     143                                if app.get_id_filename() in lliurex_apps.keys():
    150144                                        self._debug("Mergin app "+str(app.get_id())+" as is in Lliurex")
    151                                         lliurexApps[app.get_id_filename()].subsume_full(app,appstream.AppSubsumeFlags.BOTH_WAYS)
     145                                        lliurex_apps[app.get_id_filename()].subsume_full(app,appstream.AppSubsumeFlags.BOTH_WAYS)
    152146                                        store.remove_app(app)
    153147                        #Remove apps whitout pkgname
     
    161155                        #Unlike gnome-store we'll try to compare the info of the package in order of discard only the "part-of" packages
    162156                        pkg=app.get_pkgname_default()
    163                         if pkg in uniqDict.keys():
     157                        if pkg in tmp_store_apps.keys():
    164158                                fn=app.get_id_no_prefix()
    165                                 self._debug("Comparing "+fn+" with "+uniqDict[pkg]['fn'])
    166                                 if fn != uniqDict[pkg]['fn']:
     159                                self._debug("Comparing "+fn+" with "+tmp_store_apps[pkg]['fn'])
     160                                if fn != tmp_store_apps[pkg]['fn']:
    167161                                        if fn != pkg and ".desktop" not in fn:
    168162                                                self._debug("Removed duplicated "+app.get_id())
    169163                                                store.remove_app(app)
    170164                                        else:
    171                                                 self._debug("Removed duplicated "+uniqDict[pkg]['app'].get_id())
    172                                                 store.remove_app(uniqDict[pkg]['app'])
    173                                                 uniqDict.update({pkg:{'fn':app.get_id_no_prefix(),'app':app}})
     165                                                self._debug("Removed duplicated "+tmp_store_apps[pkg]['app'].get_id())
     166                                                store.remove_app(tmp_store_apps[pkg]['app'])
     167                                                tmp_store_apps.update({pkg:{'fn':app.get_id_no_prefix(),'app':app}})
    174168                        elif pkg:
    175169#                               self._debug("Adding "+app.get_id_filename()+" to uniq dict")
    176                                 uniqDict.update({pkg:{'fn':app.get_id_filename(),'app':app}})
     170                                tmp_store_apps.update({pkg:{'fn':app.get_id_filename(),'app':app}})
    177171                #Delete zomando-related debs
    178                 store=self._purge_zomandos(zmdList,store)
     172                store=self._purge_zomandos(zmd_apps,store)
    179173                #Check the blacklist
    180174                store=self._apply_blacklist(store)
     
    182176        #def _sanitize_store
    183177
    184         def _purge_zomandos(self,zmdList,store):
    185                 for appId in zmdList:
    186                         self._debug("Searching debs related to "+appId)
    187                         purgeList=store.get_apps_by_id(appId)
    188                         purgeList.extend(store.get_apps_by_id(appId+".desktop"))
    189                         for purgeApp in purgeList:
    190                                 if purgeApp:
    191                                         if not purgeApp.has_category('Zomando'):
    192                                                 self._debug("Removed related zomando app "+str(purgeApp.get_id()))
    193                                                 store.remove_app(purgeApp)
     178        def _purge_zomandos(self,zmd_apps,store):
     179                for zmd_id in zmd_apps:
     180                        self._debug("Searching debs related to "+zmd_id)
     181                        purge_list=store.get_apps_by_id(zmd_id)
     182                        purge_list.extend(store.get_apps_by_id(zmd_id+".desktop"))
     183                        for purge_app in purge_list:
     184                                if purge_app:
     185                                        if not purge_app.has_category('Zomando'):
     186                                                self._debug("Removed related zomando app "+str(purge_app.get_id()))
     187                                                store.remove_app(purge_app)
    194188                return(store)
    195189        #def _purge_zomandos
     
    209203                                blFile=open('/usr/share/lliurex-store/files/blacklist.json').read()
    210204                                blacklist=json.loads(blFile)
    211                                 blApps=[]
     205                                blacklist_apps=[]
    212206                                if flavour in blacklist:
    213                                         blApps=blacklist[flavour]
     207                                        blacklist_apps=blacklist[flavour]
    214208                                if "all" in blacklist:
    215                                         blApps.extend(blacklist["all"])
    216                                 blRegEx=[]
    217                                 for blApp in blApps:
    218                                         self._debug("Blacklisted app: "+blApp)
    219                                         resultRe=re.search('([^a-zA-Z0-9_-])',blApp)
    220                                         if resultRe:
    221                                                 if blApp[0]=='*':
    222                                                         blApp='.'+blApp
    223                                                 blRegEx.append("("+blApp+")")
     209                                        blacklist_apps.extend(blacklist["all"])
     210                                blacklist_re=[]
     211                                for blacklist_app in blacklist_apps:
     212                                        self._debug("Blacklisted app: "+blacklist_app)
     213                                        re_result=re.search('([^a-zA-Z0-9_-])',blacklist_app)
     214                                        if re_result:
     215                                                if blacklist_app[0]=='*':
     216                                                        blacklist_app='.'+blacklist_app
     217                                                blacklist_re.append("("+blacklist_app+")")
    224218                                        else:
    225                                                 app=store.get_app_by_pkgname(blApp)
     219                                                app=store.get_app_by_pkgname(blacklist_app)
    226220                                                if app:
    227221                                                        self._debug("Removed "+str(app))
    228222                                                        store.remove_app(app)
    229223                                                else:
    230                                                         self._debug("App "+blApp+" from blacklist not found in store. Assigned to RE blacklist")
    231                                                         blRegEx.append("("+blApp+")")
    232                                 if blRegEx:
     224                                                        self._debug("App "+blacklist_app+" from blacklist not found in store. Assigned to RE blacklist")
     225                                                        blacklist_re.append("("+blacklist_app+")")
     226                                if blacklist_re:
    233227                                        self._debug("Attempting to remove apps by RE match")
    234228                                        for app in store.get_apps():
    235                                                 for blApp in blRegEx:
    236                                                         resultRe=re.search(blApp,app.get_id())
    237                                                         if resultRe:
     229                                                for blacklist_app in blacklist_re:
     230                                                        re_result=re.search(blacklist_app,app.get_id())
     231                                                        if re_result:
    238232                                                                store.remove_app(app)
    239                                                                 self._debug("Removed "+str(app.get_id()) +" as matches with "+blApp)
     233                                                                self._debug("Removed "+str(app.get_id()) +" as matches with "+blacklist_app)
    240234                        else:
    241235                                self._debug('No blacklist to check')
     
    246240        #def _apply_blacklist
    247241
    248         def _download_bundles_catalogue(self):
    249                 CURSOR_UP='\033[F'
    250                 ERASE_LINE='\033[K'
    251                 content=''
    252                 applist=[]
    253                 progressBar="#"
    254                 repoList={'appimg':['https://dl.bintray.com/probono/AppImages']}
    255                 #For get the description of an app we must go to a specific url.
    256                 #$(appname) we'll be replaced with the appname so the url matches the right one.
    257                 #If other site has other url naming convention it'll be mandatory to define it with the appropiate replacements
    258                 infoList={'appimg':'https://bintray.com/probono/AppImages/$(appname)'}
    259                 self.descDict={}
    260 
    261                 for repoType,repoTypeList in repoList.items():
    262                         infoPage=infoList[repoType]
    263                         outdir=self.bundleDir+'/'+repoType+'/'
    264                         if self._chk_bundle_dir(outdir):
    265                                 for repo in repoTypeList:
    266                                         self._debug(("Fetching repo %s")%(repo))
    267 #                                       print (("Fetching %s catalogue: "+progressBar)%repoType,end="\r")
    268 #                                       progressBar=progressBar+"#"
    269 #                                       print (("Fetching %s catalogue: "+progressBar)%repoType,end="\r")
    270                                         applist=self._generate_applist(self._fetch_repo(repo))
    271 #                                       progressBar=progressBar+"##"
    272 #                                       print (("Fetching %s catalogue: "+progressBar)%repoType,end="\r")
    273                                         self._debug("Processing info...")
    274                                         self._th_generate_xml_catalog(applist,outdir,infoPage,repoType,progressBar)
    275                                         self._debug("Fetched repo "+repo)
    276 #                                       print (("Removing old entries..."))
    277                                         self._clean_bundle_catalogue(applist,outdir)
    278                         else:
    279                                 print("permission denied")
    280                 return(True)
    281 
    282         def _chk_bundle_dir(self,outdir):
    283                 msg_status=True
    284                 if not os.path.isdir(outdir):
    285                         try:
    286                                 os.makedirs(outdir)
    287                         except:
    288                                 msg_status=False
    289                 return(os.access(outdir,os.W_OK|os.R_OK|os.X_OK|os.F_OK))
    290 
    291         def _fetch_repo(self,repo):
    292                 with urllib.request.urlopen(repo) as f:
    293                         content=(f.read().decode('utf-8'))
    294                 return(content)
    295 
    296         def _generate_applist(self,content):
    297                 garbageList=[]
    298                 applist=[]
    299                 garbageList=content.split(' ')
    300                 for garbageLine in garbageList:
    301                         if garbageLine.endswith('AppImage"'):
    302                                 app=garbageLine.replace('href=":','')
    303                                 applist.append(app.replace('"',''))
    304                 return(applist)
    305 
    306         def _th_generate_xml_catalog(self,applist,outdir,infoPage,repoType,progressBar=''):
    307                 CURSOR_UP='\033[F'
    308                 ERASE_LINE='\033[K'
    309                 oldName=''
    310                 oldDesc=''
    311                 maxconnections = 10
    312                 semaphore = threading.BoundedSemaphore(value=maxconnections)
    313                 randomList = list(applist)
    314                 random.shuffle(randomList)
    315                 lenAppList=len(randomList)
    316                 inc=30/lenAppList
    317 #               print (CURSOR_UP)
    318                 for app in randomList:
    319                         th=threading.Thread(target=self._th_write_xml, args = (app,outdir,infoPage,semaphore,inc))
    320                         th.start()
    321                 os.system('setterm -cursor off')
    322                 while threading.active_count()>2: #Discard both main and own threads
    323                         for i in range(len(progressBar),int(self.progress)):
    324                                 progressBar='#'+progressBar
    325 #                       print (CURSOR_UP)
    326 #                       print (("Fetching %s catalogue: "+progressBar)%repoType,end="\r")
    327                 os.system('setterm -cursor on')
    328                 print('')
    329 
    330         def _th_write_xml(self,app,outdir,infoPage,semaphore,inc):
    331                 semaphore.acquire()
    332                 lock=threading.Lock()
    333                 nameSplitted=app.split('-')
    334                 name=nameSplitted[0]
    335                 version=nameSplitted[1]
    336                 arch=nameSplitted[2]
    337                 filename=outdir+app.lower().replace('appimage',"appdata.xml")
    338                 self._debug("checking if we need to download "+filename)
    339                 if not os.path.isfile(filename):
    340                         self._debug("Generating "+app+" xml")
    341                         f=open(filename,'w')
    342                         f.write('<?xml version="1.0" encoding="UTF-8"?>'+"\n")
    343                         f.write("<components version=\"0.10\">\n")
    344                         f.write("<component  type=\"desktop-application\">\n")
    345                         f.write("  <id>"+app.lower()+"</id>\n")
    346                         f.write("  <pkgname>"+app+"</pkgname>\n")
    347                         f.write("  <name>"+name+"</name>\n")
    348                         f.write("  <metadata_license>CC0-1.0</metadata_license>\n")
    349                         f.write("  <provides><binary>"+app+"</binary></provides>\n")
    350                         f.write("  <releases>\n")
    351                         f.write("  <release version=\""+version+"\" timestamp=\"1408573857\"></release>\n")
    352                         f.write("  </releases>\n")
    353                         f.write("  <launchable type=\"desktop-id\">"+name+".desktop</launchable>\n")
    354                         with lock:
    355                                 if name in self.descDict.keys():
    356                                         description=self.descDict[name]
    357                                 else:
    358                                         description=self._get_description(name,infoPage)
    359                                         self.descDict.update({name:description})
    360                         summary=' '.join(list(description.split(' ')[:8]))
    361                         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."
    362                         if not summary:
    363                                 summary=' '.join(list(description.split(' ')[:8]))
    364                         f.write("  <description><p></p><p>"+description+"</p></description>\n")
    365                         f.write("  <summary>"+summary+"...</summary>\n")
    366                         f.write("  <bundle type=\"appimage\">"+app+"</bundle>\n")
    367                         f.write("  <keywords>\n")
    368                         f.write("       <keyword>"+name+"</keyword>\n")
    369                         f.write("       <keyword>appimage</keyword>\n")
    370                         f.write("  </keywords>\n")
    371                         f.write("  <categories>\n")
    372                         f.write("       <category>AppImage</category>\n")
    373                         f.write("       <category>GTK</category>\n")
    374                         f.write("  </categories>\n")
    375                         f.write("<icon type=\"cached\">"+name+"_"+name+".png</icon>\n")
    376                         f.write("</component>\n")
    377                         f.write("</components>\n")
    378                         f.close()
    379                 with lock:
    380                         self.progress=self.progress+inc
    381                 semaphore.release()
    382        
    383         def _get_description(self,appName,infoPage):
    384                 desc=''
    385                 if '$(appname)' in infoPage:
    386                         infoPage=infoPage.replace('$(appname)',appName)
    387                 self._debug("Getting description from "+infoPage)
    388                 try:
    389                         with urllib.request.urlopen(infoPage) as f:
    390                                 content=(f.read().decode('utf-8'))
    391                                 soup=BeautifulSoup(content,"html.parser")
    392                                 descDiv=soup.findAll('div', attrs={ "class" : "description-text"})
    393                         if len(descDiv)>0:
    394                                 desc=descDiv[0].text
    395                                 desc=desc.replace(':','.')
    396                                 desc=desc.replace('&','&amp;')
    397                 except Exception as e:
    398                         print("Can't get description from "+infoPage)
    399                         print(str(e))
    400                         pass
    401                 return(desc)
    402 
    403         def _clean_bundle_catalogue(self,applist,outdir):
    404                 xmlList=[]
    405                 applist=[item.lower() for item in applist]
    406                 for xmlFile in os.listdir(outdir):
    407                         if xmlFile.endswith('appdata.xml'):
    408                                 xmlList.append(xmlFile.lower().replace('appdata.xml','appimage'))
    409        
    410                 if xmlList:
    411                         discardList=list(set(xmlList).difference(applist))
    412                         for discardFile in discardList:
    413                                 os.remove(outdir+'/'+discardFile.replace('appimage','appdata.xml'))
    414         #def _clean_appImg_repo
    415 
Note: See TracChangeset for help on using the changeset viewer.