#!/usr/bin/env python # -*- coding: UTF-8 -*- # Copyright 2006 (C) Peter Gill - GetPrograms # This program 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 2 of the License, or # (at your option) any later version. # # This program 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, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # All code except Popen and related functions are covered by the above GPL license # Popen and its two related functions, send_all and recv_some, are taken from # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554 cookbook recipe # and they are covered by the python PSF license which can be found at: # http://www.python.org/download/releases/2.5/license/ import urllib import zipfile import bz2 import tarfile import re import os import shutil import string import subprocess import errno import time import sys import pygtk pygtk.require('2.0') import gtk from devede_other import * if subprocess.mswindows: from win32file import ReadFile, WriteFile from win32pipe import PeekNamedPipe import msvcrt class Popen(subprocess.Popen): def recv(self, maxsize=None): return self._recv('stdout', maxsize) def recv_err(self, maxsize=None): return self._recv('stderr', maxsize) def send_recv(self, input='', maxsize=None): return self.send(input), self.recv(maxsize), self.recv_err(maxsize) def get_conn_maxsize(self, which, maxsize): if maxsize is None: maxsize = 1024 elif maxsize < 1: maxsize = 1 return getattr(self, which), maxsize def _close(self, which): getattr(self, which).close() setattr(self, which, None) if subprocess.mswindows: def send(self, input): if not self.stdin: return None try: x = msvcrt.get_osfhandle(self.stdin.fileno()) (errCode, written) = WriteFile(x, input) except ValueError: return self._close('stdin') except (subprocess.pywintypes.error, Exception), why: if why[0] in (109, errno.ESHUTDOWN): return self._close('stdin') raise return written def _recv(self, which, maxsize): conn, maxsize = self.get_conn_maxsize(which, maxsize) if conn is None: return None try: x = msvcrt.get_osfhandle(conn.fileno()) (read, nAvail, nMessage) = PeekNamedPipe(x, 0) if maxsize < nAvail: nAvail = maxsize if nAvail > 0: (errCode, read) = ReadFile(x, nAvail, None) except ValueError: return self._close(which) except (subprocess.pywintypes.error, Exception), why: if why[0] in (109, errno.ESHUTDOWN): return self._close(which) raise if self.universal_newlines: read = self._translate_newlines(read) return read class GetPrograms: """ Class to download programs needed for devede to run on windows. grep, mplayer, mencoder, ln, vcdimager, dvdauthor, mkisofs. grep, dvdauthor, mkisofs, and vcdimager should be provided in the windows package. """ def __init__(self): self.dialog = gtk.Dialog(title="Select Programs to Install", parent=None, flags=gtk.DIALOG_MODAL, buttons=None) self.progressBar = gtk.ProgressBar() self.progressBar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT) # if key is True, download # programs to check for, if not found must be installed self.programs={"mplayer":False, "grep":False, "vcdimager":False, "dvdauthor":False, "mkisofs":False, "ln":False} # everything that must downloaded and installed self.checked={"mplayer":False, "grep":False, "vcdimager":False, "dvdauthor":False, "mkisofs":False, "ln":False,"cygwin":False} def startProcessing(self): for k,v in self.checked.iteritems(): if v==True: print "downloading: ", k self.download(package=k.strip()) self.unzip(package=k.strip()) def msgbox(self,msg,title): message = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, msg) message.set_title(title) message.run() message.destroy() def checkbox_toggled(self,widget, msg=None): print "In test func: ", msg print "%s was toggled %s" % (msg, ("OFF", "ON")[widget.get_active()]) if ("OFF", "ON")[widget.get_active()] == "ON": self.checked[msg]=True self.checked["cygwin"]=True else: self.checked[msg]=False return def makeButtonBox(self,name=None, label=None): p1 = gtk.HBox(True, 1) button=gtk.CheckButton(label=name) button.connect("toggled", self.checkbox_toggled, name.lower()) p1.pack_start(button,True,True,1) button.show() lblOutput=gtk.Label(label) p1.pack_start(lblOutput,True,True,1) p1.show() lblOutput.show() return p1 def displayCheckmarkGui(self): self.dialog.add_button(gtk.STOCK_QUIT,gtk.RESPONSE_CLOSE) self.dialog.add_button(gtk.STOCK_OK,gtk.RESPONSE_OK) if self.checkProgram("vcdimager") == False: self.programs["vcdimager"]=True if self.checkProgram("dvdauthor") == False: self.programs["dvdauthor"]=True if self.checkProgram("mkisofs") == False: self.programs["mkisofs"]=True if self.checkProgram("ln") == False: self.programs["ln"]=True lblMessage=gtk.Label("Programs that need to be downloaded for\n devede to work.") lblMessage.set_justify(gtk.JUSTIFY_CENTER) lblMessage.show() self.dialog.vbox.pack_start(lblMessage,True,True,10) if self.checkProgram("mplayer") == False: p1=self.makeButtonBox("Mplayer","Check to Install") self.dialog.vbox.pack_start(p1,True,True,1) if self.checkProgram("vcdimager") == False: p2=self.makeButtonBox("Vcdimager","Check to Install") self.dialog.vbox.pack_start(p2,True,True,1) if self.checkProgram("mkisofs") == False: p3=self.makeButtonBox("Mkisofs","Check to Install") self.dialog.vbox.pack_start(p3,True,True,1) if self.checkProgram("dvdauthor") == False or self.checkProgram("spumux")==False: p4=self.makeButtonBox("Dvdauthor","Check to Install") self.dialog.vbox.pack_start(p4,True,True,1) if self.checkProgram("grep") == False: p5=self.makeButtonBox("Grep","Check to Install") self.dialog.vbox.pack_start(p5,True,True,1) if self.checkProgram("ln") == False: p6=self.makeButtonBox("Ln","Check to Install") self.dialog.vbox.pack_start(p6,True,True,1) self.progressBar.show() self.dialog.vbox.pack_start(self.progressBar,True,True,1) resp=self.dialog.run() if resp == gtk.RESPONSE_CLOSE: print "Response Close" elif resp == gtk.RESPONSE_OK: print "Response OK" self.startProcessing() self.msgbox(msg="Please restart DeVeDe", title="WinDeVeDe Installer") def download(self, location=None,package=None): reg=re.compile("Content-Length:.*") reg2=re.compile("[0-9]*[0-9]") if package == "mplayer": location="http://www2.mplayerhq.hu/MPlayer/releases/win32/MPlayer-mingw32-1.0rc1.zip" elif package == "grep": location="http://peter.m.gill.googlepages.com/grep.zip" elif package == "ln": location="http://peter.m.gill.googlepages.com/ln.zip" elif package == "vcdimager": location="http://peter.m.gill.googlepages.com/vcdimager.zip" elif package == "dvdauthor": location="http://peter.m.gill.googlepages.com/dvdauthor.zip" elif package == "mkisofs": location="http://peter.m.gill.googlepages.com/mkisofs.zip" elif package == "cygwin": location="http://peter.m.gill.googlepages.com/cygwin1.zip" else: print "Unknown package" return print location url=urllib.urlopen(location) n=0 temp=reg.search(str(url.info())) temp=temp.group() size=reg2.search(temp) size=size.group() print url.info() print "Size of file: ", int(size)/1000 , " kilobytes" output=open(package+".zip","wb") while True: s=url.read(8192) if not s: break output.write(s) n=n+len(s) downloaded=int(n)/1000 size2=int(size)/1000 print "Downloaded ", int(n)/1000 , " kilobytes of ", int(size)/1000, "." self.progressBar.set_fraction(float(downloaded)/float(size2)) self.progressBar.set_text("Downloading "+ package + ". "+ str(int((downloaded/float(size2))*100)) + "% complete.") while gtk.events_pending(): gtk.main_iteration() url.close() output.close() return def unzip(self,package): basedir=os.getcwd() bindir=os.path.join(basedir,"bin") tempdir=os.path.join(basedir,"temp") if not os.path.isdir(tempdir): os.mkdir(tempdir) shutil.move(package+".zip",tempdir) os.chdir(tempdir) file=zipfile.ZipFile(package+".zip") for name in file.namelist(): data = file.read(name) try: output=open(name,"wb") output.write(data) output.close() except IOError: print "IOError" if not os.path.isdir(name) and len(data)==0: os.mkdir(name) print name #, len(data), repr(data[:10]) file.close() if not os.path.isdir(bindir): os.mkdir(bindir) if package=="mplayer": os.chdir("mplayer") for x in os.listdir(os.getcwd()): print "moving: ", x if os.path.isdir(x): if os.path.isdir(os.path.join(bindir,x)): shutil.rmtree(os.path.join(bindir,x)) shutil.move(x,os.path.join(bindir+os.sep+x)) else: shutil.move(x,bindir) os.chdir("../") os.rmdir(package) elif package=="grep": shutil.move("grep.exe",bindir) shutil.move("cygpcre-0.dll",bindir) elif package=="ln": shutil.move("ln.exe",bindir) elif package=="vcdimager": shutil.move("vcdimager.exe",bindir) shutil.move("cygpopt-0.dll",bindir) elif package=="mkisofs": shutil.move("mkisofs.exe",bindir) elif package=="dvdauthor": shutil.move("dvdauthor.exe",bindir) shutil.move("spumux.exe",bindir) shutil.move("dvdunauthor.exe",bindir) shutil.move("mpeg2desc.exe",bindir) shutil.move("spuunmux.exe",bindir) shutil.move("cyglcms-1.dll",bindir) shutil.move("cygMagick-10.dll",bindir) shutil.move("cygtiff-5.dll",bindir) elif package=="cygwin": shutil.move("cygwin1.dll",bindir) os.chdir(basedir) return def untar(self): pass def checkProgram(self,name=None): pathlist=[os.path.join(os.getcwd(),"bin"), r'C:\WINDOWS', r'C:\WINDOWS\system32', r'C:\WINNT'] found=False if name=="mplayer": name+=".exe -v" elif name=="mencoder": name+=".exe -msglevel help" elif name=="dvdauthor": name+=".exe --help" elif name=="vcdimager": name+=".exe --help" elif name=="mkisofs": name+=".exe -help" elif name=="grep": name+=".exe --v" elif name=="ln": name+=".exe --help" elif name=="spumux": name+=".exe --help" print name for x in pathlist: print "x: ", x y=os.path.join(x,name) print "y: ", y try: #z = check_program(y) z=subprocess.Popen(y) print "z: ", z z.wait() if z.returncode == 127: continue else: found=True break except OSError: print "Error Checking Program Exist" return found def testFunc(self): print "In test func" return message = "Other end disconnected!" def recv_some(p, t=.1, e=1, tr=5, stderr=0): print "recv_some" if tr < 1: tr = 1 print "tr: ", tr x = time.time()+t y = [] r = '' pr = p.recv #print "pr: ", pr if stderr: pr = p.recv_err print "pr_err: ", pr while time.time() < x or r: r = pr() #print "r: ", r if r is None: if e: print message raise Exception(message) else: break elif r: y.append(r) else: delay=(x-time.time())/5 if delay>0: time.sleep(delay) else: time.sleep(max((x-time.time())/tr, 0)) return ''.join(y) def send_all(p, data): while len(data): sent = p.send(data) if sent is None: raise Exception(message) data = buffer(data, sent) if __name__ == "__main__": s = GetPrograms() s.displayCheckmarkGui()