IO – Zone | Developing & Experience in IT Systems

Vielleicht kennt Ihr das auch. Ihr möchtet Änderungen an dem Inhalt bestimmter Webseiten erkennen aber Ihr wollt nicht jeden Tag diese Webseite besuchen und ein RSS oder Atom Feed wird nicht angeboten. Nun gibt es ja Firefox AddOns wie z.B. den Update Scanner welchen man sich installieren kann. Doch was wenn man dann mal mit einem anderen Browser surft. Hm schwierig.

Das dachte ich mir auch als eine Firma mich bat, den Inhalt Ihrer Webseite ständig auf Änderungen zu überprüfen. Da ich allerdings großes Interesse an den Veranstaltungen und Aktivitäten dieses Unternehmens habe und daher nichts verpassen wollte, habe ich mir ein recht simples aber praktikables Bashscript programmiert. Das ist allerdings so einfach das es sich evtl. garnicht wirklich lohnt einen Eintrag darüber zu schreiben :-) .

Das Script bemerkt Änderungen an dem Inhalt einer Webseite und sendet anschließend eine Email mit dem Link zu dieser Webseite.

Ihr benötigt zu dem Script eine Liste in der Ihr die Links ablegt die überwacht werden sollen. Das Script geht jeden Eintrag in der Liste durch. Lädt dabei die Webseite herunter, erzeugt eine MD5 Summe von dem Inhalt und sendet eine Email, falls sich die MD5 Summe seit dem letzten Durchlauf geändert hat. Mögliche MD5 Kollosionen werden in diesem Script nicht beachtet ;-) .

Anschließend nur noch das Script als cronjob eintragen und schon ist das Helferlein fertig. Wer denkt das es eine geniale Idee sei und man das als Webservice anbieten sollte, dem programmiere ich natürlich auch eine professionelle Version mit XML, PHP o.a., Datenbankanbindung etc.

Die Liste sieht z.B. so aus:

0 | Wiki MD5 | http://de.wikipedia.org/wiki/Message-Digest_Algorithm_5
0 | Heise | http://www.heise.de/

Hier das Script:

#!/bin/bash

basedir="/home/raeder/scripte/watchnremind/"
watchfile="${basedir}watchlist" # Name der Liste in der die Links enthalten sind
tmpfile="${watchfile}.tmp"

mailto="Stephan.Raeder@gmx.net"

htmlfile="${basedir}htmltemp.html"

rm -v $tmpfile

cat "$watchfile" | while read entry
do
   md5sum=`echo $entry | cut -f1 -d"|" | tr -c -d [:xdigit:]`
   title=`echo $entry | cut -f2 -d"|" | sed 's/^\s\+\|\s\+$//g'`
   link=`echo $entry | cut -f3- -d"|" | sed 's/^\s\+\|\s\+$//g'`

   echo "Checking $title Url: $link"
   rm -v $htmlfile
   wget -q -O "$htmlfile" "$link"

   if [ -f "$htmlfile" ]
   then
      newmd5sum=`md5sum "$htmlfile" | cut -f1 -d" "| tr -c -d [:xdigit:]`
      if [ $newmd5sum != $md5sum ]
      then
         echo "Update on Page $link detected." | mail -s "Watch'n'Remind: Update for $title" "$mailto"
         md5sum=$newmd5sum
      fi
   else
      echo "Error while checking $title with Url: $link" | mail -s "Watch'n'Remind: Error for $title" "$mailto"
   fi

   echo -e "\n"

   echo "$md5sum | $title | $link" >> "$tmpfile"
done

mv -v "$tmpfile" "$watchfile"

, , , , ,

Als ich mir vor einigen Tagen ein Play-It von Half-Life2 auf Youtube angeschaut habe, hab ich dabei das vertragliche Downloadlimit von T-Mobile (Web’n'Walk Tarif) über 5GB/Monat überschritten. Sobald das passiert, wird man auf 64kbits gedrosselt. Dazu muss ich allerdings sagen das, dass Kontingent schon mit 2GB vorbelastet war. Insgesamt beinhaltet das Play-It 63 einzelne Videos. Das Streamen von solchen Videokollektionen ist natürlich nicht sehr vorteilhaft bei den Vertragskonditionen. Die 5GB waren recht schnell aufgebraucht und nun surfe ich bis zum Ende des Monats mit 64kbit.

Also habe ich mir gedacht ..da muss eine Lösung her. Warum nicht einfach die Videos auf den Rechner laden wenn man Zugriff zu kostenlosem und unlimtiertem Internet hat wie z.B. bei:

Anschließend kann man dann die Videos zuhause auf dem Rechner schauen, ohne Internettraffic zu verschwenden.

Die Software habe ich mit Hilfe der Youtube Data API und dem ZEND Framework entwickelt. Den Download der Videofiles bietet die API nicht an. Da habe ich mir die paar Codezeilen von Michael Kamleitner und Sajith M.R zu Nutze gemacht.Thanks.

Ihr braucht zum Benutzen also eigentlich nur das Zend Framework mit der API. Ausserdem muss noch die Einstellung “allow_url_fopen = On” in der php.ini gesetzt sein.

Die Software ruft Ihr wie folgt auf:

  1. ID der Youtube Playlist suchen (bei http://www.youtube.com/view_play_list?p=4CFA1E9436B68AB2 ist das 4CFA1E9436B68AB2)
  2. Danach dann ein Verzeichnis mit dem Namen “flvs” erzeugen, das muss in dem selben  Verzeichnis sein wo auch die zwei PHP Dateien liegen
  3. dann das Script aufrufen. Da ich eine spezielle PHP Config habe wo ich “allow_url_fopen = On” gesetzt ist, muss ich Diese noch mit angeben. Sieht dann so aus: php –php-ini /home/raeder/php.ini -f ./getPlaylist.php 4CFA1E9436B68AB2
  4. Ansonsten könnt ihr auch das Script per php -f ./getPlaylist.php 4CFA1E9436B68AB2 oder ./getPlaylist.php 4CFA1E9436B68AB2 aufrufen

In dem Ordner “./flvs” werden die Files nun gespeichert.

Die Ausgabe sieht dann etwa so aus:

Entry # 41
Download:
Video: Lets play Half-Life 2 #41 german
Video ID: _4_sb3qb82Y
File downloaded after 463.961102962 seconds. Bandwidth: 48.6375338019 Kbyte/s

Viel Spaß mit dem Tool

Anbei dann der Quelltext als Text und Attachment.

#!/usr/bin/php
<?php

set_include_path('/home/raeder/ZendFramework-1.9.7/library/' . PATH_SEPARATOR. get_include_path());
require_once ("PHPTube.php");
require_once 'Zend/Loader.php'; // the Zend dir must be in your include_path
Zend_Loader::loadClass('Zend_Gdata_YouTube');
Zend_Loader::loadClass('Zend_Gdata_Query');

$playlistId = @$argv[1];
if ( empty($playlistId)) {
        die("Playlist Id not specified.");
}

$yt = new Zend_Gdata_YouTube();
$phpTube = new PHPTube ();
// optionally set version to 2 to retrieve a version 2 feed
$yt->setMajorProtocolVersion(2);

$videoFeed = $yt->getVideoFeed("http://gdata.youtube.com/feeds/api/playlists/". $playlistId);
$count = 1;
while ( $videoFeed != null ) {
        foreach ($videoFeed as $videoEntry) {
                echo "Entry # " . $count . "\n";
                getVideoEntry($videoEntry, $count++);
                echo "\n";
        }

        try {
                $videoFeed = $videoFeed->getNextFeed();
        } catch (Exception $e) {
                break;
        }
}

function getVideoEntry($videoEntry, $No) {
        global $phpTube;
        // the videoEntry object contains many helper functions
        // that access the underlying mediaGroup object
        echo "Download:\n";
        echo 'Video: ' . $videoEntry->getVideoTitle() . "\n";
        echo 'Video ID: ' . $videoEntry->getVideoId() . "\n";

        $id = $videoEntry->getVideoId();
        $flv_http_path = $phpTube->resolveFlvPath($id) ;
        $filename = dirname(_FILE)."/flvs/Youtube_File_No_". $No ."_". $id .".flv";

        $started = microtime(true);
        $streamRead = fopen($flv_http_path, "r") or die("Can't open $flv_http_path for reading");
        $streamWrite = fopen($filename, "w") or die("Can't open $filename for writing");

        $bufferLength = 5 * 1024 * 1024;
        while ( !feof($streamRead) ) {
                fwrite($streamWrite, fread($streamRead, $bufferLength));

        fclose($streamWrite);
        fclose($streamRead);
        $diff = microtime(true)-$started;

        echo "File downloaded after ". $diff ." seconds. Bandwidth: ". (((float)filesize($filename)/1024.0)/$diff) ." Kbyte/s\n";
}

?>

Und hier die überarbeitete Version des PHPTube. Das PEAR Framework und unnötige Variablen wurden entfernt.

class PHPTube {

private $client;

function PHPTube () {
$this->client = new Zend_Http_Client('http://example.org', array(
'maxredirects' => 0,
'timeout'      => 30,
'useragent' => 'Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'));
}

public function resolveFlvPath ($video_id) {
$url = "http://www.youtube.com/watch?v=".$video_id;
$this->client->setUri($url);
$this->client->setMethod(Zend_Http_Client::GET);
$response = $this->client->request();
if ($response->isError()) {
echo "Error transmitting data.\n";
echo "Server reply was: " . $response->getStatus() ." " . $response->getMessage() . "\n";
} else {
$page = $response->getBody();
//preg_match('/watch_fullscreen\?video_id=(.*?)&l=(.*?)+&t=(.*?)&/', $page, $match);
preg_match('/"video_id": "(.*?)"/', $page, $match);
$var_id = $match[1];

preg_match('/"t": "(.*?)"/', $page, $match);
$var_t = $match[1];
$url = "";
$url .= $var_id;
$url .= "&t=";
$url .= $var_t;
return  "http://www.youtube.com/get_video?video_id=".$url;
}
}

}

, , , , , , ,

In Zusammenhang mit meinem PHP FTP Upload Script brauchte ich ein Script welches mir verschiedene Dateien auch per Mail versendet. Dies ist mit dem PEAR Framework sehr leicht zu realisieren.

Wie man PEAR auf einem shared Host System installiert (wie das bei mir der Fall war) findet Ihr hier.

Zusätzlich benötigt Ihr noch das Package Mail_Mime.

Installation:

~$ pear install Mail_mime

PEAR_Mail dient als Overlay für verschiedene MTAs und unterstützt dabei:

  • sendmail,
  • mail (das hab ich benutzt) oder
  • smtp (eigene MTA Implementierung von PEAR)

Mehr dazu hier: http://pear.php.net/manual/en/package.mail.mail.factory.php

Mit dem which Befehl von Linux kann man prüfen welchen MTA man benutzen kann. Notfalls kann man PEAR immernoch “smtp” benutzen lassen.

~$ which mail
/usr/bin/mail
~$

Nachdem alles installiert ist braucht Ihr nur noch das Script euren Bedürfnissen anzupassen und dann gehts auch schon los. Anbei noch eine kurzes Example:

./send.php mailto="Stephan.Raeder@gmx.net" subject="Mail mit Attachment "`date` file[]="datei1.txt" file[]="datei2.txt"

Hier der Quellcode:

#!/usr/bin/php
<?php
// PEAR einbinden
set_include_path('/home/raeder/pear/pear/php/' . PATH_SEPARATOR. get_include_path());
include('Mail.php');
include('Mail/mime.php');

// Eingabevariablen prüfen
$subject = @$_GET['subject'];
$files = @$_GET['file'];
$mailto = @$_GET['mailto'];

if ( empty($subject) ) {
        die("Subject not defined\n");
}

if ( empty($mailto) ) {
        die("Mailto not defined\n");
}

if ( count($files) == 0 ) {
        die("No Files defined\n");
}

$recipients = $mailto;

$headers['From']    = 'Stephan.Raeder@gmx.net';
$headers['To']      = $mailto;
$headers['Subject'] = $subject;

$body = 'Mail Inhalt';

// Mail erstellen
$mime = new Mail_mime("\n");
$mime->setTXTBody($body); // Textinhalt
// Anhänge hinzufügen
foreach ($files as $file ) {
        if ( is_file($file) ) {
                $mime->addAttachment($file, 'text/html');
        } else {
                die($file ." is not a file\n");
        }
}

$body = $mime->get();
$hdrs = $mime->headers($headers);

// MTA auswählen und senden
$mail =& Mail::factory('mail');
$res = $mail->send($recipients, $hdrs, $body);

if (PEAR::isError($res)) {
        die("Error: ". $res->getMessage() ."\n");
} else {
        echo "Mail sucessfully sent\n";
}

?>

, , ,

Jan/10

16

FTP Upload via PHP

Um verschiedene Dateien per FTP hochzuladen habe ich mir ein kleines PHP Script geschrieben. Mit Hilfe des PEAR Frameworks ist das auch nicht sonderlich kompliziert. Wir man PEAR in einem Shared Host System installiert findet Ihr hier.

Zusätzlich benötigt Ihr noch das Package Net_FTP.

Installation:

~$ pear install Net_FTP

Noch eine kurze Erklärung wie man das Script nun aufruft:

./ftp_put.php "file[]=diehochzuladendeDatei.txt" "file[]=eineandereDatei.txt"

Anbei dann mal der Quelltext dafür

#!/usr/bin/php
<?php
// PEAR einbinden
set_include_path('/home/raeder/pear/pear/php/' . PATH_SEPARATOR. get_include_path());
require_once 'Net/FTP.php';

$host = "";
$username = "";
$pass = "";
$targetDirectory = "";

// Files auswerten
$files = @$_GET['file'];
if ( count($files) == 0 ) {
        die("Error. No files specified.");
} else {
        foreach ( $files as $file ) {
                if ( ! is_file($file) || ! is_readable($file) ) {
                        die("File: $file is not readable");
                }
        }
}

// Verbindung zum FTP Server herstellen
$ftp = new Net_FTP();
$res = $ftp->connect($host, 21);
if (PEAR::isError($ftp)) {
        die("Can't connect to ftp. Error: ". $ftp->getMessage() ."\n");
}

// Login zum FTP
$res = $ftp->login($username, $pass);
if (PEAR::isError($res)) {
        $ftp->disconnect();
        die("Can't login to ftp. Error: ". $res->getMessage() ."\n");
}

// Aktuelles Verzeichnis wechseln
$res = $ftp->cd($targetDirectory);
if (PEAR::isError($res)) {
        $ftp->disconnect();
        die("Can't change Directory. Error: ". $res->getMessage() ."\n");
}

// Dateien hochladen
foreach ( $files as $file ) {
        $res = $ftp->put($file, basename($file), true, FTP_BINARY);
        if (PEAR::isError($res)) {
                $ftp->disconnect();
                die("Can't Upload File $file . Error: ". $res->getMessage() ."\n");
        } else {
                echo "File $file uploaded";
        }
}

// Verbindung trennen
$ftp->disconnect();

?>

, ,

Hallo,

ich hab im Rahmen des Semiars “Präsentationstechnik” an der h_da eine Kurzpräsentation über das Thema “Computertechnologie zur Unterstützung
von Menschen mit Behinderung” erstellt.

Da gehts z.B. auch über das Thema BCI – Brain Computer Interface. Was ich echt toll finde. Anbei ein paar Links dazu:

http://www.bbci.de/

http://www.aksioma.org/brainloop/index.html

Ping Pong über BCI: http://www.youtube.com/watch?v=qCSSBEXBCbY

Friend-II Projekt der UNI Bremen: http://www.iat.uni-bremen.de/sixcms/detail.php?id=589

Hier die Präsentation: Präsentation PDF

Viel Spaß damit.

Stephan

, ,

Dec/09

11

Bugzilla to RSS Feed

Hallo,

ich habe heute durch http://www.infoq.com/news/2009/12/Google-Chrome-News erfahren das es nun im Rahmen von Cromium OS eine Linux Version von dem Chrome Browser geben wird.

Leider ist die Entwicklung noch im Beta Stadium. Hier findet man den Status aus dem Gentoo Portage Tree: https://bugs.gentoo.org/show_bug.cgi?id=272805

Ich fänd es schön wenn man die Änderungen im Bugzilla wie in einem RSS nachvollziehen könnte. Daher habe ich einen Service geschrieben der dies generell für Bugzilla Webseiten macht.
Edit: Ab Bugzilla Version 2.2 geht das auch von Haus aus: http://www.bugzilla.org/releases/2.20/new-features.html#rss

Die Benutzung ist ganz einfach:

  1. Bugzilla Seite aufrufen z.B. https://bugs.gentoo.org/show_bug.cgi?id=272805
  2. Diese Seite dann als XML anzeigen lassen https://bugs.gentoo.org/show_bug.cgi?ctype=xml&id=272805
  3. Die Adresse kopieren und dann hier eintragen: http://dev.io-zone.org/bugzilla2RSS.php
  4. Danach habt ihr dann die URL von dem RSS Feed die ihr dann in eurem Feedreader angeben könnt.
  5. Oder ihr macht euren eigenen Service :-)

Den Quelltext habe ich auch noch hinterlegt.

Viel Spaß damit :-)

Steve

bugzilla2RSS Sourcecode

No tags

Hm ja wer kennt es nicht. Das Problem:

yt1

Ärgerlich!

Die Lösung ist jedoch einfach. Youtube hat diese Sperrung nicht im FlashPlayer integriert. D.h. wenn man es irgendwie schafft diesen Player aufzurufen dann wird das Video trotzdem abgespielt.

Lösung sind HTTP Proxys. Zu finden auf http://proxy.org/ oder in meinem Fall http://www.digiunblock.info/

Bei digiunblock.info einfach die Url eintragen und bei Options die Option “Remove Scripts” deaktivieren.

Sieht dann etwa so aus:

Youtube

Dann auf “Go”  und schon läuft das Video.

No tags

Nov/09

14

main()

Hallo,

es freut mich diesen Blog endlich eröffnen zu können und freue mich auf eine interessante und erfahrungsreiche Zeit.

Steve

No tags

Get Adobe Flash playerPlugin by wpburn.com wordpress themes