Now supports adding subtitles

Allows to cancel a job

Allows to burn de image

Show a progress bar when copying a file

When adding a subtitles file, shows the last path used

Fixed the progress bar for the number of jobs to do
This commit is contained in:
Sergio Costas 2014-08-04 12:33:25 +02:00
parent 4cc1bee474
commit 64a33e1c74
24 changed files with 495 additions and 35 deletions

View file

@ -4,6 +4,7 @@
<requires lib="gtk+" version="3.10"/> <requires lib="gtk+" version="3.10"/>
<object class="GtkTextBuffer" id="debug_buffer"/> <object class="GtkTextBuffer" id="debug_buffer"/>
<object class="GtkDialog" id="done"> <object class="GtkDialog" id="done">
<property name="width_request">640</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="type_hint">dialog</property> <property name="type_hint">dialog</property>
<child internal-child="vbox"> <child internal-child="vbox">

View file

@ -8,6 +8,12 @@
<column type="gchararray"/> <column type="gchararray"/>
</columns> </columns>
</object> </object>
<object class="GtkListStore" id="burner_store">
<columns>
<!-- column-name backend -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="converter_store"> <object class="GtkListStore" id="converter_store">
<columns> <columns>
<!-- column-name backend --> <!-- column-name backend -->
@ -343,6 +349,40 @@
<property name="height">1</property> <property name="height">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_right">4</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Burn ISOs:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="burner">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">burner_store</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext6"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
<property name="width">1</property>
<property name="height">1</property>
</packing>
</child>
</object> </object>
</child> </child>
</object> </object>

View file

@ -103,5 +103,5 @@ setup(
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data' # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
#data_files=[('share/devedeng/ui', ['ui/test.ui'])], #data_files=[('share/devedeng/ui', ['ui/test.ui'])],
data_files = get_data_files(), data_files = get_data_files(),
scripts=['src/devede_ng.py'], scripts=['src/devede_ng.py', 'src/copy_files_verbose.py'],
) )

36
src/copy_files_verbose.py Normal file
View file

@ -0,0 +1,36 @@
#!/usr/bin/env python3
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import sys
import os
if len(sys.argv) != 3:
print("Usage: copy_files_verbose input_file output_file")
sys.exit(-1)
filesize = os.path.getsize(sys.argv[1])
done = 0.0
f1 = open(sys.argv[1],"rb")
f2 = open(sys.argv[2],"wb")
while (done < filesize):
data = f1.read(65536)
f2.write(data)
done += len(data)
print("Copied %.1f%%" % (100.0 * float(done)/float(filesize)))

View file

@ -18,6 +18,7 @@
from gi.repository import Gtk from gi.repository import Gtk
import os import os
import devede.configuration_data import devede.configuration_data
import devede.add_files
class ask_subtitles: class ask_subtitles:
@ -39,7 +40,10 @@ class ask_subtitles:
wlist_languages = builder.get_object("list_languages") wlist_languages = builder.get_object("list_languages")
wencoding = builder.get_object("encoding_l") wencoding = builder.get_object("encoding_l")
wlanguage = builder.get_object("language_l") wlanguage = builder.get_object("language_l")
if (devede.add_files.add_files.last_path != None):
self.wfilename.set_current_folder(devede.add_files.add_files.last_path)
lang_selection = 0 lang_selection = 0
enc_selection = 0 enc_selection = 0

View file

@ -29,6 +29,7 @@ class avconv_converter(devede.executor.executor):
supports_play = False supports_play = False
supports_convert = True supports_convert = True
supports_menu = True supports_menu = True
supports_burn = False
display_name = "AVCONV" display_name = "AVCONV"
disc_types = ["dvd","vcd","svcd","cvd","divx","mkv"] disc_types = ["dvd","vcd","svcd","cvd","divx","mkv"]

56
src/devede/brasero.py Normal file
View file

@ -0,0 +1,56 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import subprocess
import devede.configuration_data
import devede.executor
class brasero(devede.executor.executor):
supports_analize = False
supports_play = False
supports_convert = False
supports_menu = False
supports_burn = True
display_name = "BRASERO"
@staticmethod
def check_is_installed():
try:
handle = subprocess.Popen(["brasero","-h"], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(stdout, stderr) = handle.communicate()
if 0==handle.wait():
return True
else:
return False
except:
return False
def __init__(self):
devede.executor.executor.__init__(self)
self.config = devede.configuration_data.configuration.get_config()
def burn(self,file_name):
self.command_var = ["brasero", file_name]
def process_stdout(self,data):
return
def process_stderr(self,data):
return

View file

@ -95,6 +95,7 @@ class configuration(GObject.GObject):
self.subtitles_font_size = 28 self.subtitles_font_size = 28
self.sub_language = None self.sub_language = None
self.sub_codepage = None self.sub_codepage = None
self.burner = None
config_path = os.path.join(os.environ.get("HOME"),".devede") config_path = os.path.join(os.environ.get("HOME"),".devede")
try: try:
@ -140,6 +141,8 @@ class configuration(GObject.GObject):
continue continue
if linea[:19]=="subtitle_font_size:": if linea[:19]=="subtitle_font_size:":
self.subtitles_font_size = int(linea[19:].strip()) self.subtitles_font_size = int(linea[19:].strip())
if linea[:7]=="burner:":
self.burner = int(linea[7:].strip())
config_data.close() config_data.close()
except: except:
pass pass

View file

@ -19,6 +19,8 @@ import devede.configuration_data
import devede.mplayer_detector import devede.mplayer_detector
import devede.avconv_converter import devede.avconv_converter
import devede.vlc import devede.vlc
import devede.brasero
import devede.k3b
class converter: class converter:
@ -35,7 +37,8 @@ class converter:
self.config = devede.configuration_data.configuration.get_config() self.config = devede.configuration_data.configuration.get_config()
# List of classes with conversion capabilities, in order of preference # List of classes with conversion capabilities, in order of preference
self.c = [devede.vlc.vlc_player, devede.mplayer_detector.mplayer_detector, devede.avconv_converter.avconv_converter] self.c = [devede.vlc.vlc_player, devede.mplayer_detector.mplayer_detector, devede.avconv_converter.avconv_converter,
devede.brasero.brasero, devede.k3b.k3b]
self.analizers = {} self.analizers = {}
self.default_analizer = None self.default_analizer = None
@ -45,6 +48,8 @@ class converter:
self.default_converter = None self.default_converter = None
self.menuers = {} self.menuers = {}
self.default_menuer = None self.default_menuer = None
self.burners = {}
self.default_burner = None
self.discs = [] self.discs = []
for element in self.c: for element in self.c:
@ -70,6 +75,10 @@ class converter:
self.menuers[name] = element self.menuers[name] = element
if (self.default_menuer == None): if (self.default_menuer == None):
self.default_menuer = element self.default_menuer = element
if (element.supports_burn):
self.burners[name] = element
if (self.default_burner == None):
self.default_burner = element
def get_available_programs(self): def get_available_programs(self):
@ -77,6 +86,7 @@ class converter:
menuers = [] menuers = []
converters = [] converters = []
analizers = [] analizers = []
burners = []
for e in self.analizers: for e in self.analizers:
analizers.append(e) analizers.append(e)
@ -86,14 +96,16 @@ class converter:
menuers.append(e) menuers.append(e)
for e in self.converters: for e in self.converters:
converters.append(e) converters.append(e)
for e in self.burners:
burners.append(e)
return (analizers, players, menuers, converters) return (analizers, players, menuers, converters, burners)
def get_needed_programs(self): def get_needed_programs(self):
""" returns a tupla with four lists. When a list is NONE, there are installed in the system """ returns a tupla with four lists. When a list is NONE, there are installed in the system
programs that covers the needs for that group; when not, it contains the programs valid programs that covers the needs for that group; when not, it contains the programs valid
to cover the needs for that group. to cover the needs for that group.
The groups are, in this order: ANALIZERS, PLAYERS, CONVERTERS, MENUERS The groups are, in this order: ANALIZERS, PLAYERS, CONVERTERS, MENUERS, BURNERS
(menuers are the programs that creates the mpeg files for menus) """ (menuers are the programs that creates the mpeg files for menus) """
if (self.default_analizer != None): if (self.default_analizer != None):
@ -112,6 +124,10 @@ class converter:
menuers = None menuers = None
else: else:
menuers = [] menuers = []
if (self.default_burner != None):
burners = None
else:
burners = []
for element in self.c: for element in self.c:
e = element() e = element()
@ -124,8 +140,10 @@ class converter:
converters.append(name) converters.append(name)
if (e.supports_menu) and (menuers != None): if (e.supports_menu) and (menuers != None):
menuers.append(name) menuers.append(name)
if (e.supports_burn) and (burners != None):
burners.append(name)
return ( analizers, players, converters, menuers ) return ( analizers, players, converters, menuers, burners )
def get_film_player(self): def get_film_player(self):
""" returns a class for the desired film player, or the most priviledged if the desired is not installed """ """ returns a class for the desired film player, or the most priviledged if the desired is not installed """
@ -157,4 +175,12 @@ class converter:
if (self.config.film_converter == None) or (self.config.film_converter not in self.analizers): if (self.config.film_converter == None) or (self.config.film_converter not in self.analizers):
return self.default_converter return self.default_converter
else: else:
return self.converters[self.config.film_converter] return self.converters[self.config.film_converter]
def get_burner(self):
""" returns a class for the desired burner, or the most priviledged if the desired is not installed """
if (self.config.burner == None) or (self.config.burner not in self.burners):
return self.default_burner
else:
return self.burners[self.config.burner]

View file

@ -56,15 +56,6 @@ class dvdauthor_converter(devede.executor.executor):
return return
def expand_xml(self,text):
text=text.replace('&','&amp;')
text=text.replace('<','&lt;')
text=text.replace('>','&gt;')
text=text.replace('"','&quot;')
text=text.replace("'",'&apos;')
return text
def create_dvdauthor_xml(self,movie_folder, file_movies, menu_entries, start_with_menu): def create_dvdauthor_xml(self,movie_folder, file_movies, menu_entries, start_with_menu):
xmlpath = os.path.join(movie_folder,"xml_data") xmlpath = os.path.join(movie_folder,"xml_data")

View file

@ -25,7 +25,7 @@ class end_window:
self.config = devede.configuration_data.configuration.get_config() self.config = devede.configuration_data.configuration.get_config()
def run(self,time_used): def run(self,time_used, do_burn):
builder = Gtk.Builder() builder = Gtk.Builder()
builder.set_translation_domain(self.config.gettext_domain) builder.set_translation_domain(self.config.gettext_domain)
@ -33,6 +33,7 @@ class end_window:
builder.add_from_file(os.path.join(self.config.glade,"wdone.ui")) builder.add_from_file(os.path.join(self.config.glade,"wdone.ui"))
builder.connect_signals(self) builder.connect_signals(self)
werror_window = builder.get_object("done") werror_window = builder.get_object("done")
wburn = builder.get_object("button_burn")
wdebug_buffer = builder.get_object("debug_buffer") wdebug_buffer = builder.get_object("debug_buffer")
wdebug_buffer.insert_at_cursor(self.config.get_log()) wdebug_buffer.insert_at_cursor(self.config.get_log())
wtime = builder.get_object("label_time") wtime = builder.get_object("label_time")
@ -52,6 +53,12 @@ class end_window:
wtime.set_text(time_used_str) wtime.set_text(time_used_str)
werror_window.show_all() werror_window.show_all()
if do_burn:
wburn.show()
else:
wburn.hide()
retval = werror_window.run() retval = werror_window.run()
werror_window.destroy() werror_window.destroy()
if retval == 1: if retval == 1:

View file

@ -52,6 +52,7 @@ class executor(GObject.GObject):
self.handle = None self.handle = None
def add_dependency(self, dep): def add_dependency(self, dep):
self.add_dependency2(dep) self.add_dependency2(dep)
@ -134,12 +135,15 @@ class executor(GObject.GObject):
def launch_process(self,command,redirect_output = True): def launch_process(self,command,redirect_output = True):
self.launch_command = "\n\nLaunching:" if command != None:
for e in command: self.launch_command = "\n\nLaunching:"
self.launch_command += (" "+e) for e in command:
self.launch_command += "\n" self.launch_command += (" "+e)
self.launch_command += "\n"
self.config.append_log(self.text) self.config.append_log(self.text)
self.config.append_log(self.launch_command) if command != None:
self.config.append_log(self.launch_command)
try: try:
if (self.stdin_file != None): if (self.stdin_file != None):
@ -193,14 +197,13 @@ class executor(GObject.GObject):
else: else:
GLib.source_remove(self.timer_pulse) GLib.source_remove(self.timer_pulse)
def run_pulse(self,v = None): def run_pulse(self,v = None):
if self.progress_bar == None: if self.progress_bar == None:
return return
if self.pulse_text == None: if self.pulse_text != None:
self.progress_bar[1].set_text("")
else:
self.progress_bar[1].set_text(self.pulse_text) self.progress_bar[1].set_text(self.pulse_text)
self.progress_bar[1].pulse() self.progress_bar[1].pulse()
return True return True
@ -309,4 +312,14 @@ class executor(GObject.GObject):
self.config.append_log(self.stdout_data) self.config.append_log(self.stdout_data)
self.config.append_log(self.stderr_data) self.config.append_log(self.stderr_data)
self.emit("ended",retval) self.emit("ended",retval)
def expand_xml(self,text):
text=text.replace('&','&amp;')
text=text.replace('<','&lt;')
text=text.replace('>','&gt;')
text=text.replace('"','&quot;')
text=text.replace("'",'&apos;')
return text

View file

@ -31,13 +31,22 @@ class file_copy(devede.executor.executor):
self.text = _("Copying file %(X)s") % {"X": os.path.basename(input_path)} self.text = _("Copying file %(X)s") % {"X": os.path.basename(input_path)}
self.command_var=[] self.command_var=[]
self.command_var.append("cp") self.command_var.append("copy_files_verbose.py")
self.command_var.append(input_path) self.command_var.append(input_path)
self.command_var.append(output_path) self.command_var.append(output_path)
self.use_pulse_mode = True
def process_stdout(self,data): def process_stdout(self,data):
if (data == None) or (len(data) == 0):
return
if (data[0].startswith("Copied ")):
pos = data[0].find("%")
if (pos == -1):
return
p = float(data[0][7:pos])
self.progress_bar[1].set_fraction(p/ 100.0)
self.progress_bar[1].set_text("%.1f%%" % (p))
return return
def process_stderr(self,data): def process_stderr(self,data):

View file

@ -24,6 +24,8 @@ import devede.converter
import devede.ask_subtitles import devede.ask_subtitles
import devede.preview import devede.preview
import devede.file_copy import devede.file_copy
import devede.rename_file
import devede.subtitles_mux
class file_movie(devede.interface_manager.interface_manager): class file_movie(devede.interface_manager.interface_manager):
@ -566,6 +568,33 @@ class file_movie(devede.interface_manager.interface_manager):
disc_converter = cv.get_disc_converter() disc_converter = cv.get_disc_converter()
converter = disc_converter() converter = disc_converter()
converter.convert_file(self,output_path,duration) converter.convert_file(self,output_path,duration)
if len(self.subtitles_list) != 0:
last_process = converter
if duration == 0:
duration2 = self.original_length
else:
duration2 = duration
for subt in self.subtitles_list:
renamer = devede.rename_file.rename_file()
renamer.rename(output_path, output_path+".tmp")
renamer.add_dependency(last_process)
converter.add_child_process(renamer)
subt_file = subt[0]
subt_codepage = subt[1]
subt_lang = subt[2]
subt_upper = subt[3]
if self.aspect_ratio_final >= 1.7:
final_aspect = "16:9"
else:
final_aspect = "4:3"
subt_mux = devede.subtitles_mux.subtitles_mux()
subt_mux.multiplex_subtitles( output_path+".tmp", output_path, subt_file, subt_codepage, subt_lang, subt_upper,
self.subt_font_size,self.format_pal,self.force_subtitles, final_aspect, duration2)
subt_mux.add_dependency(renamer)
converter.add_child_process(subt_mux)
last_process = subt_mux
return converter return converter

View file

@ -255,6 +255,7 @@ class interface_manager(GObject.GObject):
counter = 0 counter = 0
dv = 0 dv = 0
for item in element[1]: for item in element[1]:
print (item)
the_list.append([item]) the_list.append([item])
if (item == obj): if (item == obj):
dv = counter dv = counter

56
src/devede/k3b.py Normal file
View file

@ -0,0 +1,56 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import subprocess
import devede.configuration_data
import devede.executor
class k3b(devede.executor.executor):
supports_analize = False
supports_play = False
supports_convert = False
supports_menu = False
supports_burn = True
display_name = "K3B"
@staticmethod
def check_is_installed():
try:
handle = subprocess.Popen(["k3b","--help"], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(stdout, stderr) = handle.communicate()
if 0==handle.wait():
return True
else:
return False
except:
return False
def __init__(self):
devede.executor.executor.__init__(self)
self.config = devede.configuration_data.configuration.get_config()
def burn(self,file_name):
self.command_var = ["k3b", file_name]
def process_stdout(self,data):
return
def process_stderr(self,data):
return

View file

@ -56,7 +56,7 @@ class mkisofs(devede.executor.executor):
l = data[0].split("%") l = data[0].split("%")
p = float(l[0]) p = float(l[0])
self.progress_bar[1].set_fraction(p) self.progress_bar[1].set_fraction(p/100.0)
self.progress_bar[1].set_text("%.1f%%" % (p)) self.progress_bar[1].set_text("%.1f%%" % (p))
return return

View file

@ -1,3 +1,5 @@
#!/usr/bin/env python3
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas) # Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
# #
# This file is part of DeVeDe-NG # This file is part of DeVeDe-NG
@ -26,6 +28,7 @@ class mplayer_detector(devede.executor.executor):
supports_play = True supports_play = True
supports_convert = False supports_convert = False
supports_menu = False supports_menu = False
supports_burn = False
display_name = "MPLAYER" display_name = "MPLAYER"
@staticmethod @staticmethod

View file

@ -413,12 +413,16 @@ class devede_project:
isocreator.create_iso(data.path, data.name) isocreator.create_iso(data.path, data.name)
isocreator.add_dependency(dvdauthor) isocreator.add_dependency(dvdauthor)
run_window.add_process(isocreator) run_window.add_process(isocreator)
self.disc_image_name = os.path.join(data.path,data.name+".iso")
elif (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"): elif (self.disc_type == "vcd") or (self.disc_type == "svcd") or (self.disc_type == "cvd"):
vcdcreator = devede.vcdimager_converter.vcdimager_converter() vcdcreator = devede.vcdimager_converter.vcdimager_converter()
vcdcreator.create_cd_project(data.path, data.name, file_movies) vcdcreator.create_cd_project(data.path, data.name, file_movies)
for element in final_dependencies: for element in final_dependencies:
vcdcreator.add_dependency(element) vcdcreator.add_dependency(element)
run_window.add_process(vcdcreator) run_window.add_process(vcdcreator)
self.disc_image_name = os.path.join(data.path,data.name+".cue")
else:
self.disc_image_name = None
run_window.connect("done",self.disc_done) run_window.connect("done",self.disc_done)
self.wmain_window.hide() self.wmain_window.hide()
@ -430,7 +434,23 @@ class devede_project:
if value == 0: if value == 0:
ended = devede.end_job.end_window() ended = devede.end_job.end_window()
ended.run(time.time() - self.time_start) if self.disc_image_name == None:
do_burn = False
else:
do_burn = True
if (ended.run(time.time() - self.time_start, do_burn)):
cv = devede.converter.converter.get_converter()
burner = cv.get_burner()()
burner.burn(self.disc_image_name)
run_window = devede.runner.runner(False)
run_window.add_process(burner)
run_window.connect("done", self.disc_done2)
run_window.run()
return
self.wmain_window.show()
def disc_done2(self,object, value):
self.wmain_window.show() self.wmain_window.show()

48
src/devede/rename_file.py Normal file
View file

@ -0,0 +1,48 @@
#!/usr/bin/env python3
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import os
import devede.configuration_data
import devede.executor
class rename_file(devede.executor.executor):
def __init__(self):
devede.executor.executor.__init__(self)
self.config = devede.configuration_data.configuration.get_config()
def rename(self,file_path_input, file_path_output):
self.text = _("Renaming %(L)s to %(X)s") % {"X": os.path.basename(file_path_output), "L": os.path.basename(file_path_input)}
self.command_var=[]
self.command_var.append("mv")
self.command_var.append("-f")
self.command_var.append(file_path_input)
self.command_var.append(file_path_output)
self.use_pulse_mode = True
def process_stdout(self,data):
return
def process_stderr(self,data):
return

View file

@ -19,12 +19,13 @@ from gi.repository import Gtk,GObject
import os import os
import devede.configuration_data import devede.configuration_data
import devede.error import devede.error
import devede.ask
class runner(GObject.GObject): class runner(GObject.GObject):
__gsignals__ = {'done': (GObject.SIGNAL_RUN_FIRST, None,(int,))} __gsignals__ = {'done': (GObject.SIGNAL_RUN_FIRST, None,(int,))}
def __init__(self): def __init__(self, show_window = True):
GObject.GObject.__init__(self) GObject.GObject.__init__(self)
@ -49,7 +50,8 @@ class runner(GObject.GObject):
self.builder.add_from_file(os.path.join(self.config.glade,"wprogress.ui")) self.builder.add_from_file(os.path.join(self.config.glade,"wprogress.ui"))
self.builder.connect_signals(self) self.builder.connect_signals(self)
self.wprogress = self.builder.get_object("progress") self.wprogress = self.builder.get_object("progress")
self.wprogress.show_all() if show_window:
self.wprogress.show_all()
self.wtotal = self.builder.get_object("progress_total") self.wtotal = self.builder.get_object("progress_total")
progress_frame = self.builder.get_object("progress_frame") progress_frame = self.builder.get_object("progress_frame")
@ -69,6 +71,8 @@ class runner(GObject.GObject):
box.pack_start(f,True,True,0) box.pack_start(f,True,True,0)
box.set_orientation(Gtk.Orientation.VERTICAL) box.set_orientation(Gtk.Orientation.VERTICAL)
self.total_processes = 0 self.total_processes = 0
self.error = False
def add_process(self,process): def add_process(self,process):
@ -82,7 +86,16 @@ class runner(GObject.GObject):
def on_cancel_clicked(self,b): def on_cancel_clicked(self,b):
pass
ask_w = devede.ask.ask_window()
retval = ask_w.run(_("Cancel the current job?"),_("Cancel the current job?"))
if retval:
self.error = True
for element in self.proc_list:
element.cancel()
self.wprogress.destroy()
self.emit("done",1) # there was an error
return
def run(self, clear_log = True): def run(self, clear_log = True):
@ -105,11 +118,16 @@ class runner(GObject.GObject):
self.progress_bars = [] self.progress_bars = []
break break
self.wtotal.set_text(str(self.total_processes - len(self.proc_list))+"/"+str(self.total_processes)) self.wtotal.set_text(str(self.total_processes - len(self.proc_list))+"/"+str(self.total_processes))
self.wtotal.set_fraction((float(self.total_processes - len(self.proc_list)))/(float(self.total_processes)))
def process_ended(self,process, retval): def process_ended(self,process, retval):
if self.error:
return
if retval != 0: if retval != 0:
self.error = True
for element in self.proc_list: for element in self.proc_list:
element.cancel() element.cancel()
self.wprogress.destroy() self.wprogress.destroy()

View file

@ -68,12 +68,13 @@ class settings_window(devede.interface_manager.interface_manager):
self.add_filebutton("tempo_path", self.config.tmp_folder) self.add_filebutton("tempo_path", self.config.tmp_folder)
c = devede.converter.converter.get_converter() c = devede.converter.converter.get_converter()
(analizers, players, menuers, converters) = c.get_available_programs() (analizers, players, menuers, converters, burners) = c.get_available_programs()
self.add_combobox("analizer", analizers,self.config.film_analizer) self.add_combobox("analizer", analizers,self.config.film_analizer)
self.add_combobox("player", players,self.config.film_player) self.add_combobox("player", players,self.config.film_player)
self.add_combobox("converter", converters,self.config.film_converter) self.add_combobox("converter", converters,self.config.film_converter)
self.add_combobox("menuer", menuers,self.config.menu_converter) self.add_combobox("menuer", menuers,self.config.menu_converter)
self.add_combobox("burner", burners, self.config.burner)
builder = Gtk.Builder() builder = Gtk.Builder()
builder.set_translation_domain(self.config.gettext_domain) builder.set_translation_domain(self.config.gettext_domain)
@ -97,4 +98,5 @@ class settings_window(devede.interface_manager.interface_manager):
self.config.film_player = self.player self.config.film_player = self.player
self.config.film_converter = self.converter self.config.film_converter = self.converter
self.config.menu_converter = self.menuer self.config.menu_converter = self.menuer
self.config.burner = self.burner
self.config.save_config() self.config.save_config()

View file

@ -0,0 +1,95 @@
#!/usr/bin/env python3
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import os
import devede.configuration_data
import devede.executor
class subtitles_mux(devede.executor.executor):
def __init__(self):
devede.executor.executor.__init__(self)
self.config = devede.configuration_data.configuration.get_config()
def multiplex_subtitles(self,file_path_input, file_path_output, subtitles_path,subt_codepage, subt_lang,
subt_upper,font_size, pal, force_subtitles, aspect, duration):
self.duration = duration
self.text = _("Adding %(L)s subtitles to %(X)s") % {"X": os.path.basename(file_path_output), "L": subt_lang}
out_xml = open(file_path_input+".xml","w")
out_xml.write('<subpictures format="')
if pal:
out_xml.write('PAL')
else:
out_xml.write('NTSC')
out_xml.write('">\n')
out_xml.write('\t<stream>\n')
out_xml.write('\t\t<textsub filename="')
out_xml.write(self.expand_xml(subtitles_path))
out_xml.write('" characterset="')
out_xml.write(self.expand_xml(subt_codepage))
out_xml.write('" fontsize="')
out_xml.write(str(font_size))
if subt_upper:
out_xml.write('" bottom-margin="50')
out_xml.write('" font="arial" horizontal-alignment="center" vertical-alignment="bottom" aspect="')
out_xml.write(str(aspect))
out_xml.write('" force="')
if force_subtitles:
out_xml.write('yes')
else:
out_xml.write('no')
out_xml.write('" />\n')
out_xml.write('\t</stream>\n')
out_xml.write('</subpictures>')
out_xml.close()
self.command_var=[]
self.command_var.append("spumux")
mode = self.config.disc_type
if mode == "vcd":
mode = "svcd"
self.command_var.append("-m")
self.command_var.append(mode)
self.command_var.append(file_path_input+".xml")
self.stdin_file = file_path_input
self.stdout_file = file_path_output
def process_stderr(self,data):
if (data == None) or (len(data) == 0):
return
if self.duration == 0:
return
if data[0].startswith("STAT: "):
time_pos = data[0][6:].split(":")
current_time = 0
for t in time_pos:
current_time *= 60
current_time += float(t)
t = current_time / self.duration
self.progress_bar[1].set_fraction(t)
self.progress_bar[1].set_text("%.1f%%" % (100.0 * t))
return

View file

@ -25,6 +25,7 @@ class vlc_player(devede.executor.executor):
supports_play = True supports_play = True
supports_convert = False supports_convert = False
supports_menu = False supports_menu = False
supports_burn = False
display_name = "VLC" display_name = "VLC"
@staticmethod @staticmethod
@ -46,7 +47,7 @@ class vlc_player(devede.executor.executor):
def play_film(self,file_name): def play_film(self,file_name):
command_line = ["vlc", file_name] command_line = ["vlc", "--play-and-exit",file_name]
self.launch_process(command_line) self.launch_process(command_line)
def process_stdout(self,data): def process_stdout(self,data):