e0fde567a2a7ff7cb78be69b3c6d4017b3a4dfd8
[openblackhole/openblackhole-enigma2.git] / lib / python / Screens / CopyFiles.py
1 import os
2 import Components.Task
3 from twisted.internet import reactor, threads, task
4
5 class FailedPostcondition(Components.Task.Condition):
6         def __init__(self, exception):
7                 self.exception = exception
8         def getErrorMessage(self, task):
9                 return str(self.exception)
10         def check(self, task):
11                 return self.exception is None
12
13
14 class CopyFileTask(Components.Task.Task):
15         def openFiles(self, fileList):
16                 self.callback = None
17                 self.handles = [(open(fn[0], 'rb'), open(fn[1], 'wb')) for fn in fileList]
18                 self.end = 0
19                 for src,dst in fileList:
20                         try:
21                                 self.end += os.stat(src).st_size
22                         except:
23                                 print "Failed to stat", src
24                 if not self.end:
25                         self.end = 1
26                 print "[CopyFileTask] size:", self.end
27         def run(self, callback):
28                 print "[CopyFileTask] run"
29                 self.callback = callback
30                 self.aborted = False
31                 self.pos = 0
32                 threads.deferToThread(self.copyHandles).addBoth(self.onComplete)
33                 self.timer = task.LoopingCall(self.onTimer)
34                 self.timer.start(5, False)
35         def copyHandles(self):
36                 print "copyHandles: ", len(self.handles)
37                 try:
38                         for src, dst in self.handles:
39                                 while 1:
40                                         if self.aborted:
41                                                 raise Exception, "Aborted"
42                                         d = src.read(65536)
43                                         if not d:
44                                                 # EOF
45                                                 break
46                                         dst.write(d)
47                                         self.pos += len(d)
48                 finally:
49                         # In any event, close all handles
50                         for src, dst in self.handles:
51                                 src.close()
52                                 dst.close()
53         def abort(self):
54                 print "[CopyFileTask] abort!"
55                 self.aborted = True
56                 if self.callback is None:
57                         self.finish(aborted = True)
58         def onTimer(self):
59                 self.setProgress(self.pos)
60         def onComplete(self, result):
61                 #callback from reactor, result=None or Failure.
62                 print "[CopyFileTask] onComplete", result
63                 self.postconditions.append(FailedPostcondition(result))
64                 self.timer.stop()
65                 del self.timer
66                 if result is None:
67                         print "[CopyFileTask] done, okay"
68                 else:
69                         for s,d in fileList:
70                                 # Remove incomplete data.
71                                 try:
72                                         os.unlink(d)
73                                 except:
74                                         pass
75                 self.finish()
76
77
78 def copyFiles(fileList, name):
79         name = _("Copy") + " " + name
80         job = Components.Task.Job(name)
81         task = CopyFileTask(job, name)
82         task.openFiles(fileList)
83         Components.Task.job_manager.AddJob(job)
84