Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Tag: version_3.23.0
Fetching contributors…

Cannot retrieve contributors at this time

executable file 657 lines (543 sloc) 19.562 kB
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# Copyright 2006-2009 (C) Raster Software Vigo (Sergio Costas)
# Copyright 2006-2009 (C) Peter Gill - win32 parts
# This file is part of DeVeDe
#
# DeVeDe 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 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/>.
#################################################################
# This block contains all the functions to convert a video file #
# into an MPEG2-PS DVD-compliant file #
#################################################################
import time
import select
import signal
import subprocess
import sys
import os
import re
import shutil
import glob
import posixpath
import gtk
import devede_other
import gobject
import cairo
import dbus
if (sys.platform=="win32") or (sys.platform=="win64"):
import win32api
import devede_other
import devede_video_convert
import devede_ffmpeg_convert
import devede_avconv_convert
import devede_subtitles
import devede_xml_menu
import devede_delete
import devede_dvd
import devede_bincue
import devede_executor
import devede_dialogs
import gc
class create_all:
def cancel_clicked(self,widget,temp=False):
newtree=devede_other.create_tree(self,"wcancel_job_dialog",self.gladefile,False)
window=newtree.get_object("wcancel_job_dialog")
window.show()
value=window.run()
window.hide()
window.destroy()
if value!=-5: # no
return True
self.runner.cancel()
self.runner.wait_end()
gobject.source_remove(self.timer)
self.window.hide()
self.window.destroy()
newtree=devede_other.create_tree(self,"waborted_dialog",self.gladefile,False)
window=newtree.get_object("waborted_dialog")
window.show()
window.run()
window.hide()
window.destroy()
window=None
gc.collect()
(self.main_window_callback)() # show the main window
return True
def iso_changed(self,args,arbol):
iso_name=arbol.get_object("iso_filename")
iso_folder=arbol.get_object("final_directory")
w=arbol.get_object("button_folder_accept")
mode=True
if iso_name.get_text()=="":
mode=False
folder=iso_folder.get_current_folder()
if folder==None:
mode=False
elif folder=="":
mode=False
w.set_sensitive(mode)
def check_free_space(self,filefolder,structure,actions,erase_temporary_files,sound_duration):
""" Returns TRUE if the free space in FILEFOLDER is insuficient to generate
the disk STRUCTURE """
# TODO Windows Stuff
estado=''
freespace=''
if (sys.platform!="win32") and (sys.platform!="win64"):
try:
print "Checking "+str(filefolder)
estado=os.statvfs(filefolder) # eg. f="C:\Documents and Settings\User name\Desktop"
freespace=95*estado.f_bsize*estado.f_bavail/100000
except ImportError:
print "Error when checking free space"
freespace=0
else:
try:
test_drive = os.path.splitdrive(filefolder)[0] + "\\" # So it will also work on Windows 2000
spc, bps, fc, tc = win32api.GetDiskFreeSpace(test_drive)
freespace=fc * spc * bps
except ImportError:
freespace=0
print "Free space in "+str(filefolder)+": "+str(freespace)
print "estatus ", estado, "\n"
total=devede_other.calcula_tamano_total(structure,sound_duration,self.disk_type)
print "Free: "+str(freespace)
print "Needed: "+str(total)
if (actions!=3):
total*=actions # if we only create the MPEG files or the DVD structure...
else:
if erase_temporary_files: # or if we create the ISO image
total*=2
else:
total*=3
total*=1.1 # a safe margin of 10%
if (freespace<total):
return True,_("Insuficient free space. To create this disc\n%(total)d MBytes are needed, but only %(free)d MBytes are available.") % {'total':int(total/1000),'free':int(freespace/1000)}
else:
return False,""
def check_mp3lame(self):
runner=devede_executor.executor()
runner.launch_program(["ffmpeg","-codecs"],sep_stderr=True,keep_out=True)
runner.wait_end2()
print "Salida "+str(runner.cadena)
pos=runner.cadena.find("mp3lame")
if (pos==-1):
tree=devede_other.create_tree(self,"wno_mp3lame",self.gladefile)
w=tree.get_object("nomp3lame")
w.show()
w.run()
w.destroy()
self.has_mp3lame=False
return False
else:
self.has_mp3lame=True
return True
def __init__(self,gladefile,structure,global_vars,callback):
if (0!=devede_other.check_program("k3b -v")):
self.k3b_available=False
else:
self.k3b_available=True
if (0!=devede_other.check_program("brasero --help")):
self.brasero_available=False
else:
self.brasero_available=True
self.gladefile=gladefile
self.structure=structure
self.global_vars=global_vars
self.has_mp3lame=True
if (global_vars["disctocreate"]=="divx") and ((global_vars["encoder_video"]=="ffmpeg") or (global_vars["encoder_video"]=="avconv")):
if (False==self.check_mp3lame()):
return
self.tree=devede_other.create_tree(self,"wprogress",self.gladefile)
self.window=self.tree.get_object("wprogress")
self.partial=self.tree.get_object("progresspartial")
self.erase_temp=global_vars["erase_temporary_files"]
self.iso_creator=global_vars["iso_creator"]
self.queue=[]
self.current_action=0
self.actions=global_vars["number_actions"]
self.total=self.tree.get_object("progress_total")
self.label=self.tree.get_object("lcreating")
self.total.set_fraction(0)
self.partial.set_fraction(0)
self.partial.set_text("0%")
self.label.set_text("")
self.start_time=time.time()
self.disk_type=global_vars["disctocreate"]
self.main_window_callback=callback
self.tiempo=time.time()
def init_queue(self):
total=0
title=0
for element in self.structure:
chapter=0
for element2 in element[1:]:
if self.structure[title][chapter+1]["twopass"] == True:
self.queue.append(["C1",title,chapter])
self.queue.append(["C2",title,chapter])
else:
self.queue.append(["C",title,chapter])
stream=0
for element3 in element2["sub_list"]:
self.queue.append(["S",title,chapter,stream])
stream+=1
#if self.structure[title][chapter+1]["twopass"] == True:
# self.queue.append(["C2",title,chapter])
# stream=0
# for element3 in element2["sub_list"]:
# self.queue.append(["S",title,chapter,stream])
# stream+=1
chapter+=1
title+=1
def preview(self,filefolder):
if (self.has_mp3lame==False):
self.window.destroy()
return
self.init_queue()
newtree=devede_other.create_tree(self,"wpreview_dialog",self.gladefile,False)
timev=newtree.get_object("seconds_preview")
timev.set_value(60)
w=newtree.get_object("wpreview_dialog")
w.show()
ret=w.run()
w.hide()
self.filefolder=filefolder
if self.filefolder[-1]!=os.sep:
self.filefolder+=os.sep
self.seconds=timev.get_value()
w.destroy()
if ret!=-6:
self.window.destroy()
return
self.runner=None
self.queue.append(["PREVIEW"]) # Preview
self.total_done=0.0
self.filename="previewfile"
try:
fichero=open(self.filefolder+"write_check","w")
fichero.write("Testing")
fichero.close()
except:
self.show_error(_("Failed to write to the destination directory.\nCheck that you have privileges and free space there."))
self.window.destroy()
return
try:
os.remove(self.filefolder+"write_check")
except:
print "Failed to erase the write check file"
self.eraser=devede_delete.delete_files(self.filename,self.filefolder)
self.erase_temp=True
self.timer=gobject.timeout_add(250,self.time_callback)
self.window.show()
return
def on_iso_filename_activate(self,widg,ventana):
ventana.response(-6)
def create_disc(self):
self.time=0
if (self.has_mp3lame==False):
self.window.hide()
self.window.destroy()
(self.main_window_callback)()
return False
# first, check for empty titles
empty=False
for element in self.structure:
if len(element)<2:
empty=True
break
if empty:
newtree=devede_other.create_tree(self,"wempty_titles_dialog",self.gladefile,False)
w=newtree.get_object("wempty_titles_dialog")
w.show()
value=w.run()
w.hide()
w.destroy()
if value!=-6:
self.window.hide()
self.window.destroy()
(self.main_window_callback)()
return False
# ask the folder and filename
newtree=devede_other.create_tree(self,"wfolder_dialog",self.gladefile,False)
wdir=newtree.get_object("final_directory")
if self.global_vars["finalfolder"]!="":
wdir.set_current_folder(self.global_vars["finalfolder"])
wfile=newtree.get_object("iso_filename")
wfolder_dialog=newtree.get_object("wfolder_dialog")
do_shdw=newtree.get_object("do_shutdown")
wfile.set_text("movie")
wfile.connect("activate",self.on_iso_filename_activate,wfolder_dialog)
wfile.connect("changed",self.iso_changed,newtree)
wdir.connect("current-folder-changed",self.iso_changed,newtree)
#self.iso_changed("",newtree)
wfolder_dialog.show()
wfile.grab_focus()
print "Entro en RUN"
value=wfolder_dialog.run()
print "Salgo de RUN"
self.global_vars["shutdown_after_disc"]=do_shdw.get_active()
self.filename=wfile.get_text()
self.filename.replace("/","_")
self.filename.replace("|","_")
self.filename.replace("\\","_")
filefolder=wdir.get_current_folder()
wfolder_dialog.hide()
wfolder_dialog.destroy()
if value!=-6:
self.window.hide()
self.window.destroy()
(self.main_window_callback)()
return False
self.global_vars["finalfolder"]=filefolder
filefolder2=os.path.join(filefolder,self.filename)
self.filefolder=filefolder2
if self.filefolder[-1]!=os.sep:
self.filefolder+=os.sep
if (os.path.exists(filefolder2)):
newtree=devede_other.create_tree(self,"wfolder_exists",self.gladefile,False)
w=newtree.get_object("wfolder_exists")
wtext=newtree.get_object("folder_exists_label")
wtext.set_text(_("The file or folder\n\n%(folder)s\n\nalready exists. If you continue, it will be deleted.") % {'folder':filefolder2})
w.show()
value=w.run()
w.hide()
w.destroy()
if value!=2:
self.window.hide()
self.window.destroy()
(self.main_window_callback)()
return False
try:
os.remove(filefolder2)
except:
pass
try:
os.makedirs(filefolder2)
except:
pass
self.eraser=devede_delete.delete_files(self.filename,self.filefolder)
hasfree,msg=self.check_free_space(self.filefolder,self.structure,self.actions,self.erase_temp,self.global_vars["menu_sound_duration"])
if hasfree:
self.window.hide()
self.window.destroy()
self.show_error(msg)
(self.main_window_callback)()
return False
# erase all conflicting files
self.eraser.delete_all()
# now, create the XML files (even with VCD, SVCD or CVD, to check if we have write permissions)
xml_files=devede_xml_menu.xml_files(self.partial,self.filename,self.filefolder,self.structure,self.global_vars,self.label)
counter=0
counter2=0
if (self.disk_type=="dvd"):
if xml_files.do_menus():
nelements=xml_files.get_elements_per_menu()
while (len(self.structure[counter:])!=0):
self.queue.append(["M1",xml_files,counter,counter2])
counter+=nelements
counter2+=1
self.init_queue()
retorno=xml_files.create_files()
if retorno!=None:
self.window.hide()
self.window.destroy()
self.show_error(retorno)
(self.main_window_callback)()
return False
self.runner=None
if self.actions!=1: # want to do, at least, the DVD structure, or the VCD image
if self.disk_type=="dvd":
self.queue.append(["DVD_STRUCTURE"])
if self.actions==3: # do DVD image too
self.queue.append(["DVD_IMAGE"])
else:
self.queue.append(["CD_IMAGE"])
self.queue.append(["END"])
self.seconds=0
self.total_done=0.0
self.timer=gobject.timeout_add(250,self.time_callback)
self.window.show()
return True
def time_callback(self):
""" This method launches all the conversion stages when needed, using the standard executor
interface to manage all of them in an easy way """
self.total.set_text(str(self.current_action)+"/"+str(len(self.queue)-1))
self.total.set_fraction(float(self.current_action)/(float(len(self.queue)-1)))
if self.runner!=None:
if self.runner.initerror:
retval=-1;
else:
retval=self.runner.refresh()
if retval==0: # no error, still running
return True
else:
self.current_action+=1
retval=self.runner.wait_end()
if (retval!=0) or (self.runner.initerror):
self.window.hide()
self.window.destroy()
if self.runner.print_error==None:
self.runner.print_error=_("Unknown error")
self.show_error(self.runner.print_error)
(self.main_window_callback)()
return False
else:
self.runner.end_process(self.eraser,self.erase_temp)
self.runner=None
action=self.queue[self.current_action]
if (self.global_vars["multicore"]!=1) and (self.global_vars["hyperthreading"]==False):
cores=self.global_vars["hypercores"]
else:
cores=self.global_vars["cores"]
if action[0]=="M1":
self.runner=action[1]
self.runner.create_menu1(action[2],action[3],cores)
return True
if (action[0]=='C') or (action[0]=='C1') or (action[0]=='C2'):
title=action[1]
chapter=action[2]
if action[0]=="C":
encpass = 0
else:
encpass = int(action[0][1])
print "Segundos "+str(self.seconds)
if (self.global_vars["encoder_video"]=="ffmpeg"):
self.runner=devede_ffmpeg_convert.video_converter_ffmpeg(self.global_vars,self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,cores,self.seconds, encpass,self.global_vars["AC3_fix_ffmpeg"])
elif (self.global_vars["encoder_video"]=="avconv"):
self.runner=devede_avconv_convert.video_converter_ffmpeg(self.global_vars,self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,cores,self.seconds, encpass,self.global_vars["AC3_fix_avconv"])
else:
self.runner=devede_video_convert.video_converter(self.global_vars,self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,cores,self.seconds, encpass,self.global_vars["AC3_fix"])
return True
if action[0]=="C2":
title=action[1]
chapter=action[2]
if (self.global_vars["encoder_video"]=="ffmpeg"):
self.runner=devede_ffmpeg_convert.video_converter_ffmpeg(self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,cores,self.seconds, 2,self.global_vars["AC3_fix_ffmpeg"])
elif (self.global_vars["encoder_video"]=="avconv"):
self.runner=devede_avconv_convert.video_converter(self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,cores,self.seconds, 2,self.global_vars["AC3_fix_avconv"])
else:
self.runner=devede_video_convert.video_converter(self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,cores,self.seconds, 2,self.global_vars["AC3_fix"])
return True
if action[0]=="S":
title=action[1]
chapter=action[2]
sub_stream=action[3]
self.runner=devede_subtitles.subtitles_adder(self.structure[title][chapter+1],self.filename,self.filefolder,self.partial,self.label,self.global_vars["disctocreate"],title+1,chapter+1,sub_stream)
return True
if action[0]=="PREVIEW":
self.window.hide()
self.window.destroy()
if (sys.platform=="win32") or (sys.platform=="win64"):
mplay="mplayer.exe"
else:
mplay="mplayer"
fname=self.filefolder+"previewfile_01_01."
if self.disk_type=="divx":
fname+="avi"
else:
fname+="mpg"
parameters=[mplay,"-sid","0",fname,"-loop","1"]
newtree=devede_other.create_tree(self,"wpreviewagain_dialog",self.gladefile,False)
w=newtree.get_object("wpreviewagain_dialog")
while True:
salida=devede_executor.executor("previewfile",self.filefolder,None)
salida.launch_program(parameters,output=False)
salida.wait_end()
w.show()
ret=w.run()
w.hide()
if ret!=-6:
break
while gtk.events_pending():
gtk.main_iteration()
w.destroy()
os.remove(fname)
return False
if action[0]=="DVD_STRUCTURE":
self.runner=devede_dvd.dvd_generator(self.filename,self.filefolder,self.partial,self.label)
return True
if action[0]=="CD_IMAGE":
self.runner=devede_bincue.xvcd_generator(self.filename,self.filefolder,self.partial,self.label,self.structure,self.disk_type)
return True
if action[0]=="DVD_IMAGE":
self.runner=devede_bincue.iso_generator(self.filename,self.filefolder,self.partial,self.label,self.iso_creator)
return True
if action[0]=="END":
self.show_final_time()
return False
return True
def show_final_time(self):
if (self.erase_temp):
self.eraser.delete_xml()
self.window.hide()
self.window.destroy()
if (self.global_vars["shutdown_after_disc"]):
print "\n\nApago el ordenador\n\n"
failure=False
# First, try with ConsoleKit
try:
bus = dbus.SystemBus()
bus_object = bus.get_object("org.freedesktop.ConsoleKit", "/org/freedesktop/ConsoleKit/Manager")
bus_object.Stop(dbus_interface="org.freedesktop.ConsoleKit.Manager")
except:
failure=True
if (failure):
failure=False
# If it fails, try with HAL
try:
bus = dbus.SystemBus()
bus_object = bus.get_object("org.freedesktop.Hal", "/org/freedesktop/Hal/devices/computer")
bus_object.Shutdown(dbus_interface="org.freedesktop.Hal.Device.SystemPowerManagement")
except:
failure=True
if (failure==False):
gtk.main_quit()
newtree=devede_other.create_tree(self,"wend_dialog",self.gladefile,False)
label=newtree.get_object("elapsed")
tiempo2=devede_other.return_time(time.time()-self.tiempo,True)
label.set_text(tiempo2)
window=newtree.get_object("wend_dialog")
burn = newtree.get_object("burn_button")
# only enable button if k3b is available
# TODO: support other burners
if (self.k3b_available==False) and (self.brasero_available==False):
burn.set_sensitive(False)
burn.connect('clicked', self.burn)
window.show()
window.run()
window.hide()
window.destroy()
window = None
newtree = None
gc.collect()
(self.main_window_callback)()
def burn(self, widget):
"""Burns resulting iso"""
path = self.filefolder + self.filename + ".iso"
print path
parameters = []
if (self.brasero_available):
parameters.append("brasero")
parameters.append("--image="+path)
else:
parameters.append("k3b")
parameters.append("--burn")
parameters.append(path)
runner=devede_executor.executor()
runner.launch_program(parameters,output=False)
runner.wait_end()
def show_error(self,message):
self.window.hide()
self.window.destroy()
devede_dialogs.show_error(self.gladefile,message)
return
Jump to Line
Something went wrong with that request. Please try again.