[svn r838] - Arranged code in a better way trunk
authormorphbr
Wed Aug 29 14:42:10 2007 +0100 (2007-08-29)
branchtrunk
changeset 832daa61fffb811
parent 831 e2baa6947dbf
child 833 7d4d75351461
[svn r838] - Arranged code in a better way
gmyth-stream/server/0.3/data/gmsd
gmyth-stream/server/0.3/data/server.conf
gmyth-stream/server/0.3/debian/changelog
gmyth-stream/server/0.3/debian/compat
gmyth-stream/server/0.3/debian/control
gmyth-stream/server/0.3/debian/copyright
gmyth-stream/server/0.3/debian/gms.install
gmyth-stream/server/0.3/debian/gms.postinst
gmyth-stream/server/0.3/debian/gms.postrm
gmyth-stream/server/0.3/debian/rules
gmyth-stream/server/0.3/gms.py
gmyth-stream/server/0.3/html/index.html
gmyth-stream/server/0.3/html/menu.html
gmyth-stream/server/0.3/html/shutdown.html
gmyth-stream/server/0.3/html/status.html
gmyth-stream/server/0.3/html/stop_all.html
gmyth-stream/server/0.3/html/stop_selected.html
gmyth-stream/server/0.3/lib/__init__.py
gmyth-stream/server/0.3/lib/file_handler.py
gmyth-stream/server/0.3/lib/gmsconfig.py
gmyth-stream/server/0.3/lib/log.py
gmyth-stream/server/0.3/lib/request_handler.py
gmyth-stream/server/0.3/lib/server.py
gmyth-stream/server/0.3/lib/transcoder.py
gmyth-stream/server/0.3/lib/utils.py
gmyth-stream/server/0.3/plugins/__init__.py
gmyth-stream/server/0.3/plugins/transcoders/__init__.py
gmyth-stream/server/0.3/plugins/transcoders/gmencoder.py
gmyth-stream/server/0.3/plugins/transcoders/mencoder.py
gmyth-stream/server/0.3/plugins/transcoders/mencoder_lib/__init__.py
gmyth-stream/server/0.3/plugins/transcoders/mencoder_lib/mythtv.py
gmyth-stream/server/0.3/server.conf
gmyth-stream/server/0.3/setup.py
gmyth-stream/server/data/gmsd
gmyth-stream/server/data/server.conf
gmyth-stream/server/debian/changelog
gmyth-stream/server/debian/compat
gmyth-stream/server/debian/control
gmyth-stream/server/debian/copyright
gmyth-stream/server/debian/gms.install
gmyth-stream/server/debian/gms.postinst
gmyth-stream/server/debian/gms.postrm
gmyth-stream/server/debian/rules
gmyth-stream/server/gms.py
gmyth-stream/server/html/index.html
gmyth-stream/server/html/menu.html
gmyth-stream/server/html/shutdown.html
gmyth-stream/server/html/status.html
gmyth-stream/server/html/stop_all.html
gmyth-stream/server/html/stop_selected.html
gmyth-stream/server/lib/__init__.py
gmyth-stream/server/lib/file_handler.py
gmyth-stream/server/lib/gmsconfig.py
gmyth-stream/server/lib/log.py
gmyth-stream/server/lib/request_handler.py
gmyth-stream/server/lib/server.py
gmyth-stream/server/lib/transcoder.py
gmyth-stream/server/lib/utils.py
gmyth-stream/server/plugins/__init__.py
gmyth-stream/server/plugins/transcoders/__init__.py
gmyth-stream/server/plugins/transcoders/gmencoder.py
gmyth-stream/server/plugins/transcoders/mencoder.py
gmyth-stream/server/plugins/transcoders/mencoder_lib/__init__.py
gmyth-stream/server/plugins/transcoders/mencoder_lib/mythtv.py
gmyth-stream/server/server.conf
gmyth-stream/server/setup.py
     1.1 --- a/gmyth-stream/server/0.3/data/gmsd	Wed Aug 29 14:29:24 2007 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,61 +0,0 @@
     1.4 -#!/bin/sh
     1.5 -
     1.6 -PROGRAM_NAME=GMS
     1.7 -PROGRAM_BIN=/usr/bin/gms.py
     1.8 -PIDFILE=/var/run/gms.pid
     1.9 -LOGFILE=/var/log/gms.log
    1.10 -
    1.11 -test -x $PROGRAM_BIN || exit 0
    1.12 -
    1.13 -set -e
    1.14 -
    1.15 -. /lib/lsb/init-functions
    1.16 -. /etc/default/rcS
    1.17 -
    1.18 -case $1 in
    1.19 -  start)
    1.20 -    echo -n "Starting $PROGRAM_NAME: "
    1.21 -    if [ -f $PIDFILE ]
    1.22 -    then
    1.23 -        PID=`cat $PIDFILE`
    1.24 -
    1.25 -        if ps ax | grep -q "^$PID"
    1.26 -        then
    1.27 -            echo "$PROGRAM_NAME already running."
    1.28 -        else
    1.29 -            rm -f $PIDFILE
    1.30 -            $PROGRAM_BIN -d > $LOGFILE
    1.31 -            echo "OK"
    1.32 -        fi
    1.33 -    else
    1.34 -        $PROGRAM_BIN -d > $LOGFILE
    1.35 -        echo "OK"
    1.36 -    fi
    1.37 -    ;;
    1.38 -
    1.39 -  stop)
    1.40 -    echo -n "Stopping $PROGRAM_NAME: "
    1.41 -    if [ -f $PIDFILE ]
    1.42 -    then
    1.43 -        PID=`cat $PIDFILE`
    1.44 -        if ps ax | grep -q "^$PID"
    1.45 -        then
    1.46 -            kill -10 $PID
    1.47 -        fi
    1.48 -        rm $PIDFILE
    1.49 -    else
    1.50 -        echo "No $PROGRAM_NAME found running; no killed."
    1.51 -    fi
    1.52 -    ;;
    1.53 -
    1.54 -  restart)
    1.55 -    $0 stop
    1.56 -    sleep 1
    1.57 -    $0 start
    1.58 -    ;;
    1.59 -
    1.60 -  *)
    1.61 -    log_success_msg "Usage: $0 {stop|start|restart}"
    1.62 -    exit 1
    1.63 -    ;;
    1.64 -esac
     2.1 --- a/gmyth-stream/server/0.3/data/server.conf	Wed Aug 29 14:29:24 2007 +0100
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,2 +0,0 @@
     2.4 -[PATHS]
     2.5 -transcoded=/var/gms-media
     3.1 --- a/gmyth-stream/server/0.3/debian/changelog	Wed Aug 29 14:29:24 2007 +0100
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,6 +0,0 @@
     3.4 -gms (0.3-indt1) unstable; urgency=low
     3.5 -
     3.6 -  * First package
     3.7 -
     3.8 - -- Renato Araujo Oliveira Filho <renato.filho@indt.org>  Thu, 16 Aug 2007 14:55:00 -0300
     3.9 -
     4.1 --- a/gmyth-stream/server/0.3/debian/compat	Wed Aug 29 14:29:24 2007 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,1 +0,0 @@
     4.4 -5
     5.1 --- a/gmyth-stream/server/0.3/debian/control	Wed Aug 29 14:29:24 2007 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,13 +0,0 @@
     5.4 -Source: gms
     5.5 -Section: sound
     5.6 -Priority: optional
     5.7 -Maintainer: Renato Araujo Oliveira Filho <renato.filho@indt.org>
     5.8 -Build-Depends: debhelper (>= 5.0.38), python-support (>= 0.5), python-central (>= 0.5)
     5.9 -Standards-Version: 3.7.2
    5.10 -
    5.11 -Package: gms
    5.12 -Architecture: any
    5.13 -Depends: ${python:Depends}, libgstreamer0.10-0, gstreamer0.10-plugins-base, gstreamer0.10-plugins-good
    5.14 -Recommends: gstreamer0.10-plugins-ugly
    5.15 -Description: Media transcoder deamon
    5.16 -  Homepage: http://gmyth.sourceforge.net/
     6.1 --- a/gmyth-stream/server/0.3/debian/copyright	Wed Aug 29 14:29:24 2007 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,19 +0,0 @@
     6.4 -It was downloaded from: http://gmyth.sourceforge.net/wiki/
     6.5 -
     6.6 -License:
     6.7 -   This package is free software; you can redistribute it and/or modify
     6.8 -   it under the terms of the GNU General Public License as published by
     6.9 -   the Free Software Foundation; either version 2 of the License, or
    6.10 -   (at your option) any later version.
    6.11 -
    6.12 -   This package is distributed in the hope that it will be useful,
    6.13 -   but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.14 -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.15 -   GNU General Public License for more details.
    6.16 -
    6.17 -   You should have received a copy of the GNU General Public License
    6.18 -   along with this package; if not, write to the Free Software
    6.19 -   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
    6.20 -
    6.21 -On Debian systems, the complete text of the GNU General Public License can
    6.22 -be found in `/usr/share/common-licenses/GPL'.
     7.1 --- a/gmyth-stream/server/0.3/debian/gms.install	Wed Aug 29 14:29:24 2007 +0100
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,8 +0,0 @@
     7.4 -debian/tmp/usr/share/gms/lib/*.py usr/share/gms/lib
     7.5 -debian/tmp/usr/share/gms/plugins/*.py usr/share/gms/plugins
     7.6 -debian/tmp/usr/share/gms/plugins/transcoders/*.py usr/share/gms/plugins/transcoders
     7.7 -debian/tmp/usr/share/gms/plugins/transcoders/mencoder_lib/*.py usr/share/gms/plugins/transcoders/mencoder_lib
     7.8 -debian/tmp/usr/share/gms/html/* usr/share/gms/html
     7.9 -debian/tmp/usr/bin/* usr/bin
    7.10 -debian/etc/init.d/gmsd etc/init.d
    7.11 -debian/etc/gms/*.conf etc/gms/
     8.1 --- a/gmyth-stream/server/0.3/debian/gms.postinst	Wed Aug 29 14:29:24 2007 +0100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,29 +0,0 @@
     8.4 -#! /bin/sh
     8.5 -# postinst script for gms
     8.6 -
     8.7 -set -e
     8.8 -
     8.9 -case "$1" in
    8.10 -  configure)
    8.11 -    if ! getent passwd gms >/dev/null; then
    8.12 -      adduser --disabled-password  --quiet --system \
    8.13 -        --home /var/gms-media \
    8.14 -        --gecos "GMS media dir" --group gms
    8.15 -    fi
    8.16 -    if ! getent passwd gms | grep -q /var/run/gms; then
    8.17 -        usermod -d /var/gms-media gms
    8.18 -    fi
    8.19 -    update-rc.d gmsd defaults
    8.20 -    invoke-rc.d gmsd start
    8.21 -  ;;
    8.22 -  abort-upgrade|abort-remove|abort-deconfigure)
    8.23 -  ;;
    8.24 -  *)
    8.25 -    echo "postinst called with unknown argument \`$1'" >&2
    8.26 -    exit 1
    8.27 -  ;;
    8.28 -esac
    8.29 -
    8.30 -#DEBHELPER#
    8.31 -
    8.32 -exit 0
     9.1 --- a/gmyth-stream/server/0.3/debian/gms.postrm	Wed Aug 29 14:29:24 2007 +0100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,13 +0,0 @@
     9.4 -#!/bin/sh
     9.5 -
     9.6 -set -e
     9.7 -
     9.8 -#DEBHELPER#
     9.9 -
    9.10 -if [ "$1" = "purge" ] ; then
    9.11 -        invoke-rc.d --force gms stop
    9.12 -        deluser --quiet --system gms > /dev/null || true
    9.13 -        delgroup --quiet --system gms > /dev/null || true
    9.14 -fi
    9.15 -
    9.16 -exit 0
    10.1 --- a/gmyth-stream/server/0.3/debian/rules	Wed Aug 29 14:29:24 2007 +0100
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,52 +0,0 @@
    10.4 -#!/usr/bin/make -f
    10.5 -# -*- makefile -*-
    10.6 -
    10.7 -# Uncomment this to turn on verbose mode.
    10.8 -#export DH_VERBOSE=1
    10.9 -
   10.10 -PYVER=2.5
   10.11 -PYTHON=python$(PYVER)
   10.12 -
   10.13 -PREFIX=debian/tmp
   10.14 -
   10.15 -build: build-stamp
   10.16 -
   10.17 -build-stamp:
   10.18 -	touch build-stamp
   10.19 -
   10.20 -clean:
   10.21 -	dh_testdir
   10.22 -	dh_testroot
   10.23 -	rm -f build-stamp
   10.24 -	dh_clean
   10.25 -
   10.26 -install: build
   10.27 -	dh_testdir
   10.28 -	dh_testroot
   10.29 -	dh_installdirs
   10.30 -	dh_clean -k
   10.31 -
   10.32 -	@rm -rf build
   10.33 -	@$(PYTHON) setup.py install --prefix=$(PREFIX)/usr --no-compile --install-purelib=$(PREFIX)/usr/share/gms
   10.34 -	install -D -o root -g root -m 755 $(PREFIX)/usr/etc/init.d/gmsd  debian/$(cdbs_curpkg)/etc/init.d/gmsd
   10.35 -	install -D -o root -g root -m 755 $(PREFIX)/usr/etc/gms/server.conf  debian/$(cdbs_curpkg)/etc/gms/server.conf
   10.36 -
   10.37 -	dh_install
   10.38 -
   10.39 -# Build architecture-independent files here.
   10.40 -binary-indep: build install
   10.41 -	dh_testdir
   10.42 -	dh_testroot
   10.43 -	dh_installchangelogs
   10.44 -	dh_installdocs
   10.45 -	dh_strip
   10.46 -	dh_compress
   10.47 -	dh_fixperms
   10.48 -	dh_installdeb
   10.49 -	dh_gencontrol
   10.50 -	dh_md5sums
   10.51 -	dh_builddeb
   10.52 -
   10.53 -binary: binary-indep
   10.54 -.PHONY: clean binary-indep binary install
   10.55 -
    11.1 --- a/gmyth-stream/server/0.3/gms.py	Wed Aug 29 14:29:24 2007 +0100
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,74 +0,0 @@
    11.4 -#!/usr/bin/env python
    11.5 -
    11.6 -__author__ = "Artur Duque de Souza"
    11.7 -__author_email__ = "artur.souza@indt.org.br"
    11.8 -__license__ = "GPL"
    11.9 -__version__ = "0.3"
   11.10 -__thanks__ = "Gustavo Sverzut Barbieri"
   11.11 -__GMS_DATA_DIR__ = "/usr/share/gms/"
   11.12 -
   11.13 -import sys
   11.14 -import os
   11.15 -import mimetypes
   11.16 -import logging as log
   11.17 -
   11.18 -if os.path.exists (__GMS_DATA_DIR__):
   11.19 -    sys.path.append(__GMS_DATA_DIR__)
   11.20 -
   11.21 -from lib.server import serve_forever, load_plugins_transcoders
   11.22 -from lib.utils import config
   11.23 -
   11.24 -mimetypes.init()
   11.25 -log_level = log.INFO
   11.26 -for p in sys.argv[1:]:
   11.27 -    if p == "-v" or p == "--verbose":
   11.28 -        log_level -= 10
   11.29 -
   11.30 -log.basicConfig(level=log_level,
   11.31 -                format=("### %(asctime)s %(name)-18s \t%(levelname)-8s "
   11.32 -                        "\t%(message)s"),
   11.33 -                datefmt="%Y-%m-%d %H:%M:%S")
   11.34 -
   11.35 -if config.get_transcoded_location () is None:
   11.36 -    print "Gms not configured"
   11.37 -    exit (0)
   11.38 -
   11.39 -if not os.path.exists(config.get_transcoded_location()):
   11.40 -    os.mkdir(config.get_transcoded_location())
   11.41 -
   11.42 -
   11.43 -if "-d" in sys.argv:
   11.44 -    #run with deamon
   11.45 -    try:
   11.46 -        pid = os.fork()
   11.47 -        if pid > 0:
   11.48 -             sys.exit(0)
   11.49 -    except OSError, e:
   11.50 -        print >>sys.stderr, "Fail to start deamon: %d (%s)" % (e.errno, e.strerror) 
   11.51 -        sys.exit(1)
   11.52 -
   11.53 -    os.chdir("/")
   11.54 -    os.setsid()
   11.55 -    os.umask(0)
   11.56 -
   11.57 -    try:
   11.58 -        pid = os.fork()
   11.59 -        if pid > 0:
   11.60 -            fp = open ("/var/run/gms.pid", "w")
   11.61 -            fp.write ("%d" % pid)
   11.62 -            fp.close ()
   11.63 -            sys.exit(0)
   11.64 -    except OSError, e:
   11.65 -        print >>sys.stderr, "Fail to start deamon: %d (%s)" % (e.errno, e.strerror) 
   11.66 -        sys.exit(1)
   11.67 -
   11.68 -# main deamon
   11.69 -pd = os.path.join(__GMS_DATA_DIR__, "plugins", "transcoders")
   11.70 -if os.path.exists (pd):
   11.71 -    load_plugins_transcoders(pd)
   11.72 -
   11.73 -pd = os.path.join("plugins", "transcoders");
   11.74 -if os.path.exists (pd):
   11.75 -    load_plugins_transcoders(pd)
   11.76 -
   11.77 -serve_forever()
    12.1 --- a/gmyth-stream/server/0.3/html/index.html	Wed Aug 29 14:29:24 2007 +0100
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,9 +0,0 @@
    12.4 -<html>
    12.5 -   <head><title>GMyth-Streamer Server</title></head>
    12.6 -   <body>
    12.7 -<h1>Welcome to GMyth-Streamer Server</h1>
    12.8 -<ul>
    12.9 -%(menu)s
   12.10 -</ul>
   12.11 -   </body>
   12.12 -</html>
   12.13 \ No newline at end of file
    13.1 --- a/gmyth-stream/server/0.3/html/menu.html	Wed Aug 29 14:29:24 2007 +0100
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,1 +0,0 @@
    13.4 -<li><a href="%(url)s">%(name)s</a></li>
    14.1 --- a/gmyth-stream/server/0.3/html/shutdown.html	Wed Aug 29 14:29:24 2007 +0100
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,6 +0,0 @@
    14.4 -<html>
    14.5 -   <head><title>GMyth-Streamer Server Exited</title></head>
    14.6 -   <body>
    14.7 -      <h1>GMyth-Streamer is not running anymore</h1>
    14.8 -   </body>
    14.9 -</html>
   14.10 \ No newline at end of file
    15.1 --- a/gmyth-stream/server/0.3/html/status.html	Wed Aug 29 14:29:24 2007 +0100
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,14 +0,0 @@
    15.4 -<html>
    15.5 -   <head><title>GMyth-Streamer Server Status</title></head>
    15.6 -   <body>
    15.7 -      <h1>GMyth-Streamer Status</h1>
    15.8 -      <ul>
    15.9 -            %(running)s
   15.10 -            %(stopall)s
   15.11 -            %(stopone)s
   15.12 -      </ul>
   15.13 -      <ul>
   15.14 -            %(menu)s
   15.15 -      </ul>
   15.16 -   </body>
   15.17 -</html>
    16.1 --- a/gmyth-stream/server/0.3/html/stop_all.html	Wed Aug 29 14:29:24 2007 +0100
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,9 +0,0 @@
    16.4 -<html>
    16.5 -   <head><title>GMyth-Streamer Server Stopped Transcoders</title></head>
    16.6 -   <body>
    16.7 -      <h1>GMyth-Streamer stopped running transcoders</h1>
    16.8 -      <ul>
    16.9 -      %(menu)s
   16.10 -      </ul>
   16.11 -   </body>
   16.12 -</html>
   16.13 \ No newline at end of file
    17.1 --- a/gmyth-stream/server/0.3/html/stop_selected.html	Wed Aug 29 14:29:24 2007 +0100
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,12 +0,0 @@
    17.4 -<html>
    17.5 -   <head><title>GMyth-Streamer Server Stopped Transcoders</title></head>
    17.6 -   <body>
    17.7 -      <h1>GMyth-Streamer stopped running transcoders:</h1>
    17.8 -      <ul>
    17.9 -            %(opts)s
   17.10 -      </ul>
   17.11 -      <ul>
   17.12 -            %(menu)s
   17.13 -      </ul>
   17.14 -   </body>
   17.15 -</html>
    18.1 --- a/gmyth-stream/server/0.3/lib/file_handler.py	Wed Aug 29 14:29:24 2007 +0100
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,86 +0,0 @@
    18.4 -#!/usr/bin/env python
    18.5 -
    18.6 -__author__ = "Artur Duque de Souza"
    18.7 -__author_email__ = "artur.souza@indt.org.br"
    18.8 -__license__ = "GPL"
    18.9 -__version__ = "0.1"
   18.10 -
   18.11 -import os
   18.12 -import sys
   18.13 -import pickle
   18.14 -import logging
   18.15 -import lib.utils as utils
   18.16 -
   18.17 -from stat import *
   18.18 -
   18.19 -__all__ = ("FileList", "list_media_files")
   18.20 -
   18.21 -
   18.22 -class TranscodedFile(object):
   18.23 -    """This class creates and reads information about transcoded files."""
   18.24 -    opts = {}
   18.25 -    log = logging.getLogger("gms.file_handler")
   18.26 -
   18.27 -    def __init__(self, filename, args):
   18.28 -        if filename == "" or not os.path.exists(filename):
   18.29 -            self.opts = args.copy()
   18.30 -
   18.31 -            if self.opts["type"][0] != "myth":
   18.32 -                self.opts["original_mtime"] = os.path.getmtime(
   18.33 -                    self.opts["uri"][0])
   18.34 -
   18.35 -            name = os.path.basename(self.opts["uri"][0])
   18.36 -            self.opts["original"] = [name]
   18.37 -            output_file = os.path.basename(self.opts["outfile"][0])
   18.38 -            dat_file = output_file + ".dat";
   18.39 -            dat_path = os.path.join (utils.config.get_transcoded_location(),
   18.40 -                dat_file);
   18.41 -
   18.42 -            output = open(dat_path, "wb")
   18.43 -            # dumps data using the highest protocol
   18.44 -            pickle.dump(self.opts, output, -1)
   18.45 -            output.close()
   18.46 -        else:
   18.47 -            name = os.path.splitext(os.path.basename(filename))[0]
   18.48 -            dat_file = name + ".dat";
   18.49 -            dat_path = os.path.join (utils.config.get_transcoded_location(),
   18.50 -                dat_file);
   18.51 -            pkl_file = open(dat_path, "rb")
   18.52 -            self.opts = pickle.load(pkl_file)
   18.53 -    # __init__()
   18.54 -
   18.55 -# TranscodedFile
   18.56 -
   18.57 -
   18.58 -class FileList(list):
   18.59 -    """Class to hold file's list - reimplements str and repr."""
   18.60 -    def __str__(self):
   18.61 -        ret = ""
   18.62 -        if len(self) > 0:
   18.63 -            for item in self:
   18.64 -                ret = ret + "%s" % item
   18.65 -        return ret
   18.66 -    # __str__()
   18.67 -
   18.68 -    def __repr__(self):
   18.69 -        return self.__str__()
   18.70 -    # __repr__()
   18.71 -
   18.72 -# FileList
   18.73 -
   18.74 -def list_media_files(directory, file_list):
   18.75 -    """Show all the media files with extension defined in the var 'ext'
   18.76 -    that are in the directory, appending each one to 'file_list'."""
   18.77 -    ext = ['mpg', 'avi', 'mp4', 'nuv', 'mpeg', 'mov']
   18.78 -    for root, dirs, files in os.walk(directory):
   18.79 -        for name in files:
   18.80 -            if os.path.splitext(name)[1].strip(".") in ext:
   18.81 -                dat_file = os.path.join(sys.path[0],root,
   18.82 -                                        os.path.splitext(name)[0]+".dat")
   18.83 -
   18.84 -                if name not in file_list and \
   18.85 -                       os.path.exists(dat_file):
   18.86 -                    file_list.append(name)
   18.87 -
   18.88 -    return True
   18.89 -# list_media_files()
    19.1 --- a/gmyth-stream/server/0.3/lib/gmsconfig.py	Wed Aug 29 14:29:24 2007 +0100
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,38 +0,0 @@
    19.4 -#!/usr/bin/env
    19.5 -
    19.6 -__author__ = "Renato Araujo Oliveira Filho"
    19.7 -__author_email__ = "renato.filho@indt.org.br"
    19.8 -__license__ = "GPL"
    19.9 -__version__ = "0.3"
   19.10 -
   19.11 -
   19.12 -import os
   19.13 -import ConfigParser
   19.14 -
   19.15 -__all__ = ("GmsConfig")
   19.16 -
   19.17 -class GmsConfig:
   19.18 -    config = ConfigParser.ConfigParser()
   19.19 -    __CONFIG_FILE__ = "server.conf"
   19.20 -    __CONFIG_DIRS__ =  [os.path.join (os.path.expanduser("~"), ".gms"), \
   19.21 -                       os.path.join ("/", "etc", "gms"), \
   19.22 -		       "."]
   19.23 -
   19.24 -    def __init__(self):
   19.25 -        for path in self.__CONFIG_DIRS__:
   19.26 -            file_name = os.path.join (path, self.__CONFIG_FILE__)
   19.27 -            if os.path.exists (file_name):
   19.28 -                fp = open (file_name, "r")
   19.29 -                self.config.readfp (fp)
   19.30 -                return
   19.31 -    # __init__()
   19.32 -
   19.33 -    def get_transcoded_location (self):
   19.34 -        try:
   19.35 -            return os.path.realpath (self.config.get("PATHS", "transcoded"))
   19.36 -        except:
   19.37 -            return None
   19.38 -    # get_transcoded_location()
   19.39 -
   19.40 -
   19.41 -# GmsConfig
    20.1 --- a/gmyth-stream/server/0.3/lib/log.py	Wed Aug 29 14:29:24 2007 +0100
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,109 +0,0 @@
    20.4 -#!/usr/bin/env python
    20.5 -
    20.6 -__author__ = "Artur Duque de Souza"
    20.7 -__author_email__ = "artur.souza@indt.org.br"
    20.8 -__license__ = "GPL"
    20.9 -__version__ = "0.1"
   20.10 -
   20.11 -import os
   20.12 -import logging
   20.13 -
   20.14 -__all__ = ("Log", "log_structure")
   20.15 -
   20.16 -class log_structure(object):
   20.17 -    """Structure to hold log info."""
   20.18 -
   20.19 -    def __init__(self, log=None):
   20.20 -        self.log = log
   20.21 -        self.history = []
   20.22 -    # __init__()
   20.23 -
   20.24 -# log_structure()
   20.25 -
   20.26 -class Log(object):
   20.27 -    """This class implements a log where we can store status of
   20.28 -    all transcoders (even from those that are not running any more)."""
   20.29 -
   20.30 -    ## key = tid
   20.31 -    ## item = ls
   20.32 -    logs = {}
   20.33 -
   20.34 -    def insert(self, tid, name):
   20.35 -        """Insert a given tid on the log structure"""
   20.36 -        if not self.logs.has_key(tid):
   20.37 -            self.logs[tid] = log_structure(logging.getLogger(name))
   20.38 -            return True
   20.39 -        else:
   20.40 -            return False
   20.41 -    # insert()
   20.42 -
   20.43 -    def remove(self, tid=None):
   20.44 -        """Cleans up all log stored for a
   20.45 -        given tid or for all transcodes."""
   20.46 -        if not tid:
   20.47 -            self.logs = {}
   20.48 -        else:
   20.49 -            del(self.logs[tid])
   20.50 -
   20.51 -        return True
   20.52 -    # clean()
   20.53 -
   20.54 -    def get_status(self, tid=None, all=False):
   20.55 -        """Get the status of all transcoders or
   20.56 -        of just one of them if it's given an tid."""
   20.57 -        if not tid:
   20.58 -            ret = {}
   20.59 -            for tids, logs in self.logs.items():
   20.60 -                if len(logs.history) > 0:
   20.61 -                    if not all:
   20.62 -                        ret[tids] = logs.history[-1]
   20.63 -                    else:
   20.64 -                        ret[tids] = logs.history
   20.65 -            return ret
   20.66 -        elif self.logs.has_key(tid) and len(self.logs[tid].history) > 0:
   20.67 -            if not all:
   20.68 -                return self.logs[tid].history[-1]
   20.69 -            else:
   20.70 -                return self.logs[tid].history
   20.71 -
   20.72 -        return False
   20.73 -    # get_status()
   20.74 -
   20.75 -    def _update_status(self, tid=None, msg=""):
   20.76 -        """Update the status of a given tid. Private method that
   20.77 -        is only called inside error/info/debug wrappers"""
   20.78 -        if msg != "":
   20.79 -            self.logs[tid].history.append(msg)
   20.80 -            return True
   20.81 -        else:
   20.82 -            return False
   20.83 -    # update_status()
   20.84 -
   20.85 -    def error(self, tid, msg):
   20.86 -        """Python's Log.error wrapper"""
   20.87 -        if self.logs.has_key(tid):
   20.88 -            self.logs[tid].log.error("%s" % msg)
   20.89 -            return self._update_status(tid, msg)
   20.90 -        else:
   20.91 -            return False
   20.92 -    # error()
   20.93 -
   20.94 -    def info(self, tid, msg):
   20.95 -        """Python's Log.info wrapper"""
   20.96 -        if self.logs.has_key(tid):
   20.97 -            self.logs[tid].log.info("%s" % msg)
   20.98 -            self._update_status(tid, msg)
   20.99 -            return True
  20.100 -        else:
  20.101 -            return False
  20.102 -    # info()
  20.103 -
  20.104 -    def debug(self, tid, msg):
  20.105 -        """Python's Log.debug wrapper"""
  20.106 -        if self.logs.has_key(tid):
  20.107 -            self.logs[tid].log.debug("%s" % msg)
  20.108 -            self._update_status(tid, msg)
  20.109 -            return True
  20.110 -        else:
  20.111 -            return False
  20.112 -    # debug()
    21.1 --- a/gmyth-stream/server/0.3/lib/request_handler.py	Wed Aug 29 14:29:24 2007 +0100
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,470 +0,0 @@
    21.4 -#!/usr/bin/env python
    21.5 -
    21.6 -__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    21.7 -__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    21.8 -__license__ = "GPL"
    21.9 -__version__ = "0.3"
   21.10 -
   21.11 -import os
   21.12 -import cgi
   21.13 -import socket
   21.14 -import logging
   21.15 -import urlparse
   21.16 -import threading
   21.17 -import SocketServer
   21.18 -import BaseHTTPServer
   21.19 -import mimetypes
   21.20 -
   21.21 -import lib.utils as utils
   21.22 -import lib.file_handler as files
   21.23 -import lib.transcoder as transcoder
   21.24 -
   21.25 -from log import Log
   21.26 -
   21.27 -__all__ = ("RequestHandler")
   21.28 -
   21.29 -class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
   21.30 -    """Class that implements an HTTP request handler for our server."""
   21.31 -    log = logging.getLogger("gms.request")
   21.32 -    def_transcoder = None
   21.33 -    transcoders = utils.PluginSet(transcoder.Transcoder)
   21.34 -    transcoders_log = Log()
   21.35 -    tid_queue = []
   21.36 -
   21.37 -    menu = {
   21.38 -        "Log": "/get_log.do",
   21.39 -        "Stop": "/stop-transcoder.do",
   21.40 -        "Status": "/status.do",
   21.41 -        "All Log": "/get_all_log.do",
   21.42 -        "Version": "/version.do",
   21.43 -        "Shutdown": "/shutdown.do"
   21.44 -        }
   21.45 -
   21.46 -    @classmethod
   21.47 -    def load_plugins_transcoders(cls, directory):
   21.48 -        cls.transcoders.load_from_directory(directory)
   21.49 -
   21.50 -        if cls.def_transcoder is None and cls.transcoders:
   21.51 -            cls.def_transcoder = cls.transcoders[0].name
   21.52 -    # load_plugins_transcoders()
   21.53 -
   21.54 -
   21.55 -    def do_dispatch(self, body):
   21.56 -        self.url = self.path
   21.57 -        pieces = urlparse.urlparse(self.path)
   21.58 -        self.path = pieces[2]
   21.59 -        self.query = cgi.parse_qs(pieces[4])
   21.60 -
   21.61 -        url = {
   21.62 -            "/": self.serve_main,
   21.63 -            "/shutdown.do": self.serve_shutdown,
   21.64 -            "/stop-transcoder.do": self.serve_stop_transcoder,
   21.65 -            "/status.do": self.serve_status,
   21.66 -            "/version.do": self.serve_version,
   21.67 -            "/new_id.do": self.serve_new_id,
   21.68 -            "/get_log.do": self.serve_get_log,
   21.69 -            "/get_all_log.do": self.serve_get_all_log,
   21.70 -            "/stream.do": self.serve_stream,
   21.71 -            "/transcode.do": self.serve_transcode,
   21.72 -            "/list.do": self.serve_list,
   21.73 -            "/get_file_info.do": self.serve_file_info,
   21.74 -            }
   21.75 -
   21.76 -        try:
   21.77 -            url[self.path](body)
   21.78 -        except KeyError:
   21.79 -            try:
   21.80 -                action = self.query.get("action", None)
   21.81 -                if action and "stream.do" in action:
   21.82 -                    self.serve_stream(body)
   21.83 -                elif os.path.exists("html/%s" % self.path):
   21.84 -                    data = open("html/%s" % self.path)
   21.85 -                    self.wfile.write(data.read())
   21.86 -                else:
   21.87 -                    self.send_error(404, "File not found")
   21.88 -            except Exception, e:
   21.89 -                self.log.error(e)
   21.90 -
   21.91 -    # do_dispatch()
   21.92 -
   21.93 -
   21.94 -    def do_GET(self):
   21.95 -        self.do_dispatch(True)
   21.96 -    # do_GET()
   21.97 -
   21.98 -
   21.99 -    def do_HEAD(self):
  21.100 -        self.do_dispatch(False)
  21.101 -    # do_HEAD()
  21.102 -
  21.103 -
  21.104 -    def _nav_items(self):
  21.105 -        ret = ""
  21.106 -        for name, url in self.menu.items():
  21.107 -            ret += utils.getHTML("menu", {"name": name, "url": url})
  21.108 -        return ret
  21.109 -    # _nav_items()
  21.110 -
  21.111 -
  21.112 -    def serve_main(self, body):
  21.113 -        self.send_response(200)
  21.114 -        self.send_header("Content-Type", "text/html")
  21.115 -        self.send_header('Connection', 'close')
  21.116 -        self.end_headers()
  21.117 -        if body:
  21.118 -            self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()}))
  21.119 -    # serve_main()
  21.120 -
  21.121 -
  21.122 -    def serve_version(self, body):
  21.123 -        self.send_response(200)
  21.124 -        self.send_header("Content-Type", "text/html")
  21.125 -        self.send_header('Connection', 'close')
  21.126 -        self.end_headers()
  21.127 -        if body:
  21.128 -            self.wfile.write("Version: %s" %  __version__)
  21.129 -    # serve_version
  21.130 -
  21.131 -
  21.132 -    def serve_shutdown(self, body):
  21.133 -        self.send_response(200)
  21.134 -        self.send_header("Content-Type", "text/html")
  21.135 -        self.send_header('Connection', 'close')
  21.136 -        self.end_headers()
  21.137 -        if body:
  21.138 -            self.wfile.write(utils.getHTML("shutdown"))
  21.139 -        self.server.server_close()
  21.140 -    # serve_shutdown()
  21.141 -
  21.142 -
  21.143 -    def serve_list(self, body):
  21.144 -        self.send_response(200)
  21.145 -        self.send_header("Content-Type", "text/html")
  21.146 -        self.send_header('Connection', 'close')
  21.147 -        self.end_headers()
  21.148 -
  21.149 -        if body:
  21.150 -            file_list = []
  21.151 -            files.list_media_files(utils.config.get_transcoded_location(), file_list)
  21.152 -            output = files.FileList(map(lambda x, y: x+y, file_list,
  21.153 -                                        ["<br>"]*len(file_list)))
  21.154 -            self.wfile.write(output)
  21.155 -
  21.156 -    # serve_list()
  21.157 -
  21.158 -
  21.159 -    def serve_stop_all_transcoders(self, body):
  21.160 -        self.send_response(200)
  21.161 -        self.send_header("Content-Type", "text/html")
  21.162 -        self.send_header('Connection', 'close')
  21.163 -        self.end_headers()
  21.164 -        if body:
  21.165 -            self.server.stop_transcoders()
  21.166 -            self.wfile.write(utils.getHTML("stop_all",
  21.167 -                                           {"menu": self._nav_items()}))
  21.168 -    # serve_stop_all_transcoders()
  21.169 -
  21.170 -
  21.171 -    def serve_stop_selected_transcoders(self, body, tids=[]):
  21.172 -        self.send_response(200)
  21.173 -        self.send_header("Content-Type", "text/html")
  21.174 -        self.send_header('Connection', 'close')
  21.175 -        self.end_headers()
  21.176 -        opts = ""
  21.177 -        if body:
  21.178 -            transcoders = self.server.get_transcoders()
  21.179 -
  21.180 -            for tid in tids:
  21.181 -                for t, r in transcoders:
  21.182 -                    if t.tid == int(tid):
  21.183 -                        try:
  21.184 -                            t.stop()
  21.185 -                        except Exception, e:
  21.186 -                            self.log.info("Plugin already stopped")
  21.187 -
  21.188 -                        opts += utils._create_html_item("%s" % t)
  21.189 -
  21.190 -                        break
  21.191 -
  21.192 -                self.wfile.write(utils.getHTML("stop_selected",
  21.193 -                                               {"menu": self._nav_items(),
  21.194 -                                                "opts": opts}))
  21.195 -    # serve_stop_selected_transcoders()
  21.196 -
  21.197 -
  21.198 -    def serve_stop_transcoder(self, body):
  21.199 -        req = self.query.get("request", None)
  21.200 -        tid = self.query.get("tid", None)
  21.201 -        if req and "all" in req:
  21.202 -            self.serve_stop_all_transcoders(body)
  21.203 -        elif tid:
  21.204 -            self.serve_stop_selected_transcoders(body, tid[0].split(";"))
  21.205 -        else:
  21.206 -            self.serve_status(body)
  21.207 -    # serve_stop_transcoder()
  21.208 -
  21.209 -
  21.210 -    def serve_status(self, body):
  21.211 -        self.send_response(200)
  21.212 -        self.send_header("Content-Type", "text/html")
  21.213 -        self.send_header('Connection', 'close')
  21.214 -        self.end_headers()
  21.215 -        stopone = ""
  21.216 -        running = ""
  21.217 -        stopall = ""
  21.218 -
  21.219 -        if body:
  21.220 -            tl = self.server.get_transcoders()
  21.221 -            if not tl and not self.query.get("tid", None) and \
  21.222 -                   not self.query.get("running", None):
  21.223 -                running = "<p>No running transcoder.</p>\n"
  21.224 -
  21.225 -            elif not tl and self.query.get("tid", None):
  21.226 -                tids = self.query.get("tid")
  21.227 -                for tid in tids:
  21.228 -                    stat = self.transcoders_log.get_status(int(tid))
  21.229 -                    self.wfile.write("%s<br>" % stat)
  21.230 -                return True
  21.231 -
  21.232 -            elif self.query.get("running", None):
  21.233 -                for transcoder, request in tl:
  21.234 -                    outf = transcoder.params_first("outfile")
  21.235 -                    tid = transcoder.tid
  21.236 -                    self.wfile.write("%s:%s<br>" % (tid, outf))
  21.237 -                return True
  21.238 -
  21.239 -            elif self.query.get("tid", None):
  21.240 -                req_tid = self.query.get("tid")
  21.241 -                for transcoder, request in tl:
  21.242 -                    if str(transcoder.tid) in req_tid:
  21.243 -                        self.wfile.write("Status:%s:%s %%" % (\
  21.244 -                            transcoder.tid, transcoder.status))
  21.245 -                        return True
  21.246 -                stat = self.transcoders_log.get_status(int(req_tid[0]))
  21.247 -                self.wfile.write("%s<br>" % stat)
  21.248 -                return True
  21.249 -
  21.250 -            else:
  21.251 -                running = "<p>Running transcoders:</p>\n"
  21.252 -                stopall = utils._create_html_item("<a href='%s?request=all'>"
  21.253 -                                                 "[STOP ALL]</a>" %
  21.254 -                                                 self.menu["Stop"])
  21.255 -
  21.256 -                for transcoder, request in tl:
  21.257 -                    stopone += utils._create_html_item("%s;"
  21.258 -                                                       "<a href='%s?tid=%s'>"
  21.259 -                                                       " [STOP] </a>") % (
  21.260 -                        transcoder, self.menu["Stop"], transcoder.tid)
  21.261 -
  21.262 -            self.wfile.write(utils.getHTML("status",
  21.263 -                                           {"menu": self._nav_items(),
  21.264 -                                            "running": running,
  21.265 -                                            "stopall": stopall,
  21.266 -                                            "stopone": stopone}))
  21.267 -    # serve_status()
  21.268 -
  21.269 -
  21.270 -    def _get_transcoder(self):
  21.271 -        # get transcoder option: mencoder is the default
  21.272 -        request_transcoders = self.query.get("transcoder", ["mencoder"])
  21.273 -
  21.274 -        for t in request_transcoders:
  21.275 -            transcoder = self.transcoders.get(t)
  21.276 -            if transcoder:
  21.277 -                return transcoder
  21.278 -
  21.279 -        if not transcoder:
  21.280 -            return self.transcoders[self.def_transcoder]
  21.281 -    # _get_transcoder()
  21.282 -
  21.283 -
  21.284 -    def _get_new_id(self, tid):
  21.285 -        self.server.last_tid = utils.create_tid(tid)
  21.286 -        self.tid_queue.append(self.server.last_tid)
  21.287 -        return self.server.last_tid
  21.288 -    # _get_new_id()
  21.289 -
  21.290 -
  21.291 -    def serve_new_id(self, body):
  21.292 -        self.send_response(200)
  21.293 -        self.send_header("Content-Type", "text/html")
  21.294 -        self.send_header('Connection', 'close')
  21.295 -        self.end_headers()
  21.296 -
  21.297 -        if body:
  21.298 -            self.wfile.write("%s" % self._get_new_id(self.server.last_tid))
  21.299 -    # serve_new_id()
  21.300 -
  21.301 -    def serve_get_log(self, body):
  21.302 -        self.send_response(200)
  21.303 -        self.send_header("Content-Type", "text/html")
  21.304 -        self.send_header('Connection', 'close')
  21.305 -        self.end_headers()
  21.306 -
  21.307 -        if body:
  21.308 -            if self.query.get("tid", None):
  21.309 -                tid = int(self.query.get("tid")[0])
  21.310 -                stat = self.transcoders_log.get_status(tid)
  21.311 -                self.wfile.write("Status: %s" % stat)
  21.312 -            else:
  21.313 -                stat = self.transcoders_log.get_status()
  21.314 -                for rtid, status in stat.iteritems():
  21.315 -                    self.wfile.write("<b>%s</b>: %s<br><br>" % (rtid, status))
  21.316 -    # serve_get_log()
  21.317 -
  21.318 -    def serve_get_all_log(self, body):
  21.319 -        self.send_response(200)
  21.320 -        self.send_header("Content-Type", "text/html")
  21.321 -        self.send_header('Connection', 'close')
  21.322 -        self.end_headers()
  21.323 -
  21.324 -        if body:
  21.325 -            if self.query.get("tid", None):
  21.326 -                tid = int(self.query.get("tid")[0])
  21.327 -                stat = self.transcoders_log.get_status(tid, True)
  21.328 -                for status in stat:
  21.329 -                    self.wfile.write("%s<br><br>" % status)
  21.330 -            else:
  21.331 -                stat = self.transcoders_log.get_status(None, True)
  21.332 -                for rtid, history in stat.iteritems():
  21.333 -                    for status in history:
  21.334 -                        self.wfile.write("<b>%s</b>: %s<br>" % (rtid, status))
  21.335 -                    self.wfile.write("<br><br>")
  21.336 -    # serve_get_all_log()
  21.337 -
  21.338 -
  21.339 -    def serve_file_info(self, body):
  21.340 -        if body:
  21.341 -
  21.342 -            file_dat = self.query.get("file", None)
  21.343 -
  21.344 -            if file_dat:
  21.345 -                self.send_response(200)
  21.346 -                self.send_header("Content-Type", "text/html")
  21.347 -                self.send_header('Connection', 'close')
  21.348 -                self.end_headers()
  21.349 -
  21.350 -                try:
  21.351 -                    opts = files.TranscodedFile(file_dat[0], self.query).opts
  21.352 -                    for key in opts.keys():
  21.353 -                        self.wfile.write("%s=%s<br>" % (key, opts.get(key, "None")[0]))
  21.354 -
  21.355 -                except Exception, e:
  21.356 -                    self.send_error(500, str(e))
  21.357 -                    return
  21.358 -    # serve_file_info()
  21.359 -
  21.360 -    def serve_stream(self, body):
  21.361 -	args = self.query.get("file", None)
  21.362 -	if not args:
  21.363 -	    self.send_error(404, "File not found")
  21.364 -	    return
  21.365 -
  21.366 -        filename = args[0];
  21.367 -        if not filename:
  21.368 -            self.send_error(404, "File not found")
  21.369 -            return
  21.370 -
  21.371 -        #Only stream files on .transcode dir
  21.372 -        filename = os.path.join (utils.config.get_transcoded_location(),
  21.373 -                                 os.path.basename(filename))
  21.374 -        self.log.error("Stream file: %s" % filename)
  21.375 -        if not os.path.exists (filename):
  21.376 -            self.send_error(404, "File not found")
  21.377 -            return
  21.378 -
  21.379 -        size = int(os.path.getsize(filename))
  21.380 -        self.send_response(200)
  21.381 -        self.send_header("Content-Type", mimetypes.guess_type(filename)[0])
  21.382 -        self.send_header("Cache-Control","no-cache")
  21.383 -        self.send_header("Content-Length", size)
  21.384 -        self.end_headers()
  21.385 -
  21.386 -        media = open(filename)
  21.387 -        data_in = " "
  21.388 -        total_read = 0
  21.389 -
  21.390 -        test_tid = int(self.query.get("tid", "0")[0])
  21.391 -        if test_tid == 0 or test_tid not in self.tid_queue:
  21.392 -            test_tid = self._get_new_id(self.server.last_tid)
  21.393 -
  21.394 -        self.transcoders_log.insert(test_tid, "gms.Stream: %s" % filename)
  21.395 -
  21.396 -        try:
  21.397 -            file_data = ""
  21.398 -            while data_in != "":
  21.399 -                data_in = media.read(4096)
  21.400 -                file_data += data_in
  21.401 -
  21.402 -                #total_read += 4096
  21.403 -            self.wfile.write(file_data)
  21.404 -                #status = utils.progress_bar(total_read, size, 50)
  21.405 -                #msg_status = "Status:%s:%s%%" % (test_tid, status)
  21.406 -                #self.transcoders_log._update_status(test_tid, msg_status)
  21.407 -
  21.408 -            self.transcoders_log._update_status(test_tid, "OK: Done")
  21.409 -
  21.410 -        except Exception, e:
  21.411 -            self.log.error("Stream error: %s" %e)
  21.412 -            self.transcoders_log._update_status(test_tid, "Error: %s" % e)
  21.413 -    # serve_stream()
  21.414 -
  21.415 -    def serve_transcode(self, body):
  21.416 -        type = self.query.get("type", None)[0]
  21.417 -        if type.upper() == "FILE":
  21.418 -            self.send_error(404, "Transcode local files not allowed")
  21.419 -            return
  21.420 -
  21.421 -        transcoder = self._get_transcoder()
  21.422 -        try:
  21.423 -            obj = transcoder(self.query)
  21.424 -        except Exception, e:
  21.425 -            self.send_error(500, str(e))
  21.426 -            return
  21.427 -
  21.428 -        self.send_response(200)
  21.429 -        self.send_header("Content-Type", obj.get_mimetype())
  21.430 -        self.send_header("Cache-Control","no-cache")
  21.431 -
  21.432 -        if (obj.name == "gmencoder"):
  21.433 -            self.send_header("Transfer-Encoding", "chunked")
  21.434 -
  21.435 -        self.end_headers()
  21.436 -
  21.437 -        if body:
  21.438 -            test_tid = int(self.query.get("tid", "0")[0])
  21.439 -            if test_tid == 0 or test_tid not in self.tid_queue:
  21.440 -                test_tid = self._get_new_id(self.server.last_tid)
  21.441 -
  21.442 -            if self.query.get("transcoder", None):
  21.443 -                self.transcoders_log.insert(test_tid, "gms.%s" % obj.name)
  21.444 -                obj.tid = test_tid
  21.445 -                obj.log = self.transcoders_log
  21.446 -
  21.447 -                self.server.add_transcoders(self, obj)
  21.448 -                if obj.start(self.wfile):
  21.449 -                    self.transcoders_log.info (test_tid, "OK")
  21.450 -                else:
  21.451 -                    self.transcoders_log.info (test_tid, "Fail")
  21.452 -
  21.453 -                self.server.del_transcoders(self, obj)
  21.454 -                files.TranscodedFile("", self.query)
  21.455 -
  21.456 -    # serve_stream()
  21.457 -
  21.458 -
  21.459 -    def log_request(self, code='-', size='-'):
  21.460 -        self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
  21.461 -    # log_request()
  21.462 -
  21.463 -
  21.464 -    def log_error(self, format, *args):
  21.465 -        self.log.error("%s: %s" % (self.address_string(), format % args))
  21.466 -    # log_error()
  21.467 -
  21.468 -
  21.469 -    def log_message(self, format, *args):
  21.470 -        self.log.info("%s: %s" % (self.address_string(), format % args))
  21.471 -    # log_message()
  21.472 -
  21.473 -# RequestHandler
    22.1 --- a/gmyth-stream/server/0.3/lib/server.py	Wed Aug 29 14:29:24 2007 +0100
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,117 +0,0 @@
    22.4 -#!/usr/bin/env python
    22.5 -
    22.6 -__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    22.7 -__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    22.8 -__license__ = "GPL"
    22.9 -__version__ = "0.4"
   22.10 -
   22.11 -import os
   22.12 -import threading
   22.13 -import SocketServer
   22.14 -import BaseHTTPServer
   22.15 -import socket
   22.16 -import urlparse
   22.17 -import cgi
   22.18 -import lib.utils as utils
   22.19 -import logging
   22.20 -
   22.21 -from log import Log
   22.22 -from request_handler import RequestHandler
   22.23 -
   22.24 -__all__ = ("Server", "serve_forever", "load_plugins_transcoders")
   22.25 -
   22.26 -class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
   22.27 -    log = logging.getLogger("gms.server")
   22.28 -    last_tid = 0
   22.29 -    run = True
   22.30 -    _transcoders = {}
   22.31 -    _lock = threading.RLock()
   22.32 -
   22.33 -    def serve_forever(self):
   22.34 -        self.log.info("GMyth-Streamer serving HTTP on %s:%s" %
   22.35 -                      self.socket.getsockname())
   22.36 -        try:
   22.37 -            while self.run:
   22.38 -                self.handle_request()
   22.39 -        except KeyboardInterrupt, e:
   22.40 -            pass
   22.41 -
   22.42 -        self.log.debug("Stopping all remaining transcoders...")
   22.43 -        self.stop_transcoders()
   22.44 -        self.log.debug("Transcoders stopped!")
   22.45 -    # serve_forever()
   22.46 -
   22.47 -
   22.48 -    def get_request(self):
   22.49 -        skt = self.socket
   22.50 -        old = skt.gettimeout()
   22.51 -        skt.settimeout(0.5)
   22.52 -        while self.run:
   22.53 -            try:
   22.54 -                r = skt.accept()
   22.55 -                skt.settimeout(old)
   22.56 -                return r
   22.57 -            except socket.timeout, e:
   22.58 -                pass
   22.59 -        raise socket.error("Not running")
   22.60 -    # get_request()
   22.61 -
   22.62 -
   22.63 -    def server_close(self):
   22.64 -        self.run = False
   22.65 -        self.stop_transcoders()
   22.66 -
   22.67 -        BaseHTTPServer.HTTPServer.server_close(self)
   22.68 -    # server_close()
   22.69 -
   22.70 -
   22.71 -    def stop_transcoders(self):
   22.72 -        self._lock.acquire()
   22.73 -        for transcoder, request in self._transcoders.iteritems():
   22.74 -            self.log.info("Stop transcoder: %s, client=%s" %
   22.75 -                          (transcoder, request.client_address))
   22.76 -            transcoder.stop()
   22.77 -        self._lock.release()
   22.78 -    # stop_transcoders()
   22.79 -
   22.80 -
   22.81 -    def get_transcoders(self):
   22.82 -        self._lock.acquire()
   22.83 -        try:
   22.84 -            return self._transcoders.items()
   22.85 -        finally:
   22.86 -            self._lock.release()
   22.87 -    # get_transcoders()
   22.88 -
   22.89 -
   22.90 -    def add_transcoders(self, request, transcoder):
   22.91 -        self._lock.acquire()
   22.92 -        try:
   22.93 -            self._transcoders[transcoder] = request
   22.94 -        finally:
   22.95 -            self._lock.release()
   22.96 -    # add_transcoders()
   22.97 -
   22.98 -
   22.99 -    def del_transcoders(self, request, transcoder):
  22.100 -        self._lock.acquire()
  22.101 -        try:
  22.102 -            del self._transcoders[transcoder]
  22.103 -        finally:
  22.104 -            self._lock.release()
  22.105 -    # del_transcoders()
  22.106 -# Server
  22.107 -
  22.108 -
  22.109 -
  22.110 -def serve_forever(host="0.0.0.0", port=40000):
  22.111 -    addr = (host, port)
  22.112 -    RequestHandler.protocol_version = "HTTP/1.0"
  22.113 -    httpd = Server(addr, RequestHandler)
  22.114 -    httpd.serve_forever()
  22.115 -# serve_forever()
  22.116 -
  22.117 -
  22.118 -def load_plugins_transcoders(directory):
  22.119 -    RequestHandler.load_plugins_transcoders(directory)
  22.120 -# load_plugins_transcoders()
    23.1 --- a/gmyth-stream/server/0.3/lib/transcoder.py	Wed Aug 29 14:29:24 2007 +0100
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,58 +0,0 @@
    23.4 -#!/usr/bin/env python
    23.5 -
    23.6 -__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    23.7 -__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    23.8 -__license__ = "GPL"
    23.9 -__version__ = "0.4"
   23.10 -
   23.11 -__all__ = ("Transcoder")
   23.12 -
   23.13 -class Transcoder(object):
   23.14 -    """Transcoder's Class: parent class to implement
   23.15 -    a plugin for transcoding data."""
   23.16 -    priority = 0   # negative values have higher priorities
   23.17 -    name = None # to be used in requests
   23.18 -    status = None
   23.19 -    log = None
   23.20 -    tid = -1
   23.21 -
   23.22 -    def __init__(self, params):
   23.23 -        self.params = params
   23.24 -    # __init__()
   23.25 -
   23.26 -    def params_first(self, key, default=None):
   23.27 -        if default is None:
   23.28 -            return self.params[key][0]
   23.29 -        else:
   23.30 -            try:
   23.31 -                return self.params[key][0]
   23.32 -            except:
   23.33 -                return default
   23.34 -    # params_first()
   23.35 -
   23.36 -    def get_mimetype(self):
   23.37 -        return "application/octet-stream"
   23.38 -    # get_mimetype()
   23.39 -
   23.40 -    def start(self, outfile):
   23.41 -        pass
   23.42 -    # start()
   23.43 -
   23.44 -    def stop(self):
   23.45 -        pass
   23.46 -    # stop()
   23.47 -
   23.48 -    def get_legth (self):
   23.49 -        pass
   23.50 -    # get_leght ()
   23.51 -
   23.52 -    def get_progress (self):
   23.53 -        pass
   23.54 -    # get_progress ()
   23.55 -
   23.56 -    def __str__(self):
   23.57 -        return '%s: %s( params=%s ) - Status: %s%%' % \
   23.58 -               (self.__class__.__name__, self.tid,
   23.59 -                self.params, self.status)
   23.60 -    # __str__()
   23.61 -# Transcoder
    24.1 --- a/gmyth-stream/server/0.3/lib/utils.py	Wed Aug 29 14:29:24 2007 +0100
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,193 +0,0 @@
    24.4 -#!/usr/bin/env
    24.5 -
    24.6 -__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    24.7 -__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    24.8 -__license__ = "GPL"
    24.9 -__version__ = "0.3"
   24.10 -
   24.11 -import os
   24.12 -import stat
   24.13 -import sys
   24.14 -import logging
   24.15 -import urllib
   24.16 -import gobject
   24.17 -import imp
   24.18 -
   24.19 -import gmsconfig
   24.20 -
   24.21 -log = logging.getLogger("gms.utils")
   24.22 -config = gmsconfig.GmsConfig()
   24.23 -
   24.24 -__all__ = ("which", "load_plugins", "PluginSet", "getHTML",
   24.25 -           "progress_bar", "create_tid", "list_media_files")
   24.26 -
   24.27 -def which(app):
   24.28 -    """Function to implement which(1) unix command"""
   24.29 -    pl = os.environ["PATH"].split(os.pathsep)
   24.30 -    for p in pl:
   24.31 -        path = os.path.join(p, app)
   24.32 -        if os.path.isfile(path):
   24.33 -            st = os.stat(path)
   24.34 -            if st[stat.ST_MODE] & 0111:
   24.35 -                return path
   24.36 -    return ""
   24.37 -# which()
   24.38 -
   24.39 -
   24.40 -def _load_module(pathlist, name):
   24.41 -    fp, path, desc = imp.find_module(name, pathlist)
   24.42 -    try:
   24.43 -        module = imp.load_module(name, fp, path, desc)
   24.44 -        return module
   24.45 -    finally:
   24.46 -        if fp:
   24.47 -            fp.close()
   24.48 -# _load_module()
   24.49 -
   24.50 -
   24.51 -class PluginSet(object):
   24.52 -    def __init__(self, basetype, *items):
   24.53 -        self.basetype = basetype
   24.54 -        self.map = {}
   24.55 -        self.list = []
   24.56 -
   24.57 -        for i in items:
   24.58 -            self._add(i)
   24.59 -        self._sort()
   24.60 -    # __init__()
   24.61 -
   24.62 -
   24.63 -    def _add(self, item):
   24.64 -        self.map[item.name] = item
   24.65 -        self.list.append(item)
   24.66 -    # _add()
   24.67 -
   24.68 -
   24.69 -    def add(self, item):
   24.70 -        self._add()
   24.71 -        self._sort()
   24.72 -    # add()
   24.73 -
   24.74 -
   24.75 -    def __getitem__(self, spec):
   24.76 -        if isinstance(spec, basestring):
   24.77 -            return self.map[spec]
   24.78 -        else:
   24.79 -            return self.list[spec]
   24.80 -    # __getitem__()
   24.81 -
   24.82 -
   24.83 -    def get(self, name, default=None):
   24.84 -        return self.map.get(name, default)
   24.85 -    # get()
   24.86 -
   24.87 -
   24.88 -    def __iter__(self):
   24.89 -        return self.list.__iter__()
   24.90 -    # __iter__()
   24.91 -
   24.92 -
   24.93 -    def __len__(self):
   24.94 -        return len(self.list)
   24.95 -    # __len__()
   24.96 -
   24.97 -
   24.98 -    def _sort(self):
   24.99 -        self.list.sort(lambda a, b: cmp(a.priority, b.priority))
  24.100 -    # _sort()
  24.101 -
  24.102 -
  24.103 -    def update(self, pluginset):
  24.104 -        self.map.update(pluginset.map)
  24.105 -        self.list.extend(pluginset.list)
  24.106 -        self._sort()
  24.107 -    # update()
  24.108 -
  24.109 -
  24.110 -    def load_from_directory(self, directory):
  24.111 -        for i in load_plugins(directory, self.basetype):
  24.112 -            self._add(i)
  24.113 -        self._sort()
  24.114 -    # load_from_directory()
  24.115 -
  24.116 -
  24.117 -    def __str__(self):
  24.118 -        lst = []
  24.119 -        for o in self.list:
  24.120 -            lst.append('"%s" (%s)' % (o.name, o.__name__))
  24.121 -
  24.122 -        return "%s(basetype=%s, items=[%s])" % \
  24.123 -               (self.__class__.__name__,
  24.124 -                self.basetype.__name__,
  24.125 -                ", ".join(lst))
  24.126 -    # __str__()
  24.127 -# PluginSet
  24.128 -
  24.129 -
  24.130 -def load_plugins(directory, basetype):
  24.131 -    """Function to load plugins from a given directory"""
  24.132 -    tn = basetype.__name__
  24.133 -    log.debug("Loading plugins from %s, type=%s" % (directory, tn))
  24.134 -
  24.135 -
  24.136 -    plugins = []
  24.137 -    for d in os.listdir(directory):
  24.138 -        if not d.endswith(".py"):
  24.139 -            continue
  24.140 -
  24.141 -        name = d[0: -3]
  24.142 -        if name == "__init__":
  24.143 -            continue
  24.144 -
  24.145 -        directory.replace(os.path.sep, ".")
  24.146 -        mod = _load_module([directory], name)
  24.147 -        for sym in dir(mod):
  24.148 -            cls = getattr(mod, sym)
  24.149 -            if isinstance(cls, type) and issubclass(cls, basetype) and \
  24.150 -                cls != basetype:
  24.151 -                plugins.append(cls)
  24.152 -                log.info("Loaded %s (%s) from %s" % \
  24.153 -                         (cls.__name__, tn, os.path.join(directory, d)))
  24.154 -
  24.155 -    return plugins
  24.156 -# load_plugins()
  24.157 -
  24.158 -def getHTML(html_file, params={}):
  24.159 -    """This function parses an html file with the given
  24.160 -    parameters and returns a formated web-page"""
  24.161 -    try:
  24.162 -        filename = os.path.join(sys.path[0], "html", html_file + ".html")
  24.163 -        html = open(filename).read() % params
  24.164 -        return html
  24.165 -    except Exception, e:
  24.166 -        return "HTML format error. Wrong keys: %s" % e
  24.167 -
  24.168 -# getHTML
  24.169 -
  24.170 -def _create_html_item(opt):
  24.171 -    """Create an <li> item using HTML."""
  24.172 -    return "<li>%s</li>\n" % opt
  24.173 -# _create_html_item
  24.174 -
  24.175 -def progress_bar(value, max, barsize):
  24.176 -    """Creates and displays a progressbar. By OSantana"""
  24.177 -    chars = int(value * barsize / float(max))
  24.178 -    percent = int((value / float(max)) * 100)
  24.179 -    sys.stdout.write("#" * chars)
  24.180 -    sys.stdout.write(" " * (barsize - chars + 2))
  24.181 -    if value >= max:
  24.182 -        sys.stdout.write("done.\n\n")
  24.183 -    else:
  24.184 -        sys.stdout.write("[%3i%%]\r" % (percent))
  24.185 -        sys.stdout.flush()
  24.186 -    return percent
  24.187 -# progress_bar() by osantana
  24.188 -
  24.189 -def create_tid(last_tid):
  24.190 -    """Function to generate TIDs (ids for transcoders).
  24.191 -    At first it just do +1 on last_tid but can be implemented
  24.192 -    to generate more sparse TIDs"""
  24.193 -    tid = last_tid + 1
  24.194 -    return tid
  24.195 -# create_id()
  24.196 -
    25.1 --- a/gmyth-stream/server/0.3/plugins/transcoders/gmencoder.py	Wed Aug 29 14:29:24 2007 +0100
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,134 +0,0 @@
    25.4 -#!/usr/bin/env python
    25.5 -
    25.6 -__author__ = "Renato Filho"
    25.7 -__author_email__ = "renato.filho@indt.org.br"
    25.8 -__license__ = "GPL"
    25.9 -__version__ = "0.2"
   25.10 -
   25.11 -import os
   25.12 -import sys
   25.13 -import shlex
   25.14 -import signal
   25.15 -import subprocess
   25.16 -import time
   25.17 -
   25.18 -import select
   25.19 -import fcntl
   25.20 -
   25.21 -import lib.utils as utils
   25.22 -import lib.server as server
   25.23 -import lib.transcoder as transcoder
   25.24 -
   25.25 -__all__ = ("TranscoderGMencoder",)
   25.26 -
   25.27 -class TranscoderGMencoder(transcoder.Transcoder):
   25.28 -    gmencoder_path = utils.which("gmencoder")
   25.29 -    name = "gmencoder"
   25.30 -    priority = -1
   25.31 -    proc = None
   25.32 -
   25.33 -    def __init__(self, params):
   25.34 -        self.status = 0
   25.35 -        transcoder.Transcoder.__init__(self, params)
   25.36 -        self.opts = []
   25.37 -        self.opts.append (self.gmencoder_path)
   25.38 -        self.opts.append ("-d")
   25.39 -        self._parser_params ()
   25.40 -
   25.41 -    # __init__()
   25.42 -
   25.43 -    def _insert_param (self, name, value):
   25.44 -        if (value != ""):
   25.45 -            self.opts.append(name)
   25.46 -            self.opts.append(value)
   25.47 -
   25.48 -    def _parser_params (self):
   25.49 -        self._insert_param("-i", \
   25.50 -            "%s://%s" % (self.params_first("type", "file"),
   25.51 -                         self.params_first("uri", "")))
   25.52 -        self._insert_param("--video-encode", self.params_first("ve", "ffenc_mpeg1video"))
   25.53 -        self._insert_param("--video-opts", "bitrate=300000,pass=512,quantizer=0.01,quant-type=1")
   25.54 -        #self._insert_param("--video-fps", self.params_first("fps", ""))
   25.55 -        self._insert_param("--video-fps", self.params_first("fps", "10"))
   25.56 -        self._insert_param("--video-width", self.params_first("width", "320"))
   25.57 -        self._insert_param("--video-height", self.params_first("height", "240"))
   25.58 -        self._insert_param("--audio-rate", "32000")
   25.59 -        self._insert_param("--audio-encode", self.params_first("ae", ""))
   25.60 -    # _parse_params
   25.61 -
   25.62 -    def start(self, outfd):
   25.63 -        outfile = self.params_first("outfile", "")
   25.64 -
   25.65 -        if outfile != "":
   25.66 -            path = os.path.join(utils.config.get_transcoded_location(), outfile)
   25.67 -            self._insert_param("-o", "file://%s" % path)
   25.68 -        else:
   25.69 -            self._insert_param ("-o", "fd://%d" % outfd.fileno())
   25.70 -            self.opts.append ("-c")
   25.71 -
   25.72 -        cmd = " ".join(self.opts)
   25.73 -        self.log.info(self.tid, "GMencoder: %s" % cmd)
   25.74 -
   25.75 -        try:
   25.76 -            self.proc = subprocess.Popen(self.opts, stdin=subprocess.PIPE,
   25.77 -                                         stdout=subprocess.PIPE)
   25.78 -
   25.79 -	    if outfile:
   25.80 -           	outfd.write("OK   ")
   25.81 -
   25.82 -        except Exception, e:
   25.83 -            self.log.error(self.tid, "Error: executing GMencoder: %s" % e)
   25.84 -            outfd.write("Error: GMencoder: %s" % e)
   25.85 -            return False
   25.86 -
   25.87 -        try:
   25.88 -	    if not outfile:
   25.89 -	    	p = select.poll()
   25.90 -	    	p.register (outfd, select.POLLNVAL | select.POLLERR | select.POLLHUP | select.POLLIN )
   25.91 -
   25.92 -            while (self.proc and self.proc.poll() == None):
   25.93 -                r, w, x = select.select([self.proc.stdout], [], [], 1)
   25.94 -                if self.proc.stdout in r:
   25.95 -                    progress = self.proc.stdout.readline()
   25.96 -                    if (progress.find ("PROGRESS") >= 0):
   25.97 -                        self.status = progress.split (":")[1]
   25.98 -		    elif (progress.find ("Erro") >= 0):
   25.99 -			return False
  25.100 -
  25.101 -		    if not outfile:
  25.102 -			    ret = p.poll(0)
  25.103 -			    if ret:
  25.104 -			    	print "Lost Connection"
  25.105 -		    		self.stop ()
  25.106 -			    	return False
  25.107 -
  25.108 -        except Exception, e:
  25.109 -            self.log.error(self.tid, "Problems handling data: %s" % e)
  25.110 -            return False
  25.111 -
  25.112 -        self.status = 100;
  25.113 -
  25.114 -
  25.115 -        return True
  25.116 -    # start()
  25.117 -
  25.118 -
  25.119 -    def stop(self):
  25.120 -        if self.proc:
  25.121 -            self.log.info(self.tid, "Stopped GMencoder plugin")
  25.122 -            try:
  25.123 -                os.kill(self.proc.pid, signal.SIGKILL)
  25.124 -                self.proc.wait()
  25.125 -            except Exception, e:
  25.126 -                pass
  25.127 -
  25.128 -            self.proc = None
  25.129 -    # stop()
  25.130 -
  25.131 -    def get_progress(self):
  25.132 -        return self.status
  25.133 -
  25.134 -    def get_lenght(self):
  25.135 -        return -1
  25.136 -
  25.137 -# TranscoderGMencoder
    26.1 --- a/gmyth-stream/server/0.3/plugins/transcoders/mencoder.py	Wed Aug 29 14:29:24 2007 +0100
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,334 +0,0 @@
    26.4 -#!/usr/bin/env python
    26.5 -
    26.6 -__author__ = "Artur Duque de Souza"
    26.7 -__author_email__ = "artur.souza@indt.org.br"
    26.8 -__license__ = "GPL"
    26.9 -__version__ = "0.3"
   26.10 -
   26.11 -import os
   26.12 -import time
   26.13 -import fcntl
   26.14 -import shlex
   26.15 -import socket
   26.16 -import struct
   26.17 -import signal
   26.18 -import subprocess
   26.19 -
   26.20 -import lib.utils as utils
   26.21 -import lib.server as server
   26.22 -import plugins.transcoders.mencoder_lib.mythtv as mythtv
   26.23 -
   26.24 -from select import select
   26.25 -import lib.transcoder as transcoder
   26.26 -
   26.27 -__all__ = ("TranscoderMencoder",)
   26.28 -
   26.29 -class TranscoderMencoder(transcoder.Transcoder):
   26.30 -    """Transcoder class that implements a transcoder using Mencoder"""
   26.31 -    mencoder_path = utils.which("mencoder")
   26.32 -    name = "mencoder"
   26.33 -    priority = -1
   26.34 -    args = {}
   26.35 -    proc = None
   26.36 -    gmyth = None
   26.37 -
   26.38 -    # only works with avi container
   26.39 -    status = 0
   26.40 -
   26.41 -    def _setup_params(self):
   26.42 -        params_first = self.params_first
   26.43 -
   26.44 -        # general_opts
   26.45 -        self.args["local"]    = params_first("local", False)
   26.46 -        self.args["language"] = params_first("language", False)
   26.47 -        self.args["subtitle"] = params_first("subtitle", False)
   26.48 -        self.args["format"]   = params_first("format", "mpeg1")
   26.49 -        self.args["outfile"]  = params_first("outfile", "-")
   26.50 -
   26.51 -        # input_opt
   26.52 -        self.args["type"]     = params_first("type", "file")
   26.53 -        self.args["input"]    = params_first("uri", "-")
   26.54 -
   26.55 -        # audio_opts
   26.56 -        self.args["acodec"]   = params_first("acodec", "mp2")
   26.57 -        self.args["abitrate"] = params_first("abitrate", 192)
   26.58 -        self.args["volume"]   = params_first("volume", 5)
   26.59 -
   26.60 -        # video_opts
   26.61 -        self.args["mux"]      = params_first("mux", "mpeg")
   26.62 -        self.args["fps"]      = params_first("fps", 25)
   26.63 -        self.args["vcodec"]   = params_first("vcodec", "mpeg1video")
   26.64 -        self.args["vbitrate"] = params_first("vbitrate", 400)
   26.65 -        self.args["width"]    = params_first("width", 320)
   26.66 -        self.args["height"]   = params_first("height", 240)
   26.67 -    # _setup_params()
   26.68 -
   26.69 -
   26.70 -    def _setup_audio(self):
   26.71 -        if self.args["acodec"] == "mp3lame":
   26.72 -            audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % (
   26.73 -                self.args["abitrate"], self.args["volume"])
   26.74 -        else:
   26.75 -            audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (
   26.76 -                self.args["acodec"], self.args["abitrate"])
   26.77 -
   26.78 -        return audio
   26.79 -    # _setup_audio()
   26.80 -
   26.81 -
   26.82 -    def _setup_video(self):
   26.83 -        video = " -of %s" % self.args["mux"]
   26.84 -        video += " -ofps %s" % self.args["fps"]
   26.85 -
   26.86 -        vcodec = self.args["vcodec"]
   26.87 -        if vcodec == "nuv" or vcodec == "xvid"\
   26.88 -               or vcodec == "qtvideo" or vcodec == "copy":
   26.89 -            video += " -ovc %s" % vcodec
   26.90 -        else:
   26.91 -            video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
   26.92 -                vcodec, self.args["vbitrate"])
   26.93 -
   26.94 -        if self.args["mux"] == "mpeg":
   26.95 -            video += " -mpegopts format=%s" % self.args["format"]
   26.96 -
   26.97 -        video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"])
   26.98 -        return video
   26.99 -    # _setup_video()
  26.100 -
  26.101 -
  26.102 -    def _arg_append(self, args, options):
  26.103 -        for arg in shlex.split(options):
  26.104 -            args.append(arg)
  26.105 -    # arg_append()
  26.106 -
  26.107 -    def _setup_mencoder_opts(self, args):
  26.108 -        args.append(self.mencoder_path)
  26.109 -
  26.110 -        if self.args["type"] and self.args["type"] == "tv":
  26.111 -            self._arg_append(args, self.args["tv"])
  26.112 -        elif self.args["outfile"] == "-" and self.args["type"]:
  26.113 -            args.append(self.args["input"])
  26.114 -        else:
  26.115 -            args.append("-")
  26.116 -
  26.117 -        if self.args["language"]:
  26.118 -            self._arg_append(args, "-alang %s" % self.args["language"])
  26.119 -
  26.120 -        if self.args["subtitle"]:
  26.121 -            self._arg_append(args, "-slang %s" % self.args["subtitle"])
  26.122 -            self._arg_append(args, "-subfps %s" % self.args["fps"])
  26.123 -
  26.124 -        self._arg_append(args, "-idx")
  26.125 -        self._arg_append(args, "-cache 1024")
  26.126 -        self._arg_append(args, self._setup_audio())
  26.127 -        self._arg_append(args, self._setup_video())
  26.128 -
  26.129 -        self._arg_append(args, "-really-quiet")
  26.130 -
  26.131 -        if self.args["outfile"] != "-":
  26.132 -            self.args["outfile"] = ".transcoded/%s" % (
  26.133 -                                   os.path.basename(self.args["outfile"]))
  26.134 -
  26.135 -        self._arg_append(args, "-o %s" % self.args["outfile"])
  26.136 -        self._arg_append(args, "2>%s" % os.devnull)
  26.137 -    # _setup_args()
  26.138 -
  26.139 -    def _setup_filename(self):
  26.140 -        """This function setups the file to encode parsing the uri.
  26.141 -        So, type can be:
  26.142 -        * file
  26.143 -        * dvd
  26.144 -        * myth
  26.145 -
  26.146 -        If the last one is detected we have to parse the uri to find args.
  26.147 -        Then we store all the args inside a dictionary: self.args['gmyth-cat']
  26.148 -        """
  26.149 -        _type = self.args["type"]
  26.150 -
  26.151 -        if _type == "file":
  26.152 -            if not os.path.exists(self.args["input"]):
  26.153 -                raise IOError,\
  26.154 -                      "File requested does not exist: %s." % self.args["input"]
  26.155 -            else:
  26.156 -                self.args["input"] = "file://%s" % self.args["input"]
  26.157 -
  26.158 -        elif _type == "dvd":
  26.159 -            self.args["input"] = "dvd://%s" % self.args["input"]
  26.160 -
  26.161 -        elif _type == "myth":
  26.162 -            self.args["gmyth-cat"] = mythtv._setup_mythfilename(self)
  26.163 -
  26.164 -        elif _type == "tv":
  26.165 -            driver = self.params_first("driver", "v4l2")
  26.166 -            norm = self.params_first("norm", "pal-m")
  26.167 -            channel = self.params_first("channel", "13")
  26.168 -            chanlist = self.params_first("chanlist", "us-bcast")
  26.169 -            outfmt = self.params_first("outfmt", "yuy2")
  26.170 -            vdev = self.params_first("vdev", "/dev/video0")
  26.171 -            adev = self.params_first("adev", "/dev/dsp")
  26.172 -            self.args["tv"] = "tv:// -v -tv driver=%s:norm=%s:channel=%s:" \
  26.173 -                              "chanlist=%s:width=%s:height=%s:outfmt=%s:" \
  26.174 -                              "device=%s:adevice=%s" % (driver, norm,
  26.175 -                                                        channel, chanlist,
  26.176 -                                                        self.args["width"],
  26.177 -                                                        self.args["height"],
  26.178 -                                                        outfmt, vdev, adev)
  26.179 -    # _setup_filename()
  26.180 -
  26.181 -
  26.182 -    def __init__(self, params):
  26.183 -        transcoder.Transcoder.__init__(self, params)
  26.184 -        self.mencoder_opts = []
  26.185 -
  26.186 -        try:
  26.187 -            self._setup_params()
  26.188 -            self._setup_filename()
  26.189 -            self._setup_mencoder_opts(self.mencoder_opts)
  26.190 -        except Exception, e:
  26.191 -            if self.log:
  26.192 -                self.log.error(self.tid, "Error: %s" % e)
  26.193 -            else:
  26.194 -                raise
  26.195 -    # __init__()
  26.196 -
  26.197 -
  26.198 -    def _check_opened_file(self, stdw, _stdin):
  26.199 -        loop = True
  26.200 -        while loop:
  26.201 -            try:
  26.202 -                return open(self.args["outfile"])
  26.203 -            except:
  26.204 -                os.write(stdw, _stdin.read(1024))
  26.205 -    # _check_opened_file
  26.206 -
  26.207 -
  26.208 -    def _start_outfile(self, outfd):
  26.209 -        finished = False
  26.210 -
  26.211 -        # Configuring stdin
  26.212 -        try:
  26.213 -            filename = self.args["input"].split("://")[1]
  26.214 -            _stdin = open(filename)
  26.215 -            size = int(os.path.getsize(filename))
  26.216 -        except Exception, e:
  26.217 -            self.log.error(self.tid, "Error: Mencoder stdin"\
  26.218 -                           " setup error: %s" % e)
  26.219 -            outfd.write("Error: Mencoder stdin setup error: %s" %e)
  26.220 -            return False
  26.221 -
  26.222 -        self.status = 0
  26.223 -        total_read = 0
  26.224 -
  26.225 -        # Configuring pipes
  26.226 -        stdr, stdw = os.pipe()
  26.227 -
  26.228 -        if not self._run_mencoder(input=stdr):
  26.229 -            return False
  26.230 -
  26.231 -        stdout = self._check_opened_file(stdw, _stdin)
  26.232 -        outfd.write("OK   ")
  26.233 -
  26.234 -        try:
  26.235 -            while self.proc and self.proc.poll() == None:
  26.236 -                if not finished:
  26.237 -                    data_in = _stdin.read(4096)
  26.238 -                    if data_in != "":
  26.239 -                        os.write(stdw, data_in)
  26.240 -                        total_read += 4096
  26.241 -                        d = stdout.read(4096)
  26.242 -                        self.status = utils.progress_bar(total_read,
  26.243 -                                                         size, 50)
  26.244 -                    else:
  26.245 -                        finished = True
  26.246 -                        os.close(stdw)
  26.247 -
  26.248 -                else:
  26.249 -                    d = stdout.read(4096)
  26.250 -
  26.251 -        except Exception, e:
  26.252 -            self.log.error(self.tid, "Error: %s" % e)
  26.253 -            self.stop()
  26.254 -            return False
  26.255 -
  26.256 -        self.log.info(self.tid, "OK: Done")
  26.257 -        return True
  26.258 -    # _start_outfile()
  26.259 -
  26.260 -
  26.261 -    def _start(self, outfd):
  26.262 -        # Play a file on disk or DVD
  26.263 -        if not self._run_mencoder(output=subprocess.PIPE):
  26.264 -            return False
  26.265 -
  26.266 -        try:
  26.267 -            while self.proc and self.proc.poll() == None:
  26.268 -                d = self.proc.stdout.read(1024)
  26.269 -                outfd.write(d)
  26.270 -        except Exception, e:
  26.271 -            self.log.error(self.tid, "Error: %s" % e)
  26.272 -            return False
  26.273 -
  26.274 -        self.log.info(self.tid, "OK: Done")
  26.275 -        return True
  26.276 -    # _start()
  26.277 -
  26.278 -    def _run_mencoder(self, input=None, output=None):
  26.279 -        try:
  26.280 -            self.proc = subprocess.Popen(self.mencoder_opts, stdin=input,
  26.281 -                                         stdout=output, close_fds=True)
  26.282 -        except Exception, e:
  26.283 -            self.log.error(self.tid, "Error: Mencoder: %s" % e)
  26.284 -            return False
  26.285 -
  26.286 -        return True
  26.287 -    # _run_mencoder()
  26.288 -
  26.289 -    def start(self, outfd):
  26.290 -        cmd = " ".join(self.mencoder_opts)
  26.291 -        self.log.debug(self.tid, "Plugin's tid: %s" % self.tid)
  26.292 -        self.log.debug(self.tid, "Mencoder: %s" % cmd)
  26.293 -
  26.294 -        ret = False
  26.295 -
  26.296 -        if self.args["outfile"] == "-" and \
  26.297 -               self.args["type"] in ["file", "dvd", "tv"]:
  26.298 -            ret = self._start(outfd)
  26.299 -
  26.300 -        elif self.args["type"] == "myth":
  26.301 -            ret = mythtv.start_myth(self, outfd)
  26.302 -
  26.303 -        else:
  26.304 -            ret = self._start_outfile(outfd)
  26.305 -
  26.306 -        self.stop()
  26.307 -
  26.308 -        if not ret:
  26.309 -            self.log.error(self.tid, "Error: Problems while "\
  26.310 -                           "starting streaming.")
  26.311 -
  26.312 -        return ret
  26.313 -    # start()
  26.314 -
  26.315 -    def _aux_stop(self, obj, next=False):
  26.316 -        if obj:
  26.317 -            try:
  26.318 -                os.kill(obj.pid, signal.SIGKILL)
  26.319 -                if next:
  26.320 -                    os.kill(obj.pid+1, signal.SIGKILL)
  26.321 -            except OSError, e:
  26.322 -                pass
  26.323 -
  26.324 -            try:
  26.325 -                obj.wait()
  26.326 -            except Exception, e:
  26.327 -                pass
  26.328 -
  26.329 -            obj = None
  26.330 -    # _aux_stop
  26.331 -
  26.332 -    def stop(self):
  26.333 -        self._aux_stop(self.proc, True)
  26.334 -        self._aux_stop(self.gmyth)
  26.335 -    # stop()
  26.336 -
  26.337 -# TranscoderMencoder
    27.1 --- a/gmyth-stream/server/0.3/plugins/transcoders/mencoder_lib/mythtv.py	Wed Aug 29 14:29:24 2007 +0100
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,109 +0,0 @@
    27.4 -import os
    27.5 -import subprocess
    27.6 -import fcntl
    27.7 -
    27.8 -import lib.utils as utils
    27.9 -import lib.server as server
   27.10 -
   27.11 -from select import select
   27.12 -
   27.13 -def _setup_mythfilename(self):
   27.14 -    # mythtv:mythtv@192.168.3.110:6543/1002_20070426230000.nuv
   27.15 -    try:
   27.16 -        _mysql = self.args["input"].split("@")[0].split(":")
   27.17 -    except IndexError, e:
   27.18 -        _mysql = ["mythtv", "mythtv"]
   27.19 -
   27.20 -    try:
   27.21 -        _args = self.args["input"].split("@")[1].split(":")
   27.22 -    except IndexError, e:
   27.23 -        _args = self.args["input"].split(":")
   27.24 -
   27.25 -    gmyth_dict = {}
   27.26 -    gmyth_dict["mysql"] = _mysql
   27.27 -    gmyth_dict["backend"] = _args[0]
   27.28 -    gmyth_dict["port"] = _args[1].split("/", 1)[0]
   27.29 -
   27.30 -    _tmp_file = _args[1].split("/", 1)[1]
   27.31 -
   27.32 -    if _tmp_file.find("channel") >= 0:
   27.33 -        gmyth_dict["kind"] = "c"
   27.34 -        gmyth_dict["cfile"] = _tmp_file.split("=")[1]
   27.35 -    else:
   27.36 -        gmyth_dict["kind"] = "f"
   27.37 -        gmyth_dict["cfile"] = _tmp_file
   27.38 -
   27.39 -    self.args["input"] = "-"
   27.40 -    return gmyth_dict
   27.41 -# _setup_mythfilename
   27.42 -
   27.43 -def _setup_mythfile(err):
   27.44 -    size = err.readline().split("Size:")[1]
   27.45 -    flags = fcntl.fcntl (err, fcntl.F_GETFL, 0) | os.O_NONBLOCK
   27.46 -    fcntl.fcntl(err, fcntl.F_SETFL, flags)
   27.47 -    return size
   27.48 -# _setup_mythfile
   27.49 -
   27.50 -def _setup_gmythcat(self):
   27.51 -    gmyth_cat = utils.which("gmyth-cat")
   27.52 -    if self.args.has_key("gmyth-cat"):
   27.53 -        return [ utils.which("gmyth-cat"),
   27.54 -                 "-h", self.args["gmyth-cat"]["backend"],
   27.55 -                 "-p", self.args["gmyth-cat"]["port"],
   27.56 -                 "-" + self.args["gmyth-cat"]["kind"],
   27.57 -                 self.args["gmyth-cat"]["cfile"]
   27.58 -                 ]
   27.59 -    else:
   27.60 -        self.log.error(self.tid, "Error: URI error")
   27.61 -        return []
   27.62 -# _setup_gmythcat
   27.63 -
   27.64 -def start_myth(self, outfd):
   27.65 -    opts = _setup_gmythcat(self)
   27.66 -    try:
   27.67 -        self.gmyth = subprocess.Popen(opts, stdout=subprocess.PIPE,
   27.68 -                                      stderr=subprocess.PIPE,
   27.69 -                                      close_fds=True)
   27.70 -    except Exception, e:
   27.71 -        self.log.error(self.tid, "Error: gmyth-cat: %s" % e)
   27.72 -        return False
   27.73 -
   27.74 -    if not self._run_mencoder(input=self.gmyth.stdout,
   27.75 -                              output=subprocess.PIPE):
   27.76 -        return False
   27.77 -
   27.78 -    if self.args["gmyth-cat"]["kind"] == "f":
   27.79 -        try:
   27.80 -            size = _setup_mythfile(self.gmyth.stderr)
   27.81 -            self.log.debug(self.tid, "Info: Size of file: %s" % size)
   27.82 -        except Exception, e:
   27.83 -            self.log.error(self.tid, "Error: Problems getting size of"\
   27.84 -                           " file: %s" % e)
   27.85 -            outfd.write("Error: Problems getting size of file: %s" % e)
   27.86 -            return False
   27.87 -
   27.88 -    outfd.write("OK     ")
   27.89 -
   27.90 -    try:
   27.91 -        while self.proc and self.proc.poll() == None:
   27.92 -            r, w, x = select([self.gmyth.stderr, self.proc.stdout],
   27.93 -                             [], [], 0)
   27.94 -            if self.proc.stdout in r:
   27.95 -                d = self.proc.stdout.read(4096)
   27.96 -                outfd.write(d)
   27.97 -
   27.98 -            if self.gmyth.stderr in r:
   27.99 -                partial = self.gmyth.stderr.readline()
  27.100 -                if partial != "":
  27.101 -                    self.status = utils.progress_bar(int(partial),
  27.102 -                                                     int(size), 50)
  27.103 -
  27.104 -    except IndexError, e:
  27.105 -        pass
  27.106 -    except Exception, e:
  27.107 -        self.log.error(self.tid, "Error: %s" % e)
  27.108 -        return False
  27.109 -
  27.110 -    self.log.info(self.tid, "OK: Done")
  27.111 -    return True
  27.112 -# _start_myth()
    28.1 --- a/gmyth-stream/server/0.3/server.conf	Wed Aug 29 14:29:24 2007 +0100
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,2 +0,0 @@
    28.4 -[PATHS]
    28.5 -transcoded=./.transcoded
    29.1 --- a/gmyth-stream/server/0.3/setup.py	Wed Aug 29 14:29:24 2007 +0100
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,17 +0,0 @@
    29.4 -from distutils.core import setup
    29.5 -from glob import glob
    29.6 -
    29.7 -setup(name='gms',
    29.8 -      version='0.6',
    29.9 -      description='carman rich view package',
   29.10 -      long_description='carman rich view (SDL based) package',
   29.11 -      url='http://www.indt.org.br',
   29.12 -      scripts=['gms.py'],
   29.13 -      package_dir={'lib': 'lib', 'plugins' : 'plugins','data' : 'data' },
   29.14 -      packages=['lib','plugins','plugins.transcoders','plugins.transcoders.mencoder_lib'],
   29.15 -      data_files = [
   29.16 -               ('share/gms/html', glob("html/*")),
   29.17 -               ('etc/init.d', ['data/gmsd']),
   29.18 -               ('etc/gms', ['data/server.conf'])
   29.19 -               ],
   29.20 -      )
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/gmyth-stream/server/data/gmsd	Wed Aug 29 14:42:10 2007 +0100
    30.3 @@ -0,0 +1,61 @@
    30.4 +#!/bin/sh
    30.5 +
    30.6 +PROGRAM_NAME=GMS
    30.7 +PROGRAM_BIN=/usr/bin/gms.py
    30.8 +PIDFILE=/var/run/gms.pid
    30.9 +LOGFILE=/var/log/gms.log
   30.10 +
   30.11 +test -x $PROGRAM_BIN || exit 0
   30.12 +
   30.13 +set -e
   30.14 +
   30.15 +. /lib/lsb/init-functions
   30.16 +. /etc/default/rcS
   30.17 +
   30.18 +case $1 in
   30.19 +  start)
   30.20 +    echo -n "Starting $PROGRAM_NAME: "
   30.21 +    if [ -f $PIDFILE ]
   30.22 +    then
   30.23 +        PID=`cat $PIDFILE`
   30.24 +
   30.25 +        if ps ax | grep -q "^$PID"
   30.26 +        then
   30.27 +            echo "$PROGRAM_NAME already running."
   30.28 +        else
   30.29 +            rm -f $PIDFILE
   30.30 +            $PROGRAM_BIN -d > $LOGFILE
   30.31 +            echo "OK"
   30.32 +        fi
   30.33 +    else
   30.34 +        $PROGRAM_BIN -d > $LOGFILE
   30.35 +        echo "OK"
   30.36 +    fi
   30.37 +    ;;
   30.38 +
   30.39 +  stop)
   30.40 +    echo -n "Stopping $PROGRAM_NAME: "
   30.41 +    if [ -f $PIDFILE ]
   30.42 +    then
   30.43 +        PID=`cat $PIDFILE`
   30.44 +        if ps ax | grep -q "^$PID"
   30.45 +        then
   30.46 +            kill -10 $PID
   30.47 +        fi
   30.48 +        rm $PIDFILE
   30.49 +    else
   30.50 +        echo "No $PROGRAM_NAME found running; no killed."
   30.51 +    fi
   30.52 +    ;;
   30.53 +
   30.54 +  restart)
   30.55 +    $0 stop
   30.56 +    sleep 1
   30.57 +    $0 start
   30.58 +    ;;
   30.59 +
   30.60 +  *)
   30.61 +    log_success_msg "Usage: $0 {stop|start|restart}"
   30.62 +    exit 1
   30.63 +    ;;
   30.64 +esac
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/gmyth-stream/server/data/server.conf	Wed Aug 29 14:42:10 2007 +0100
    31.3 @@ -0,0 +1,2 @@
    31.4 +[PATHS]
    31.5 +transcoded=/var/gms-media
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/gmyth-stream/server/debian/changelog	Wed Aug 29 14:42:10 2007 +0100
    32.3 @@ -0,0 +1,6 @@
    32.4 +gms (0.3-indt1) unstable; urgency=low
    32.5 +
    32.6 +  * First package
    32.7 +
    32.8 + -- Renato Araujo Oliveira Filho <renato.filho@indt.org>  Thu, 16 Aug 2007 14:55:00 -0300
    32.9 +
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/gmyth-stream/server/debian/compat	Wed Aug 29 14:42:10 2007 +0100
    33.3 @@ -0,0 +1,1 @@
    33.4 +5
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/gmyth-stream/server/debian/control	Wed Aug 29 14:42:10 2007 +0100
    34.3 @@ -0,0 +1,13 @@
    34.4 +Source: gms
    34.5 +Section: sound
    34.6 +Priority: optional
    34.7 +Maintainer: Renato Araujo Oliveira Filho <renato.filho@indt.org>
    34.8 +Build-Depends: debhelper (>= 5.0.38), python-support (>= 0.5), python-central (>= 0.5)
    34.9 +Standards-Version: 3.7.2
   34.10 +
   34.11 +Package: gms
   34.12 +Architecture: any
   34.13 +Depends: ${python:Depends}, libgstreamer0.10-0, gstreamer0.10-plugins-base, gstreamer0.10-plugins-good
   34.14 +Recommends: gstreamer0.10-plugins-ugly
   34.15 +Description: Media transcoder deamon
   34.16 +  Homepage: http://gmyth.sourceforge.net/
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/gmyth-stream/server/debian/copyright	Wed Aug 29 14:42:10 2007 +0100
    35.3 @@ -0,0 +1,19 @@
    35.4 +It was downloaded from: http://gmyth.sourceforge.net/wiki/
    35.5 +
    35.6 +License:
    35.7 +   This package is free software; you can redistribute it and/or modify
    35.8 +   it under the terms of the GNU General Public License as published by
    35.9 +   the Free Software Foundation; either version 2 of the License, or
   35.10 +   (at your option) any later version.
   35.11 +
   35.12 +   This package is distributed in the hope that it will be useful,
   35.13 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.14 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   35.15 +   GNU General Public License for more details.
   35.16 +
   35.17 +   You should have received a copy of the GNU General Public License
   35.18 +   along with this package; if not, write to the Free Software
   35.19 +   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
   35.20 +
   35.21 +On Debian systems, the complete text of the GNU General Public License can
   35.22 +be found in `/usr/share/common-licenses/GPL'.
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/gmyth-stream/server/debian/gms.install	Wed Aug 29 14:42:10 2007 +0100
    36.3 @@ -0,0 +1,8 @@
    36.4 +debian/tmp/usr/share/gms/lib/*.py usr/share/gms/lib
    36.5 +debian/tmp/usr/share/gms/plugins/*.py usr/share/gms/plugins
    36.6 +debian/tmp/usr/share/gms/plugins/transcoders/*.py usr/share/gms/plugins/transcoders
    36.7 +debian/tmp/usr/share/gms/plugins/transcoders/mencoder_lib/*.py usr/share/gms/plugins/transcoders/mencoder_lib
    36.8 +debian/tmp/usr/share/gms/html/* usr/share/gms/html
    36.9 +debian/tmp/usr/bin/* usr/bin
   36.10 +debian/etc/init.d/gmsd etc/init.d
   36.11 +debian/etc/gms/*.conf etc/gms/
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/gmyth-stream/server/debian/gms.postinst	Wed Aug 29 14:42:10 2007 +0100
    37.3 @@ -0,0 +1,29 @@
    37.4 +#! /bin/sh
    37.5 +# postinst script for gms
    37.6 +
    37.7 +set -e
    37.8 +
    37.9 +case "$1" in
   37.10 +  configure)
   37.11 +    if ! getent passwd gms >/dev/null; then
   37.12 +      adduser --disabled-password  --quiet --system \
   37.13 +        --home /var/gms-media \
   37.14 +        --gecos "GMS media dir" --group gms
   37.15 +    fi
   37.16 +    if ! getent passwd gms | grep -q /var/run/gms; then
   37.17 +        usermod -d /var/gms-media gms
   37.18 +    fi
   37.19 +    update-rc.d gmsd defaults
   37.20 +    invoke-rc.d gmsd start
   37.21 +  ;;
   37.22 +  abort-upgrade|abort-remove|abort-deconfigure)
   37.23 +  ;;
   37.24 +  *)
   37.25 +    echo "postinst called with unknown argument \`$1'" >&2
   37.26 +    exit 1
   37.27 +  ;;
   37.28 +esac
   37.29 +
   37.30 +#DEBHELPER#
   37.31 +
   37.32 +exit 0
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/gmyth-stream/server/debian/gms.postrm	Wed Aug 29 14:42:10 2007 +0100
    38.3 @@ -0,0 +1,13 @@
    38.4 +#!/bin/sh
    38.5 +
    38.6 +set -e
    38.7 +
    38.8 +#DEBHELPER#
    38.9 +
   38.10 +if [ "$1" = "purge" ] ; then
   38.11 +        invoke-rc.d --force gms stop
   38.12 +        deluser --quiet --system gms > /dev/null || true
   38.13 +        delgroup --quiet --system gms > /dev/null || true
   38.14 +fi
   38.15 +
   38.16 +exit 0
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/gmyth-stream/server/debian/rules	Wed Aug 29 14:42:10 2007 +0100
    39.3 @@ -0,0 +1,52 @@
    39.4 +#!/usr/bin/make -f
    39.5 +# -*- makefile -*-
    39.6 +
    39.7 +# Uncomment this to turn on verbose mode.
    39.8 +#export DH_VERBOSE=1
    39.9 +
   39.10 +PYVER=2.5
   39.11 +PYTHON=python$(PYVER)
   39.12 +
   39.13 +PREFIX=debian/tmp
   39.14 +
   39.15 +build: build-stamp
   39.16 +
   39.17 +build-stamp:
   39.18 +	touch build-stamp
   39.19 +
   39.20 +clean:
   39.21 +	dh_testdir
   39.22 +	dh_testroot
   39.23 +	rm -f build-stamp
   39.24 +	dh_clean
   39.25 +
   39.26 +install: build
   39.27 +	dh_testdir
   39.28 +	dh_testroot
   39.29 +	dh_installdirs
   39.30 +	dh_clean -k
   39.31 +
   39.32 +	@rm -rf build
   39.33 +	@$(PYTHON) setup.py install --prefix=$(PREFIX)/usr --no-compile --install-purelib=$(PREFIX)/usr/share/gms
   39.34 +	install -D -o root -g root -m 755 $(PREFIX)/usr/etc/init.d/gmsd  debian/$(cdbs_curpkg)/etc/init.d/gmsd
   39.35 +	install -D -o root -g root -m 755 $(PREFIX)/usr/etc/gms/server.conf  debian/$(cdbs_curpkg)/etc/gms/server.conf
   39.36 +
   39.37 +	dh_install
   39.38 +
   39.39 +# Build architecture-independent files here.
   39.40 +binary-indep: build install
   39.41 +	dh_testdir
   39.42 +	dh_testroot
   39.43 +	dh_installchangelogs
   39.44 +	dh_installdocs
   39.45 +	dh_strip
   39.46 +	dh_compress
   39.47 +	dh_fixperms
   39.48 +	dh_installdeb
   39.49 +	dh_gencontrol
   39.50 +	dh_md5sums
   39.51 +	dh_builddeb
   39.52 +
   39.53 +binary: binary-indep
   39.54 +.PHONY: clean binary-indep binary install
   39.55 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/gmyth-stream/server/gms.py	Wed Aug 29 14:42:10 2007 +0100
    40.3 @@ -0,0 +1,74 @@
    40.4 +#!/usr/bin/env python
    40.5 +
    40.6 +__author__ = "Artur Duque de Souza"
    40.7 +__author_email__ = "artur.souza@indt.org.br"
    40.8 +__license__ = "GPL"
    40.9 +__version__ = "0.3"
   40.10 +__thanks__ = "Gustavo Sverzut Barbieri"
   40.11 +__GMS_DATA_DIR__ = "/usr/share/gms/"
   40.12 +
   40.13 +import sys
   40.14 +import os
   40.15 +import mimetypes
   40.16 +import logging as log
   40.17 +
   40.18 +if os.path.exists (__GMS_DATA_DIR__):
   40.19 +    sys.path.append(__GMS_DATA_DIR__)
   40.20 +
   40.21 +from lib.server import serve_forever, load_plugins_transcoders
   40.22 +from lib.utils import config
   40.23 +
   40.24 +mimetypes.init()
   40.25 +log_level = log.INFO
   40.26 +for p in sys.argv[1:]:
   40.27 +    if p == "-v" or p == "--verbose":
   40.28 +        log_level -= 10
   40.29 +
   40.30 +log.basicConfig(level=log_level,
   40.31 +                format=("### %(asctime)s %(name)-18s \t%(levelname)-8s "
   40.32 +                        "\t%(message)s"),
   40.33 +                datefmt="%Y-%m-%d %H:%M:%S")
   40.34 +
   40.35 +if config.get_transcoded_location () is None:
   40.36 +    print "Gms not configured"
   40.37 +    exit (0)
   40.38 +
   40.39 +if not os.path.exists(config.get_transcoded_location()):
   40.40 +    os.mkdir(config.get_transcoded_location())
   40.41 +
   40.42 +
   40.43 +if "-d" in sys.argv:
   40.44 +    #run with deamon
   40.45 +    try:
   40.46 +        pid = os.fork()
   40.47 +        if pid > 0:
   40.48 +             sys.exit(0)
   40.49 +    except OSError, e:
   40.50 +        print >>sys.stderr, "Fail to start deamon: %d (%s)" % (e.errno, e.strerror) 
   40.51 +        sys.exit(1)
   40.52 +
   40.53 +    os.chdir("/")
   40.54 +    os.setsid()
   40.55 +    os.umask(0)
   40.56 +
   40.57 +    try:
   40.58 +        pid = os.fork()
   40.59 +        if pid > 0:
   40.60 +            fp = open ("/var/run/gms.pid", "w")
   40.61 +            fp.write ("%d" % pid)
   40.62 +            fp.close ()
   40.63 +            sys.exit(0)
   40.64 +    except OSError, e:
   40.65 +        print >>sys.stderr, "Fail to start deamon: %d (%s)" % (e.errno, e.strerror) 
   40.66 +        sys.exit(1)
   40.67 +
   40.68 +# main deamon
   40.69 +pd = os.path.join(__GMS_DATA_DIR__, "plugins", "transcoders")
   40.70 +if os.path.exists (pd):
   40.71 +    load_plugins_transcoders(pd)
   40.72 +
   40.73 +pd = os.path.join("plugins", "transcoders");
   40.74 +if os.path.exists (pd):
   40.75 +    load_plugins_transcoders(pd)
   40.76 +
   40.77 +serve_forever()
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/gmyth-stream/server/html/index.html	Wed Aug 29 14:42:10 2007 +0100
    41.3 @@ -0,0 +1,9 @@
    41.4 +<html>
    41.5 +   <head><title>GMyth-Streamer Server</title></head>
    41.6 +   <body>
    41.7 +<h1>Welcome to GMyth-Streamer Server</h1>
    41.8 +<ul>
    41.9 +%(menu)s
   41.10 +</ul>
   41.11 +   </body>
   41.12 +</html>
   41.13 \ No newline at end of file
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/gmyth-stream/server/html/menu.html	Wed Aug 29 14:42:10 2007 +0100
    42.3 @@ -0,0 +1,1 @@
    42.4 +<li><a href="%(url)s">%(name)s</a></li>
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/gmyth-stream/server/html/shutdown.html	Wed Aug 29 14:42:10 2007 +0100
    43.3 @@ -0,0 +1,6 @@
    43.4 +<html>
    43.5 +   <head><title>GMyth-Streamer Server Exited</title></head>
    43.6 +   <body>
    43.7 +      <h1>GMyth-Streamer is not running anymore</h1>
    43.8 +   </body>
    43.9 +</html>
   43.10 \ No newline at end of file
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/gmyth-stream/server/html/status.html	Wed Aug 29 14:42:10 2007 +0100
    44.3 @@ -0,0 +1,14 @@
    44.4 +<html>
    44.5 +   <head><title>GMyth-Streamer Server Status</title></head>
    44.6 +   <body>
    44.7 +      <h1>GMyth-Streamer Status</h1>
    44.8 +      <ul>
    44.9 +            %(running)s
   44.10 +            %(stopall)s
   44.11 +            %(stopone)s
   44.12 +      </ul>
   44.13 +      <ul>
   44.14 +            %(menu)s
   44.15 +      </ul>
   44.16 +   </body>
   44.17 +</html>
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/gmyth-stream/server/html/stop_all.html	Wed Aug 29 14:42:10 2007 +0100
    45.3 @@ -0,0 +1,9 @@
    45.4 +<html>
    45.5 +   <head><title>GMyth-Streamer Server Stopped Transcoders</title></head>
    45.6 +   <body>
    45.7 +      <h1>GMyth-Streamer stopped running transcoders</h1>
    45.8 +      <ul>
    45.9 +      %(menu)s
   45.10 +      </ul>
   45.11 +   </body>
   45.12 +</html>
   45.13 \ No newline at end of file
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/gmyth-stream/server/html/stop_selected.html	Wed Aug 29 14:42:10 2007 +0100
    46.3 @@ -0,0 +1,12 @@
    46.4 +<html>
    46.5 +   <head><title>GMyth-Streamer Server Stopped Transcoders</title></head>
    46.6 +   <body>
    46.7 +      <h1>GMyth-Streamer stopped running transcoders:</h1>
    46.8 +      <ul>
    46.9 +            %(opts)s
   46.10 +      </ul>
   46.11 +      <ul>
   46.12 +            %(menu)s
   46.13 +      </ul>
   46.14 +   </body>
   46.15 +</html>
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/gmyth-stream/server/lib/file_handler.py	Wed Aug 29 14:42:10 2007 +0100
    47.3 @@ -0,0 +1,86 @@
    47.4 +#!/usr/bin/env python
    47.5 +
    47.6 +__author__ = "Artur Duque de Souza"
    47.7 +__author_email__ = "artur.souza@indt.org.br"
    47.8 +__license__ = "GPL"
    47.9 +__version__ = "0.1"
   47.10 +
   47.11 +import os
   47.12 +import sys
   47.13 +import pickle
   47.14 +import logging
   47.15 +import lib.utils as utils
   47.16 +
   47.17 +from stat import *
   47.18 +
   47.19 +__all__ = ("FileList", "list_media_files")
   47.20 +
   47.21 +
   47.22 +class TranscodedFile(object):
   47.23 +    """This class creates and reads information about transcoded files."""
   47.24 +    opts = {}
   47.25 +    log = logging.getLogger("gms.file_handler")
   47.26 +
   47.27 +    def __init__(self, filename, args):
   47.28 +        if filename == "" or not os.path.exists(filename):
   47.29 +            self.opts = args.copy()
   47.30 +
   47.31 +            if self.opts["type"][0] != "myth":
   47.32 +                self.opts["original_mtime"] = os.path.getmtime(
   47.33 +                    self.opts["uri"][0])
   47.34 +
   47.35 +            name = os.path.basename(self.opts["uri"][0])
   47.36 +            self.opts["original"] = [name]
   47.37 +            output_file = os.path.basename(self.opts["outfile"][0])
   47.38 +            dat_file = output_file + ".dat";
   47.39 +            dat_path = os.path.join (utils.config.get_transcoded_location(),
   47.40 +                dat_file);
   47.41 +
   47.42 +            output = open(dat_path, "wb")
   47.43 +            # dumps data using the highest protocol
   47.44 +            pickle.dump(self.opts, output, -1)
   47.45 +            output.close()
   47.46 +        else:
   47.47 +            name = os.path.splitext(os.path.basename(filename))[0]
   47.48 +            dat_file = name + ".dat";
   47.49 +            dat_path = os.path.join (utils.config.get_transcoded_location(),
   47.50 +                dat_file);
   47.51 +            pkl_file = open(dat_path, "rb")
   47.52 +            self.opts = pickle.load(pkl_file)
   47.53 +    # __init__()
   47.54 +
   47.55 +# TranscodedFile
   47.56 +
   47.57 +
   47.58 +class FileList(list):
   47.59 +    """Class to hold file's list - reimplements str and repr."""
   47.60 +    def __str__(self):
   47.61 +        ret = ""
   47.62 +        if len(self) > 0:
   47.63 +            for item in self:
   47.64 +                ret = ret + "%s" % item
   47.65 +        return ret
   47.66 +    # __str__()
   47.67 +
   47.68 +    def __repr__(self):
   47.69 +        return self.__str__()
   47.70 +    # __repr__()
   47.71 +
   47.72 +# FileList
   47.73 +
   47.74 +def list_media_files(directory, file_list):
   47.75 +    """Show all the media files with extension defined in the var 'ext'
   47.76 +    that are in the directory, appending each one to 'file_list'."""
   47.77 +    ext = ['mpg', 'avi', 'mp4', 'nuv', 'mpeg', 'mov']
   47.78 +    for root, dirs, files in os.walk(directory):
   47.79 +        for name in files:
   47.80 +            if os.path.splitext(name)[1].strip(".") in ext:
   47.81 +                dat_file = os.path.join(sys.path[0],root,
   47.82 +                                        os.path.splitext(name)[0]+".dat")
   47.83 +
   47.84 +                if name not in file_list and \
   47.85 +                       os.path.exists(dat_file):
   47.86 +                    file_list.append(name)
   47.87 +
   47.88 +    return True
   47.89 +# list_media_files()
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/gmyth-stream/server/lib/gmsconfig.py	Wed Aug 29 14:42:10 2007 +0100
    48.3 @@ -0,0 +1,38 @@
    48.4 +#!/usr/bin/env
    48.5 +
    48.6 +__author__ = "Renato Araujo Oliveira Filho"
    48.7 +__author_email__ = "renato.filho@indt.org.br"
    48.8 +__license__ = "GPL"
    48.9 +__version__ = "0.3"
   48.10 +
   48.11 +
   48.12 +import os
   48.13 +import ConfigParser
   48.14 +
   48.15 +__all__ = ("GmsConfig")
   48.16 +
   48.17 +class GmsConfig:
   48.18 +    config = ConfigParser.ConfigParser()
   48.19 +    __CONFIG_FILE__ = "server.conf"
   48.20 +    __CONFIG_DIRS__ =  [os.path.join (os.path.expanduser("~"), ".gms"), \
   48.21 +                       os.path.join ("/", "etc", "gms"), \
   48.22 +		       "."]
   48.23 +
   48.24 +    def __init__(self):
   48.25 +        for path in self.__CONFIG_DIRS__:
   48.26 +            file_name = os.path.join (path, self.__CONFIG_FILE__)
   48.27 +            if os.path.exists (file_name):
   48.28 +                fp = open (file_name, "r")
   48.29 +                self.config.readfp (fp)
   48.30 +                return
   48.31 +    # __init__()
   48.32 +
   48.33 +    def get_transcoded_location (self):
   48.34 +        try:
   48.35 +            return os.path.realpath (self.config.get("PATHS", "transcoded"))
   48.36 +        except:
   48.37 +            return None
   48.38 +    # get_transcoded_location()
   48.39 +
   48.40 +
   48.41 +# GmsConfig
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/gmyth-stream/server/lib/log.py	Wed Aug 29 14:42:10 2007 +0100
    49.3 @@ -0,0 +1,109 @@
    49.4 +#!/usr/bin/env python
    49.5 +
    49.6 +__author__ = "Artur Duque de Souza"
    49.7 +__author_email__ = "artur.souza@indt.org.br"
    49.8 +__license__ = "GPL"
    49.9 +__version__ = "0.1"
   49.10 +
   49.11 +import os
   49.12 +import logging
   49.13 +
   49.14 +__all__ = ("Log", "log_structure")
   49.15 +
   49.16 +class log_structure(object):
   49.17 +    """Structure to hold log info."""
   49.18 +
   49.19 +    def __init__(self, log=None):
   49.20 +        self.log = log
   49.21 +        self.history = []
   49.22 +    # __init__()
   49.23 +
   49.24 +# log_structure()
   49.25 +
   49.26 +class Log(object):
   49.27 +    """This class implements a log where we can store status of
   49.28 +    all transcoders (even from those that are not running any more)."""
   49.29 +
   49.30 +    ## key = tid
   49.31 +    ## item = ls
   49.32 +    logs = {}
   49.33 +
   49.34 +    def insert(self, tid, name):
   49.35 +        """Insert a given tid on the log structure"""
   49.36 +        if not self.logs.has_key(tid):
   49.37 +            self.logs[tid] = log_structure(logging.getLogger(name))
   49.38 +            return True
   49.39 +        else:
   49.40 +            return False
   49.41 +    # insert()
   49.42 +
   49.43 +    def remove(self, tid=None):
   49.44 +        """Cleans up all log stored for a
   49.45 +        given tid or for all transcodes."""
   49.46 +        if not tid:
   49.47 +            self.logs = {}
   49.48 +        else:
   49.49 +            del(self.logs[tid])
   49.50 +
   49.51 +        return True
   49.52 +    # clean()
   49.53 +
   49.54 +    def get_status(self, tid=None, all=False):
   49.55 +        """Get the status of all transcoders or
   49.56 +        of just one of them if it's given an tid."""
   49.57 +        if not tid:
   49.58 +            ret = {}
   49.59 +            for tids, logs in self.logs.items():
   49.60 +                if len(logs.history) > 0:
   49.61 +                    if not all:
   49.62 +                        ret[tids] = logs.history[-1]
   49.63 +                    else:
   49.64 +                        ret[tids] = logs.history
   49.65 +            return ret
   49.66 +        elif self.logs.has_key(tid) and len(self.logs[tid].history) > 0:
   49.67 +            if not all:
   49.68 +                return self.logs[tid].history[-1]
   49.69 +            else:
   49.70 +                return self.logs[tid].history
   49.71 +
   49.72 +        return False
   49.73 +    # get_status()
   49.74 +
   49.75 +    def _update_status(self, tid=None, msg=""):
   49.76 +        """Update the status of a given tid. Private method that
   49.77 +        is only called inside error/info/debug wrappers"""
   49.78 +        if msg != "":
   49.79 +            self.logs[tid].history.append(msg)
   49.80 +            return True
   49.81 +        else:
   49.82 +            return False
   49.83 +    # update_status()
   49.84 +
   49.85 +    def error(self, tid, msg):
   49.86 +        """Python's Log.error wrapper"""
   49.87 +        if self.logs.has_key(tid):
   49.88 +            self.logs[tid].log.error("%s" % msg)
   49.89 +            return self._update_status(tid, msg)
   49.90 +        else:
   49.91 +            return False
   49.92 +    # error()
   49.93 +
   49.94 +    def info(self, tid, msg):
   49.95 +        """Python's Log.info wrapper"""
   49.96 +        if self.logs.has_key(tid):
   49.97 +            self.logs[tid].log.info("%s" % msg)
   49.98 +            self._update_status(tid, msg)
   49.99 +            return True
  49.100 +        else:
  49.101 +            return False
  49.102 +    # info()
  49.103 +
  49.104 +    def debug(self, tid, msg):
  49.105 +        """Python's Log.debug wrapper"""
  49.106 +        if self.logs.has_key(tid):
  49.107 +            self.logs[tid].log.debug("%s" % msg)
  49.108 +            self._update_status(tid, msg)
  49.109 +            return True
  49.110 +        else:
  49.111 +            return False
  49.112 +    # debug()
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/gmyth-stream/server/lib/request_handler.py	Wed Aug 29 14:42:10 2007 +0100
    50.3 @@ -0,0 +1,470 @@
    50.4 +#!/usr/bin/env python
    50.5 +
    50.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    50.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    50.8 +__license__ = "GPL"
    50.9 +__version__ = "0.3"
   50.10 +
   50.11 +import os
   50.12 +import cgi
   50.13 +import socket
   50.14 +import logging
   50.15 +import urlparse
   50.16 +import threading
   50.17 +import SocketServer
   50.18 +import BaseHTTPServer
   50.19 +import mimetypes
   50.20 +
   50.21 +import lib.utils as utils
   50.22 +import lib.file_handler as files
   50.23 +import lib.transcoder as transcoder
   50.24 +
   50.25 +from log import Log
   50.26 +
   50.27 +__all__ = ("RequestHandler")
   50.28 +
   50.29 +class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
   50.30 +    """Class that implements an HTTP request handler for our server."""
   50.31 +    log = logging.getLogger("gms.request")
   50.32 +    def_transcoder = None
   50.33 +    transcoders = utils.PluginSet(transcoder.Transcoder)
   50.34 +    transcoders_log = Log()
   50.35 +    tid_queue = []
   50.36 +
   50.37 +    menu = {
   50.38 +        "Log": "/get_log.do",
   50.39 +        "Stop": "/stop-transcoder.do",
   50.40 +        "Status": "/status.do",
   50.41 +        "All Log": "/get_all_log.do",
   50.42 +        "Version": "/version.do",
   50.43 +        "Shutdown": "/shutdown.do"
   50.44 +        }
   50.45 +
   50.46 +    @classmethod
   50.47 +    def load_plugins_transcoders(cls, directory):
   50.48 +        cls.transcoders.load_from_directory(directory)
   50.49 +
   50.50 +        if cls.def_transcoder is None and cls.transcoders:
   50.51 +            cls.def_transcoder = cls.transcoders[0].name
   50.52 +    # load_plugins_transcoders()
   50.53 +
   50.54 +
   50.55 +    def do_dispatch(self, body):
   50.56 +        self.url = self.path
   50.57 +        pieces = urlparse.urlparse(self.path)
   50.58 +        self.path = pieces[2]
   50.59 +        self.query = cgi.parse_qs(pieces[4])
   50.60 +
   50.61 +        url = {
   50.62 +            "/": self.serve_main,
   50.63 +            "/shutdown.do": self.serve_shutdown,
   50.64 +            "/stop-transcoder.do": self.serve_stop_transcoder,
   50.65 +            "/status.do": self.serve_status,
   50.66 +            "/version.do": self.serve_version,
   50.67 +            "/new_id.do": self.serve_new_id,
   50.68 +            "/get_log.do": self.serve_get_log,
   50.69 +            "/get_all_log.do": self.serve_get_all_log,
   50.70 +            "/stream.do": self.serve_stream,
   50.71 +            "/transcode.do": self.serve_transcode,
   50.72 +            "/list.do": self.serve_list,
   50.73 +            "/get_file_info.do": self.serve_file_info,
   50.74 +            }
   50.75 +
   50.76 +        try:
   50.77 +            url[self.path](body)
   50.78 +        except KeyError:
   50.79 +            try:
   50.80 +                action = self.query.get("action", None)
   50.81 +                if action and "stream.do" in action:
   50.82 +                    self.serve_stream(body)
   50.83 +                elif os.path.exists("html/%s" % self.path):
   50.84 +                    data = open("html/%s" % self.path)
   50.85 +                    self.wfile.write(data.read())
   50.86 +                else:
   50.87 +                    self.send_error(404, "File not found")
   50.88 +            except Exception, e:
   50.89 +                self.log.error(e)
   50.90 +
   50.91 +    # do_dispatch()
   50.92 +
   50.93 +
   50.94 +    def do_GET(self):
   50.95 +        self.do_dispatch(True)
   50.96 +    # do_GET()
   50.97 +
   50.98 +
   50.99 +    def do_HEAD(self):
  50.100 +        self.do_dispatch(False)
  50.101 +    # do_HEAD()
  50.102 +
  50.103 +
  50.104 +    def _nav_items(self):
  50.105 +        ret = ""
  50.106 +        for name, url in self.menu.items():
  50.107 +            ret += utils.getHTML("menu", {"name": name, "url": url})
  50.108 +        return ret
  50.109 +    # _nav_items()
  50.110 +
  50.111 +
  50.112 +    def serve_main(self, body):
  50.113 +        self.send_response(200)
  50.114 +        self.send_header("Content-Type", "text/html")
  50.115 +        self.send_header('Connection', 'close')
  50.116 +        self.end_headers()
  50.117 +        if body:
  50.118 +            self.wfile.write(utils.getHTML("index", {"menu": self._nav_items()}))
  50.119 +    # serve_main()
  50.120 +
  50.121 +
  50.122 +    def serve_version(self, body):
  50.123 +        self.send_response(200)
  50.124 +        self.send_header("Content-Type", "text/html")
  50.125 +        self.send_header('Connection', 'close')
  50.126 +        self.end_headers()
  50.127 +        if body:
  50.128 +            self.wfile.write("Version: %s" %  __version__)
  50.129 +    # serve_version
  50.130 +
  50.131 +
  50.132 +    def serve_shutdown(self, body):
  50.133 +        self.send_response(200)
  50.134 +        self.send_header("Content-Type", "text/html")
  50.135 +        self.send_header('Connection', 'close')
  50.136 +        self.end_headers()
  50.137 +        if body:
  50.138 +            self.wfile.write(utils.getHTML("shutdown"))
  50.139 +        self.server.server_close()
  50.140 +    # serve_shutdown()
  50.141 +
  50.142 +
  50.143 +    def serve_list(self, body):
  50.144 +        self.send_response(200)
  50.145 +        self.send_header("Content-Type", "text/html")
  50.146 +        self.send_header('Connection', 'close')
  50.147 +        self.end_headers()
  50.148 +
  50.149 +        if body:
  50.150 +            file_list = []
  50.151 +            files.list_media_files(utils.config.get_transcoded_location(), file_list)
  50.152 +            output = files.FileList(map(lambda x, y: x+y, file_list,
  50.153 +                                        ["<br>"]*len(file_list)))
  50.154 +            self.wfile.write(output)
  50.155 +
  50.156 +    # serve_list()
  50.157 +
  50.158 +
  50.159 +    def serve_stop_all_transcoders(self, body):
  50.160 +        self.send_response(200)
  50.161 +        self.send_header("Content-Type", "text/html")
  50.162 +        self.send_header('Connection', 'close')
  50.163 +        self.end_headers()
  50.164 +        if body:
  50.165 +            self.server.stop_transcoders()
  50.166 +            self.wfile.write(utils.getHTML("stop_all",
  50.167 +                                           {"menu": self._nav_items()}))
  50.168 +    # serve_stop_all_transcoders()
  50.169 +
  50.170 +
  50.171 +    def serve_stop_selected_transcoders(self, body, tids=[]):
  50.172 +        self.send_response(200)
  50.173 +        self.send_header("Content-Type", "text/html")
  50.174 +        self.send_header('Connection', 'close')
  50.175 +        self.end_headers()
  50.176 +        opts = ""
  50.177 +        if body:
  50.178 +            transcoders = self.server.get_transcoders()
  50.179 +
  50.180 +            for tid in tids:
  50.181 +                for t, r in transcoders:
  50.182 +                    if t.tid == int(tid):
  50.183 +                        try:
  50.184 +                            t.stop()
  50.185 +                        except Exception, e:
  50.186 +                            self.log.info("Plugin already stopped")
  50.187 +
  50.188 +                        opts += utils._create_html_item("%s" % t)
  50.189 +
  50.190 +                        break
  50.191 +
  50.192 +                self.wfile.write(utils.getHTML("stop_selected",
  50.193 +                                               {"menu": self._nav_items(),
  50.194 +                                                "opts": opts}))
  50.195 +    # serve_stop_selected_transcoders()
  50.196 +
  50.197 +
  50.198 +    def serve_stop_transcoder(self, body):
  50.199 +        req = self.query.get("request", None)
  50.200 +        tid = self.query.get("tid", None)
  50.201 +        if req and "all" in req:
  50.202 +            self.serve_stop_all_transcoders(body)
  50.203 +        elif tid:
  50.204 +            self.serve_stop_selected_transcoders(body, tid[0].split(";"))
  50.205 +        else:
  50.206 +            self.serve_status(body)
  50.207 +    # serve_stop_transcoder()
  50.208 +
  50.209 +
  50.210 +    def serve_status(self, body):
  50.211 +        self.send_response(200)
  50.212 +        self.send_header("Content-Type", "text/html")
  50.213 +        self.send_header('Connection', 'close')
  50.214 +        self.end_headers()
  50.215 +        stopone = ""
  50.216 +        running = ""
  50.217 +        stopall = ""
  50.218 +
  50.219 +        if body:
  50.220 +            tl = self.server.get_transcoders()
  50.221 +            if not tl and not self.query.get("tid", None) and \
  50.222 +                   not self.query.get("running", None):
  50.223 +                running = "<p>No running transcoder.</p>\n"
  50.224 +
  50.225 +            elif not tl and self.query.get("tid", None):
  50.226 +                tids = self.query.get("tid")
  50.227 +                for tid in tids:
  50.228 +                    stat = self.transcoders_log.get_status(int(tid))
  50.229 +                    self.wfile.write("%s<br>" % stat)
  50.230 +                return True
  50.231 +
  50.232 +            elif self.query.get("running", None):
  50.233 +                for transcoder, request in tl:
  50.234 +                    outf = transcoder.params_first("outfile")
  50.235 +                    tid = transcoder.tid
  50.236 +                    self.wfile.write("%s:%s<br>" % (tid, outf))
  50.237 +                return True
  50.238 +
  50.239 +            elif self.query.get("tid", None):
  50.240 +                req_tid = self.query.get("tid")
  50.241 +                for transcoder, request in tl:
  50.242 +                    if str(transcoder.tid) in req_tid:
  50.243 +                        self.wfile.write("Status:%s:%s %%" % (\
  50.244 +                            transcoder.tid, transcoder.status))
  50.245 +                        return True
  50.246 +                stat = self.transcoders_log.get_status(int(req_tid[0]))
  50.247 +                self.wfile.write("%s<br>" % stat)
  50.248 +                return True
  50.249 +
  50.250 +            else:
  50.251 +                running = "<p>Running transcoders:</p>\n"
  50.252 +                stopall = utils._create_html_item("<a href='%s?request=all'>"
  50.253 +                                                 "[STOP ALL]</a>" %
  50.254 +                                                 self.menu["Stop"])
  50.255 +
  50.256 +                for transcoder, request in tl:
  50.257 +                    stopone += utils._create_html_item("%s;"
  50.258 +                                                       "<a href='%s?tid=%s'>"
  50.259 +                                                       " [STOP] </a>") % (
  50.260 +                        transcoder, self.menu["Stop"], transcoder.tid)
  50.261 +
  50.262 +            self.wfile.write(utils.getHTML("status",
  50.263 +                                           {"menu": self._nav_items(),
  50.264 +                                            "running": running,
  50.265 +                                            "stopall": stopall,
  50.266 +                                            "stopone": stopone}))
  50.267 +    # serve_status()
  50.268 +
  50.269 +
  50.270 +    def _get_transcoder(self):
  50.271 +        # get transcoder option: mencoder is the default
  50.272 +        request_transcoders = self.query.get("transcoder", ["mencoder"])
  50.273 +
  50.274 +        for t in request_transcoders:
  50.275 +            transcoder = self.transcoders.get(t)
  50.276 +            if transcoder:
  50.277 +                return transcoder
  50.278 +
  50.279 +        if not transcoder:
  50.280 +            return self.transcoders[self.def_transcoder]
  50.281 +    # _get_transcoder()
  50.282 +
  50.283 +
  50.284 +    def _get_new_id(self, tid):
  50.285 +        self.server.last_tid = utils.create_tid(tid)
  50.286 +        self.tid_queue.append(self.server.last_tid)
  50.287 +        return self.server.last_tid
  50.288 +    # _get_new_id()
  50.289 +
  50.290 +
  50.291 +    def serve_new_id(self, body):
  50.292 +        self.send_response(200)
  50.293 +        self.send_header("Content-Type", "text/html")
  50.294 +        self.send_header('Connection', 'close')
  50.295 +        self.end_headers()
  50.296 +
  50.297 +        if body:
  50.298 +            self.wfile.write("%s" % self._get_new_id(self.server.last_tid))
  50.299 +    # serve_new_id()
  50.300 +
  50.301 +    def serve_get_log(self, body):
  50.302 +        self.send_response(200)
  50.303 +        self.send_header("Content-Type", "text/html")
  50.304 +        self.send_header('Connection', 'close')
  50.305 +        self.end_headers()
  50.306 +
  50.307 +        if body:
  50.308 +            if self.query.get("tid", None):
  50.309 +                tid = int(self.query.get("tid")[0])
  50.310 +                stat = self.transcoders_log.get_status(tid)
  50.311 +                self.wfile.write("Status: %s" % stat)
  50.312 +            else:
  50.313 +                stat = self.transcoders_log.get_status()
  50.314 +                for rtid, status in stat.iteritems():
  50.315 +                    self.wfile.write("<b>%s</b>: %s<br><br>" % (rtid, status))
  50.316 +    # serve_get_log()
  50.317 +
  50.318 +    def serve_get_all_log(self, body):
  50.319 +        self.send_response(200)
  50.320 +        self.send_header("Content-Type", "text/html")
  50.321 +        self.send_header('Connection', 'close')
  50.322 +        self.end_headers()
  50.323 +
  50.324 +        if body:
  50.325 +            if self.query.get("tid", None):
  50.326 +                tid = int(self.query.get("tid")[0])
  50.327 +                stat = self.transcoders_log.get_status(tid, True)
  50.328 +                for status in stat:
  50.329 +                    self.wfile.write("%s<br><br>" % status)
  50.330 +            else:
  50.331 +                stat = self.transcoders_log.get_status(None, True)
  50.332 +                for rtid, history in stat.iteritems():
  50.333 +                    for status in history:
  50.334 +                        self.wfile.write("<b>%s</b>: %s<br>" % (rtid, status))
  50.335 +                    self.wfile.write("<br><br>")
  50.336 +    # serve_get_all_log()
  50.337 +
  50.338 +
  50.339 +    def serve_file_info(self, body):
  50.340 +        if body:
  50.341 +
  50.342 +            file_dat = self.query.get("file", None)
  50.343 +
  50.344 +            if file_dat:
  50.345 +                self.send_response(200)
  50.346 +                self.send_header("Content-Type", "text/html")
  50.347 +                self.send_header('Connection', 'close')
  50.348 +                self.end_headers()
  50.349 +
  50.350 +                try:
  50.351 +                    opts = files.TranscodedFile(file_dat[0], self.query).opts
  50.352 +                    for key in opts.keys():
  50.353 +                        self.wfile.write("%s=%s<br>" % (key, opts.get(key, "None")[0]))
  50.354 +
  50.355 +                except Exception, e:
  50.356 +                    self.send_error(500, str(e))
  50.357 +                    return
  50.358 +    # serve_file_info()
  50.359 +
  50.360 +    def serve_stream(self, body):
  50.361 +	args = self.query.get("file", None)
  50.362 +	if not args:
  50.363 +	    self.send_error(404, "File not found")
  50.364 +	    return
  50.365 +
  50.366 +        filename = args[0];
  50.367 +        if not filename:
  50.368 +            self.send_error(404, "File not found")
  50.369 +            return
  50.370 +
  50.371 +        #Only stream files on .transcode dir
  50.372 +        filename = os.path.join (utils.config.get_transcoded_location(),
  50.373 +                                 os.path.basename(filename))
  50.374 +        self.log.error("Stream file: %s" % filename)
  50.375 +        if not os.path.exists (filename):
  50.376 +            self.send_error(404, "File not found")
  50.377 +            return
  50.378 +
  50.379 +        size = int(os.path.getsize(filename))
  50.380 +        self.send_response(200)
  50.381 +        self.send_header("Content-Type", mimetypes.guess_type(filename)[0])
  50.382 +        self.send_header("Cache-Control","no-cache")
  50.383 +        self.send_header("Content-Length", size)
  50.384 +        self.end_headers()
  50.385 +
  50.386 +        media = open(filename)
  50.387 +        data_in = " "
  50.388 +        total_read = 0
  50.389 +
  50.390 +        test_tid = int(self.query.get("tid", "0")[0])
  50.391 +        if test_tid == 0 or test_tid not in self.tid_queue:
  50.392 +            test_tid = self._get_new_id(self.server.last_tid)
  50.393 +
  50.394 +        self.transcoders_log.insert(test_tid, "gms.Stream: %s" % filename)
  50.395 +
  50.396 +        try:
  50.397 +            file_data = ""
  50.398 +            while data_in != "":
  50.399 +                data_in = media.read(4096)
  50.400 +                file_data += data_in
  50.401 +
  50.402 +                #total_read += 4096
  50.403 +            self.wfile.write(file_data)
  50.404 +                #status = utils.progress_bar(total_read, size, 50)
  50.405 +                #msg_status = "Status:%s:%s%%" % (test_tid, status)
  50.406 +                #self.transcoders_log._update_status(test_tid, msg_status)
  50.407 +
  50.408 +            self.transcoders_log._update_status(test_tid, "OK: Done")
  50.409 +
  50.410 +        except Exception, e:
  50.411 +            self.log.error("Stream error: %s" %e)
  50.412 +            self.transcoders_log._update_status(test_tid, "Error: %s" % e)
  50.413 +    # serve_stream()
  50.414 +
  50.415 +    def serve_transcode(self, body):
  50.416 +        type = self.query.get("type", None)[0]
  50.417 +        if type.upper() == "FILE":
  50.418 +            self.send_error(404, "Transcode local files not allowed")
  50.419 +            return
  50.420 +
  50.421 +        transcoder = self._get_transcoder()
  50.422 +        try:
  50.423 +            obj = transcoder(self.query)
  50.424 +        except Exception, e:
  50.425 +            self.send_error(500, str(e))
  50.426 +            return
  50.427 +
  50.428 +        self.send_response(200)
  50.429 +        self.send_header("Content-Type", obj.get_mimetype())
  50.430 +        self.send_header("Cache-Control","no-cache")
  50.431 +
  50.432 +        if (obj.name == "gmencoder"):
  50.433 +            self.send_header("Transfer-Encoding", "chunked")
  50.434 +
  50.435 +        self.end_headers()
  50.436 +
  50.437 +        if body:
  50.438 +            test_tid = int(self.query.get("tid", "0")[0])
  50.439 +            if test_tid == 0 or test_tid not in self.tid_queue:
  50.440 +                test_tid = self._get_new_id(self.server.last_tid)
  50.441 +
  50.442 +            if self.query.get("transcoder", None):
  50.443 +                self.transcoders_log.insert(test_tid, "gms.%s" % obj.name)
  50.444 +                obj.tid = test_tid
  50.445 +                obj.log = self.transcoders_log
  50.446 +
  50.447 +                self.server.add_transcoders(self, obj)
  50.448 +                if obj.start(self.wfile):
  50.449 +                    self.transcoders_log.info (test_tid, "OK")
  50.450 +                else:
  50.451 +                    self.transcoders_log.info (test_tid, "Fail")
  50.452 +
  50.453 +                self.server.del_transcoders(self, obj)
  50.454 +                files.TranscodedFile("", self.query)
  50.455 +
  50.456 +    # serve_stream()
  50.457 +
  50.458 +
  50.459 +    def log_request(self, code='-', size='-'):
  50.460 +        self.log.info('"%s" %s %s', self.requestline, str(code), str(size))
  50.461 +    # log_request()
  50.462 +
  50.463 +
  50.464 +    def log_error(self, format, *args):
  50.465 +        self.log.error("%s: %s" % (self.address_string(), format % args))
  50.466 +    # log_error()
  50.467 +
  50.468 +
  50.469 +    def log_message(self, format, *args):
  50.470 +        self.log.info("%s: %s" % (self.address_string(), format % args))
  50.471 +    # log_message()
  50.472 +
  50.473 +# RequestHandler
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/gmyth-stream/server/lib/server.py	Wed Aug 29 14:42:10 2007 +0100
    51.3 @@ -0,0 +1,117 @@
    51.4 +#!/usr/bin/env python
    51.5 +
    51.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    51.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    51.8 +__license__ = "GPL"
    51.9 +__version__ = "0.4"
   51.10 +
   51.11 +import os
   51.12 +import threading
   51.13 +import SocketServer
   51.14 +import BaseHTTPServer
   51.15 +import socket
   51.16 +import urlparse
   51.17 +import cgi
   51.18 +import lib.utils as utils
   51.19 +import logging
   51.20 +
   51.21 +from log import Log
   51.22 +from request_handler import RequestHandler
   51.23 +
   51.24 +__all__ = ("Server", "serve_forever", "load_plugins_transcoders")
   51.25 +
   51.26 +class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
   51.27 +    log = logging.getLogger("gms.server")
   51.28 +    last_tid = 0
   51.29 +    run = True
   51.30 +    _transcoders = {}
   51.31 +    _lock = threading.RLock()
   51.32 +
   51.33 +    def serve_forever(self):
   51.34 +        self.log.info("GMyth-Streamer serving HTTP on %s:%s" %
   51.35 +                      self.socket.getsockname())
   51.36 +        try:
   51.37 +            while self.run:
   51.38 +                self.handle_request()
   51.39 +        except KeyboardInterrupt, e:
   51.40 +            pass
   51.41 +
   51.42 +        self.log.debug("Stopping all remaining transcoders...")
   51.43 +        self.stop_transcoders()
   51.44 +        self.log.debug("Transcoders stopped!")
   51.45 +    # serve_forever()
   51.46 +
   51.47 +
   51.48 +    def get_request(self):
   51.49 +        skt = self.socket
   51.50 +        old = skt.gettimeout()
   51.51 +        skt.settimeout(0.5)
   51.52 +        while self.run:
   51.53 +            try:
   51.54 +                r = skt.accept()
   51.55 +                skt.settimeout(old)
   51.56 +                return r
   51.57 +            except socket.timeout, e:
   51.58 +                pass
   51.59 +        raise socket.error("Not running")
   51.60 +    # get_request()
   51.61 +
   51.62 +
   51.63 +    def server_close(self):
   51.64 +        self.run = False
   51.65 +        self.stop_transcoders()
   51.66 +
   51.67 +        BaseHTTPServer.HTTPServer.server_close(self)
   51.68 +    # server_close()
   51.69 +
   51.70 +
   51.71 +    def stop_transcoders(self):
   51.72 +        self._lock.acquire()
   51.73 +        for transcoder, request in self._transcoders.iteritems():
   51.74 +            self.log.info("Stop transcoder: %s, client=%s" %
   51.75 +                          (transcoder, request.client_address))
   51.76 +            transcoder.stop()
   51.77 +        self._lock.release()
   51.78 +    # stop_transcoders()
   51.79 +
   51.80 +
   51.81 +    def get_transcoders(self):
   51.82 +        self._lock.acquire()
   51.83 +        try:
   51.84 +            return self._transcoders.items()
   51.85 +        finally:
   51.86 +            self._lock.release()
   51.87 +    # get_transcoders()
   51.88 +
   51.89 +
   51.90 +    def add_transcoders(self, request, transcoder):
   51.91 +        self._lock.acquire()
   51.92 +        try:
   51.93 +            self._transcoders[transcoder] = request
   51.94 +        finally:
   51.95 +            self._lock.release()
   51.96 +    # add_transcoders()
   51.97 +
   51.98 +
   51.99 +    def del_transcoders(self, request, transcoder):
  51.100 +        self._lock.acquire()
  51.101 +        try:
  51.102 +            del self._transcoders[transcoder]
  51.103 +        finally:
  51.104 +            self._lock.release()
  51.105 +    # del_transcoders()
  51.106 +# Server
  51.107 +
  51.108 +
  51.109 +
  51.110 +def serve_forever(host="0.0.0.0", port=40000):
  51.111 +    addr = (host, port)
  51.112 +    RequestHandler.protocol_version = "HTTP/1.0"
  51.113 +    httpd = Server(addr, RequestHandler)
  51.114 +    httpd.serve_forever()
  51.115 +# serve_forever()
  51.116 +
  51.117 +
  51.118 +def load_plugins_transcoders(directory):
  51.119 +    RequestHandler.load_plugins_transcoders(directory)
  51.120 +# load_plugins_transcoders()
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/gmyth-stream/server/lib/transcoder.py	Wed Aug 29 14:42:10 2007 +0100
    52.3 @@ -0,0 +1,58 @@
    52.4 +#!/usr/bin/env python
    52.5 +
    52.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    52.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    52.8 +__license__ = "GPL"
    52.9 +__version__ = "0.4"
   52.10 +
   52.11 +__all__ = ("Transcoder")
   52.12 +
   52.13 +class Transcoder(object):
   52.14 +    """Transcoder's Class: parent class to implement
   52.15 +    a plugin for transcoding data."""
   52.16 +    priority = 0   # negative values have higher priorities
   52.17 +    name = None # to be used in requests
   52.18 +    status = None
   52.19 +    log = None
   52.20 +    tid = -1
   52.21 +
   52.22 +    def __init__(self, params):
   52.23 +        self.params = params
   52.24 +    # __init__()
   52.25 +
   52.26 +    def params_first(self, key, default=None):
   52.27 +        if default is None:
   52.28 +            return self.params[key][0]
   52.29 +        else:
   52.30 +            try:
   52.31 +                return self.params[key][0]
   52.32 +            except:
   52.33 +                return default
   52.34 +    # params_first()
   52.35 +
   52.36 +    def get_mimetype(self):
   52.37 +        return "application/octet-stream"
   52.38 +    # get_mimetype()
   52.39 +
   52.40 +    def start(self, outfile):
   52.41 +        pass
   52.42 +    # start()
   52.43 +
   52.44 +    def stop(self):
   52.45 +        pass
   52.46 +    # stop()
   52.47 +
   52.48 +    def get_legth (self):
   52.49 +        pass
   52.50 +    # get_leght ()
   52.51 +
   52.52 +    def get_progress (self):
   52.53 +        pass
   52.54 +    # get_progress ()
   52.55 +
   52.56 +    def __str__(self):
   52.57 +        return '%s: %s( params=%s ) - Status: %s%%' % \
   52.58 +               (self.__class__.__name__, self.tid,
   52.59 +                self.params, self.status)
   52.60 +    # __str__()
   52.61 +# Transcoder
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/gmyth-stream/server/lib/utils.py	Wed Aug 29 14:42:10 2007 +0100
    53.3 @@ -0,0 +1,193 @@
    53.4 +#!/usr/bin/env
    53.5 +
    53.6 +__author__ = "Gustavo Sverzut Barbieri / Artur Duque de Souza"
    53.7 +__author_email__ = "barbieri@gmail.com / artur.souza@indt.org.br"
    53.8 +__license__ = "GPL"
    53.9 +__version__ = "0.3"
   53.10 +
   53.11 +import os
   53.12 +import stat
   53.13 +import sys
   53.14 +import logging
   53.15 +import urllib
   53.16 +import gobject
   53.17 +import imp
   53.18 +
   53.19 +import gmsconfig
   53.20 +
   53.21 +log = logging.getLogger("gms.utils")
   53.22 +config = gmsconfig.GmsConfig()
   53.23 +
   53.24 +__all__ = ("which", "load_plugins", "PluginSet", "getHTML",
   53.25 +           "progress_bar", "create_tid", "list_media_files")
   53.26 +
   53.27 +def which(app):
   53.28 +    """Function to implement which(1) unix command"""
   53.29 +    pl = os.environ["PATH"].split(os.pathsep)
   53.30 +    for p in pl:
   53.31 +        path = os.path.join(p, app)
   53.32 +        if os.path.isfile(path):
   53.33 +            st = os.stat(path)
   53.34 +            if st[stat.ST_MODE] & 0111:
   53.35 +                return path
   53.36 +    return ""
   53.37 +# which()
   53.38 +
   53.39 +
   53.40 +def _load_module(pathlist, name):
   53.41 +    fp, path, desc = imp.find_module(name, pathlist)
   53.42 +    try:
   53.43 +        module = imp.load_module(name, fp, path, desc)
   53.44 +        return module
   53.45 +    finally:
   53.46 +        if fp:
   53.47 +            fp.close()
   53.48 +# _load_module()
   53.49 +
   53.50 +
   53.51 +class PluginSet(object):
   53.52 +    def __init__(self, basetype, *items):
   53.53 +        self.basetype = basetype
   53.54 +        self.map = {}
   53.55 +        self.list = []
   53.56 +
   53.57 +        for i in items:
   53.58 +            self._add(i)
   53.59 +        self._sort()
   53.60 +    # __init__()
   53.61 +
   53.62 +
   53.63 +    def _add(self, item):
   53.64 +        self.map[item.name] = item
   53.65 +        self.list.append(item)
   53.66 +    # _add()
   53.67 +
   53.68 +
   53.69 +    def add(self, item):
   53.70 +        self._add()
   53.71 +        self._sort()
   53.72 +    # add()
   53.73 +
   53.74 +
   53.75 +    def __getitem__(self, spec):
   53.76 +        if isinstance(spec, basestring):
   53.77 +            return self.map[spec]
   53.78 +        else:
   53.79 +            return self.list[spec]
   53.80 +    # __getitem__()
   53.81 +
   53.82 +
   53.83 +    def get(self, name, default=None):
   53.84 +        return self.map.get(name, default)
   53.85 +    # get()
   53.86 +
   53.87 +
   53.88 +    def __iter__(self):
   53.89 +        return self.list.__iter__()
   53.90 +    # __iter__()
   53.91 +
   53.92 +
   53.93 +    def __len__(self):
   53.94 +        return len(self.list)
   53.95 +    # __len__()
   53.96 +
   53.97 +
   53.98 +    def _sort(self):
   53.99 +        self.list.sort(lambda a, b: cmp(a.priority, b.priority))
  53.100 +    # _sort()
  53.101 +
  53.102 +
  53.103 +    def update(self, pluginset):
  53.104 +        self.map.update(pluginset.map)
  53.105 +        self.list.extend(pluginset.list)
  53.106 +        self._sort()
  53.107 +    # update()
  53.108 +
  53.109 +
  53.110 +    def load_from_directory(self, directory):
  53.111 +        for i in load_plugins(directory, self.basetype):
  53.112 +            self._add(i)
  53.113 +        self._sort()
  53.114 +    # load_from_directory()
  53.115 +
  53.116 +
  53.117 +    def __str__(self):
  53.118 +        lst = []
  53.119 +        for o in self.list:
  53.120 +            lst.append('"%s" (%s)' % (o.name, o.__name__))
  53.121 +
  53.122 +        return "%s(basetype=%s, items=[%s])" % \
  53.123 +               (self.__class__.__name__,
  53.124 +                self.basetype.__name__,
  53.125 +                ", ".join(lst))
  53.126 +    # __str__()
  53.127 +# PluginSet
  53.128 +
  53.129 +
  53.130 +def load_plugins(directory, basetype):
  53.131 +    """Function to load plugins from a given directory"""
  53.132 +    tn = basetype.__name__
  53.133 +    log.debug("Loading plugins from %s, type=%s" % (directory, tn))
  53.134 +
  53.135 +
  53.136 +    plugins = []
  53.137 +    for d in os.listdir(directory):
  53.138 +        if not d.endswith(".py"):
  53.139 +            continue
  53.140 +
  53.141 +        name = d[0: -3]
  53.142 +        if name == "__init__":
  53.143 +            continue
  53.144 +
  53.145 +        directory.replace(os.path.sep, ".")
  53.146 +        mod = _load_module([directory], name)
  53.147 +        for sym in dir(mod):
  53.148 +            cls = getattr(mod, sym)
  53.149 +            if isinstance(cls, type) and issubclass(cls, basetype) and \
  53.150 +                cls != basetype:
  53.151 +                plugins.append(cls)
  53.152 +                log.info("Loaded %s (%s) from %s" % \
  53.153 +                         (cls.__name__, tn, os.path.join(directory, d)))
  53.154 +
  53.155 +    return plugins
  53.156 +# load_plugins()
  53.157 +
  53.158 +def getHTML(html_file, params={}):
  53.159 +    """This function parses an html file with the given
  53.160 +    parameters and returns a formated web-page"""
  53.161 +    try:
  53.162 +        filename = os.path.join(sys.path[0], "html", html_file + ".html")
  53.163 +        html = open(filename).read() % params
  53.164 +        return html
  53.165 +    except Exception, e:
  53.166 +        return "HTML format error. Wrong keys: %s" % e
  53.167 +
  53.168 +# getHTML
  53.169 +
  53.170 +def _create_html_item(opt):
  53.171 +    """Create an <li> item using HTML."""
  53.172 +    return "<li>%s</li>\n" % opt
  53.173 +# _create_html_item
  53.174 +
  53.175 +def progress_bar(value, max, barsize):
  53.176 +    """Creates and displays a progressbar. By OSantana"""
  53.177 +    chars = int(value * barsize / float(max))
  53.178 +    percent = int((value / float(max)) * 100)
  53.179 +    sys.stdout.write("#" * chars)
  53.180 +    sys.stdout.write(" " * (barsize - chars + 2))
  53.181 +    if value >= max:
  53.182 +        sys.stdout.write("done.\n\n")
  53.183 +    else:
  53.184 +        sys.stdout.write("[%3i%%]\r" % (percent))
  53.185 +        sys.stdout.flush()
  53.186 +    return percent
  53.187 +# progress_bar() by osantana
  53.188 +
  53.189 +def create_tid(last_tid):
  53.190 +    """Function to generate TIDs (ids for transcoders).
  53.191 +    At first it just do +1 on last_tid but can be implemented
  53.192 +    to generate more sparse TIDs"""
  53.193 +    tid = last_tid + 1
  53.194 +    return tid
  53.195 +# create_id()
  53.196 +
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/gmyth-stream/server/plugins/transcoders/gmencoder.py	Wed Aug 29 14:42:10 2007 +0100
    54.3 @@ -0,0 +1,134 @@
    54.4 +#!/usr/bin/env python
    54.5 +
    54.6 +__author__ = "Renato Filho"
    54.7 +__author_email__ = "renato.filho@indt.org.br"
    54.8 +__license__ = "GPL"
    54.9 +__version__ = "0.2"
   54.10 +
   54.11 +import os
   54.12 +import sys
   54.13 +import shlex
   54.14 +import signal
   54.15 +import subprocess
   54.16 +import time
   54.17 +
   54.18 +import select
   54.19 +import fcntl
   54.20 +
   54.21 +import lib.utils as utils
   54.22 +import lib.server as server
   54.23 +import lib.transcoder as transcoder
   54.24 +
   54.25 +__all__ = ("TranscoderGMencoder",)
   54.26 +
   54.27 +class TranscoderGMencoder(transcoder.Transcoder):
   54.28 +    gmencoder_path = utils.which("gmencoder")
   54.29 +    name = "gmencoder"
   54.30 +    priority = -1
   54.31 +    proc = None
   54.32 +
   54.33 +    def __init__(self, params):
   54.34 +        self.status = 0
   54.35 +        transcoder.Transcoder.__init__(self, params)
   54.36 +        self.opts = []
   54.37 +        self.opts.append (self.gmencoder_path)
   54.38 +        self.opts.append ("-d")
   54.39 +        self._parser_params ()
   54.40 +
   54.41 +    # __init__()
   54.42 +
   54.43 +    def _insert_param (self, name, value):
   54.44 +        if (value != ""):
   54.45 +            self.opts.append(name)
   54.46 +            self.opts.append(value)
   54.47 +
   54.48 +    def _parser_params (self):
   54.49 +        self._insert_param("-i", \
   54.50 +            "%s://%s" % (self.params_first("type", "file"),
   54.51 +                         self.params_first("uri", "")))
   54.52 +        self._insert_param("--video-encode", self.params_first("ve", "ffenc_mpeg1video"))
   54.53 +        self._insert_param("--video-opts", "bitrate=300000,pass=512,quantizer=0.01,quant-type=1")
   54.54 +        #self._insert_param("--video-fps", self.params_first("fps", ""))
   54.55 +        self._insert_param("--video-fps", self.params_first("fps", "10"))
   54.56 +        self._insert_param("--video-width", self.params_first("width", "320"))
   54.57 +        self._insert_param("--video-height", self.params_first("height", "240"))
   54.58 +        self._insert_param("--audio-rate", "32000")
   54.59 +        self._insert_param("--audio-encode", self.params_first("ae", ""))
   54.60 +    # _parse_params
   54.61 +
   54.62 +    def start(self, outfd):
   54.63 +        outfile = self.params_first("outfile", "")
   54.64 +
   54.65 +        if outfile != "":
   54.66 +            path = os.path.join(utils.config.get_transcoded_location(), outfile)
   54.67 +            self._insert_param("-o", "file://%s" % path)
   54.68 +        else:
   54.69 +            self._insert_param ("-o", "fd://%d" % outfd.fileno())
   54.70 +            self.opts.append ("-c")
   54.71 +
   54.72 +        cmd = " ".join(self.opts)
   54.73 +        self.log.info(self.tid, "GMencoder: %s" % cmd)
   54.74 +
   54.75 +        try:
   54.76 +            self.proc = subprocess.Popen(self.opts, stdin=subprocess.PIPE,
   54.77 +                                         stdout=subprocess.PIPE)
   54.78 +
   54.79 +	    if outfile:
   54.80 +           	outfd.write("OK   ")
   54.81 +
   54.82 +        except Exception, e:
   54.83 +            self.log.error(self.tid, "Error: executing GMencoder: %s" % e)
   54.84 +            outfd.write("Error: GMencoder: %s" % e)
   54.85 +            return False
   54.86 +
   54.87 +        try:
   54.88 +	    if not outfile:
   54.89 +	    	p = select.poll()
   54.90 +	    	p.register (outfd, select.POLLNVAL | select.POLLERR | select.POLLHUP | select.POLLIN )
   54.91 +
   54.92 +            while (self.proc and self.proc.poll() == None):
   54.93 +                r, w, x = select.select([self.proc.stdout], [], [], 1)
   54.94 +                if self.proc.stdout in r:
   54.95 +                    progress = self.proc.stdout.readline()
   54.96 +                    if (progress.find ("PROGRESS") >= 0):
   54.97 +                        self.status = progress.split (":")[1]
   54.98 +		    elif (progress.find ("Erro") >= 0):
   54.99 +			return False
  54.100 +
  54.101 +		    if not outfile:
  54.102 +			    ret = p.poll(0)
  54.103 +			    if ret:
  54.104 +			    	self.log.info(self.tid, "Lost connection")
  54.105 +		    		self.stop ()
  54.106 +			    	return False
  54.107 +
  54.108 +        except Exception, e:
  54.109 +            self.log.error(self.tid, "Problems handling data: %s" % e)
  54.110 +            return False
  54.111 +
  54.112 +        self.status = 100;
  54.113 +
  54.114 +
  54.115 +        return True
  54.116 +    # start()
  54.117 +
  54.118 +
  54.119 +    def stop(self):
  54.120 +        if self.proc:
  54.121 +            self.log.info(self.tid, "Stopped GMencoder plugin")
  54.122 +            try:
  54.123 +                os.kill(self.proc.pid, signal.SIGKILL)
  54.124 +                self.proc.wait()
  54.125 +            except Exception, e:
  54.126 +                pass
  54.127 +
  54.128 +            self.proc = None
  54.129 +    # stop()
  54.130 +
  54.131 +    def get_progress(self):
  54.132 +        return self.status
  54.133 +
  54.134 +    def get_lenght(self):
  54.135 +        return -1
  54.136 +
  54.137 +# TranscoderGMencoder
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/gmyth-stream/server/plugins/transcoders/mencoder.py	Wed Aug 29 14:42:10 2007 +0100
    55.3 @@ -0,0 +1,334 @@
    55.4 +#!/usr/bin/env python
    55.5 +
    55.6 +__author__ = "Artur Duque de Souza"
    55.7 +__author_email__ = "artur.souza@indt.org.br"
    55.8 +__license__ = "GPL"
    55.9 +__version__ = "0.3"
   55.10 +
   55.11 +import os
   55.12 +import time
   55.13 +import fcntl
   55.14 +import shlex
   55.15 +import socket
   55.16 +import struct
   55.17 +import signal
   55.18 +import subprocess
   55.19 +
   55.20 +import lib.utils as utils
   55.21 +import lib.server as server
   55.22 +import plugins.transcoders.mencoder_lib.mythtv as mythtv
   55.23 +
   55.24 +from select import select
   55.25 +import lib.transcoder as transcoder
   55.26 +
   55.27 +__all__ = ("TranscoderMencoder",)
   55.28 +
   55.29 +class TranscoderMencoder(transcoder.Transcoder):
   55.30 +    """Transcoder class that implements a transcoder using Mencoder"""
   55.31 +    mencoder_path = utils.which("mencoder")
   55.32 +    name = "mencoder"
   55.33 +    priority = -1
   55.34 +    args = {}
   55.35 +    proc = None
   55.36 +    gmyth = None
   55.37 +
   55.38 +    # only works with avi container
   55.39 +    status = 0
   55.40 +
   55.41 +    def _setup_params(self):
   55.42 +        params_first = self.params_first
   55.43 +
   55.44 +        # general_opts
   55.45 +        self.args["local"]    = params_first("local", False)
   55.46 +        self.args["language"] = params_first("language", False)
   55.47 +        self.args["subtitle"] = params_first("subtitle", False)
   55.48 +        self.args["format"]   = params_first("format", "mpeg1")
   55.49 +        self.args["outfile"]  = params_first("outfile", "-")
   55.50 +
   55.51 +        # input_opt
   55.52 +        self.args["type"]     = params_first("type", "file")
   55.53 +        self.args["input"]    = params_first("uri", "-")
   55.54 +
   55.55 +        # audio_opts
   55.56 +        self.args["acodec"]   = params_first("acodec", "mp2")
   55.57 +        self.args["abitrate"] = params_first("abitrate", 192)
   55.58 +        self.args["volume"]   = params_first("volume", 5)
   55.59 +
   55.60 +        # video_opts
   55.61 +        self.args["mux"]      = params_first("mux", "mpeg")
   55.62 +        self.args["fps"]      = params_first("fps", 25)
   55.63 +        self.args["vcodec"]   = params_first("vcodec", "mpeg1video")
   55.64 +        self.args["vbitrate"] = params_first("vbitrate", 400)
   55.65 +        self.args["width"]    = params_first("width", 320)
   55.66 +        self.args["height"]   = params_first("height", 240)
   55.67 +    # _setup_params()
   55.68 +
   55.69 +
   55.70 +    def _setup_audio(self):
   55.71 +        if self.args["acodec"] == "mp3lame":
   55.72 +            audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % (
   55.73 +                self.args["abitrate"], self.args["volume"])
   55.74 +        else:
   55.75 +            audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (
   55.76 +                self.args["acodec"], self.args["abitrate"])
   55.77 +
   55.78 +        return audio
   55.79 +    # _setup_audio()
   55.80 +
   55.81 +
   55.82 +    def _setup_video(self):
   55.83 +        video = " -of %s" % self.args["mux"]
   55.84 +        video += " -ofps %s" % self.args["fps"]
   55.85 +
   55.86 +        vcodec = self.args["vcodec"]
   55.87 +        if vcodec == "nuv" or vcodec == "xvid"\
   55.88 +               or vcodec == "qtvideo" or vcodec == "copy":
   55.89 +            video += " -ovc %s" % vcodec
   55.90 +        else:
   55.91 +            video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
   55.92 +                vcodec, self.args["vbitrate"])
   55.93 +
   55.94 +        if self.args["mux"] == "mpeg":
   55.95 +            video += " -mpegopts format=%s" % self.args["format"]
   55.96 +
   55.97 +        video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"])
   55.98 +        return video
   55.99 +    # _setup_video()
  55.100 +
  55.101 +
  55.102 +    def _arg_append(self, args, options):
  55.103 +        for arg in shlex.split(options):
  55.104 +            args.append(arg)
  55.105 +    # arg_append()
  55.106 +
  55.107 +    def _setup_mencoder_opts(self, args):
  55.108 +        args.append(self.mencoder_path)
  55.109 +
  55.110 +        if self.args["type"] and self.args["type"] == "tv":
  55.111 +            self._arg_append(args, self.args["tv"])
  55.112 +        elif self.args["outfile"] == "-" and self.args["type"]:
  55.113 +            args.append(self.args["input"])
  55.114 +        else:
  55.115 +            args.append("-")
  55.116 +
  55.117 +        if self.args["language"]:
  55.118 +            self._arg_append(args, "-alang %s" % self.args["language"])
  55.119 +
  55.120 +        if self.args["subtitle"]:
  55.121 +            self._arg_append(args, "-slang %s" % self.args["subtitle"])
  55.122 +            self._arg_append(args, "-subfps %s" % self.args["fps"])
  55.123 +
  55.124 +        self._arg_append(args, "-idx")
  55.125 +        self._arg_append(args, "-cache 1024")
  55.126 +        self._arg_append(args, self._setup_audio())
  55.127 +        self._arg_append(args, self._setup_video())
  55.128 +
  55.129 +        self._arg_append(args, "-really-quiet")
  55.130 +
  55.131 +        if self.args["outfile"] != "-":
  55.132 +            self.args["outfile"] = ".transcoded/%s" % (
  55.133 +                                   os.path.basename(self.args["outfile"]))
  55.134 +
  55.135 +        self._arg_append(args, "-o %s" % self.args["outfile"])
  55.136 +        self._arg_append(args, "2>%s" % os.devnull)
  55.137 +    # _setup_args()
  55.138 +
  55.139 +    def _setup_filename(self):
  55.140 +        """This function setups the file to encode parsing the uri.
  55.141 +        So, type can be:
  55.142 +        * file
  55.143 +        * dvd
  55.144 +        * myth
  55.145 +
  55.146 +        If the last one is detected we have to parse the uri to find args.
  55.147 +        Then we store all the args inside a dictionary: self.args['gmyth-cat']
  55.148 +        """
  55.149 +        _type = self.args["type"]
  55.150 +
  55.151 +        if _type == "file":
  55.152 +            if not os.path.exists(self.args["input"]):
  55.153 +                raise IOError,\
  55.154 +                      "File requested does not exist: %s." % self.args["input"]
  55.155 +            else:
  55.156 +                self.args["input"] = "file://%s" % self.args["input"]
  55.157 +
  55.158 +        elif _type == "dvd":
  55.159 +            self.args["input"] = "dvd://%s" % self.args["input"]
  55.160 +
  55.161 +        elif _type == "myth":
  55.162 +            self.args["gmyth-cat"] = mythtv._setup_mythfilename(self)
  55.163 +
  55.164 +        elif _type == "tv":
  55.165 +            driver = self.params_first("driver", "v4l2")
  55.166 +            norm = self.params_first("norm", "pal-m")
  55.167 +            channel = self.params_first("channel", "13")
  55.168 +            chanlist = self.params_first("chanlist", "us-bcast")
  55.169 +            outfmt = self.params_first("outfmt", "yuy2")
  55.170 +            vdev = self.params_first("vdev", "/dev/video0")
  55.171 +            adev = self.params_first("adev", "/dev/dsp")
  55.172 +            self.args["tv"] = "tv:// -v -tv driver=%s:norm=%s:channel=%s:" \
  55.173 +                              "chanlist=%s:width=%s:height=%s:outfmt=%s:" \
  55.174 +                              "device=%s:adevice=%s" % (driver, norm,
  55.175 +                                                        channel, chanlist,
  55.176 +                                                        self.args["width"],
  55.177 +                                                        self.args["height"],
  55.178 +                                                        outfmt, vdev, adev)
  55.179 +    # _setup_filename()
  55.180 +
  55.181 +
  55.182 +    def __init__(self, params):
  55.183 +        transcoder.Transcoder.__init__(self, params)
  55.184 +        self.mencoder_opts = []
  55.185 +
  55.186 +        try:
  55.187 +            self._setup_params()
  55.188 +            self._setup_filename()
  55.189 +            self._setup_mencoder_opts(self.mencoder_opts)
  55.190 +        except Exception, e:
  55.191 +            if self.log:
  55.192 +                self.log.error(self.tid, "Error: %s" % e)
  55.193 +            else:
  55.194 +                raise
  55.195 +    # __init__()
  55.196 +
  55.197 +
  55.198 +    def _check_opened_file(self, stdw, _stdin):
  55.199 +        loop = True
  55.200 +        while loop:
  55.201 +            try:
  55.202 +                return open(self.args["outfile"])
  55.203 +            except:
  55.204 +                os.write(stdw, _stdin.read(1024))
  55.205 +    # _check_opened_file
  55.206 +
  55.207 +
  55.208 +    def _start_outfile(self, outfd):
  55.209 +        finished = False
  55.210 +
  55.211 +        # Configuring stdin
  55.212 +        try:
  55.213 +            filename = self.args["input"].split("://")[1]
  55.214 +            _stdin = open(filename)
  55.215 +            size = int(os.path.getsize(filename))
  55.216 +        except Exception, e:
  55.217 +            self.log.error(self.tid, "Error: Mencoder stdin"\
  55.218 +                           " setup error: %s" % e)
  55.219 +            outfd.write("Error: Mencoder stdin setup error: %s" %e)
  55.220 +            return False
  55.221 +
  55.222 +        self.status = 0
  55.223 +        total_read = 0
  55.224 +
  55.225 +        # Configuring pipes
  55.226 +        stdr, stdw = os.pipe()
  55.227 +
  55.228 +        if not self._run_mencoder(input=stdr):
  55.229 +            return False
  55.230 +
  55.231 +        stdout = self._check_opened_file(stdw, _stdin)
  55.232 +        outfd.write("OK   ")
  55.233 +
  55.234 +        try:
  55.235 +            while self.proc and self.proc.poll() == None:
  55.236 +                if not finished:
  55.237 +                    data_in = _stdin.read(4096)
  55.238 +                    if data_in != "":
  55.239 +                        os.write(stdw, data_in)
  55.240 +                        total_read += 4096
  55.241 +                        d = stdout.read(4096)
  55.242 +                        self.status = utils.progress_bar(total_read,
  55.243 +                                                         size, 50)
  55.244 +                    else:
  55.245 +                        finished = True
  55.246 +                        os.close(stdw)
  55.247 +
  55.248 +                else:
  55.249 +                    d = stdout.read(4096)
  55.250 +
  55.251 +        except Exception, e:
  55.252 +            self.log.error(self.tid, "Error: %s" % e)
  55.253 +            self.stop()
  55.254 +            return False
  55.255 +
  55.256 +        self.log.info(self.tid, "OK: Done")
  55.257 +        return True
  55.258 +    # _start_outfile()
  55.259 +
  55.260 +
  55.261 +    def _start(self, outfd):
  55.262 +        # Play a file on disk or DVD
  55.263 +        if not self._run_mencoder(output=subprocess.PIPE):
  55.264 +            return False
  55.265 +
  55.266 +        try:
  55.267 +            while self.proc and self.proc.poll() == None:
  55.268 +                d = self.proc.stdout.read(1024)
  55.269 +                outfd.write(d)
  55.270 +        except Exception, e:
  55.271 +            self.log.error(self.tid, "Error: %s" % e)
  55.272 +            return False
  55.273 +
  55.274 +        self.log.info(self.tid, "OK: Done")
  55.275 +        return True
  55.276 +    # _start()
  55.277 +
  55.278 +    def _run_mencoder(self, input=None, output=None):
  55.279 +        try:
  55.280 +            self.proc = subprocess.Popen(self.mencoder_opts, stdin=input,
  55.281 +                                         stdout=output, close_fds=True)
  55.282 +        except Exception, e:
  55.283 +            self.log.error(self.tid, "Error: Mencoder: %s" % e)
  55.284 +            return False
  55.285 +
  55.286 +        return True
  55.287 +    # _run_mencoder()
  55.288 +
  55.289 +    def start(self, outfd):
  55.290 +        cmd = " ".join(self.mencoder_opts)
  55.291 +        self.log.debug(self.tid, "Plugin's tid: %s" % self.tid)
  55.292 +        self.log.debug(self.tid, "Mencoder: %s" % cmd)
  55.293 +
  55.294 +        ret = False
  55.295 +
  55.296 +        if self.args["outfile"] == "-" and \
  55.297 +               self.args["type"] in ["file", "dvd", "tv"]:
  55.298 +            ret = self._start(outfd)
  55.299 +
  55.300 +        elif self.args["type"] == "myth":
  55.301 +            ret = mythtv.start_myth(self, outfd)
  55.302 +
  55.303 +        else:
  55.304 +            ret = self._start_outfile(outfd)
  55.305 +
  55.306 +        self.stop()
  55.307 +
  55.308 +        if not ret:
  55.309 +            self.log.error(self.tid, "Error: Problems while "\
  55.310 +                           "starting streaming.")
  55.311 +
  55.312 +        return ret
  55.313 +    # start()
  55.314 +
  55.315 +    def _aux_stop(self, obj, next=False):
  55.316 +        if obj:
  55.317 +            try:
  55.318 +                os.kill(obj.pid, signal.SIGKILL)
  55.319 +                if next:
  55.320 +                    os.kill(obj.pid+1, signal.SIGKILL)
  55.321 +            except OSError, e:
  55.322 +                pass
  55.323 +
  55.324 +            try:
  55.325 +                obj.wait()
  55.326 +            except Exception, e:
  55.327 +                pass
  55.328 +
  55.329 +            obj = None
  55.330 +    # _aux_stop
  55.331 +
  55.332 +    def stop(self):
  55.333 +        self._aux_stop(self.proc, True)
  55.334 +        self._aux_stop(self.gmyth)
  55.335 +    # stop()
  55.336 +
  55.337 +# TranscoderMencoder
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/gmyth-stream/server/plugins/transcoders/mencoder_lib/mythtv.py	Wed Aug 29 14:42:10 2007 +0100
    56.3 @@ -0,0 +1,109 @@
    56.4 +import os
    56.5 +import subprocess
    56.6 +import fcntl
    56.7 +
    56.8 +import lib.utils as utils
    56.9 +import lib.server as server
   56.10 +
   56.11 +from select import select
   56.12 +
   56.13 +def _setup_mythfilename(self):
   56.14 +    # mythtv:mythtv@192.168.3.110:6543/1002_20070426230000.nuv
   56.15 +    try:
   56.16 +        _mysql = self.args["input"].split("@")[0].split(":")
   56.17 +    except IndexError, e:
   56.18 +        _mysql = ["mythtv", "mythtv"]
   56.19 +
   56.20 +    try:
   56.21 +        _args = self.args["input"].split("@")[1].split(":")
   56.22 +    except IndexError, e:
   56.23 +        _args = self.args["input"].split(":")
   56.24 +
   56.25 +    gmyth_dict = {}
   56.26 +    gmyth_dict["mysql"] = _mysql
   56.27 +    gmyth_dict["backend"] = _args[0]
   56.28 +    gmyth_dict["port"] = _args[1].split("/", 1)[0]
   56.29 +
   56.30 +    _tmp_file = _args[1].split("/", 1)[1]
   56.31 +
   56.32 +    if _tmp_file.find("channel") >= 0:
   56.33 +        gmyth_dict["kind"] = "c"
   56.34 +        gmyth_dict["cfile"] = _tmp_file.split("=")[1]
   56.35 +    else:
   56.36 +        gmyth_dict["kind"] = "f"
   56.37 +        gmyth_dict["cfile"] = _tmp_file
   56.38 +
   56.39 +    self.args["input"] = "-"
   56.40 +    return gmyth_dict
   56.41 +# _setup_mythfilename
   56.42 +
   56.43 +def _setup_mythfile(err):
   56.44 +    size = err.readline().split("Size:")[1]
   56.45 +    flags = fcntl.fcntl (err, fcntl.F_GETFL, 0) | os.O_NONBLOCK
   56.46 +    fcntl.fcntl(err, fcntl.F_SETFL, flags)
   56.47 +    return size
   56.48 +# _setup_mythfile
   56.49 +
   56.50 +def _setup_gmythcat(self):
   56.51 +    gmyth_cat = utils.which("gmyth-cat")
   56.52 +    if self.args.has_key("gmyth-cat"):
   56.53 +        return [ utils.which("gmyth-cat"),
   56.54 +                 "-h", self.args["gmyth-cat"]["backend"],
   56.55 +                 "-p", self.args["gmyth-cat"]["port"],
   56.56 +                 "-" + self.args["gmyth-cat"]["kind"],
   56.57 +                 self.args["gmyth-cat"]["cfile"]
   56.58 +                 ]
   56.59 +    else:
   56.60 +        self.log.error(self.tid, "Error: URI error")
   56.61 +        return []
   56.62 +# _setup_gmythcat
   56.63 +
   56.64 +def start_myth(self, outfd):
   56.65 +    opts = _setup_gmythcat(self)
   56.66 +    try:
   56.67 +        self.gmyth = subprocess.Popen(opts, stdout=subprocess.PIPE,
   56.68 +                                      stderr=subprocess.PIPE,
   56.69 +                                      close_fds=True)
   56.70 +    except Exception, e:
   56.71 +        self.log.error(self.tid, "Error: gmyth-cat: %s" % e)
   56.72 +        return False
   56.73 +
   56.74 +    if not self._run_mencoder(input=self.gmyth.stdout,
   56.75 +                              output=subprocess.PIPE):
   56.76 +        return False
   56.77 +
   56.78 +    if self.args["gmyth-cat"]["kind"] == "f":
   56.79 +        try:
   56.80 +            size = _setup_mythfile(self.gmyth.stderr)
   56.81 +            self.log.debug(self.tid, "Info: Size of file: %s" % size)
   56.82 +        except Exception, e:
   56.83 +            self.log.error(self.tid, "Error: Problems getting size of"\
   56.84 +                           " file: %s" % e)
   56.85 +            outfd.write("Error: Problems getting size of file: %s" % e)
   56.86 +            return False
   56.87 +
   56.88 +    outfd.write("OK     ")
   56.89 +
   56.90 +    try:
   56.91 +        while self.proc and self.proc.poll() == None:
   56.92 +            r, w, x = select([self.gmyth.stderr, self.proc.stdout],
   56.93 +                             [], [], 0)
   56.94 +            if self.proc.stdout in r:
   56.95 +                d = self.proc.stdout.read(4096)
   56.96 +                outfd.write(d)
   56.97 +
   56.98 +            if self.gmyth.stderr in r:
   56.99 +                partial = self.gmyth.stderr.readline()
  56.100 +                if partial != "":
  56.101 +                    self.status = utils.progress_bar(int(partial),
  56.102 +                                                     int(size), 50)
  56.103 +
  56.104 +    except IndexError, e:
  56.105 +        pass
  56.106 +    except Exception, e:
  56.107 +        self.log.error(self.tid, "Error: %s" % e)
  56.108 +        return False
  56.109 +
  56.110 +    self.log.info(self.tid, "OK: Done")
  56.111 +    return True
  56.112 +# _start_myth()
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/gmyth-stream/server/server.conf	Wed Aug 29 14:42:10 2007 +0100
    57.3 @@ -0,0 +1,2 @@
    57.4 +[PATHS]
    57.5 +transcoded=./.transcoded
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/gmyth-stream/server/setup.py	Wed Aug 29 14:42:10 2007 +0100
    58.3 @@ -0,0 +1,17 @@
    58.4 +from distutils.core import setup
    58.5 +from glob import glob
    58.6 +
    58.7 +setup(name='gms',
    58.8 +      version='0.6',
    58.9 +      description='carman rich view package',
   58.10 +      long_description='carman rich view (SDL based) package',
   58.11 +      url='http://www.indt.org.br',
   58.12 +      scripts=['gms.py'],
   58.13 +      package_dir={'lib': 'lib', 'plugins' : 'plugins','data' : 'data' },
   58.14 +      packages=['lib','plugins','plugins.transcoders','plugins.transcoders.mencoder_lib'],
   58.15 +      data_files = [
   58.16 +               ('share/gms/html', glob("html/*")),
   58.17 +               ('etc/init.d', ['data/gmsd']),
   58.18 +               ('etc/gms', ['data/server.conf'])
   58.19 +               ],
   58.20 +      )