now handles spaces in command names (in the naming of the export folder)
[pyvconv.git] / command_executer.py
blob2f1a5d6af9e744f6ffb53a10667d4fe5d48dcea6
1 # Pyvconv - A simple frontend for ffmpeg/mencoder
2 # Copyright (C) 2008, Kristian Rumberg (kristianrumberg@gmail.com)
4 # Permission to use, copy, modify, and/or distribute this software for any
5 # purpose with or without fee is hereby granted, provided that the above
6 # copyright notice and this permission notice appear in all copies.
8 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 import re
17 import os
18 import time
19 import datetime
20 import subprocess
21 import thread
22 import threading
23 import signal
24 from commands import Variable
26 class CommandExecuterView:
27 def __init__(self):
28 pass
30 def recieve_executor(self, executor):
31 pass
33 def starting_conversion(self, infile, index, total, outfile):
34 pass
36 def update_progress(self, logline):
37 pass
39 def error(self):
40 pass
42 def finished_all(self):
43 pass
45 class CommandExecuter:
46 def mk_unique_subdir(self, parentdir):
47 p = re.compile("[\ ,\/]")
48 namepart = p.sub("_", self.command.get_name())
49 print namepart
51 t = datetime.datetime.now()
52 newdir = parentdir + "/" + namepart + "_" + str(time.mktime(t.timetuple()))
54 if os.path.isdir(newdir):
55 raise OSError("Unable to make up unique name for new folder")
56 elif os.path.isfile(newdir):
57 raise OSError("a file with the same name as the desired " \
58 "dir, '%s', already exists." % newdir)
59 else:
60 os.mkdir(newdir)
61 return newdir
63 def __init__(self, cmdexecview, command, infilelist, outdir):
64 self.cmdexecview = cmdexecview
65 self.command = command
66 self.infilelist = infilelist
67 self.outdir = self.mk_unique_subdir(outdir)
69 self.please_abort = False
71 self.shared_vars_lock = threading.Lock()
72 thread.start_new_thread(self._run_conversion, ())
74 def abort(self):
75 self.shared_vars_lock.acquire()
76 self.please_abort = True
77 self.shared_vars_lock.release()
79 def _run_conversion(self):
80 index = 0
81 total = len(self.infilelist)
83 for infile in self.infilelist:
84 outfile = self.outdir + "/" + os.path.basename(infile) + "_converted"
86 index = index + 1
88 self.command.put_var(Variable("in", infile))
89 self.command.put_var(Variable("out", outfile))
91 self.cmdexecview.starting_conversion(infile, index, total, outfile)
93 p = subprocess.Popen(str(self.command), shell = True, universal_newlines=True, stderr = subprocess.PIPE)
94 ostream = p.stderr
96 self.cmdexecview.recieve_executor(self)
98 newline = str(chr(32) * 4)
99 buff = ""
100 c = 1
101 iskip = 10
102 skipc = 0
104 while c:
105 c = ostream.read(1)
106 buff = buff + c
107 if buff.endswith(newline):
108 skipc = (skipc + 1) % iskip
109 if skipc == 0:
110 self.cmdexecview.update_progress(buff.strip())
111 buff = ""
113 self.shared_vars_lock.acquire()
114 if self.please_abort == True:
115 ostream.close()
116 os.kill(p.pid, signal.SIGTERM)
117 return
118 self.shared_vars_lock.release()
120 ostream.close()
122 res = p.wait()
124 if res < 0:
125 self.cmdexecview.error()
126 return
128 self.cmdexecview.finished_all()