GIT repositories

Index page of all the GIT repositories that are clonable form this server via HTTPS. Übersichtsseite aller GIT-Repositories, die von diesem Server aus über git clone (HTTPS) erreichbar sind.

Services

A bunch of service scripts to convert, analyse and generate data. Ein paar Services zum Konvertieren, Analysieren und Generieren von Daten.

GNU octave web interface

A web interface for GNU Octave, which allows to run scientific calculations from netbooks, tables or smartphones. The interface provides a web form generator for Octave script parameters with pre-validation, automatic script list generation, as well presenting of output text, figures and files in a output HTML page. Ein Webinterface für GNU-Octave, mit dem wissenschaftliche Berechnungen von Netbooks, Tablets oder Smartphones aus durchgeführt werden können. Die Schnittstelle beinhaltet einen Formulargenerator für Octave-Scriptparameter, mit Einheiten und Einfabevalidierung. Textausgabe, Abbildungen und generierte Dateien werden abgefangen und in einer HTML-Seite dem Nutzer als Ergebnis zur Verfügung gestellt.

Mediastream Download Klasse

Media stream download class

This class is an easy to use wrapper around the commandline programm mimms, which must be installed on your (*nix) system. See the example how to use it.

Diese Klasse ist um das Kommandozeilenprogramm mimms gestrickt, welches auf dem (*nix) System installiert sein muss. Ein Blick in das nachfolgende Beispiel verrät wie es funktioniert:

Sample source code

Anwendungsbeispiel

<?php
include_once('swlib/swlib.class.php');
 
use sw\MediaStreamLoader;
 
// Class configuration. This config is used for all instances.
MediaStreamLoader::config(array(
  'mimms-bin' => '/usr/bin/mimms',
  'default-download-directory' => '/tmp'
));
 
// Instantiate
$mimms = new MediaStreamLoader();
 
// Set a callback for the progress if you like ...
$mimms->setProgressCallback(function(array $progress){
  //
  // $progress['progress']  : The progress from 0 to 1 (not in percent)
  // $progress['loaded']    : Bytes loaded
  // $progress['total']     : Total bytes that have to be loaded
  // $progress['remaining'] : Remaining time in seconds
  //
  print "Progress: {$progress['progress']} | " .
        "Loaded {$progress['loaded']}/{$progress['total']} | " .
        "Remaining: {$progress['remaining']}" .
        "\n";
});
 
// The stream you like to fetch. It MUST start with mms://
$mimms->setStreamUrl('mms:// [...] .wmv');
 
// Dsbug: Say we're starting
print "[STARTING]\n";
 
// Start the download
$details = $mimms->download();
 
// We're finished
print "[FINISHED]\n\n";
 
// The variable $detaile contains everything you need to know about the success
// and result of the process ...

Output

Ausgabe

$ php mimms.test.php
[STARTING]
Progress: 0 | Loaded 244316/531816775 | Remaining: 22769
Progress: 0.001 | Loaded 463472/531816775 | Remaining: 12706
Progress: 0.001 | Loaded 683673/531816775 | Remaining: 9134
Progress: 0.002 | Loaded 903874/531816775 | Remaining: 7209
Progress: 0.002 | Loaded 1163919/531816775 | Remaining: 5929
Progress: 0.003 | Loaded 1352663/531816775 | Remaining: 5296
Progress: 0.003 | Loaded 1562378/531816775 | Remaining: 4802
Progress: 0.003 | Loaded 1793064/531816775 | Remaining: 4393
Progress: 0.004 | Loaded 2013265/531816775 | Remaining: 4088
Progress: 0.004 | Loaded 2243952/531816775 | Remaining: 3839
Progress: 0.005 | Loaded 2453667/531816775 | Remaining: 3635
Progress: 0.005 | Loaded 2673868/531816775 | Remaining: 3479
Progress: 0.005 | Loaded 2873098/531816775 | Remaining: 3364
Progress: 0.006 | Loaded 3103784/531816775 | Remaining: 3252
Progress: 0.006 | Loaded 3323985/531816775 | Remaining: 3152
Progress: 0.007 | Loaded 3544186/531816775 | Remaining: 3063
Progress: 0.007 | Loaded 3764387/531816775 | Remaining: 3008
Progress: 0.007 | Loaded 3984588/531816775 | Remaining: 2962
Progress: 0.008 | Loaded 4204789/531816775 | Remaining: 2905
Progress: 0.008 | Loaded 4435476/531816775 | Remaining: 2837
Progress: 0.009 | Loaded 4645191/531816775 | Remaining: 2815
Progress: 0.009 | Loaded 4865392/531816775 | Remaining: 2775
Progress: 0.01 | Loaded 5075107/531816775 | Remaining: 2764
Progress: 0.01 | Loaded 5295308/531816775 | Remaining: 2736
Progress: 0.01 | Loaded 5525995/531816775 | Remaining: 2711
Progress: 0.011 | Loaded 5756682/531816775 | Remaining: 2657
Progress: 0.011 | Loaded 5955911/531816775 | Remaining: 2660
Progress: 0.012 | Loaded 6165626/531816775 | Remaining: 2651

[...]

Progress: 1 | Loaded 531816775/531816775 | Remaining: 0
[FINISHED]

Class source code

Klassen-Quelltext

<?php
 
/**
 * Exceptions for MIMMS media stream downloader class
 *
 * @gpackage de.atwillys.sw.php.swLib
 * @author Stefan Wilhelm
 * @copyright Stefan Wilhelm, 2007-2012
 * @license GPL
 * @version 1.0
 */
namespace sw;
 
class MediaStreamLoaderException extends LException {
 
}
<?php
 
/**
 * MIMMS media stream downloader class
 *
 * @gpackage de.atwillys.sw.php.swLib
 * @author Stefan Wilhelm
 * @copyright Stefan Wilhelm, 2007-2012
 * @license GPL
 * @version 1.0
 */
 
namespace sw;
 
class MediaStreamLoader {
 
  /**
   * Class configuration
   * @var array
   */
  protected static $config = array(
      'mimms-bin' => '/usr/bin/mimms',
      'time-limit' => 0,
      'default-download-directory' => '/tmp'
  );
 
  /**
   * The progress callback function/method reference.
   * @var mixed
   */
  private $progressCallback = null;
 
  /**
   * Contains the url of the multimedia stream
   * @var string
   */
  protected $streamUrl = '';
 
  /**
   * Contains the path of the output file
   * @var string
   */
  protected $outputFile = '';
 
  /**
   * Returns the class configuration. If a configuration array is given, modifies
   * the configuration by key merging.
   * @param array $config
   * @return array
   */
  public static final function config(array $config = array()) {
    if (!empty($config)) {
      self::$config = array_merge(self::$config, $config);
      Tracer::trace_r($config, '$config', 3);
    }
 
    if (empty(self::$config['mimms-bin']) || !FileSystem::isFile(self::$config['mimms-bin']) || !FileSystem::isExecutable(self::$config['mimms-bin'])) {
      $mimms = trim(exec('which mimms'), "\t\n\r ");
      Tracer::trace("mimms binary search result (which mimms)=$mimms", 2);
      if (empty($mimms)) {
        throw new MediaStreamLoaderException("Your configutation is incorrect: can't find the mimms binary: :binary", array(':binary' => self::$config['mimms-bin']));
      } else {
        Tracer::trace("Warning: The configured mimms binary path is wrong (" . self::$config['mimms-bin'] . "), but found binary '$mimms'");
      }
      self::$config['mimms-bin'] = $mimms;
    }
    return self::$config;
  }
 
  /**
   * Converts string data size formats to SI (e.g. 100K to 100000)
   * @param string $text
   * @return int
   */
  protected function sizeToBytes($text) {
    if (preg_match('/([\d\.]+)[\s]*([\w]*)/i', $text, $matches)) {
      array_shift($matches);
      $n = doubleval(reset($matches));
      $u = strtolower(trim(end($matches)));
      if (strlen($u) > 1)
        $u = substr($u, 0, 1);
      switch ($u) {
        case 't': $n *= 1024;
        case 'g': $n *= 1024;
        case 'm': $n *= 1024;
        case 'k': $n *= 1024;
      }
      return intval($n);
    } else {
      return false;
    }
  }
 
  /**
   * Converts a time duration string (e.g. "01:45:00.0") to seconds
   * @param string $timeString
   * @return int
   */
  protected function timeToSeconds($timeString) {
    $timeString = explode(':', $timeString);
    $t = 0;
    foreach (array_reverse($timeString) as $k => $v) {
      $t += $v * pow(60, $k);
    }
    return $t;
  }
 
  /**
   * Sets the progress callback. The function/method pattern has to be as
   * function(array $progress) { ... }
   * @param mixed $callback
   */
  public function setProgressCallback($callback) {
    if (empty($callback)) {
      $this->progressCallback = null;
    } else if (!is_callable($callback)) {
      throw new MediaStreamLoaderException('Specified progress callback is not callable.');
    } else {
      $this->progressCallback = $callback;
    }
  }
 
  /**
   * Sets the stream URI to download
   * @param string $url
   */
  public function setStreamUrl($url) {
    $this->streamUrl = trim($url);
  }
 
  /**
   * Returns the URI of the stream
   * @return string
   */
  public function getStreamUrl() {
    return $this->streamUrl;
  }
 
  /**
   * Returns the file basename that the stream url contains
   * @return string
   */
  public function getStreamFileName() {
    return FileSystem::getBasename(parse_url($this->streamUrl, PHP_URL_PATH));
  }
 
  /**
   * Sets the output file path
   * @param string $path
   */
  public function setOutputFile($path) {
    $this->outputFile = trim($path);
  }
 
  /**
   * Returns the output file path
   * @return string
   */
  public function getOutputFile() {
    return $this->outputFile;
  }
 
  /**
   * Internal ShellProcess onStdOut/inStdErr callback
   * @param string& $text
   */
  public function onStdOutCallback(&$text) {
    $this->lastOutputTime = time();
    $passthrough = array();
    $progress = '';
 
    foreach (explode("\n", trim($text, "\n\r\t ")) as $t) {
      if (stripos($t, 'remaining') !== false) {
        $progress = $t;
      } else {
        $passthrough[] = $t;
      }
    }
    $text = implode("\n", $passthrough);
 
    if (!empty($progress) && !empty($this->progressCallback)) {
      list($loaded, $progress) = explode('/', $progress, 2);
      list($toload, $progress) = explode('(', $progress, 2);
      list($rate, $progress) = explode(',', $progress, 2);
      $rmtime = trim(str_replace(')', '', $progress));
      $progress = array(
          'progress' => round($this->sizeToBytes($loaded) / $this->sizeToBytes($toload), 3),
          'loaded' => $this->sizeToBytes($loaded),
          'total' => $this->sizeToBytes($toload),
          'speed' => $this->sizeToBytes($rate),
          'remaining' => $this->timeToSeconds(str_replace(array('remaining', ' '), '', $rmtime))
      );
      call_user_func($this->progressCallback, $progress);
    }
  }
 
  /**
   * 
   */
  public function onProcessRunningCallback() {
    if (isset($this->lastOutputTime)) {
      if (time() - $this->lastOutputTime > 60) {
        throw new MediaStreamLoaderException('mimms was hanging');
      }
    }
    return true;
  }
 
  /**
   * Downloads the stream
   */
  public function download() {
    if (empty($this->streamUrl)) {
      throw new MediaStreamLoaderException("No stream URI specified.");
    } else if (empty($this->outputFile)) {
      $this->outputFile = FileSystem::getBasename(parse_url($this->streamUrl, PHP_URL_PATH));
    }
 
    if (empty($this->outputFile)) {
      throw new MediaStreamLoaderException("Could not determine output file path from URI ':uri'", array(':uri' => $this->streamUrl));
    } else if (strpos($this->outputFile, '/') !== 0) {
      if (!FileSystem::isDirectory(self::$config['default-download-directory'])) {
        throw new MediaStreamLoaderException("Download directory does not exist: ':dir'", array(':dir' => self::$config['default-download-directory']));
      } else if (!FileSystem::isWritable(self::$config['default-download-directory']) || !FileSystem::isExecutable(self::$config['default-download-directory'])) {
        throw new MediaStreamLoaderException("Download directory is not writable: ':dir'", array(':dir' => self::$config['default-download-directory']));
      }
      $this->outputFile = self::$config['default-download-directory'] . '/' . $this->outputFile;
    }
 
    if (FileSystem::isFile($this->outputFile)) {
      throw new MediaStreamLoaderException("Output file exists already: ':file'", array(':file' => $this->outputFile));
    }
 
    $cmd = self::$config['mimms-bin'] . ' ' . escapeshellarg($this->streamUrl) . ' ' . escapeshellarg($this->outputFile) . ' 2>&1';
    $proc = new ShellProcess();
    $proc->setCommand($cmd);
    $proc->setCallbacks(array('onStdOut' => array($this, 'onStdOutCallback'), 'onprocessrunning' => array($this, 'onProcessRunningCallback')));
    $proc->setTerminateOnAbort(true);
    $proc->setTimeout(self::$config['time-limit']);
    $proc->setFetchOutput(true);
    $proc->run();
 
    Tracer::trace_r($proc, '$proc', 2);
    return $proc->getStdOut();
  }
 
}