Changeset 7118


Ignore:
Timestamp:
Apr 5, 2018, 2:57:59 PM (19 months ago)
Author:
Juanma
Message:

WIP on bundles support

Location:
lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins
Files:
4 edited

Legend:

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

    r7096 r7118  
    11#The name of the main class must match the file name in lowercase
     2import re
    23import urllib
    34from urllib.request import Request
     
    67import json
    78import os
    8 from subprocess import call
    99import sys
    1010import threading
    11 from bs4 import BeautifulSoup
     11import queue
     12import time
    1213import random
    13 import time
    1414import gi
    1515from gi.repository import Gio
    1616gi.require_version('AppStreamGlib', '1.0')
    1717from gi.repository import AppStreamGlib as appstream
     18from bs4 import BeautifulSoup
     19#from subprocess import call
    1820
    1921class appimagemanager:
    2022        def __init__(self):
    21                 self.dbg=False
     23                self.dbg=True
    2224                self.progress=0
    2325                self.partial_progress=0
     
    3436                #$(appname) we'll be replaced with the appname so the url matches the right one.
    3537                #If other site has other url naming convention it'll be mandatory to define it with the appropiate replacements
    36                 self.repos={'probono':{'url':'https://dl.bintray.com/probono/AppImages', 'url_info':'https://bintray.com/probono/AppImages/$(appname)'}}
     38                self.repos={'appimagehub':{'type':'json','url':'https://appimage.github.io/feed.json','url_info':''}}
    3739                #Appimges not stored in a repo must be listed in this file, providing the download url and the info url (if there's any)
    3840                self.external_appimages="/usr/share/lliurex-store/files/external_appimages.json"
     41                #Queue pool
     42                self.queue=queue.Queue()
    3943                self.disabled=False
    40                 self.count=0
    4144        #def __init__
    4245
     
    183186
    184187        def _load_appimage_store(self,store):
    185                 self._download_bundles_catalogue()
     188                self._get_bundles_catalogue()
    186189                if os.path.exists(self.bundles_dir):
    187190                        for bundle_type in self.bundle_types:
     
    208211        #def _generic_file_load
    209212
    210         def _download_bundles_catalogue(self):
    211                 CURSOR_UP='\033[F'
    212                 ERASE_LINE='\033[K'
    213                 content=''
     213        def _get_bundles_catalogue(self):
    214214                applist=[]
    215                 progress_bar="#"
    216                 self.descriptions_dict={}
     215                appdict={}
    217216                all_apps=[]
    218217                outdir=self.bundles_dir+'/appimg/'
    219218                #Load repos
    220219                for repo_name,repo_info in self.repos.items():
    221                         if self._chk_bundle_dir(outdir):
    222                                 self._debug("Fetching repo %s"%repo_info['url'])
    223 ##                                      print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r")
    224 ##                                      progress_bar=progress_bar+"#"
    225 ##                                      print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r")
    226                                 applist=self._generate_applist(self._fetch_repo(repo_info['url']),repo_name)
    227 ##                                      progress_bar=progress_bar+"##"
    228 ##                                      print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r")
    229                                 self._debug("Processing info...")
    230                                 self._th_generate_xml_catalog(applist,outdir,repo_info['url_info'],repo_info['url'],repo_name,progress_bar)
    231                                 self._debug("Fetched repo "+repo_info['url'])
    232                                 all_apps.extend(applist)
    233                         else:
     220                        if not os.path.isdir(self.bundles_dir):
     221                                try:
     222                                        os.makedirs(self.bundles_dir)
     223                                except:
    234224                                        self._debug("appImage catalogue could not be fetched: Permission denied")
     225                        self._debug("Fetching repo %s"%repo_info['url'])
     226                        if repo_info['type']=='json':
     227                                applist=self._process_appimage_json(self._fetch_repo(repo_info['url']),repo_name)
     228
     229                        self._debug("Fetched repo "+repo_info['url'])
     230                        self._th_generate_xml_catalog(applist,outdir,repo_info['url_info'],repo_info['url'],repo_name)
     231                        all_apps.extend(applist)
    235232                #Load external apps
    236233                for app_name,app_info in self._get_external_appimages().items():
    237                         if self._chk_bundle_dir(outdir):
    238                                 appimage=app_info['url'].split('/')[-1]
    239                                 appimage_url='/'.join(app_info['url'].split('/')[0:-1])
     234                        if os.path.isdir(self.bundles_dir):
     235                                appinfo=self._init_appinfo()
     236                                appinfo['name']=app_info['url'].split('/')[-1]
     237                                appinfo['package']=app_info['url'].split('/')[-1]
     238                                appinfo['homepage']='/'.join(app_info['url'].split('/')[0:-1])
    240239                                self._debug("Fetching external appimage %s"%app_info['url'])
    241                                 applist=[appimage]
    242                                 self._debug("Processing info...")
    243                                 self._th_generate_xml_catalog(applist,outdir,app_info['url_info'],appimage_url,app_name,progress_bar)
     240                                appinfo['bundle']='appimage'
     241                                applist=[appinfo]
     242                                self._th_generate_xml_catalog(applist,outdir,app_info['url_info'],app_info['url'],app_name)
    244243                                self._debug("Fetched appimage "+app_info['url'])
    245244                                all_apps.extend(applist)
    246245                        else:
    247246                                self._debug("External appImage could not be fetched: Permission denied")
    248 
    249 
    250 ##              print (("Removing old entries..."))
    251                 self._clean_bundle_catalogue(all_apps,outdir)
     247                self._debug("Removing old entries...")
     248#               self._clean_bundle_catalogue(all_apps,outdir)
    252249                return(True)
    253         #def _download_bundles_catalogue
    254 
    255         def _get_external_appimages(self):
    256                 external_appimages={}
    257                 if os.path.isfile(self.external_appimages):
    258                         try:
    259                                 with open(self.external_appimages) as appimages:
    260                                         external_appimages=json.load(appimages)
    261                         except:
    262                                 self._debug("Can't load %s"%self.external_appimages)
    263                 self._debug(external_appimages)
    264                 return external_appimages
    265 
    266         def _chk_bundle_dir(self,outdir):
    267                 msg_status=True
    268                 if not os.path.isdir(outdir):
    269                         try:
    270                                 os.makedirs(outdir)
    271                         except Exception as e:
    272                                 msg_status=False
    273                                 print(e)
    274                 return(os.access(outdir,os.W_OK|os.R_OK|os.X_OK|os.F_OK))
    275         #def _chk_bundle_dir
    276 
     250        #def _get_bundles_catalogue
     251       
    277252        def _fetch_repo(self,repo):
    278253                req=Request(repo, headers={'User-Agent':'Mozilla/5.0'})
     
    282257                return(content)
    283258        #def _fetch_repo
    284 
    285         def _generate_applist(self,content,repo_name):
    286                 garbage_list=[]
     259       
     260        def _get_external_appimages(self):
     261                external_appimages={}
     262                if os.path.isfile(self.external_appimages):
     263                        try:
     264                                with open(self.external_appimages) as appimages:
     265                                        external_appimages=json.load(appimages)
     266                        except:
     267                                self._debug("Can't load %s"%self.external_appimages)
     268                self._debug(external_appimages)
     269                return external_appimages
     270        #def _get_external_appimages
     271       
     272        def _process_appimage_json(self,data,repo_name):
     273                maxconnections = 10
     274                semaphore = threading.BoundedSemaphore(value=maxconnections)
    287275                applist=[]
    288                 #webscrapping for probono repo
    289                 if repo_name=='probono':
    290                         garbage_list=content.split(' ')
    291                         for garbage_line in garbage_list:
    292                                 if garbage_line.endswith('AppImage"'):
    293                                         app=garbage_line.replace('href=":','')
    294                                         applist.append(app.replace('"',''))
    295                 #Example of a webscrapping from another site
    296 #               if repo_name='other_repo_name':
    297 #                       for garbage_line in garbage_list:
    298 #                                       if garbage_line.startswith('file="'):
    299 #                                               if 'appimage' in garbage_line:
    300 #                                                       app=garbage_line.replace('file="','')
    301 #                                                       app=app.replace('\n','')
    302 #                                                       self._debug("Add %s"%app)
    303 #                                                       applist.append(app.replace('"',''))
    304 
    305                 return(applist)
    306         #def _generate_applist
    307 
    308         def _th_generate_xml_catalog(self,applist,outdir,info_url,repo,repo_name,progress_bar=''):
    309                 CURSOR_UP='\033[F'
    310                 ERASE_LINE='\033[K'
     276                json_data=json.loads(data)
     277                if 'items' in json_data.keys():
     278                        for appimage in json_data['items']:
     279                                appinfo=self._th_process_appimage(appimage,semaphore)
     280                                if appinfo:
     281                                        applist.append(appinfo)
     282                                        #                               th=threading.Thread(target=self._th_process_appimage, args = (appimage,semaphore))
     283#                               th.start()
     284
     285#               while threading.active_count()>1:
     286#                       print("%s"%threading.active_count())
     287#                       time.sleep(0.1)
     288
     289#               while not self.queue.empty():
     290#                       applist.append(self.queue.get())
     291#                       self._debug("Added %s"%applist[-1])
     292                self._debug("JSON: %s"%applist)
     293                return (applist)
     294        #_process_appimage_json
     295
     296        def _th_process_appimage(self,appimage,semaphore):
     297                appinfo=None
     298#               semaphore.acquire()
     299#               lock=threading.Lock()
     300                releases=[]
     301                if 'links' in appimage.keys():
     302                        if appimage['links']:
     303                                appinfo=self.load_json_appinfo(appimage)
     304#Deprecated. appImage releases will be load on the info stage
     305#                       releases=self._get_releases_from_json(appimage)
     306#                       if releases:
     307#                               appinfo['releases']=releases
     308#                               for release in releases:
     309#                                       #Release has the direct download url
     310#                                       tmp_release=release.split('/')
     311#                                       tmp_appinfo=appinfo.copy()
     312#                                       rel_number=tmp_release[-2]
     313#                                       rel_name=tmp_release[-1].lower().replace('.appimage','')
     314#                                       self._debug("Release: %s"%release)
     315#                                       tmp_appinfo['name']=rel_name
     316#                                       tmp_appinfo['package']=tmp_release[-1]
     317#                                       tmp_appinfo['homepage']='/'.join(tmp_release[0:-1])
     318#                                       self.queue.put(tmp_appinfo)
     319#Threading disabled
     320#                               self.queue.put(appinfo)
     321                return(appinfo)
     322        #def _th_process_appimage
     323
     324        def load_json_appinfo(self,appimage):
     325                appinfo=self._init_appinfo()
     326                appinfo['name']=appimage['name']
     327                appinfo['package']=appimage['name']
     328                if 'license' in appimage.keys():
     329                        appinfo['license']=appimage['license']
     330                appinfo['summary']=''
     331                if 'description' in appimage.keys():
     332                        appinfo['description']=appimage['description']
     333                if 'categories' in appimage.keys():
     334                        appinfo['categories']=appimage['categories']
     335                if 'icon' in appimage.keys():
     336                        appinfo['icon']=appimage['icon']
     337                if 'screenshots' in appimage.keys():
     338                        appinfo['thumbnails']=appimage['screenshots']
     339                if 'links' in appimage.keys():
     340                        if appimage['links']:
     341                                for link in appimage['links']:
     342                                        if 'url' in link.keys() and link['type']=='Download':
     343                                                appinfo['homepage']=link['url']
     344                elif 'authors' in appimage.keys():
     345                        if appimage['authors']:
     346                                for author in appimage['authors']:
     347                                        if 'url' in author.keys():
     348                                                appinfo['homepage']=author['url']
     349                appinfo['bundle']='appimage'
     350                return appinfo
     351        #def load_json_appinfo
     352
     353        def _get_releases_from_json(self,appimage):
     354                releases=[]
     355                if appimage['links']:
     356                        for link in appimage['links']:
     357                                if 'type' in link.keys():
     358                                        if link['type']=='Download':
     359                                                self._debug("Info url: %s"%link['url'])
     360                                                try:
     361                                                        sw_git=False
     362                                                        with urllib.request.urlopen(link['url']) as f:
     363                                                                if 'github' in link['url']:
     364                                                                        sw_git=True
     365                                                                content=(f.read().decode('utf-8'))
     366                                                                soup=BeautifulSoup(content,"html.parser")
     367                                                                package_a=soup.findAll('a', attrs={ "href" : re.compile(r'.*[aA]pp[iI]mage$')})
     368                                                                for package_data in package_a:
     369                                                                        package_name=package_data.findAll('strong', attrs={ "class" : "pl-1"})
     370                                                                        package_link=package_data['href']
     371                                                                        if sw_git:
     372                                                                                package_link="https://github.com"+package_link
     373                                                                                releases.append(package_link)
     374                                                                                self._debug("Link: %s"%package_link)
     375                                                except Exception as e:
     376                                                        print(e)
     377                return releases
     378        #def _get_releases_from_json
     379
     380        def _th_generate_xml_catalog(self,applist,outdir,info_url,repo,repo_name):
    311381                maxconnections = 10
    312382                semaphore = threading.BoundedSemaphore(value=maxconnections)
    313383                random_applist = list(applist)
    314384                random.shuffle(random_applist)
    315                 len_applist=len(random_applist)
    316                 inc=30/len_applist
    317 #               print (CURSOR_UP)
    318                 for app in random_applist:
    319                         th=threading.Thread(target=self._th_write_xml, args = (app,outdir,info_url,repo,repo_name,semaphore,inc))
     385                for app in applist:
     386                        th=threading.Thread(target=self._th_write_xml, args = (app,outdir,info_url,repo,repo_name,semaphore))
    320387                        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(progress_bar),int(self.progress)):
    324 #                               progress_bar='#'+progress_bar
    325 #                       print (CURSOR_UP)
    326 #                       print (("Fetching %s catalogue: "+progress_bar)%repo_type,end="\r")
    327 #               os.system('setterm -cursor on')
    328388        #def _th_generate_xml_catalog
    329389
    330         def _th_write_xml(self,app,outdir,info_url,repo,repo_name,semaphore,inc):
     390        def _th_write_xml(self,appinfo,outdir,info_url,repo,repo_name,semaphore):
    331391                semaphore.acquire()
    332392                lock=threading.Lock()
    333                 name_splitted=app.split('-')
    334                 name=name_splitted[0]
    335                 if len(name_splitted)>1:
    336                         version=name_splitted[1]
    337                 if len(name_splitted)>2:
    338                         arch=name_splitted[2]
    339                 filename=outdir+app.lower().replace('appimage',"appdata.xml")
     393                self._debug("Populating %s"%appinfo)
     394                package=appinfo['name'].lower().replace(".appimage","")
     395                if len(package)>40:
     396                        tmp_package=package.split('-')
     397                        tam=0
     398                        pos=1
     399                        index=0
     400                        banned=['linux32','linux64','i386','x86_64','ia32','amd64']
     401                        for tmp_name in tmp_package:
     402                                if (tam<len(tmp_name) and pos<index) and tmp_name not in banned:
     403                                        tam=len(tmp_name)
     404                                        pos=index
     405                                index+=1
     406                        print("Removed: %s"%tmp_package[pos])
     407                        tmp_package[pos]=''
     408                        package='-'.join(tmp_package)
     409                        package=package.replace("--","-")
     410                        package=package.replace("-.",".")
     411
     412                filename=outdir+package.lower().replace('appimage',"appdata")+".xml"
    340413                self._debug("checking if we need to download "+filename)
    341414                if not os.path.isfile(filename):
    342                         self._write_xml_file(filename,app,name,version,info_url,repo,repo_name,lock)
    343                 with lock:
    344                         self.progress=self.progress+inc
     415                        repo_info={'info_url':info_url,'repo':repo,repo_name:'repo_name'}
     416                        self._write_xml_file(filename,appinfo,repo_info,lock)
    345417                semaphore.release()
    346418        #def _th_write_xml
    347419
    348         def _write_xml_file(self,filename,app,name,version,info_url,repo,repo_name,lock):
    349                         self._debug("Generating "+app+" xml")
     420        def _write_xml_file(self,filename,appinfo,repo_info,lock):
     421                        name=appinfo['name'].lower().replace(".appimage","")
     422                        self._debug("Generating %s xml"%appinfo['package'])
    350423                        f=open(filename,'w')
    351424                        f.write('<?xml version="1.0" encoding="UTF-8"?>'+"\n")
    352425                        f.write("<components version=\"0.10\">\n")
    353426                        f.write("<component  type=\"desktop-application\">\n")
    354                         f.write("  <id>"+app.lower()+"</id>\n")
    355                         f.write("  <pkgname>"+app+"</pkgname>\n")
    356                         if version:
    357                                 version='-'+version
    358                         f.write("  <name>"+name+version+"</name>\n")
     427                        f.write("  <id>%s</id>\n"%appinfo['package'].lower())
     428                        f.write("  <pkgname>%s</pkgname>\n"%appinfo['package'])
     429                        f.write("  <name>%s</name>\n"%name)
    359430                        f.write("  <metadata_license>CC0-1.0</metadata_license>\n")
    360                         f.write("  <provides><binary>"+app+"</binary></provides>\n")
    361                         f.write("  <releases>\n")
    362                         f.write("  <release version=\""+version+"\" timestamp=\"1408573857\"></release>\n")
    363                         f.write("  </releases>\n")
    364                         f.write("  <launchable type=\"desktop-id\">"+name+".desktop</launchable>\n")
    365                         with lock:
    366                                 try:
    367                                         if name in self.descriptions_dict.keys():
    368                                                 (description,icon)=self.descriptions_dict[name]
    369                                         else:
    370                                                 (description,icon)=self._get_description_icon(name,info_url,repo_name)
    371                                                 self.descriptions_dict.update({name:[description,icon]})
    372                                 except:
    373                                         description=''
    374                                         icon=''
     431                        f.write("  <provides><binary>%s</binary></provides>\n"%appinfo['package'])
     432                        if 'releases' in appinfo.keys():
     433                                f.write("  <releases>\n")
     434                                for release in appinfo['releases']:
     435                                        tmp_release=release.split('/')
     436                                        rel_number='/'.join(tmp_release[-2:])
     437                                        f.write("    <release version=\"%s\" urgency=\"medium\">"%rel_number)
     438                                        f.write("</release>\n")
     439                                f.write("  </releases>\n")
     440                        f.write("  <launchable type=\"desktop-id\">%s.desktop</launchable>\n"%name)
     441                        if appinfo['description']=='':
     442                                with lock:
     443                                        try:
     444                                                if appinfo['name'] in self.descriptions_dict.keys():
     445                                                        (description,icon)=self.descriptions_dict[appinfo['name']]
     446                                                else:
     447                                                        (description,icon)=self._get_description_icon(appinfo['name'],repo_info)
     448                                                        self.descriptions_dict.update({appinfo['name']:[description,icon]})
     449                                        except:
     450                                                description=''
     451                                                icon=''
     452                        else:
     453                                description=appinfo['description']
    375454                        summary=' '.join(list(description.split(' ')[:8]))
    376                         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
    377                         if not summary:
     455                        if len(description.split(' '))>8:
     456                                summary+="... "
     457                        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"%(name,description)
     458                        if summary=='':
    378459                                summary=' '.join(list(description.split(' ')[:8]))
    379                         f.write("  <description><p></p><p>"+description+"</p></description>\n")
    380                         f.write("  <summary>"+summary+"...</summary>\n")
    381                         f.write('  <url type="homepage">'+repo+'</url>\n')
    382                         f.write("  <bundle type=\"appimage\">"+app+"</bundle>\n")
     460                        f.write("  <description><p></p><p>%s</p></description>\n"%description)
     461                        f.write("  <summary>%s</summary>\n"%summary)
     462#                       f.write("  <icon type=\"local\">%s</icon>\n"%appinfo['icon'])
     463                        f.write("<icon type=\"cached\">"+name+"_"+name+".png</icon>\n")
     464                        f.write("  <url type=\"homepage\">%s</url>\n"%appinfo['homepage'])
     465                        f.write("  <bundle type=\"appimage\">%s</bundle>\n"%appinfo['name'])
    383466                        f.write("  <keywords>\n")
    384                         f.write("       <keyword>"+name+"</keyword>\n")
     467                        keywords=name.split("-")
     468                        banned_keywords=["linux","x86_64","i386","ia32","amd64"]
     469                        for keyword in keywords:
     470                                #Better than isalpha method for this purpose
     471                                if keyword.isidentifier() and keyword not in banned_keywords:
     472                                        f.write("       <keyword>%s</keyword>\n"%keyword)
    385473                        f.write("       <keyword>appimage</keyword>\n")
    386474                        f.write("  </keywords>\n")
    387475                        f.write("  <categories>\n")
    388476                        f.write("       <category>AppImage</category>\n")
    389 #                       f.write("       <category>GTK</category>\n")
     477                        if 'categories' in appinfo.keys():
     478                                for category in appinfo['categories']:
     479                                        f.write("       <category>%s</category>\n"%category)
    390480                        f.write("  </categories>\n")
    391 #                       f.write("<icon type=\"cached\">"+name+"_"+name+".png</icon>\n")
    392                         f.write("<icon type=\"local\">"+icon+"</icon>\n")
    393481                        f.write("</component>\n")
    394482                        f.write("</components>\n")
     
    468556                return(target_file)
    469557        #def _download_file
     558       
     559        def _chk_bundle_dir(self,outdir):
     560                msg_status=True
     561                if not os.path.isdir(outdir):
     562                        try:
     563                                os.makedirs(outdir)
     564                        except Exception as e:
     565                                msg_status=False
     566                                print(e)
     567                return(os.access(outdir,os.W_OK|os.R_OK|os.X_OK|os.F_OK))
     568        #def _chk_bundle_dir
     569       
     570        def _init_appinfo(self):
     571                appInfo={'appstream_id':'',\
     572                'id':'',\
     573                'name':'',\
     574                'version':'',\
     575                'releases':[],\
     576                'package':'',\
     577                'license':'',\
     578                'summary':'',\
     579                'description':'',\
     580                'categories':[],\
     581                'icon':'',\
     582                'screenshot':'',\
     583                'thumbnails':[],\
     584                'video':'',\
     585                'homepage':'',\
     586                'installerUrl':'',\
     587                'state':'',\
     588                'depends':'',\
     589                'kudos':'',\
     590                'suggests':'',\
     591                'extraInfo':'',\
     592                'size':'',\
     593                'bundle':'',\
     594                'updatable':'',\
     595                }
     596                return(appInfo)
     597        #def _init_appinfo
  • lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/appimage_catalogue.py

    r7115 r7118  
    1717gi.require_version('AppStreamGlib', '1.0')
    1818from gi.repository import AppStreamGlib as appstream
    19 
     19import queue
     20import time
    2021
    2122class appimageToAppstream:
     
    2930                #Appimges not stored in a repo must be listed in this file, providing the download url and the info url (if there's any)
    3031                self.external_appimages="/usr/share/lliurex-store/files/external_appimages.json"
    31                 self.disabled=False
    3232                self.conf_dir=os.getenv("HOME")+"/.cache/lliurex-store"
    3333                self.bundles_dir=self.conf_dir+"/bundles"
    34                 self.count=0
     34                self.queue=queue.Queue()
    3535        #def __init__
    3636
     
    4747                #Load repos
    4848                for repo_name,repo_info in self.repos.items():
    49                         if os.path.isdir(self.bundles_dir):
    50                                 self._debug("Fetching repo %s"%repo_info['url'])
    51                                 if repo_info['type']=='repo':
    52                                         applist=self._generate_applist(self._fetch_repo(repo_info['url']),repo_name)
    53                                         self._debug("Processing info...")
    54                                 elif repo_info['type']=='json':
    55                                         applist=self._process_appimage_json(self._fetch_repo(repo_info['url']),repo_name)
    56                                 self._debug("Fetched repo "+repo_info['url'])
    57                                 self._th_generate_xml_catalog(applist,outdir,repo_info['url_info'],repo_info['url'],repo_name)
    58                                 all_apps.extend(applist)
    59                         else:
    60                                 self._debug("appImage catalogue could not be fetched: Permission denied")
     49                        if not os.path.isdir(self.bundles_dir):
     50                                try:
     51                                        os.makedirs(self.bundles_dir)
     52                                except:
     53                                        self._debug("appImage catalogue could not be fetched: Permission denied")
     54                        self._debug("Fetching repo %s"%repo_info['url'])
     55                        if repo_info['type']=='repo':
     56                                applist=self._generate_applist(self._fetch_repo(repo_info['url']),repo_name)
     57                                self._debug("Processing info...")
     58                        elif repo_info['type']=='json':
     59                                applist=self._process_appimage_json(self._fetch_repo(repo_info['url']),repo_name)
     60
     61                        self._debug("Fetched repo "+repo_info['url'])
     62                        self._th_generate_xml_catalog(applist,outdir,repo_info['url_info'],repo_info['url'],repo_name)
     63                        all_apps.extend(applist)
    6164                #Load external apps
    6265                for app_name,app_info in self._get_external_appimages().items():
     
    7679                self._debug("Removing old entries...")
    7780#               self._clean_bundle_catalogue(all_apps,outdir)
    78                 return(True)
    7981        #def _download_bundles_catalogue
    8082
     
    148150                if 'items' in json_data.keys():
    149151                        for appimage in json_data['items']:
    150                                 th=threading.Thread(target=self._th_write_xml, args = (app,outdir,info_url,repo,repo_name,semaphore))
     152                                th=threading.Thread(target=self._th_process_appimage, args = (appimage,semaphore))
    151153                                th.start()
    152154
    153 
    154                                 releases=[]
    155                                 if 'links' in appimage.keys():
    156                                         releases=self._get_releases_from_json(appimage)
    157                                 if releases:
    158                                         appinfo=self.load_json_appinfo(appimage)
    159                                         appinfo['releases']=releases
    160                                         applist.append(appinfo)
    161 #                                       for release in releases:
    162 #                                               tmp_appinfo=appinfo.copy()
    163 #                                               self._debug("Release: %s"%release)
    164 #                                               tmp_appinfo['name']=release
    165 #                                               tmp_appinfo['package']=release
    166 #                                               applist.append(tmp_appinfo)
     155                while threading.active_count()>1:
     156                    time.sleep(0.1)
     157
     158                while not self.queue.empty():
     159                    applist.append(self.queue.get())
    167160                self._debug("JSON: %s"%applist)
    168161                return (applist)
    169162        #_process_appimage_json
     163
     164        def _th_process_appimage(self,appimage,semaphore):
     165                releases=[]
     166                if 'links' in appimage.keys():
     167                        releases=self._get_releases_from_json(appimage)
     168                if releases:
     169                        appinfo=self.load_json_appinfo(appimage)
     170                        appinfo['releases']=releases
     171#                       self.queue.put(appinfo)
     172                        for release in releases:
     173                                #Release has the direct download url
     174                                tmp_release=release.split('/')
     175                                tmp_appinfo=appinfo.copy()
     176                                rel_number=tmp_release[-2]
     177                                rel_name=tmp_release[-1].lower().replace('.appimage','')
     178                                self._debug("Release: %s"%release)
     179                                tmp_appinfo['name']=rel_name
     180                                tmp_appinfo['package']=tmp_release[-1]
     181                                tmp_appinfo['homepage']='/'.join(tmp_release[0:-1])
     182                                self.queue.put(tmp_appinfo)
     183        #def _th_process_appimage
    170184
    171185        def load_json_appinfo(self,appimage):
     
    184198                if 'screenshots' in appimage.keys():
    185199                        appinfo['thumbnails']=appimage['screenshots']
    186                 if 'authors' in appimage.keys():
     200                if 'links' in appimage.keys():
     201                        if appimage['links']:
     202                                for link in appimage['links']:
     203                                        if 'url' in link.keys() and link['type']=='Download':
     204                                                appinfo['homepage']=link['url']
     205                elif 'authors' in appimage.keys():
    187206                        if appimage['authors']:
    188207                                for author in appimage['authors']:
     
    201220                                                self._debug("Info url: %s"%link['url'])
    202221                                                try:
     222                                                        sw_git=False
    203223                                                        with urllib.request.urlopen(link['url']) as f:
     224                                                                if 'github' in link['url']:
     225                                                                        sw_git=True
    204226                                                                content=(f.read().decode('utf-8'))
    205227                                                                soup=BeautifulSoup(content,"html.parser")
    206228                                                                package_a=soup.findAll('a', attrs={ "href" : re.compile(r'.*[aA]pp[iI]mage$')})
    207229                                                                for package_data in package_a:
    208                                                                         package_soup=BeautifulSoup(str(package_data),"html.parser")
    209                                                                         package_name=package_soup.findAll('strong', attrs={ "class" : "pl-1"})
    210                                                                         self._debug("Release name: %s"%package_name)
    211                                                                         for name in package_name:
    212                                                                                 releases.append(name.get_text())
     230                                                                        package_name=package_data.findAll('strong', attrs={ "class" : "pl-1"})
     231                                                                        package_link=package_data['href']
     232                                                                        if sw_git:
     233                                                                                package_link="https://github.com"+package_link
     234                                                                                releases.append(package_link)
     235                                                                                self._debug("Link: %s"%package_link)
    213236                                                except Exception as e:
    214237                                                        print(e)
     
    230253                lock=threading.Lock()
    231254                self._debug("Populating %s"%appinfo)
    232                 filename=outdir+appinfo['package'].lower().replace('appimage',"appdata")+".xml"
     255                package=appinfo['name'].lower().replace(".appimage","")
     256                if len(package)>40:
     257                        tmp_package=package.split('-')
     258                        tam=0
     259                        pos=1
     260                        index=0
     261                        banned=['linux32','linux64','i386','x86_64','ia32','amd64']
     262                        for tmp_name in tmp_package:
     263                                if (tam<len(tmp_name) and pos<index) and tmp_name not in banned:
     264                                        tam=len(tmp_name)
     265                                        pos=index
     266                                index+=1
     267                        print("Removed: %s"%tmp_package[pos])
     268                        tmp_package[pos]=''
     269                        package='-'.join(tmp_package)
     270                        package=package.replace("--","-")
     271                        package=package.replace("-.",".")
     272
     273                filename=outdir+package.lower().replace('appimage',"appdata")+".xml"
    233274                self._debug("checking if we need to download "+filename)
    234275                if not os.path.isfile(filename):
     
    249290                        f.write("  <name>%s</name>\n"%name)
    250291                        f.write("  <metadata_license>CC0-1.0</metadata_license>\n")
    251                         f.write("  <provides><binary>%s</binary></provides>\n"%appinfo['name'])
     292                        f.write("  <provides><binary>%s</binary></provides>\n"%appinfo['package'])
    252293                        if 'releases' in appinfo.keys():
    253294                                f.write("  <releases>\n")
    254295                                for release in appinfo['releases']:
    255                                         f.write("    <release version=\"%s\" urgency=\"medium\">"%release)
     296                                        tmp_release=release.split('/')
     297                                        rel_number='/'.join(tmp_release[-2:])
     298                                        f.write("    <release version=\"%s\" urgency=\"medium\">"%rel_number)
    256299                                        f.write("</release>\n")
    257300                                f.write("  </releases>\n")
  • lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/infoManager.py

    r7096 r7118  
    165165                                if bundle.get_kind()==0:
    166166                                        kind=bundle.get_id().split('.')[-1]
    167                                         appInfo['bundle']=kind.lower()
     167                                        appInfo['bundle'].append(kind.lower())
    168168                                        if kind.lower=='sh':
    169169                                                appInfo['installerUrl']=bundle.get_id()
     
    196196                'extraInfo':'',\
    197197                'size':'',\
    198                 'bundle':'',\
     198                'bundle':[],\
    199199                'updatable':'',\
     200                'releases':[]
    200201                }
    201202                return(appInfo)
  • lliurex-store/trunk/fuentes/python3-lliurex-store.install/usr/share/lliurexstore/plugins/snapManager.py

    r7092 r7118  
    116116                self._set_status(1)
    117117                for pkg in pkgs:
    118                         store.add_app(self._generate_appstream_app(pkg))
     118                        app=self.store.get_app_by_pkgname(pkg.get_name())
     119                        if app:
     120                                bundle=appstream.Bundle()
     121                                bundle.set_kind(bundle.kind_from_string('SNAP'))
     122                                bundle.set_id(pkg.get_name()+'.snap')
     123                                app.add_bundle(bundle)
     124#                               store.add_app(self._generate_appstream_app_from_snap(pkg))
     125                        else:
     126                                store.add_app(self._generate_appstream_app_from_snap(pkg))
    119127                return(store)
    120128
    121         def _generate_appstream_app(self,pkg):
     129        def _generate_appstream_app_from_snap(self,pkg):
    122130                bundle=appstream.Bundle()
    123131                app=appstream.App()
     
    130138                app.add_bundle(bundle)
    131139                app.set_name("C",pkg.get_name())
    132                 app.add_pkgname(pkg.get_name()+'.snap')
     140#               app.add_pkgname(pkg.get_name()+'.snap')
     141                app.add_pkgname(pkg.get_name())
    133142                app.add_category("Snap")
    134143                release=appstream.Release()
     
    246255                pkg=None
    247256                try:
    248                         pkg=self.snap_client.list_one_sync(app_info['name'])
     257                        pkg=self.snap_client.list_one_sync(app_info['package'])
    249258                        app_info['state']='installed'
    250259                        pkgs=[pkg]
     
    252261                        app_info['state']='available'
    253262                        if self.cli_mode:
    254                                 pkgs=self._search_snap(app_info['name'])
    255                         else:
    256                                 pkgs=self._search_snap_async(app_info['name'])
     263                                pkgs=self._search_snap(app_info['package'])
     264                        else:
     265                                pkgs=self._search_snap_async(app_info['package'])
    257266                        self._debug("Getting extended info for %s %s"%(app_info['name'],pkgs))
    258267                if type(pkgs)==type([]):
Note: See TracChangeset for help on using the changeset viewer.