summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobi Oetiker <tobi@oetiker.ch>2008-06-02 22:03:33 +0200
committerTobi Oetiker <tobi@oetiker.ch>2008-06-02 22:03:33 +0200
commit8793d83042d5cf388a30ee5f8637fa6554334aa6 (patch)
treeca1d1a68cd3513f1eab9fa9a14559f687d233aae
parent6b239270a134ef8f26d59a7ab9b35eeeeceb9c47 (diff)
downloadsmokeping-8793d83042d5cf388a30ee5f8637fa6554334aa6.tar.gz
smokeping-8793d83042d5cf388a30ee5f8637fa6554334aa6.tar.xz
initial support for mrt integration
-rw-r--r--qooxdoo/source/class/Mtr/Application.js89
-rw-r--r--qooxdoo/source/class/Mtr/Server.js74
-rw-r--r--qooxdoo/source/class/Mtr/ui/ActionButton.js160
-rw-r--r--qooxdoo/source/class/Mtr/ui/Cellrenderer.js46
-rw-r--r--qooxdoo/source/class/Mtr/ui/TraceTable.js215
-rw-r--r--qooxdoo/source/index.html2
-rwxr-xr-xqooxdoo/source/mtr.cgi26
-rw-r--r--qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm128
-rw-r--r--qooxdoo/source/translation/C.po70
-rw-r--r--qooxdoo/source/translation/de.po106
-rw-r--r--qooxdoo/source/translation/en.po78
-rw-r--r--qooxdoo/source/translation/fr.po70
-rw-r--r--qooxdoo/source/translation/messages.pot85
13 files changed, 1116 insertions, 33 deletions
diff --git a/qooxdoo/source/class/Mtr/Application.js b/qooxdoo/source/class/Mtr/Application.js
new file mode 100644
index 0000000..7d28f59
--- /dev/null
+++ b/qooxdoo/source/class/Mtr/Application.js
@@ -0,0 +1,89 @@
+/* ************************************************************************
+
+#module(Mtr)
+#resource(Mtr.image:image)
+#embed(Mtr.image/*)
+
+************************************************************************ */
+
+qx.Class.define('Mtr.Application',
+{
+ extend: qx.application.Gui,
+
+ members:
+ {
+ main: function()
+ {
+ var self=this;
+ this.base(arguments);
+
+ qx.io.Alias.getInstance().add(
+ 'MT', qx.core.Setting.get('Mtr.resourceUri')
+ );
+
+ // if we run with a file:// url make sure
+ // the app finds the Mtr service (Mtr.cgi)
+
+ Mtr.Server.getInstance().setLocalUrl(
+ 'http://johan.oetiker.ch/~oetiker/mtr/'
+ );
+
+ var base_layout = new qx.ui.layout.VerticalBoxLayout();
+ with(base_layout){
+ setPadding(8);
+ setLocation(0,0);
+ setWidth('100%');
+ setHeight('100%');
+ setSpacing(10);
+ setBackgroundColor('white');
+ };
+ base_layout.addToDocument();
+ var top = new qx.ui.layout.HorizontalBoxLayout();
+ top.set({
+ height: 'auto'
+ });
+ var title = new qx.ui.basic.Atom(this.tr("MTR AJAX Frontend"));
+ with(title){
+ setTextColor('#b0b0b0');
+ setFont(qx.ui.core.Font.fromString('20px bold sans-serif'));
+ }
+ top.add(title);
+ top.add(new qx.ui.basic.HorizontalSpacer());
+ top.add(new Mtr.ui.ActionButton());
+ base_layout.add(top);
+ var trace = new Mtr.ui.TraceTable();
+ base_layout.add(trace);
+ },
+
+ close : function(e)
+ {
+ this.base(arguments);
+ // return "Mtr Web UI: "
+ // + "Do you really want to close the application?";
+ },
+
+
+ terminate : function(e) {
+ this.base(arguments);
+ }
+
+ /********************************************************************
+ * Functional Block Methods
+ ********************************************************************/
+
+ },
+
+
+
+
+ /*
+ *****************************************************************************
+ SETTINGS
+ *****************************************************************************
+ */
+
+ settings : {
+ 'Mtr.resourceUri' : './resource'
+ }
+});
+
diff --git a/qooxdoo/source/class/Mtr/Server.js b/qooxdoo/source/class/Mtr/Server.js
new file mode 100644
index 0000000..3e77047
--- /dev/null
+++ b/qooxdoo/source/class/Mtr/Server.js
@@ -0,0 +1,74 @@
+/* ************************************************************************
+#module(Mtr)
+************************************************************************ */
+
+/**
+ * A Mtr specific rpc call which works
+ */
+
+qx.Class.define('Mtr.Server', {
+ extend: qx.io.remote.Rpc,
+ type: "singleton",
+
+ /*
+ *****************************************************************************
+ CONSTRUCTOR
+ *****************************************************************************
+ */
+
+ /**
+ * @param local_url {String} When running the application in file:// mode.
+ * where will we find our RPC server.
+ */
+ construct: function (local_url) {
+
+ with(this){
+ base(arguments);
+ setTimeout(7000000);
+ setUrl('mtr.cgi');
+ setServiceName('Mtr');
+ setCrossDomain(true);
+ }
+
+ return this;
+ },
+
+ /*
+ *****************************************************************************
+ MEMBERS
+ *****************************************************************************
+ */
+
+ members :
+ {
+
+ /*
+ ---------------------------------------------------------------------------
+ CORE METHODS
+ ---------------------------------------------------------------------------
+ */
+
+ /**
+ * Tell about the BaseUrl we found.
+ *
+ * @type member
+ *
+ * @param {void}
+ *
+ * @return BaseUrl {Strings}
+ */
+
+ getBaseUrl: function(){
+ return this.__base_url;
+ },
+
+ setLocalUrl: function(local_url){
+ if ( document.location.host === '' ) {
+ with(this){
+ setUrl(local_url+'mtr.cgi');
+ }
+ }
+ }
+
+ }
+});
diff --git a/qooxdoo/source/class/Mtr/ui/ActionButton.js b/qooxdoo/source/class/Mtr/ui/ActionButton.js
new file mode 100644
index 0000000..0c02598
--- /dev/null
+++ b/qooxdoo/source/class/Mtr/ui/ActionButton.js
@@ -0,0 +1,160 @@
+/* ************************************************************************
+#module(Mtr)
+************************************************************************ */
+
+/**
+ * a widget showing the Mtr graph overview
+ */
+
+qx.Class.define('Mtr.ui.ActionButton',
+{
+ extend: qx.ui.layout.HorizontalBoxLayout,
+
+ /*
+ *****************************************************************************
+ CONSTRUCTOR
+ *****************************************************************************
+ */
+
+ construct: function () {
+ this.base(arguments);
+
+ this.set({
+ height: 'auto',
+ width: 'auto',
+ verticalChildrenAlign: 'middle'
+ });
+ var lab1 = new qx.ui.basic.Label(this.tr("Host"));
+ lab1.set({
+ paddingRight: 6
+ });
+ this.add(lab1);
+ var host = new qx.ui.form.TextField();
+ host.set({
+ width: 200,
+ height: 'auto',
+ border: 'dark-shadow',
+ padding: 1
+ });
+ this.add(host);
+ this.__host = host;
+
+ var lab2 = new qx.ui.basic.Label(this.tr("Delay"));
+ lab2.set({
+ paddingRight: 6,
+ paddingLeft: 12
+ });
+ this.add(lab2);
+ var delay = new qx.ui.form.Spinner(1,5,60);
+ delay.set({
+ border: 'dark-shadow'
+ });
+ this.add(delay);
+ this.__delay = delay;
+
+ var lab3 = new qx.ui.basic.Label(this.tr("Rounds"));
+ lab3.set({
+ paddingRight: 6,
+ paddingLeft: 12
+ });
+ this.add(lab3);
+ var rounds = new qx.ui.form.Spinner(1,20,200);
+ rounds.set({
+ border: 'dark-shadow'
+ });
+ this.add(rounds);
+ this.__rounds = rounds;
+
+ var button = new qx.ui.form.Button('');
+ this.__button = button;
+ button.set({
+ marginLeft: 10,
+ width: 50,
+ height: 'auto',
+ border: 'dark-shadow',
+ padding: 2
+ });
+ this.add(button);
+
+ qx.event.message.Bus.subscribe('mtr.status',this.__set_status,this);
+ qx.event.message.Bus.dispatch('mtr.status','stopped');
+
+ var start_trace = function(event) {
+ qx.event.message.Bus.dispatch('mtr.cmd',{
+ action: button.getUserData('action'),
+ host: host.getValue(),
+ delay: delay.getValue(),
+ rounds: rounds.getValue()
+ });
+ };
+
+ button.addEventListener('execute', start_trace );
+
+ var history_action = function(event){
+ host.setValue(event.getData());
+ start_trace();
+ }
+ qx.client.History.getInstance().addEventListener('request', history_action);
+
+ // if we got called with a host on the commandline
+ var initial_host = qx.client.History.getInstance().getState();
+ if (initial_host){
+ host.setValue(initial_host);
+ // dispatch this task once all the initializations are done
+ qx.client.Timer.once(start_trace,this,0);
+ }
+ },
+
+ members: {
+ __set_status: function(m){
+ var host = this.__host;
+ var rounds = this.__rounds;
+ var delay = this.__delay;
+ with(this.__button){
+ // this.debug(m.getData());
+ switch(m.getData()){
+ case 'starting':
+ if (getUserData('action') == 'go') {
+ setLabel(this.tr("Starting"));
+ setEnabled(false);
+ host.setEnabled(false);
+ rounds.setEnabled(false);
+ delay.setEnabled(false);
+ }
+ break;
+ case 'stopping':
+ if (getUserData('action') == 'stop') {
+ setLabel(this.tr("Stopping"));
+ setEnabled(false);
+ host.setEnabled(false);
+ rounds.setEnabled(false);
+ delay.setEnabled(false);
+ }
+ break;
+ case 'stopped':
+ setUserData('action','go');
+ setLabel(this.tr("Go"));
+ setEnabled(true);
+ host.setEnabled(true);
+ rounds.setEnabled(true);
+ delay.setEnabled(true);
+ break;
+ case 'started':
+ setUserData('action','stop');
+ setLabel(this.tr("Stop"));
+ setEnabled(true);
+ host.setEnabled(false);
+ rounds.setEnabled(false);
+ delay.setEnabled(false);
+ break;
+ default:
+ alert('Unknown Status Message: '+m.getData());
+ }
+ }
+ }
+ }
+
+
+});
+
+
diff --git a/qooxdoo/source/class/Mtr/ui/Cellrenderer.js b/qooxdoo/source/class/Mtr/ui/Cellrenderer.js
new file mode 100644
index 0000000..2b2e45e
--- /dev/null
+++ b/qooxdoo/source/class/Mtr/ui/Cellrenderer.js
@@ -0,0 +1,46 @@
+/* ************************************************************************
+
+ Mtr Frontend
+
+ Author:
+ * Tobias Oetiker
+
+************************************************************************ */
+/* ************************************************************************
+#module(Mtr)
+************************************************************************ */
+
+/**
+ * A configurable cell renderre
+ */
+
+qx.Class.define('Mtr.ui.Cellrenderer',
+{
+ extend: qx.ui.table.cellrenderer.Number,
+ /**
+ * Format a number with a configurable number of fraction digits
+ * and add optional pre and postfix.
+ * @param digits {Integer} how many digits should there be. Default is 0.
+ * @param prefix {String} optional prefix.
+ * @param postfix {String} optional postfix.
+ */
+
+ construct: function (digits,postfix,prefix) {
+ if (digits == undefined){
+ digits = 0;
+ }
+ this.base(arguments)
+ var format = new qx.util.format.NumberFormat();
+ format.set({
+ maximumFractionDigits: digits,
+ minimumFractionDigits: digits
+ });
+ if (postfix != undefined){
+ format.setPostfix(postfix);
+ }
+ if (prefix != undefined){
+ format.setPrefix(prefix);
+ }
+ this.setNumberFormat(format);
+ }
+});
diff --git a/qooxdoo/source/class/Mtr/ui/TraceTable.js b/qooxdoo/source/class/Mtr/ui/TraceTable.js
new file mode 100644
index 0000000..1097f22
--- /dev/null
+++ b/qooxdoo/source/class/Mtr/ui/TraceTable.js
@@ -0,0 +1,215 @@
+/* ************************************************************************
+#module(Mtr)
+************************************************************************ */
+
+/**
+ * a widget showing the Mtr target tree
+ */
+
+qx.Class.define('Mtr.ui.TraceTable',
+{
+ extend: qx.ui.table.Table,
+
+ /*
+ *****************************************************************************
+ CONSTRUCTOR
+ *****************************************************************************
+ */
+
+
+ construct: function () {
+
+ var tableModel = new qx.ui.table.model.Simple();
+ this.__tableModel = tableModel;
+ tableModel.setColumns([ this.tr("Hop"), this.tr("Host"),this.tr("Ip"),
+ this.tr("Loss [%]"), this.tr("Sent [ms]"), this.tr("Last [ms]"), //"; help syntax highliter
+ this.tr("Avg [ms]"), this.tr("Best [ms]"), this.tr("Worst [ms]"), this.tr("StDev [ms]") ]);
+ var custom = {
+ tableColumnModel: function(obj) {
+ return new qx.ui.table.columnmodel.Resize(obj);
+ }
+ };
+ with(this){
+ base(arguments,tableModel,custom);
+ set({
+ width: '100%',
+ height: '1*',
+ border: 'dark-shadow',
+ showCellFocusIndicator: false,
+ statusBarVisible: false
+ });
+ };
+ var tcm = this.getTableColumnModel();
+
+ tcm.setDataCellRenderer(3, new Mtr.ui.Cellrenderer(0,' %'));
+ tcm.setDataCellRenderer(4, new Mtr.ui.Cellrenderer(0));
+
+ var render_ms = new Mtr.ui.Cellrenderer(1);
+
+ for (var i=5;i<10;i++){
+ tcm.setDataCellRenderer(i, render_ms);
+ }
+
+
+ // Obtain the behavior object to manipulate
+ var resizeBehavior = tcm.getBehavior();
+ // This uses the set() method to set all attriutes at once; uses flex
+ resizeBehavior.set(0, { width:"1*", minWidth:20, maxWidth:30 });
+ resizeBehavior.set(1, { width:"10*", minWidth:80, maxWidth:300 });
+ resizeBehavior.set(2, { width:"6*", minWidth:60, maxWidth:200 });
+
+ for (var i=3;i<10;i++){
+ resizeBehavior.set(i, { width:"2*", minWidth:40, maxWidth:100 });
+ }
+ qx.event.message.Bus.subscribe('mtr.cmd',this.__handle_mtr,this);
+ },
+
+ /*
+ *****************************************************************************
+ Statics
+ *****************************************************************************
+ */
+ members: {
+ __make_empty_row: function (){
+ return ([undefined,'waiting for name','waiting for ip',0,0,undefined,undefined,undefined,undefined,undefined,0,0,0]);
+ },
+ __handle_mtr: function(m){
+ var self = this;
+ var f_hop = 0,f_host=1,f_ip=2,f_loss=3,f_snt=4,f_last=5,f_avg=6,f_best=7,f_worst=8,f_stdev=9,f_cnt=10,f_sum=11,f_sqsum=12;
+ var fill_table;
+ fill_table = function(retval,exc,id){
+ if (exc == null){
+ if ( self.__handle == undefined ) {
+ qx.event.message.Bus.dispatch('mtr.status','started');
+ }
+ self.__handle = retval['handle'];
+ var tableModel = self.__tableModel;
+ var rowcount = tableModel.getRowCount();
+ var lines = retval['output'].length;
+ var data = self.__data;
+ for(var i=0;i<lines;i++){
+ var cmd = retval['output'][i][0];
+ var row = retval['output'][i][1];
+ var value = retval['output'][i][2];
+ if (rowcount <= row){
+ for (var ii=rowcount;rowcount <= row;rowcount++){
+ data.push(self.__make_empty_row());
+ };
+ };
+ var drow = data[row];
+ drow[f_hop] = row+1;
+ switch(cmd){
+ case 'h':
+ drow[f_ip] = value;
+ break;
+ case 'd':
+ drow[f_host] = value;
+ break;
+ case 'p':
+ var snt = data[0][f_snt];
+ if (row == 0) {
+ snt++;
+ for (ii=0;ii<rowcount;ii++){
+ if (retval['again'] && snt > data[ii][f_cnt]){
+ data[ii][f_snt] = snt-1;
+ } else {
+ data[ii][f_snt] = snt;
+ }
+ data[ii][f_loss]=(1-data[ii][f_cnt]/data[ii][f_snt])*100;
+ }
+ }
+ value = value/1000.0;
+ drow[f_last] = value;
+
+ var best = drow[f_best];
+ if (best == undefined || best > value){
+ drow[f_best] = value;
+ }
+
+ var worst = drow[f_worst];
+ if (worst == undefined || worst < value){
+ drow[f_worst] = value;
+ }
+
+ var cnt = drow[f_cnt]+1;
+
+ if (cnt > drow[f_snt]){
+ drow[f_snt] = cnt;
+ }
+
+ drow[f_cnt] = cnt;
+
+ drow[f_loss] = (1-cnt/drow[f_snt])*100;
+
+ var sum = drow[f_sum]+value;
+ drow[f_sum] = sum;
+ var sqsum = drow[f_sqsum]+value*value;
+ drow[f_sqsum] = sqsum;
+
+ drow[f_avg] = sum/cnt;
+ drow[f_stdev] = Math.sqrt((cnt*sqsum-sum*sum)/(cnt*(cnt-1)))
+ break;
+
+ default:
+ self.debug(row);
+ break;
+ }
+ }
+
+ tableModel.setData(data);
+ if (retval['again']){
+ var next_round = function (){Mtr.Server.getInstance().callAsync(
+ fill_table,'run_mtr',{ handle: retval['handle'],
+ point: retval['point']})};
+ qx.client.Timer.once(next_round,self,0);
+ } else
+ {
+ for (var i=0;i<10;i++){
+ tableModel.setColumnSortable(i,true);
+ }
+ qx.event.message.Bus.dispatch('mtr.status','stopped');
+ self.__handle = undefined;
+ }
+ }
+ else {
+ alert(exc);
+ if (self.__handle){
+ self.__handle = undefined;
+ }
+ for (var i=0;i<10;i++){
+ self.__tableModel.setColumnSortable(i,true);
+ }
+ qx.event.message.Bus.dispatch('mtr.status','stopped');
+ }
+ };
+
+ var handle_returns = function (data,exc,id){
+ if (exc != null){
+ alert(exc);
+ }
+ };
+
+ var cmd = m.getData();
+ switch(cmd['action']){
+ case 'stop':
+ qx.event.message.Bus.dispatch('mtr.status','stopping');
+ Mtr.Server.getInstance().callAsync(handle_returns,'stop_mtr',this.__handle);
+ break;
+ case 'go':
+ this.__data = [this.__make_empty_row()];
+ this.__tableModel.setData(this.__data);
+ this.__delay = cmd['delay'];
+ for (var i=0;i<10;i++){
+ this.__tableModel.setColumnSortable(i,false);
+ }
+ qx.event.message.Bus.dispatch('mtr.status','starting');
+ Mtr.Server.getInstance().callAsync(fill_table,'run_mtr',{host: cmd['host'], rounds: cmd['rounds'], delay: cmd['delay']});
+ break;
+ default:
+ alert('Unknown Command '+cmd['action']);
+ }
+ }
+ }
+});
+
+
diff --git a/qooxdoo/source/index.html b/qooxdoo/source/index.html
index 4dd0962..072fa3e 100644
--- a/qooxdoo/source/index.html
+++ b/qooxdoo/source/index.html
@@ -2,6 +2,6 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Smokeping</title>
- <script type="text/javascript" src="script/Smokeping.js"></script>
+ <script type="text/javascript" src="script/Mtr.js"></script>
</head>
</html>
diff --git a/qooxdoo/source/mtr.cgi b/qooxdoo/source/mtr.cgi
new file mode 100755
index 0000000..1cf543c
--- /dev/null
+++ b/qooxdoo/source/mtr.cgi
@@ -0,0 +1,26 @@
+#!/usr/sepp/bin/perl-5.8.8 -w
+use strict;
+$ENV{PATH}="/usr/pack/mtr-0.72-mo/amd64-debian-linux3.1/sbin";
+use lib qw( perl );
+
+use CGI;
+use CGI::Util qw(expires);
+use CGI::Session;
+use Qooxdoo::JSONRPC;
+
+$Qooxdoo::JSONRPC::debug=1;
+
+# Change this space-separated list of directories to include
+# Qooxdoo::JSONRPC.pm and co-located Services
+
+# If this module can't be found, the previous line is incorrect
+
+# Instantiating the CGI module which parses the HTTP request
+
+my $cgi = new CGI;
+my $session = new CGI::Session;
+
+# You can customise this harness here to handle cases before treating
+# the request as being JSON-RPC
+Qooxdoo::JSONRPC::handle_request ($cgi, $session);
+
diff --git a/qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm b/qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm
new file mode 100644
index 0000000..6aead46
--- /dev/null
+++ b/qooxdoo/source/perl/Qooxdoo/Services/Mtr.pm
@@ -0,0 +1,128 @@
+package Qooxdoo::Services::Mtr;
+use strict;
+use POSIX qw(setsid :sys_wait_h);
+use Time::HiRes qw(usleep);
+
+sub GetAccessibility {
+ return "public";
+}
+
+sub launch {
+ my $error = shift;
+ $SIG{CHLD} = \&REAPER;
+ defined(my $pid = fork) or do { $error->set_error(101,"Can't fork: $!");return $error};
+ if ($pid){
+ open my $x, ">/tmp/mtr_session.$pid" or do {
+ $error->set_error(199,"Opening /tmp/mtr_session.$$: $!");
+ return $error;
+ };
+ close ($x);
+ return $pid;
+ }
+ chdir '/' or die "Can't chdir to /: $!";
+ open STDOUT, ">>/tmp/mtr_session.$$"
+ or die "Can't write to /tmp/mtr_session.$$: $!";
+ open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
+ setsid or die "Can't start a new session: $!";
+ open STDERR, '>&STDOUT' or die "Can't dup stdout: $!";
+ exec @_;
+}
+
+sub get_number {
+ my $error = shift;
+ my $data = shift;
+ $data = 'Undefined' unless defined $data;
+ if ($data =~ /^(\d+)$/){
+ return $1;
+ }
+ else {
+ $error->set_error(104,"Expected a number but got: $data");
+ return $error;
+ }
+}
+
+sub method_stop_mtr {
+ my $error = shift;
+ my $arg = shift;
+ my $handle = get_number($error,$arg);
+ return $handle if ref $handle;
+ my $data = "/tmp/mtr_session.".$handle;
+ if (-r $data){
+ warn "Sending kill $handle";
+ kill('KILL',$handle);
+ }
+}
+
+sub method_run_mtr
+{
+ my $error = shift;
+ my $arg = shift;
+ my $handle = get_number($error,$arg->{handle});
+ my $point = get_number($error,$arg->{point});
+ if ($arg->{host}){
+ my $delay = get_number($error,$arg->{delay});
+ return $delay if ref $delay;
+ my $rounds = get_number($error,$arg->{rounds});
+ return $rounds if ref $rounds;
+ $handle = launch ($error,"mtr","-4","--raw","--report-cycles=$rounds","--interval=$delay",$arg->{host});
+ $point = 0;
+ }
+ return $point if ref $point;
+ return $handle if ref $handle;
+ my $data = "/tmp/mtr_session.".$handle;
+ if (open my $fh,$data){
+ my $again;
+ my $size;
+ my $rounds = 0;
+ do {
+ $size = -s $fh;
+ # make sure we reap any zombi instances of mtr
+ # this is especially important when running with speedy of fastcgi
+ waitpid($handle,WNOHANG);
+ $again = kill(0, $handle);
+ usleep(1000*200) if $rounds;
+# print STDERR "$again, $handle, $size, $point\n";
+ $rounds ++;
+ } while ($again and $point >= $size);
+ if (seek $fh, $point,0){
+ my @array;
+ while (<$fh>){
+ if (not /^[a-z]\s/){
+ waitpid($handle,WNOHANG);
+ if (/Name or service not known/){
+ $error->set_error(108,"Unknown hostname.");
+ return $error;
+ }
+ else {
+ $error->set_error(107,"ERROR: $_. See $data for more information.");
+ return $error;
+ }
+ }
+ last unless /\n$/; # stop when we find an incomplete line
+ $point = tell($fh);
+ chomp;
+ my @line = split (/\s+/,$_);
+ push @array,\@line;
+ };
+ close $fh;
+ unlink $data unless $again;
+ return {
+ handle=>$handle,
+ point=>$point,
+ output=>\@array,
+ again=> $again,
+ }
+ }
+ else {
+ $error->set_error(102,"Seeking in mtr output to $point: $!");
+ return $error;
+ }
+ }
+ else {
+ $error->set_error(103,"Opening $data: $!");
+ return $error;
+ }
+}
+
+1;
+
diff --git a/qooxdoo/source/translation/C.po b/qooxdoo/source/translation/C.po
index a015dc0..1bb1e39 100644
--- a/qooxdoo/source/translation/C.po
+++ b/qooxdoo/source/translation/C.po
@@ -7,10 +7,78 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-11-17 12:18-0600\n"
+"POT-Creation-Date: 2008-06-02 20:43+0200\n"
"PO-Revision-Date: 2007-10-19 09:30+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
+
+#: source/class/Mtr/Application.js:45
+msgid "MTR AJAX Frontend"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:27 source/class/Mtr/ui/TraceTable.js:24
+msgid "Host"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:42
+msgid "Delay"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:55
+msgid "Rounds"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:118
+msgid "Starting"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:127
+msgid "Stopping"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:136
+msgid "Go"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:144
+msgid "Stop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Hop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Ip"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Last [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Loss [%]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Sent [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Avg [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Best [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "StDev [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Worst [ms]"
+msgstr ""
diff --git a/qooxdoo/source/translation/de.po b/qooxdoo/source/translation/de.po
index aab249d..73ea3b4 100644
--- a/qooxdoo/source/translation/de.po
+++ b/qooxdoo/source/translation/de.po
@@ -1,21 +1,94 @@
-# German translations for PACKAGE package. ö
-# Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# Automatically generated, 2007.
+# German translations for MTR Ajax Frontend.
+# Copyright (C) 2008 Tobias Oetiker
+#
#
msgid ""
msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
+"Project-Id-Version: MTR-AJAX-Frontend 1.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-11-17 12:18-0600\n"
-"PO-Revision-Date: 2007-10-19 09:30+0200\n"
-"Last-Translator: Automatically generated\n"
-"Language-Team: none\n"
+"POT-Creation-Date: 2008-06-02 20:43+0200\n"
+"PO-Revision-Date: 2008-05-31 08:50+0200\n"
+"Last-Translator: oetiker <(null)>\n"
+"Language-Team: English <en@li.org>\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+#: source/class/Mtr/Application.js:45
+msgid "MTR AJAX Frontend"
+msgstr "MTR Ajax Frontend"
+
+#: source/class/Mtr/ui/ActionButton.js:27 source/class/Mtr/ui/TraceTable.js:24
+msgid "Host"
+msgstr "Host"
+
+#: source/class/Mtr/ui/ActionButton.js:42
+msgid "Delay"
+msgstr "Abstand"
+
+#: source/class/Mtr/ui/ActionButton.js:55
+msgid "Rounds"
+msgstr "Runden"
+
+#: source/class/Mtr/ui/ActionButton.js:118
+#, fuzzy
+msgid "Starting"
+msgstr "Start"
+
+#: source/class/Mtr/ui/ActionButton.js:127
+#, fuzzy
+msgid "Stopping"
+msgstr "Stop"
+
+#: source/class/Mtr/ui/ActionButton.js:136
+msgid "Go"
+msgstr "Start"
+
+#: source/class/Mtr/ui/ActionButton.js:144
+msgid "Stop"
+msgstr "Stop"
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Hop"
+msgstr "Schritt"
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Ip"
+msgstr "Ip"
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Last [ms]"
+msgstr "Letzte [ms]"
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Loss [%]"
+msgstr "Loss [%]"
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Sent [ms]"
+msgstr "Gesendet"
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Avg [ms]"
+msgstr "ø [ms]"
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Best [ms]"
+msgstr "Best [ms]"
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "StDev [ms]"
+msgstr "StdAbw [ms]"
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Worst [ms]"
+msgstr "Worst [ms]"
+
+#, fuzzy
+#~ msgid "Host:"
+#~ msgstr "GWP"
+
#~ msgid "Start Date"
#~ msgstr "Start-Datum"
@@ -57,18 +130,9 @@ msgstr ""
#~ msgid "Snap"
#~ msgstr "Sonntag"
-#~ msgid "Client"
-#~ msgstr "GWP"
-
-#~ msgid "Hostname"
-#~ msgstr "GWP"
-
#~ msgid "Team"
#~ msgstr "Team"
-#~ msgid "Ip"
-#~ msgstr "Ip"
-
#~ msgid "User"
#~ msgstr "Benutzer"
@@ -109,10 +173,6 @@ msgstr ""
#~ msgid "Data Set 2"
#~ msgstr "Daten-Quelle"
-#, fuzzy
-#~ msgid "Start"
-#~ msgstr "Start"
-
#~ msgid "End"
#~ msgstr "Ende"
diff --git a/qooxdoo/source/translation/en.po b/qooxdoo/source/translation/en.po
index faed222..eb61d2e 100644
--- a/qooxdoo/source/translation/en.po
+++ b/qooxdoo/source/translation/en.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-11-17 12:18-0600\n"
+"POT-Creation-Date: 2008-06-02 20:43+0200\n"
"PO-Revision-Date: 2007-10-26 23:25+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -16,6 +16,76 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+#: source/class/Mtr/Application.js:45
+msgid "MTR AJAX Frontend"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:27 source/class/Mtr/ui/TraceTable.js:24
+msgid "Host"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:42
+msgid "Delay"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:55
+msgid "Rounds"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:118
+#, fuzzy
+msgid "Starting"
+msgstr "Start"
+
+#: source/class/Mtr/ui/ActionButton.js:127
+msgid "Stopping"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:136
+msgid "Go"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:144
+msgid "Stop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Hop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Ip"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Last [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Loss [%]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+#, fuzzy
+msgid "Sent [ms]"
+msgstr "Client"
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Avg [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Best [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "StDev [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Worst [ms]"
+msgstr ""
+
#~ msgid "Start Date"
#~ msgstr "Start Date"
@@ -57,9 +127,6 @@ msgstr ""
#~ msgid "Snap"
#~ msgstr "Sunday"
-#~ msgid "Client"
-#~ msgstr "Client"
-
#~ msgid "Low"
#~ msgstr "Low"
@@ -89,9 +156,6 @@ msgstr ""
#~ msgid "Data Set 2"
#~ msgstr "Data Source"
-#~ msgid "Start"
-#~ msgstr "Start"
-
#~ msgid "End"
#~ msgstr "End"
diff --git a/qooxdoo/source/translation/fr.po b/qooxdoo/source/translation/fr.po
index 9755e0c..702126f 100644
--- a/qooxdoo/source/translation/fr.po
+++ b/qooxdoo/source/translation/fr.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-11-17 12:18-0600\n"
+"POT-Creation-Date: 2008-06-02 20:43+0200\n"
"PO-Revision-Date: 2007-10-19 09:30+0200\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
@@ -15,3 +15,71 @@ msgstr ""
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: source/class/Mtr/Application.js:45
+msgid "MTR AJAX Frontend"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:27 source/class/Mtr/ui/TraceTable.js:24
+msgid "Host"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:42
+msgid "Delay"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:55
+msgid "Rounds"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:118
+msgid "Starting"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:127
+msgid "Stopping"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:136
+msgid "Go"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:144
+msgid "Stop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Hop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Ip"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Last [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Loss [%]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Sent [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Avg [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Best [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "StDev [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Worst [ms]"
+msgstr ""
diff --git a/qooxdoo/source/translation/messages.pot b/qooxdoo/source/translation/messages.pot
index e69de29..e034fed 100644
--- a/qooxdoo/source/translation/messages.pot
+++ b/qooxdoo/source/translation/messages.pot
@@ -0,0 +1,85 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-06-02 20:43+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: source/class/Mtr/Application.js:45
+msgid "MTR AJAX Frontend"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:27 source/class/Mtr/ui/TraceTable.js:24
+msgid "Host"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:42
+msgid "Delay"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:55
+msgid "Rounds"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:118
+msgid "Starting"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:127
+msgid "Stopping"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:136
+msgid "Go"
+msgstr ""
+
+#: source/class/Mtr/ui/ActionButton.js:144
+msgid "Stop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Hop"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:24
+msgid "Ip"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Last [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Loss [%]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:25
+msgid "Sent [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Avg [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Best [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "StDev [ms]"
+msgstr ""
+
+#: source/class/Mtr/ui/TraceTable.js:26
+msgid "Worst [ms]"
+msgstr ""