fixes bug #436
[enigma2.git] / lib / python / Components / Ipkg.py
1 from enigma import eConsoleAppContainer
2 from Tools.Directories import fileExists
3
4 class IpkgComponent:
5         EVENT_INSTALL = 0
6         EVENT_DOWNLOAD = 1
7         EVENT_INFLATING = 2
8         EVENT_CONFIGURING = 3
9         EVENT_REMOVE = 4
10         EVENT_UPGRADE = 5
11         EVENT_LISTITEM = 9
12         EVENT_DONE = 10
13         EVENT_ERROR = 11
14         EVENT_MODIFIED = 12
15         
16         CMD_INSTALL = 0
17         CMD_LIST = 1
18         CMD_REMOVE = 2
19         CMD_UPDATE = 3
20         CMD_UPGRADE = 4
21         
22         def __init__(self, ipkg = '/usr/bin/ipkg'):
23                 self.ipkg = ipkg
24                 self.opkgAvail = fileExists('/usr/bin/opkg')
25                 self.cmd = eConsoleAppContainer()
26                 self.cache = None
27                 self.callbackList = []
28                 self.setCurrentCommand()
29                 
30         def setCurrentCommand(self, command = None):
31                 self.currentCommand = command
32                 
33         def runCmd(self, cmd):
34                 print "executing", self.ipkg, cmd
35                 self.cmd.appClosed.append(self.cmdFinished)
36                 self.cmd.dataAvail.append(self.cmdData)
37                 if self.cmd.execute(self.ipkg + " " + cmd):
38                         self.cmdFinished(-1)
39
40         def startCmd(self, cmd, args = None):
41                 if cmd == self.CMD_UPDATE:
42                         self.runCmd("update")
43                 elif cmd == self.CMD_UPGRADE:
44                         append = ""
45                         if args["test_only"]:
46                                 append = " -test"
47                         self.runCmd("upgrade" + append)
48                 elif cmd == self.CMD_LIST:
49                         self.fetchedList = []
50                         if args['installed_only']:
51                                 self.runCmd("list_installed")
52                         else:
53                                 self.runCmd("list")
54                 elif cmd == self.CMD_INSTALL:
55                         self.runCmd("install " + args['package'])
56                 elif cmd == self.CMD_REMOVE:
57                         self.runCmd("remove " + args['package'])
58                 self.setCurrentCommand(cmd)
59         
60         def cmdFinished(self, retval):
61                 self.callCallbacks(self.EVENT_DONE)
62                 self.cmd.appClosed.remove(self.cmdFinished)
63                 self.cmd.dataAvail.remove(self.cmdData)
64
65         def cmdData(self, data):
66                 print "data:", data
67                 if self.cache is None:
68                         self.cache = data
69                 else:
70                         self.cache += data
71
72                 if '\n' in data:
73                         splitcache = self.cache.split('\n')
74                         if self.cache[-1] == '\n':
75                                 iteration = splitcache
76                                 self.cache = None
77                         else:
78                                 iteration = splitcache[:-1]
79                                 self.cache = splitcache[-1]
80                         for mydata in iteration:
81                                 if mydata != '':
82                                         self.parseLine(mydata)
83                 
84         def parseLine(self, data):
85                 if self.currentCommand == self.CMD_LIST:
86                         item = data.split(' - ', 2)
87                         self.fetchedList.append(item)
88                         self.callCallbacks(self.EVENT_LISTITEM, item)
89                 else:
90                         if data.find('Downloading') == 0:
91                                 self.callCallbacks(self.EVENT_DOWNLOAD, data.split(' ', 5)[1].strip())
92                         elif data.find('Upgrading') == 0:
93                                 if self.opkgAvail:
94                                         self.callCallbacks(self.EVENT_UPGRADE, data.split(' ', 1)[1].split(' ')[0])
95                                 else:
96                                         self.callCallbacks(self.EVENT_UPGRADE, data.split('    ', 1)[1].split(' ')[0])
97                         elif data.find('Installing') == 0:
98                                 self.callCallbacks(self.EVENT_INSTALL, data.split(' ', 1)[1].split(' ')[0])
99                         elif data.find('Removing') == 0:
100                                 self.callCallbacks(self.EVENT_REMOVE, data.split(' ', 1)[1].split(' ')[1])
101                         elif data.find('Configuring') == 0:
102                                 self.callCallbacks(self.EVENT_CONFIGURING, data.split(' ', 1)[1].split(' ')[0])
103                         elif data.find('An error occurred') == 0:
104                                 self.callCallbacks(self.EVENT_ERROR, None)
105                         elif data.find('Failed to download') == 0:
106                                 self.callCallbacks(self.EVENT_ERROR, None)
107                         elif data.find('ipkg_download: ERROR:') == 0:
108                                 self.callCallbacks(self.EVENT_ERROR, None)
109                         elif data.find('    Configuration file \'') >= 0:
110                                 # Note: the config file update question doesn't end with a newline, so
111                                 # if we get multiple config file update questions, the next ones
112                                 # don't necessarily start at the beginning of a line
113                                 self.callCallbacks(self.EVENT_MODIFIED, data.split(' \'', 1)[1][:-1])
114
115         def callCallbacks(self, event, param = None):
116                 for callback in self.callbackList:
117                         callback(event, param)
118
119         def addCallback(self, callback):
120                 self.callbackList.append(callback)
121                 
122         def getFetchedList(self):
123                 return self.fetchedList
124         
125         def stop(self):
126                 self.cmd.kill()
127                 
128         def isRunning(self):
129                 return self.cmd.running()
130
131         def write(self, what):
132                 if what:
133                         # We except unterminated commands
134                         what += "\n"
135                         self.cmd.write(what, len(what))