#!/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 . ########################################################################### # This block contains generic help functions that are used in the program # ########################################################################### import os import subprocess import stat import sys import shutil import cairo import gtk import struct import urllib import devede_executor class check_utf(devede_executor.executor): """ This class allows to detect if a file is pure ASCII, UTF-8 or UTF-16, and allows to convert from UTF-16 to UFT-8 """ def check_ascii(self,filename): try: file=open(filename,"rb") except: return False while True: element=file.read(1) if len(element)==0: return True if ord(element)>127: return False def read_utf8_element(self,file,base_value,nb): value=base_value for counter in range(nb-1): element=file.read(1) if element=="": return False if (ord(element)>191) or (ord(element)<128): return False value*=64 # rotate value 6 bits to the left value+=ord(element)-128 return value def check_utf8(self,filename): try: file=open(filename,"rb") except: return False while True: el=file.read(1) if el=="": file.close() return True element=ord(el) if element<128: continue if element<194: # it's a mid-sequence element or a 2-byte start sequence for an element smaller than 128 print "Elemento 1" file.close() return False # invalid element found if element<224: # two-byte element value=self.read_utf8_element(file,element-192, 2) if value==False: print "Elemento 2" file.close() return False # invalid sequence if value<128: print "Elemento 3" file.close() return False # invalid value for a 2-byte sequence continue if element<240: # three-byte element value=self.read_utf8_element(file,element-224, 3) if value==False: print "Elemento 4" file.close() return False # invalid sequence if value<2048: print "Elemento 5" file.close() return False # invalid value for a 3-byte sequence continue if element<245: # four-byte element value=self.read_utf8_element(file,element-240, 4) if value==False: print "Elemento 6" file.close() return False # invalid sequence if value<65536: print "Elemento 7" file.close() return False # invalid value for a 4-byte sequence continue file.close() return False # invalid value def read_16(self,file,format_b): element=file.read(2) if element=="": return "" if len(element)!=2: return False value=struct.unpack(format_b,element)[0] return value def read_full16(self,file,format_b): value=self.read_16(file, format_b) if value=="": return True # end of file if value==False: return False if (value>=56320) and (value<=57343): # invalid value return False if (value>55295) and (value<56320): # surrogate pair value-=55296 value2=self.read_16(file, format_b) if (value2==False) or (value2==""): return False if (value2<56320) or (value2>57343): # invalid surrogate pair return False value2-=56320 return ((value*1024+value2)+65536) else: return value def write_utf8(self,file,value): if value<128: file.write(struct.pack("B",value)) elif value<2048: v1=(value/64) & 31 v2= value & 63 file.write(struct.pack("BB",v1+192,v2+128)) elif value<65536: v1=(value/4096) & 15 v2=(value/64) & 63 v3= value & 63 file.write(struct.pack("BBB",v1+224,v2+128,v3+128)) else: v1=(value/262143) & 7 v2=(value/4096) & 63 v3=(value/64) & 63 v4= value & 63 file.write(struct.pack("BBBB",v1+240,v2+128,v3+128,v4+128)) def check_utf16BE(self,filename): try: file=open(filename,"rb") except: return False value=self.read_16(file, ">H") file.close() if value==65279: return True return False def check_utf16LE(self,filename): try: file=open(filename,"rb") except: return False value=self.read_16(file, " '+ out_file return self.launch_shell(command_line, output=False).wait() def convert_16_to_8(self,infile_n,outfile_n): if self.check_utf16BE(infile_n): format_b=">H" else: format_b="(pos+1)): if (videofile["ofps2"][pos+1]=="9"): rational_fps=True # if it's rational, we have to use a different pair of values to achieve good precission if (videofile["ofps"]==24) and (videofile["fps"]==25) and (videofile["copy_audio"]==False) and (videofile["ismpeg"]==False): if rational_fps: return 25025,24000 else: return 25,24 else: return 1,1 def get_font_params(font_name): font_elements=[] font_temp=font_name font_elements=font_name.split(" ") if (len(font_elements))<2: fontname="Sans" fontstyle=cairo.FONT_WEIGHT_NORMAL fontslant=cairo.FONT_SLANT_NORMAL fontsize=12 else: fontname="" fontstyle=cairo.FONT_WEIGHT_NORMAL fontslant=cairo.FONT_SLANT_NORMAL for counter2 in range(len(font_elements)-1): if font_elements[counter2]=="Bold": fontstyle=cairo.FONT_WEIGHT_BOLD elif font_elements[counter2]=="Italic": fontslant=cairo.FONT_SLANT_ITALIC else: fontname+=" "+font_elements[counter2] if fontname!="": fontname=fontname[1:] else: fontname="Sans" try: fontsize=float(font_elements[-1]) except: fontsize=12 return fontname,fontstyle,fontslant,fontsize def calcula_tamano_parcial(vrate,arate,filesize,length,subs,ismpeg,isvob,cutting,speed1,speed2): """ Calculates the estimated final size. VRATE and ARATE is the bit rate for video and audio. FILESIZE is the size of the original file. LENGTH is the file length in seconds SUBS is the number of subs ISMPEG is true if the file is already an MPEG-compliant file CUTTING is different than 0 if we are cutting the file in half. """ if (speed1!=speed2): # we are speeding up the film, so we must take it into account length=int((float(length))*((float(speed2))/(float(speed1)))) if ismpeg or isvob: l=filesize/1000 else: l=float(((vrate+arate)*length)/8) if cutting!=0: l/=2 l+=float((8*subs*length)/8) # add the subtitles (assume 8kbit/sec for each one) return l def calcule_menu_size(structure,sound_duration): # each menu needs 1128 kbits/sec * sound_duration / 8 return (141*sound_duration)*((len(structure)+9)/10) def calcula_tamano_total(structure,sound_duration,disktype): """ Calculates the total size of the DVD """ print "Calculating size for disk :"+str(disktype) total=0.0 for element in structure: if len(element)>1: for film in element[1:]: speed1,speed2=get_speedup(film) total+=calcula_tamano_parcial(film["vrate"],film["arate"],film["filesize"],film["olength"],len(film["sub_list"]),film["ismpeg"],film["isvob"],film["cutting"],speed1,speed2) if disktype=="dvd": total+=calcule_menu_size(structure,sound_duration) return total def check_program(programa): """ This function allows to check that a program is available in the system, just by calling it without arguments and checking the error returned """ if (sys.platform=="win32") or (sys.platform=="win64"): launcher=devede_executor.executor() p=launcher.launch_program(programa,win32arg=False) else: p=subprocess.Popen(programa+" >/dev/null 2>/dev/null",shell=True) p.wait() return p.returncode def load_config(global_vars): """ Load the configuration """ home=get_home_directory() global_vars["PAL"]=True global_vars["multicore"]=1 # it shouldn't use multicore by default # TODO change to allow a windows temp directory if (sys.platform=="win32") or (sys.platform=="win64"): #global_vars["temp_folder"]=os.environ["TEMP"] global_vars["temp_folder"]=os.path.join(home,"Local Settings", "Temp") else: global_vars["temp_folder"]="/var/tmp" print "Temp Directory is: " , global_vars["temp_folder"] if (sys.platform=="win32") or (sys.platform=="win64"): home=os.path.join(home,"Application Data", "devede","devede.devede") else: home+=".devede" print "home load: ", home menuformat_found=False try: archivo=open(home,"r") while True: linea=archivo.readline() print "linea: ", linea if linea=="": break if linea[-1]=="\n": linea=linea[:-1] if linea=="pal": global_vars["PAL"]=True if linea=="ntsc": global_vars["PAL"]=False if linea[:13]=="video_format:": if linea[13:]=="pal": global_vars["PAL"]=True if linea[13:]=="ntsc": global_vars["PAL"]=False if linea[:12]=="temp_folder:": global_vars["temp_folder"]=linea[12:] if linea[:10]=="multicore:": global_vars["multicore"]=int(linea[10:]) # don't remember multicore if linea[:13]=="final_folder:": global_vars["finalfolder"]=linea[13:] if linea[:13]=="sub_language:": global_vars["sub_language"]=linea[13:] if linea[:13]=="sub_codepage:": global_vars["sub_codepage"]=linea[13:] #if linea[:]==":": # global_vars[""]=linea[:] archivo.close() except IOError: pass def save_config(global_vars): """ Stores the configuration """ home=get_home_directory() if (sys.platform=="win32") or (sys.platform=="win64"): home=os.path.join(home,"Application Data", "devede") if not os.path.isdir(home): os.mkdir(home) home=os.path.join(home, "devede.devede") else: home+=".devede" if global_vars["temp_folder"][-1]!=os.sep: global_vars["temp_folder"]+=os.sep try: archivo=open(home,"w") if global_vars["PAL"]: archivo.write("video_format:pal\n") else: archivo.write("video_format:ntsc\n") archivo.write("temp_folder:"+global_vars["temp_folder"]+"\n") archivo.write("multicore:"+str(global_vars["multicore"])+"\n") if global_vars["finalfolder"]!="": archivo.write("final_folder:"+str(global_vars["finalfolder"])+"\n") archivo.write("sub_language:"+str(global_vars["sub_language"])+"\n") archivo.write("sub_codepage:"+str(global_vars["sub_codepage"])+"\n") archivo.close() except IOError: pass def get_new_param(parameters): """ This function groups the parameters passed by the user into a list """ new_param="" while(True): if (parameters.find(" ")==0): parameters=parameters[1:] # erase blank spaces at start else: break if len(parameters)==0: return "","" p0=0 while True: p1=parameters.find('\\',p0) p2=parameters.find(' ',p0) if p2==p1+1: p0=p2+1 else: if p2<0: # no next space, take all the string retorno="" doble=False print parameters for letra in parameters: if (letra!='\\') or doble: retorno+=letra doble=False else: doble=True return "",retorno else: retorno="" doble=False print parameters[:p2] for letra in parameters[:p2]: if (letra!='\\') or doble: retorno+=letra doble=False else: doble=True return parameters[p2+1:],retorno def get_home_directory(): if (sys.platform=="win32") or (sys.platform=="win64"): home=os.environ["USERPROFILE"] else: home=os.environ.get("HOME") if home[-1]!=os.sep: home=home+os.sep print home return home def return_time(seconds,empty): """ cuts a time in seconds into seconds, minutes and hours """ seconds2=int(seconds) hours=str(seconds2/3600) if empty: if len(hours)==1: hours="0"+hours else: if hours=="0": hours="" if hours!="": hours+=":" minutes=str((seconds2/60)%60) if empty or (hours!=""): if len(minutes)==1: minutes="0"+minutes elif (minutes=="0") and (hours==""): minutes="" if minutes!="": minutes+=":" secs=str(seconds2%60) if (len(secs)==1) and (minutes!=""): secs="0"+secs return hours+minutes+secs def get_max_titles(disctocreate): """ Returns the maximum number of titles/chapters for each type of disc """ if disctocreate=="dvd": return 61 else: return 99 def get_dvd_size(tree,disctocreate): """ Returns the size for the currently selected disk type, and the minimum and maximum videorate for the current video disk """ if tree!=None: w=tree.get_object("dvdsize") active=w.get_active() # here we choose the size in Mbytes for the media if 0==active: tamano=170.0 elif 1==active: tamano=700.0 elif 2==active: tamano=750.0 elif 3==active: tamano=1100.0 elif 4==active: tamano=4200.0 else: tamano=8000.0 else: tamano=0 if disctocreate=="vcd": minvrate=1152 maxvrate=1152 elif (disctocreate=="svcd") or (disctocreate=="cvd"): minvrate=400 maxvrate=2300 elif (disctocreate=="dvd"): minvrate=400 maxvrate=8500 elif (disctocreate=="divx"): minvrate=300 maxvrate=6000 tamano*=0.92 # a safe margin of 8% to ensure that it never will be bigger # (it's important to have in mind the space needed by disk structures like # directories, file entries, and so on) return tamano,minvrate,maxvrate def get_picture_type(filename): try: f=open(filename,"r") except: return "" ftype="" line=f.read(4) if (line[0]=="\211") and (line[1:]=="PNG"): ftype="png" line2=f.read(7) if (line[0]=="\377") and (line[1]=="\330") and (line[2]=="\377") and (line[3]=="\340") and (line2[2:6]=="JFIF") and (line2[6]=="\000"): ftype="jpeg" f.close() print "tipo: "+str(ftype) return ftype def create_tree(sobject,filename,builderpath="",autoconnect=True): tree=gtk.Builder() tree.set_translation_domain("devede") filename=os.path.join(builderpath,filename+".ui") print "Creating window "+filename tree.add_from_file(filename) if autoconnect: tree.connect_signals(sobject) return tree def check_for_ImgBurn(): if os.path.exists(os.path.join("bin", "ImgBurn.exe")): return True return False def ImgBurn_path(): if os.path.exists(os.path.join("bin", "ImgBurn.exe")): return os.path.join("bin", "ImgBurn.exe") return None def check_updates(): """ Check for updates by comparing version.txt version against current version on the server. """ class Check(urllib.FancyURLopener): version = 'Mozilla/5.0 (compatible; DeVeDe Update Check; http://www.majorsilence.com/devede)' file=open(os.path.join(os.getcwd(),"version.txt")) version=file.readline()[6:].replace("\n","").strip() version = version.replace("DeVeDe", "") version = version.strip() print "Using Version: ", version #set default timeout to 10 seconds if no response #If there is a response but no data sent, will hang for several minutes urllib.socket.setdefaulttimeout(10) o = Check() try: page= o.open("http://files.majorsilence.com/devede/current-version.txt") result = page.read().replace("\n","") result = result.replace("DeVeDe", "") result = result.strip() print "Newest Version: ", result except: return (False, _("Error checking for updates. Web Error") ) #if (len(version)>5): # this should be done better # return (False, _("Error checking for updates. Version number Error") ) #version = str(version).split(".") #result = str(result).split(".") try: print int(version[i]), " ", int(result[i]) if int(version.replace(".", "")) < int(result.replace(".", "")): return (True, _("New Version of DeVeDe available. Current Version in use is ") + str(version) + (". New Version is ") + str(result)) except: pass return (False, _("No new version of DeVeDe available at this time") )