"""
The external threads, which executes commands and sends the output back to the main
application.
"""
# Initialize i18n
from constants import localedir,unixname,audioinfostring,data_file_list,execution_thread_done
from tools import gettext,get_tempdir
gettext = gettext(unixname, localedir)
gettext.textdomain(unixname)
_ = gettext.gettext
import sys
import os
import log4py
import popen2
from re import sub
from string import zfill,split,find
from threading import Thread
from time import sleep
from tools import mkdirtree,get_tempdir
# this is for installations with both python-gtk versions
try:
import pygtk
pygtk.require('2.0')
except:
pass
try:
import gtk
except (RuntimeError, TypeError, NameError), detail:
logger = log4py.Logger().get_instance()
logger.error(_("An error occured: %s") % detail)
sys.exit(1)
class ExecutionThread (Thread):
def __init__(self, command, filelist, cddb_info, waitreload_lockfile, callback_function, loglevel = log4py.LOGLEVEL_NORMAL):
Thread.__init__(self)
self.__ExecutionThread_command = command
self.__ExecutionThread_filelist = filelist
self.__ExecutionThread_cddb_info = cddb_info
self.__ExecutionThread_waitreload_lockfile = waitreload_lockfile
self.__ExecutionThread_callback_function = callback_function
self.__ExecutionThread_logger = log4py.Logger().get_instance(self)
self.__ExecutionThread_logger.set_loglevel(loglevel)
def __ExecutionThread_platform_command(self, command):
""" Creates a cmd file on win32 platforms. Otherwise win32 won't execute some commands. """
if (sys.platform != "win32"):
return command
else:
tmp_command = "%s%stmp_command.cmd" % (get_tempdir(), os.sep)
file = open(tmp_command, "w")
file.write("%s\n" % command)
file.close()
return tmp_command
def run(self):
sys.stderr = sys.stdout
for i in range(len(self.__ExecutionThread_filelist)):
command = self.__ExecutionThread_command
file = self.__ExecutionThread_filelist[i]
if (file != data_file_list):
# this is executed for audio files only (in that case the only entry of filelist is "data_file_list"
track_number = zfill(file, 2)
if (self.__ExecutionThread_cddb_info.has_key(file)):
cdtitle = sub("\/", r"\\", self.__ExecutionThread_cddb_info.get_text())
if (cdtitle == ""):
cdtitle = _("Unknown")
trackname = self.__ExecutionThread_cddb_info[file]
trackname = sub("\/", r"\\", trackname)
trackname = sub("\"", "'", trackname)
else:
cdtitle = _("Unknown")
trackname = _("Unknown")
command = sub("%n", track_number, command)
command = sub("%c", cdtitle, command)
command = sub("%t", trackname, command)
filename = split(command, "\"")[1]
directory = os.path.dirname(filename)
if (not os.path.exists(directory)):
self.__ExecutionThread_logger.debug(_("Creating directory %s") % directory)
mkdirtree(directory)
fileString = "%s %d of %d\n" % (audioinfostring, i + 1, len(self.__ExecutionThread_filelist))
gtk.threads_enter()
self.__ExecutionThread_callback_function(fileString)
gtk.threads_leave()
command = self.__ExecutionThread_platform_command(command)
self.__ExecutionThread_logger.debug(_("Executing %s") % command)
pipe = popen2.popen2(command)
line = None
sendreturn = gtk.FALSE
while (line != ""):
line = pipe[0].readline()
if (sendreturn == gtk.TRUE): # ignore the empty line resulting from the <CR>
line = None
sendreturn = gtk.FALSE
if (line != "") and (line != None):
if (find(line, "Re-load disk and hit <CR>") != -1):
sendreturn = gtk.TRUE
gtk.threads_enter()
self.__ExecutionThread_callback_function(line)
gtk.threads_leave()
if (sendreturn == gtk.TRUE):
sleep(0.5)
while (os.path.exists(self.__ExecutionThread_waitreload_lockfile)):
sleep(0.25)
pipe[1].write("\n")
pipe[1].flush()
pipe[0].close()
pipe[1].close()
pipe = None
if (sys.platform == "win32"):
# Remove temporary file created on win32 platform
os.remove(command)
gtk.threads_enter()
self.__ExecutionThread_callback_function(execution_thread_done)
gtk.threads_leave()
|