""" 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 line = None sendreturn = gtk.FALSE if (line != "") and (line != None): if (find(line, "Re-load disk and hit ") != -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()