#!/bin/bash # A script to run Jokosher 0.2 # Checks dependencies and complains if you don't have them # If you do have them, downloads and compiles appropriate GStreamer and runs # Jokosher. # Written in both bash and python to cater for everything. # sil, 2006-11-04 true=5 FOO=6 true << FOO # -------------------------------------------------------------- # This is the Python part # -------------------------------------------------------------- import sys, os has_zenity = sys.argv[1] # Check if we have lots of Python modules missing = [] required = [ ('pygtk','python-gtk2'), ('cairo','python-cairo'), ('dbus','python-dbus'), ('gnomevfs','python-gnome2'), ('pkg_resources','python-setuptools'), ('xml.dom.minidom','python-xml') ] for module, name in required: try: __import__(module) except: missing.append(name) try: import subprocess ret = subprocess.call("which cvs > /dev/null", shell=True) if ret != 0: missing.append("cvs") # check we're running on Ubuntu try: output = subprocess.Popen(["lsb_release", "-is"], stdout=subprocess.PIPE).communicate()[0].strip() ON_UBUNTU = output == 'Ubuntu' if ON_UBUNTU: # Now check for the build deps for gstreamer, etc aptargs = """ -o Debug::NoLocking=true -qq -s build-dep gstreamer0.10-alsa gstreamer0.10-gnomevfs gstreamer0.10-plugins-base gstreamer0.10-plugins-good gstreamer0.10-plugins-ugly gstreamer0.10-tools gstreamer0.10-x libgstreamer0.10-0 libgstreamer0.10-dev python-gst0.10 gnonlin""" # we need NoLocking above so it works as a user and doesn't require root aptargs = aptargs.split() aptargs.insert(0,"apt-get") output = subprocess.Popen(aptargs, stdout=subprocess.PIPE).communicate()[0] missing += [x.split()[1] for x in output.split('\n') if x.startswith('Inst ')] except OSError: # Probably an OSError because lsb_release doesn't exist ON_UBUNTU = False except ImportError: pass # probably don't have subprocess, which is caught by the Python check if sys.hexversion < 0x02040000: missing.append("Python 2.4 or greater") if missing or not ON_UBUNTU: if ON_UBUNTU: missing_msg_xterm = "Jokosher is missing some dependencies. Please install:\n%s" % \ ' '.join(missing) missing_msg = ("Jokosher is missing %s dependencies. Would you like "+ \ "to install them now?") % len(missing) if has_zenity != 'yes': os.system("""xterm -e 'echo "%s" && read' """ % missing_msg_xterm) sys.exit(1) else: ret = os.system("""zenity --question --title="" --text="%s" """ % missing_msg) if ret != 0: os.system("""zenity --error --title="" --text="This script will now exit." """) sys.exit(1) else: # they want to install the packages # thanks to deskbar-apt for this bit! from tempfile import mktemp fn = mktemp() fp = open(fn,"w") fp.write( '\n'.join( ['%s\tinstall' % x for x in missing] ) ) fp.close() cmd = [ '/usr/bin/gksudo', '-m', 'Please enter your password to install the required Jokosher packages', '--', '/usr/sbin/synaptic', '--non-interactive', '--hide-main-window', '--progress-str','Please wait, this can take some time', '--finish-str','Installation complete!', '--set-selections-file',fn ] ret = os.spawnv(os.P_WAIT,cmd[0],cmd) os.remove(fn) if ret != 0: # this doesn't work because synaptic returns 0 even if you cancel. Bah! os.system("""zenity --error --title="" --text="Dependency """ + \ """installation failed. This script will now exit. Please file """+ """a bug at https://launchpad.net/products/jokosher/+filebug" """) sys.exit(1) # all dependencies installed. Fall through to Jokosher install else: missing_msg = "This script is designed to run on Ubuntu only. Please " + \ "refer to the Jokosher site for how to install the 0.2 " + \ "release on other distributions." missing_msg_xterm = missing_msg if has_zenity == 'yes': os.system("""zenity --error --text="%s" """ % missing_msg) sys.exit(1) else: os.system("""xterm -e 'echo "%s" && read' """ % missing_msg_xterm) sys.exit(1) # They've got all the requirements # We now need to download and compile GStreamer, and download Jokosher import urllib, threading, gobject, gtk, string class WorkThread(threading.Thread): def __init__(self,progress): super(WorkThread,self).__init__() self.CODIR=os.path.expanduser('~/Jokosher0.2checkout') self.JOKDIR=os.path.join(self.CODIR,'jokosher') self.GSTDIR=os.path.join(self.CODIR,'gst') self.progress = progress def show_output(self, text, progress): # schedule as an idle_add so it happens on the main thread gobject.idle_add(self.update_label, text, progress) def update_label(self, text, progress): self.progress.set_text(text) self.progress.set_fraction(progress / 100.0) def makedirs(self): try: os.makedirs(self.JOKDIR) os.makedirs(self.GSTDIR) except: pass # probably already exists def fetchscript(self): self.show_output("Fetching script", 10) urllib.urlretrieve('http://www.jokosher.org/0.2/run-jokosher-with-gst', os.path.join(self.CODIR,'run-jokosher-with-gst')) return 0 def fetchjokosher(self): self.show_output("Fetching Jokosher",20) if not os.path.exists(os.path.join(self.JOKDIR,"README")): JOKTARBALL = os.path.join(self.CODIR,'jokosher-0.2.tar.gz') urllib.urlretrieve('http://www.jokosher.org/scripts/download.php/src/www.jokosher.org/0.2/jokosher-0.2.tar.gz', JOKTARBALL) # untar it ret = os.system("tar xvfpz %s -C %s" % (JOKTARBALL, self.JOKDIR)) self.check_error(ret, "Error downloading or unpacking Jokosher tarball") # and remove tarball os.remove(JOKTARBALL) def installextensions(self): import shutil self.show_output("Installing default extensions", 25) EXTDIR = os.path.expanduser('~/.jokosher/extensions') OLD_JOKOSHER_RC = os.path.expanduser("~/.jokosher") if os.path.isfile(OLD_JOKOSHER_RC): os.remove(OLD_JOKOSHER_RC) try: os.makedirs(EXTDIR) except OSError: pass # already exists for f in os.listdir(os.path.join(self.JOKDIR,'extensions')): shutil.copyfile(os.path.join(self.JOKDIR,'extensions',f), os.path.join(EXTDIR,f)) def fetchgstreamer(self): os.chdir(self.GSTDIR) CVSCMD="cvs -d:pserver:anoncvs@anoncvs.freedesktop.org:/cvs/gstreamer co -D 2006-11-13 %s" self.GSTMODS=['gstreamer','gst-plugins-base','gst-plugins-good','gst-plugins-ugly', 'gst-python','gnonlin'] # in build order, so "gstreamer" first filespresent = {"gstreamer":"TODO", "gst-plugins-base":"REQUIREMENTS", "gst-plugins-good":"REQUIREMENTS", "gst-plugins-ugly":"REQUIREMENTS", "gst-python":"TODO", "gnonlin":"REQUIREMENTS"} counter = 30 for mod in self.GSTMODS: self.show_output("Fetching %s" % mod, counter) counter += 1 if not os.path.exists(os.path.join(self.GSTDIR,mod,filespresent[mod])): self.check_error(os.system(CVSCMD % mod), "Error getting %s from CVS" % mod) def fetchthings(self): self.check_error(self.fetchscript(), "Error downloading Jokosher launching script") self.fetchjokosher() self.installextensions() self.fetchgstreamer() def envar(self, var, value): t = string.Template(value) os.environ[var] = t.safe_substitute(os.environ, GST=self.GSTDIR) def setenvars(self): # Set a load of envars to point at the private GStreamer # This is needed so that private plugins-base, etc, will compile, because they # need to know about the private gst # Copied from the shell script # set up a bunch of paths import string self.show_output("Setting up environment", 35) self.envar("PATH","$GST/gstreamer/tools:$GST/gst-plugins/tools:" + \ "$GST/gst-player/src:$GST/gst-editor/src:$GST/prefix/bin:$PATH") # if LD_LIBRARY_PATH is empty then it will look in . here, but we don't care self.envar("LD_LIBRARY_PATH","$GST/prefix/lib:$LD_LIBRARY_PATH") for path in "audio cdda interfaces netbuffer riff rtp tag video".split(): self.envar("LD_LIBRARY_PATH", "$GST/gst-plugins-base/gst-libs/gst/%s/.libs:$LD_LIBRARY_PATH" % path) for path in "base net check controller dataprotocol".split(): self.envar("LD_LIBRARY_PATH", "$GST/gstreamer/libs/gst/%s/.libs:$LD_LIBRARY_PATH" % path) self.envar("LD_LIBRARY_PATH","$GST/gstreamer/gst/.libs:$LD_LIBRARY_PATH") self.envar("PKG_CONFIG_PATH", "$GST/prefix/lib/pkgconfig:" + \ "$GST/gstreamer/pkgconfig:$GST/gst-plugins/pkgconfig:" + \ "$GST/gst-plugins-base/pkgconfig:$GST/gst-plugins-good/pkgconfig:" + \ "$GST/gst-python/pkgconfig:$PKG_CONFIG_PATH") self.envar("GST_PLUGIN_PATH","$GST/gstreamer:$GST/gst-plugins:" + \ "$GST/gst-plugins-base:$GST/gst-plugins-good:$GST/gst-plugins-ugly:" + \ "$GST/gst-plugins-bad:$GST/gst-ffmpeg:$GST/gnonlin:" + \ "$GST/gst-monkeysaudio:$GST/plugins:$GST_PLUGIN_PATH") self.envar("GST_PLUGIN_SYSTEM_PATH","") self.envar("GST_REGISTRY","$GST/gstreamer/registry.xml") self.envar("MANPATH","$GST/gstreamer/tools:$GST/prefix/share/man:$MANPATH") pythonver=sys.version[:3] # if PYTHONPATH is empty then it will look in . here, but we don't care self.envar("PYTHONPATH", "$GST/gst-python:$GST/prefix/lib/python%s/" + \ "site-packages:$PYTHONPATH") def compilegstreamer(self): counter = 40 for mod in self.GSTMODS: self.show_output("Compiling %s" % mod, counter) counter += 5 os.chdir(os.path.join(self.GSTDIR,mod)) self.check_error(os.system("./autogen.sh"), "Failed configure of %s" % mod) self.check_error(os.system("make"), "Failed make of %s" % mod) def run(self): self.makedirs() self.fetchthings() self.setenvars() self.compilegstreamer() fp = open(os.path.join(self.CODIR,"finished"), "w") fp.write("Finished: tag file") fp.close() os.system('zenity --info --title="" ' + '--text="You can now run this script to run Jokosher"') def check_error(self, rettotal, details="None"): if rettotal != 0: os.system('zenity --error --title="" ' + '--text="Installation failed. Please rerun this script. ' + 'If this problem recurs, please file a bug at '+ '\nhttps://launchpad.net/products/jokosher/+filebug.' + '\n\nDetails:\n' + details + '"') print os.path.abspath(".") sys.exit(1) gobject.threads_init() # create the Gtk window that displays stuff w = gtk.Window() v = gtk.VBox() p = gtk.ProgressBar() p.set_text("Starting") p.set_fraction(0) v.add(p) w.add(v) w.connect("destroy", lambda _: gtk.main_quit()) w.show_all() # create the thread that does the work workthread = WorkThread(p) workthread.setDaemon(true) # if the window exits, the workthread exits workthread.start() def checkWorkThread(*args): if not workthread.isAlive(): gtk.main_quit() gobject.timeout_add(1000, checkWorkThread) gobject.timeout_add(1000, checkWorkThread) gtk.main() sys.exit(0) # -------------------------------------------------------------- # End Python part # -------------------------------------------------------------- thisstr = """ FOO # -------------------------------------------------------------- # This is the bash part # -------------------------------------------------------------- # First, see if this script has already built Jokosher CODIR=$HOME/Jokosher0.2checkout if [ -f $CODIR/finished ]; then /bin/bash $CODIR/run-jokosher-with-gst exit fi # Check if we have Zenity, which Python needs later which zenity > /dev/null if [ $? = 0 ]; then ZENITY=yes else ZENITY=no fi # Check if we have Python which python > /dev/null if [ $? = 0 ]; then # We have Python, rerun this script with it python $0 $ZENITY else # No Python! Display an error zenity --error --text "Please install Python to run Jokosher." || \ xterm -e 'echo Please install Python to run Jokosher. Press ENTER to exit. && read' fi # -------------------------------------------------------------- # End bash part # -------------------------------------------------------------- # """