source: epi/trunk/fuentes/python3-epi/epimanager.py @ 7315

Last change on this file since 7315 was 7315, checked in by jrpelegrina, 18 months ago

Fixed added i386 architecture

File size: 14.5 KB
Line 
1#!/usr/bin/env python3
2
3import os
4import subprocess
5import sys
6import json
7import platform
8#import socket
9import tempfile
10import time
11import datetime
12import urllib.request
13
14import lliurexstore.storeManager as StoreManager
15
16
17class EpiManager:
18       
19        def __init__(self):
20
21
22                self.storeManager=StoreManager.StoreManager()
23                self.reposPath="/etc/apt/sources.list.d/"
24                self.sources_list="epi.list"
25                self.epi_sources=os.path.join(self.reposPath,self.sources_list)
26                self.epi_keyring="/tmp/epi_keyring"
27                                               
28                self.order=0
29                self.epiFiles={}
30                self.arquitecture=False
31                self.update=False
32                self.zomando_name={}
33                self.epi_base={"repository":[],
34                                        "force32" : False,
35                                        "required_x" : False,
36                                        "script": {},
37                                        "depends":"",
38                                        "zomando":"",
39                                        "required_root":False
40                                        }
41
42                #self.read_conf(epi_file)
43       
44               
45        #def __init__   
46
47       
48        def check_connection(self):
49       
50                try:
51                        res=urllib.request.urlopen("http://lliurex.net")
52                        return True
53                       
54                except:
55                        return False   
56
57        #def check_connection   
58
59        def read_conf(self,epi_file):
60
61
62                if os.path.exists(epi_file):
63                        f=open(epi_file)
64                        epi_load=json.load(f)
65                        epi_conf=self.epi_base.copy()
66                        f.close()
67                        epi_conf.update(epi_load)
68                        self.epiFiles[self.order]=epi_conf
69                        self.zomando_name[self.order]=epi_conf["zomando"]
70                        try:
71                                if epi_conf["depends"]!="":
72                                        self.order=self.order+1
73                                        self.read_conf(epi_conf["depends"])
74                        except :
75                                pass           
76
77        #def read_conf         
78
79
80        def get_pkg_info(self):
81
82                pkg_list=[]
83                self.pkg_info={}
84                tmp_list=self.epiFiles.copy()
85
86                for item in tmp_list:
87                        pkg_list=[]
88                        pkg_list=tmp_list[item]["pkg_list"]
89                       
90                        info=self.get_store_info(pkg_list,item)
91
92                        cont=0
93
94                        for element in pkg_list:
95                                name=element["name"]
96                                if info[name]["status"]=="installed":
97                                        cont=cont+1
98
99                        if cont==len(pkg_list):
100                                if item>0:
101                                        self.epiFiles.pop(item)
102                                        self.zomando_name.pop(item)
103                                else:
104                                        self.epiFiles[item]["status"]="installed"
105                                        self.pkg_info.update(info)
106                        else:
107                                self.epiFiles[item]["status"]="availabled"
108                                self.pkg_info.update(info)     
109
110        #def get_pkg_info                               
111                                                       
112
113        def get_store_info(self,pkg_list,order):                       
114
115                        self.getStatus_byscript=False
116                        pkg_info={}
117                                               
118                        for item in pkg_list:
119                                app=item["name"]
120                                name=""
121                                summary=""
122                                status=""
123                                description=""
124                                icon=""
125                                debian_name=""
126                                component=""
127                                try:
128                                        pkg=item["key_store"]
129                                        action="info"
130                                        self.storeManager.execute_action(action,pkg)
131                                        while self.storeManager.is_action_running(action):
132                                                time.sleep(0.2)
133
134                                        ret=self.storeManager.get_status(action)
135
136                                        if ret["status"]==0:
137                                                data=self.storeManager.get_result(action)
138
139                                                if len(data)>0:
140
141                                                        description=data["info"][0]["description"]
142                                                        icon=data["info"][0]["icon"]
143                                                        name=data["info"][0]["name"]
144                                                        summary=data["info"][0]["summary"]
145                                                        debian_name=data["info"][0]["package"]
146                                                        component=data["info"][0]["component"]
147
148                                                        status=self.check_pkg_status(app,order)
149                                                        if not self.getStatus_byscript and status!="installed":
150                                                                if (data["info"][0]["state"]) !="":
151                                                                        status=data["info"][0]["state"]
152
153                                                else:
154                                                        status=self.check_pkg_status(app,order)         
155                                        else:
156                                                status=self.check_pkg_status(app,order) 
157                               
158                                except:
159                                        status=self.check_pkg_status(app,order) 
160                                                       
161                               
162                                pkg_info[app]={}
163                                pkg_info[app]["debian_name"]=debian_name
164                                pkg_info[app]["component"]=component
165                                pkg_info[app]["status"]=status
166                                pkg_info[app]["description"]=description
167                                pkg_info[app]["icon"]=icon
168                                pkg_info[app]["name"]=name
169                                pkg_info[app]["summary"]=summary
170
171                        return pkg_info
172
173        #def get_store_info                     
174
175        def check_pkg_status(self,pkg,order=None):
176       
177
178                try:
179                        if self.epiFiles[order]["script"]["getStatus"]:
180                                self.getStatus_byscript=True
181                except:
182                        pass
183
184                if self.getStatus_byscript:
185                        if order !=None:
186                                try:
187                                        script=self.epiFiles[order]["script"]["name"]
188                                        if os.path.exists(script):
189                                                cmd=script +' getStatus ' + pkg;
190                                                p=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
191                                                poutput=p.communicate()
192                                                if len(poutput)>0:
193                                                        if poutput[0].decode("utf-8").split("\n")[0]=='0':
194                                                                return "installed"
195                                               
196                                except Exception as e:
197                                        self.getStatus_byscript=False
198                                        #print (str(e))
199                                        pass
200                else:                                   
201
202                        cmd='dpkg -l '+ pkg + '| grep "^i[i]"'
203                        p=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
204                        poutput,perror=p.communicate()
205
206                        if len(poutput)>0:
207                                return "installed"
208               
209                               
210                return "available"     
211
212        #def check_pkg_status                                   
213               
214        def check_root(self):
215
216                self.root=False
217
218                try:
219                        f=open("/etc/epi.token","w")
220                        f.close()
221                        os.remove("/etc/epi.token")
222                        self.download_path="/var/cache/epi-downloads"
223                        self.root=True
224                except:
225                        if not os.path.exists(os.path.expanduser("~/.cache/epi-downloads/")):
226                                os.mkdir(os.path.expanduser("~/.cache/epi-downloads/"))
227                        self.download_path=os.path.expanduser("~/.cache/epi-downloads/")
228
229        #def check_root         
230
231
232        def required_root (self):
233
234                cont=0
235
236                if not self.root:
237                        for item in self.epiFiles:
238                                if self.epiFiles[item]["type"]!="file":
239                                        cont=cont+1
240
241                                else:
242                                        if self.epiFiles[item]["required_root"]:
243                                                cont=cont+1
244                                                       
245                        if cont>0:
246                                return True
247                        else:
248                                return False   
249
250                else:
251                        return False           
252
253        #def required_root             
254
255
256       
257        def check_update_repos(self):
258               
259                #Only update repos if needed
260                current_date=datetime.date.today().strftime('%y%m%d')
261                filename='/var/cache/apt/pkgcache.bin'
262                lastmod=os.path.getmtime(filename)
263                lastupdate=datetime.datetime.fromtimestamp(lastmod).strftime('%y%m%d')
264                cmd=""
265
266                if current_date !=lastupdate or self.update:
267                        cmd="LANG=C LANGUAGE=en apt-get update; "
268                else:
269                        for item in self.epi_conf["pkg_list"]:
270                                update_repo=False
271                                app=item["name"]
272                                command="LANG=C LANGUAGE=en apt-cache policy %s"%app
273                                p=subprocess.Popen(command,shell=True, stdout=subprocess.PIPE)
274                                output=p.communicate()
275                                if str(output[0]) != '':
276                                        tmp=str(output[0]).split("\\n")
277                                        if len(tmp)>1:
278                                                if tmp[2].split(":")[1]=="":
279                                                        update_repo=True
280                                                       
281                                        else:
282                                                update_repo=True
283                                               
284
285                                else:
286                                        update_repo=True
287
288                                if update_repo: 
289                                        cmd="LANG=C LANGUAGE=en apt-get update; "
290                                        return cmd             
291
292                return cmd
293               
294        #def check_update_repos
295
296        def check_arquitecture(self):
297
298                self.force32=self.epi_conf['force32']
299                cmd=""
300               
301                if self.force32:
302                        if platform.architecture()[0]=='64bit':
303                                cmd='dpkg --add-architecture i386; '
304                                self.update=True
305                                                               
306                self.arquitecture=True
307                return cmd             
308
309        #def check_arquitecture
310       
311        def add_repository_keys(self,order):
312
313                self.epi_conf=self.epiFiles[order]
314
315                cmd=""
316                self.type=self.epi_conf["type"]
317
318                if self.type=="apt":
319
320                        repos_list=self.epi_conf["repository"]
321
322                        if len(repos_list)>0:
323                                f = open(self.epi_sources,'w')
324                                for item in repos_list:
325                                        if item["url"]!="":
326                                                lines=item["url"].split(";")
327                                                for line in lines:
328                                                        f.write(line+'\n')
329                                        try:
330                                                key_cmd=item["key_cmd"]
331                                                if key_cmd !="":
332                                                        cmd=cmd+key_cmd+';'     
333                                        except Exception as e:
334                                                if len(self.epi_conf["script"])>0:
335                                                        try:
336                                                                if self.epi_conf["script"]["addRepoKeys"]:
337                                                                        script=self.epi_conf["script"]["name"]
338                                                                        if os.path.exists(script):
339                                                                                command=script + ' addRepoKeys;'
340                                                                                cmd=cmd+command
341                                                        except Exception as e:
342                                                                #print (str(e))
343                                                                pass
344
345                                f.close()
346                                self.update=True
347
348                       
349                return cmd             
350
351        #def add_repository_keys       
352
353
354        def get_app_version(self,item=None):
355
356                self.force32=self.epi_conf["force32"]
357
358                if self.force32:
359                        version=item["version"]["32b"]
360                       
361                else:
362                        try:
363                                version=item["version"]["all"]
364                        except Exception as e:
365                                if platform.architecture()[0]=='64bit': 
366                                        version=item["version"]["64b"]
367                                else:
368                                        version=item["version"]["32b"]
369                       
370                return version
371
372        #def get_app_version   
373                                               
374        def download_app(self):
375
376                self.manage_download=True
377                self.download_folder={}
378                cmd=""
379
380                self.type=self.epi_conf["type"]
381                if self.type !='apt':
382
383                        self.token_result_download=tempfile.mkstemp("_result_download")
384                       
385                        if self.type=="file":
386                                if len(self.epi_conf["script"])>0:
387                                        try:
388                                                if self.epi_conf["script"]["download"]:
389                                                        script=self.epi_conf["script"]["name"]
390                                                        if os.path.exists(script):
391                                                                cmd=script +' download; echo $? >' + self.token_result_download[1] +';'
392                                                                self.manage_download=False
393                                        except:
394                                                pass                   
395
396                        if self.manage_download:
397
398                                for item in self.epi_conf["pkg_list"]:
399                                        version=self.get_app_version(item)
400                                        if self.type=="deb":
401                                                name=item["name"]+".deb"
402                                                tmp_file=os.path.join(self.download_path,name)
403                                        else:
404                                                try:
405                                                        tmp_file=os.path.join(self.download_path,item["alias_download"])
406                                                except Exception as e: 
407                                                        #name=item["name"]
408                                                        tmp_file=os.path.join(self.download_path,version)
409                               
410                                        url=item["url_download"]
411                                       
412                                        if os.path.exists(tmp_file):
413                                                cmd=cmd+'rm -f '+ tmp_file +';'
414                                        self.download_folder["name"]=tmp_file
415                                        cmd=cmd+'wget ' +url+version + ' --progress=bar:force -O ' + tmp_file +'; '
416
417                                cmd=cmd + ' echo $? >' + self.token_result_download[1] +';'     
418                       
419
420                return cmd                     
421                                       
422        #def download_app               
423
424
425        def check_download(self):
426
427               
428                result=True
429
430                if self.type !='apt':
431
432                       
433                        if os.path.exists(self.token_result_download[1]):
434                                file=open(self.token_result_download[1])
435                                content=file.readline()
436                                if '0' not in content:
437                                        result=False
438                                file.close()
439                                os.remove(self.token_result_download[1])
440
441                                if result:     
442                                        if self.manage_download:
443                                                pkgs_todownload=len(self.download_folder)
444                                                cont=0
445
446                                                for item in self.download_folder:
447                                                        if os.path.exists(self.download_folder[item]):
448                                                                cont=cont+1
449
450                                                if cont != pkgs_todownload:
451                                                        result=False
452
453                return result
454
455        #def check_download             
456
457        def preinstall_app(self):
458       
459
460                cmd=""
461
462                if len(self.epi_conf["script"])>0:
463                        self.token_result_preinstall=tempfile.mkstemp("_result_preinstall")
464                        script=self.epi_conf["script"]["name"]
465                        if os.path.exists(script):
466                                cmd=script +' preInstall; echo $? >' + self.token_result_preinstall[1] +';'
467
468                return cmd             
469
470        #def preinstall_app     
471       
472
473        def check_preinstall(self):
474               
475                result=True
476
477                try:
478                        if os.path.exists(self.token_result_preinstall[1]):
479                                file=open(self.token_result_preinstall[1])
480                                content=file.readline()
481                                if '0' not in content:
482                                        result=False
483                                file.close()
484                                os.remove(self.token_result_preinstall[1])
485
486                except:                 
487                        pass
488
489                return result
490
491
492        #def check_preinstall_app       
493
494        def install_app(self):
495       
496                add_i386=""
497               
498                if not self.arquitecture:
499                        add_i386=self.check_arquitecture()
500
501
502                cmd=""
503               
504                if self.type=="apt":
505
506                        update_repos=self.check_update_repos()
507                        cmd=add_i386+update_repos+"LANG=C LANGUAGE=en DEBIAN_FRONTEND=noninteractive apt-get install --reinstall --allow-downgrades --allow-remove-essential --allow-change-held-packages --yes "
508                        for item in self.epi_conf["pkg_list"]:
509                                app=item["name"]
510                                cmd=cmd + app +" "
511
512       
513                       
514                elif self.type=="deb":
515                       
516                        cmd="dpkg -i "
517                        for item in self.epi_conf["pkg_list"]:
518                                name=item["name"]+".deb"
519                                pkg=self.download_folder["name"]
520                                cmd=cmd+pkg +" "
521
522                       
523                else:
524                        self.token_result_install=tempfile.mkstemp("_result")
525                        script=self.epi_conf["script"]["name"]
526                        if os.path.exists(script):
527                                cmd=script + ' installPackage; echo $? >' + self.token_result_install[1]
528
529                cmd=cmd+";"
530                return cmd     
531
532        #def install_app       
533
534
535        def check_install_remove(self,action):
536
537                dpkg_status={}
538                cont=0
539                token=""
540               
541                if action=="install":
542                               
543                        if self.type !="file":
544                                pkgs=self.epi_conf["pkg_list"]
545                       
546                                for item in pkgs:
547                                        status=self.check_pkg_status(item["name"])
548                               
549                                        if status=="installed":
550                                                cont=cont+1
551                               
552                                        dpkg_status[item["name"]]=status
553
554                                if cont==len(pkgs):
555                                        result=True
556               
557                                else:
558                                        result=False
559
560                        else:
561                                token=self.token_result_install[1]     
562                                if os.path.exists(token):
563                                        file=open(token)
564                                        content=file.readline()
565                                        if '0' not in content:
566                                                result=False
567                                        else:
568                                                result=True     
569                                                                               
570                                        file.close()
571                                        os.remove(token)
572
573                else:
574               
575                        if self.epiFiles[0]["type"] !="file":
576                                        pkgs=self.epiFiles[0]["pkg_list"]                       
577                                        for item in pkgs:
578                                                status=self.check_pkg_status(item["name"])
579                                                if status!="installed":
580                                                        cont=cont+1
581                                                dpkg_status[item["name"]]=status
582
583               
584                        token=self.token_result_remove[1]
585                        if os.path.exists(token):
586                                        file=open(token)
587                                        content=file.readline()
588                                        if '0' not in content:
589                                                result=False
590                                        else:
591                                                result=True     
592                                                       
593                                        file.close()
594                                        os.remove(token)
595
596                return dpkg_status,result                       
597
598       
599               
600        #def check_install_remove       
601
602        def postinstall_app(self):
603       
604
605                cmd=""
606               
607                if len(self.epi_conf["script"])>0:
608                        self.token_result_postinstall=tempfile.mkstemp("_result_postinstall")
609                        script=self.epi_conf["script"]["name"]
610                        if os.path.exists(script):
611                                cmd=script + ' postInstall; echo $? >' + self.token_result_postinstall[1] +';'
612
613                return cmd     
614
615        #def postinstall_app   
616       
617        def check_postinstall(self):
618               
619                result=True
620
621                try:
622                        if os.path.exists(self.token_result_postinstall[1]):
623                                file=open(self.token_result_postinstall[1])
624                                content=file.readline()
625                                if '0' not in content:
626                                        result=False
627                                file.close()
628                                os.remove(self.token_result_postinstall[1])
629                except:
630                        pass                   
631
632                return result
633
634        #def check_postinstall 
635
636        def remove_repo_keys(self):
637       
638                if os.path.exists(self.epi_sources):
639                        os.remove(self.epi_sources)     
640
641                if os.path.exists(self.epi_keyring):
642                        os.remove(self.epi_keyring)     
643
644        #def remove_repo_keys   
645
646        def uninstall_app(self,order):
647
648                cmd=""
649
650                if self.epiFiles[order]["script"]["remove"]:
651                        self.token_result_remove=tempfile.mkstemp("_result_remove")
652                        script=self.epiFiles[order]["script"]["name"]
653                        if os.path.exists(script):
654                                cmd=script + ' remove; echo $? >' + self.token_result_remove[1] + ';'
655
656                return cmd
657
658        #def uninstall_app     
659
660        def zerocenter_feedback(self,order,action,result=None):
661
662                zomando_name=self.zomando_name[order]
663
664                if zomando_name!="":
665                        if action=="init":
666                                cmd="zero-center add-pulsating-color " +zomando_name
667                        elif action=="install":
668                                if result:
669                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-configured " +zomando_name
670                                       
671                                else:
672                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-failed " +zomando_name
673                        elif action=="uninstall":
674                                if result:
675                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-non-configured " +zomando_name
676                                else:
677                                        cmd="zero-center remove-pulsating-color "+zomando_name + " ;zero-center set-failed " +zomando_name
678
679                        os.system(cmd)         
680
681        #def zero-center_feedback       
682
683
684#class ApplicationInstallerManager
685
686
687if __name__=="__main__":
688       
689        epi=EpiManager()
Note: See TracBrowser for help on using the repository browser.