|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
Formats of the logs and details of the statisticsDear WorkRavers
Thanks to the developers for a great app. I've been using it for many years. 1. Can you please explaine the difference between mouse movement and effective mouse movements? 2. I echo the desire for the idlelog..log format that was sent by Joe: [Workrave-user] accessing Workrave's idlelog data from a cron job From: Joe Wells <jbwells@bl...> - 2008-12-26 23:37 Thanks again, Roelof ------------------------------------------------------------------------------ This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword _______________________________________________ Workrave-user mailing list Workrave-user@... https://lists.sourceforge.net/lists/listinfo/workrave-user |
|
|
Re: Formats of the logs and details of the statisticsroelof.burger@... writes:
> Dear WorkRavers > 2. I echo the desire for the idlelog..log format that was sent by Joe: > [Workrave-user] accessing Workrave's idlelog data from a cron job > From: Joe Wells <jbwells@bl...> - 2008-12-26 23:37 I attach two programs that parse Workrave's idle log file. The first program is a C♯ program by David Simner. This is the program that he used to get the data that he formatted with a spreadsheet program to make the graph in the bug report at <URL:https://bugs.launchpad.net/bugs/78959>. This program has two files. I have never compiled this program, and David Simner says he no longer uses it and does not know if it still works. Nonetheless, it should show the basic idea of how to write such a program. The second program is a Perl program I wrote. It finds idle log records since yesterday at 20:00 and prints the length of each idle time at least 1 hour long since then as a floating point number on a line by itself. The idea is that some other program will then use this output to reward the user for being good and avoiding using their computer when they should be getting ready for bed and sleeping. The reward I use is to allow myself to read a set of blogs for a time duration that depends on how good I have been. I personally find this much more useful at getting myself to not use the computer than Workrave's built in controls which do not match my needs very well. I still need Workrave to collect the idle time data. I hope these programs are useful to others. Both are licensed for general use under the GNU GPL version 3, so it would be no problem to include them with Workrave in the contributed program area. -- With my best regards, Joe Wells // Copyright 2007 David Simner // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You can find a copy of the GNU General Public License at // <URL:http://www.gnu.org/licenses/>. using System; using System.IO; namespace Workrave { class BinaryReaderBigEndian : BinaryReader { public BinaryReaderBigEndian(Stream input) : base(input) {} public override ushort ReadUInt16() { return (ushort) ((ReadByte() << 8) | ReadByte()); } public override uint ReadUInt32() { return (uint) ((ReadByte() << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte()); } } } // Copyright 2007 David Simner // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You can find a copy of the GNU General Public License at // <URL:http://www.gnu.org/licenses/>. using System; using System.Diagnostics; using System.IO; namespace Workrave { class ww { [STAThread] static void Main(string[] p_strArgs) { FileStream fsInput = null; BinaryReaderBigEndian brInput = null; try { fsInput = new FileStream( @"c:\CHANGEME.log", FileMode.Open, FileAccess.Read, FileShare.Read ); brInput = new BinaryReaderBigEndian( fsInput ); DateTime dtStart = new DateTime( 2005, 12, 9 ); DateTime dtPrint = dtStart.AddMinutes( 5 ); DateTime dtEnd = new DateTime( 2005, 12, 10 ); double dFractionalActive = 0; while( brInput.BaseStream.Position < brInput.BaseStream.Length ) { Debug.Assert( brInput.ReadUInt16() == 0x0f ); Debug.Assert( brInput.ReadByte() == 0x02 ); uint uiStartTimeOfIdleInterval = brInput.ReadUInt32(); uint uiEndTimeOfIdleIntervalAndStartOfActivePart = brInput.ReadUInt32(); uint uiEndTimeOfActiveInterval = brInput.ReadUInt32(); ushort usElapsedActiveTimeAfterTheIdleInterval = brInput.ReadUInt16(); DateTime dtStartActive = new DateTime( 621355968000000000 + TimeSpan.TicksPerSecond * uiEndTimeOfIdleIntervalAndStartOfActivePart ); DateTime dtEndActive = new DateTime( 621355968000000000 + TimeSpan.TicksPerSecond * uiEndTimeOfActiveInterval ); for( ; ; ) { // is active block relevant? if( ((dtStart <= dtStartActive) && (dtStartActive < dtEnd)) // it starts within us || ((dtStart <= dtEndActive) && (dtEndActive < dtEnd)) // it ends within us || ((dtStartActive < dtStart) && (dtEnd <= dtEndActive)) // it starts before and ends after us ) { if( dtPrint <= dtEndActive ) // it ends after the printing point { if( dtStartActive < dtStart ) // it starts before us dFractionalActive = 1; else if( dtStartActive < dtPrint ) dFractionalActive += (double) (dtPrint.Ticks - dtStartActive.Ticks) / (5 * TimeSpan.TicksPerMinute); Console.WriteLine( string.Format( "{0},{1}", dtPrint, dFractionalActive ) ); dtStart = dtPrint; dtPrint = dtStart.AddMinutes( 5 ); dFractionalActive = 0; } else { if( dtStartActive < dtStart ) // it starts before us dFractionalActive += (double) (dtEndActive.Ticks - dtStart.Ticks) / (5 * TimeSpan.TicksPerMinute); else dFractionalActive += (double) (dtEndActive.Ticks - dtStartActive.Ticks) / (5 * TimeSpan.TicksPerMinute); break; } /* // before you go active while( dtStart <= dtStartActive ) { Console.WriteLine( string.Format( "{0},{1}", dtStart, dFractionalActive ) ); dtStart = dtStart.AddMinutes( 1 ); dFractionalActive = 0; } // you go active dFractionalActive += ; Console.WriteLine( string.Format( "{0},{1}", dtStart, dFractionalActive ) ); dtStart = dtStart.AddMinutes( 1 ); dFractionalActive = 1;*/ } else break; } } } finally { if( brInput != null ) { brInput.Close(); brInput = null; } if( fsInput != null ) { fsInput.Close(); fsInput = null; } } } } } #!/bin/sh # -*-Perl-*- case "$PATH" in *:) ;; *) PATH="$PATH:";; esac # Next line shows how to augment PATH so that this program will work # also on machines where Perl is in a strange location. PATH="${PATH}/usr/local/bin:/usr/local/bin/apps" export PATH exec perl -S -x -- "$0" "$@" #!perl -w # To prevent Emacs's indentation code from trying to parse the stuff # above. (); # This program groks the user's Workrave idle log file. It finds # records since yesterday at 20:00 and prints the length of each idle # time at least 1 hour long since then as a floating point number on a # line by itself. (The idea is that some other program will then use # this output to reward the user for being good and avoiding using # their computer when they should be getting ready for bed and # sleeping.) There is also lots of debugging output. # Copyright 2008, 2009 Joe Wells # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You can find a copy of the GNU General Public License at # <URL:http://www.gnu.org/licenses/>. use English; use strict; use User::pwent; ###my $JBWHome; ###BEGIN { ### my $pw = getpwnam('jbw') || die "Can't find user jbw: $OS_ERROR"; ### $JBWHome = $pw->dir; ### push (@INC, "$JBWHome/church/lib/perl"); } ### ###use JBW::Utils qw(&get_file_contents &max); # get_file_contents and max are procedures defined in my personal Perl # library. I have copied them into this program for its public # release. sub get_file_contents { my $file = shift; open (FILE, "<$file") || die "failed to open $file: $OS_ERROR"; local $INPUT_RECORD_SEPARATOR = undef; my $file_contents = <FILE>; die "file slurp returned undef for file: $file" if ! defined $file_contents; # Perl bug workaround. Next line consumes special end-of-file # status waiting for the next reader. This should be cleared # anyway by the close operation, but Perl seems to have a bug # regarding this. my $dummy = <FILE>; close (FILE); return $file_contents; } sub max { my $max; while (scalar(@_)) { if ((! defined $max) || $_[0] >= $max) { $max = $_[0]; } shift; } return $max; } my $me = getpwuid ($REAL_USER_ID); if (! defined $me) { die "can not find my passwd entry"; } my $home = $me->dir; if (! defined ($home)) { die "eeek"; } my $IdleLog = get_file_contents("$home/.workrave/idlelog..log"); # C: unsigned 8-bit integer (“c” is for “char”) # n: unsigned 16-bit integer in big-endian order (“n” is for “network” order) # N: unsigned 32-bit integer in big-endian order # 17 bytes total my $IdleLogRecordFormat = ' n # size (should always be 15, encoded in bytes as 0 followed by 15) C # format version (should always be 2, encoded as the byte 2) N # begin time N # end idle time N # end time n # active time '; my @all_record_fields = unpack ("($IdleLogRecordFormat)*", $IdleLog); use POSIX qw(strftime mktime); sub format_date_time { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime($_[0]); my $result = strftime ('%Y-%m-%dT%H:%M:%S', $sec,$min,$hour,$mday,$mon,$year,$wday,$yday); return $result; } sub format_time { my $sec = $_[0]; # *** next line is wrong because it does floating point division! my $min = $sec / 60; $sec %= 60; my $hour = $min / 60; $min %= 60; return (strftime ('%H:%M:%S', $sec, $min, $hour, 0, 0, 0, 0, 0)); } my $minute_length = 60; my $hour_length = 60 * $minute_length; my $day_length = 24 * $hour_length; my $now = time(); my $yesterday = $now - $day_length; my $yesterday_evening_good_sleep_period_start; { my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = localtime($yesterday); $yesterday_evening_good_sleep_period_start = mktime (0, 0, 20, $mday, $mon, $year, 0, 0, 0); } while (@all_record_fields) { my ($size, $format_version, $begin_time, $end_idle_time, $end_time, $active_time) = @all_record_fields; shift @all_record_fields; shift @all_record_fields; shift @all_record_fields; shift @all_record_fields; shift @all_record_fields; shift @all_record_fields; # print "size: [$size], format_version: [$format_version]\n"; if (($size != 15) || ($format_version != 2)) { die "invalid data in file" } next if (($end_idle_time < $yesterday_evening_good_sleep_period_start) && scalar (@all_record_fields)); my $idle_duration = ($end_idle_time - $begin_time); my $good_begin_time = max ($begin_time, $yesterday_evening_good_sleep_period_start); my $good_idle_duration = max (0, ($end_idle_time - $good_begin_time)); my $good_idle_duration_hours = $good_idle_duration / $hour_length; next if (($good_idle_duration < $minute_length) && scalar (@all_record_fields)); print STDERR "begin_time: @{[format_date_time($begin_time)]}, end_idle_time: @{[format_date_time($end_idle_time)]}\n"; #print STDERR "good_idle_duration: @{[format_time($good_idle_duration)]}, idle_duration: @{[format_time($idle_duration)]}\n"; print STDERR "end_time: @{[format_date_time($end_time)]}, active_time: @{[format_time($active_time)]}\n"; print STDERR "good_idle_duration_hours: $good_idle_duration_hours\n"; next if ($end_idle_time < $yesterday_evening_good_sleep_period_start); next if ($good_idle_duration_hours < 1); print "$good_idle_duration_hours\n"; } ------------------------------------------------------------------------------ This SF.net email is sponsored by: SourcForge Community SourceForge wants to tell your story. http://p.sf.net/sfu/sf-spreadtheword _______________________________________________ Workrave-user mailing list Workrave-user@... https://lists.sourceforge.net/lists/listinfo/workrave-user |
| Free embeddable forum powered by Nabble | Forum Help |