[scripts] AggSetCoord: -i option (in-place)

This commit is contained in:
Matteo Cypriani 2013-07-31 12:42:41 -04:00
parent 1ffbe7a8c1
commit 1307ac6dc5
1 changed files with 84 additions and 29 deletions

View File

@ -10,6 +10,7 @@ owlps-aggsetcoord - set the coordinates in an aggregation CSV file
B<owlps-aggsetcoord>
[ B<-h> | B<-V> ]
[ B<-v> ]
[ B<-i> ]
[ B<-c> <I<coordinates>> [ B<-l> <I<line_selection>> ] ]
[ B<-m> <I<mac>> ]
[ <I<aggregation_file>> ]
@ -40,13 +41,15 @@ Alternatively, using the B<-c> option will disable interpolation but apply an
arbitrary set of coordinates to the lines containing only default values.
In theory, you can provide more than one I<aggregation_file> at once, but don't
do that unless you really know what you're doing. The (list of) aggregation file
name(s) I<must> be placed after the options. If no file is provided, the
standard input is read.
do that unless you really know what you're doing; you cannot specify multiple
input files when using the B<-i> option. The (list of) aggregation file name(s)
I<must> be placed after the options. If no file is provided, the standard input
is read.
The results are written on the standard output. It is advised to use graphical
diff tools such as I<vimdiff> to visualise the differences between the input
file and the result and make sure it corresponds to what was expected.
Unless B<-i> is used, the results are written on the standard output. It is
advised to use graphical diff tools such as I<vimdiff> to visualise the
differences between the input file and the result and make sure it corresponds
to what was expected.
=head1 OPTIONS
@ -65,6 +68,10 @@ Print version message and exit.
Turn on verbose mode (displays a trace on the standard error).
=item B<-i>
Modify the input file in-place. The original file is saved with suffix ".orig".
=item B<-c> <I<coordinates>>
Apply I<coordinates> to every positioning request with default X, Y and Z. A
@ -103,6 +110,9 @@ owlps(7), owlps-aggregatord(1)
use strict;
use Getopt::Std;
use Pod::Usage;
use File::Temp qw/tempfile/;
use File::Basename qw/dirname/;
use File::Copy qw/move/;
use OwlPS::TimeInterpolation;
use OwlPS::CSV;
@ -129,6 +139,12 @@ use constant BASE_COORD => "0.00";
## Global variables ##
# Output file handle
my $output_handle = *STDOUT;
# Names of the temporary and final output files
my ($tmp_output_file, $output_file);
# Verbose mode
my $verbose;
@ -196,6 +212,12 @@ sub print_warning(@) {
}
# Prints the arguments to the output handle.
sub output(@) {
print $output_handle @_;
}
# Returns true if $mac is the transmitter's MAC address selected by the user, or
# if the user didn't select any particular MAC address.
# Parameters: $mac
@ -230,7 +252,7 @@ sub check_oldest_lines() {
while ($prev_lines[0]) {
# If the oldest stored line is empty, just print it and delete it
if ($prev_lines[0] eq "\n") {
print shift @prev_lines;
output(shift @prev_lines);
next;
}
@ -255,7 +277,7 @@ sub check_oldest_lines() {
|| !is_selected_mac($mac)
|| is_complete($x, $y, $z))
{
print shift @prev_lines;
output(shift @prev_lines);
next; # Jump to the next oldest line
}
@ -317,7 +339,7 @@ sub apply_interpolation($$$$$$) {
## Option parsing ##
$Getopt::Std::STANDARD_HELP_VERSION = 1;
use constant OPTIONS => 'c:hl:m:vV';
use constant OPTIONS => 'c:hil:m:vV';
my %options;
if (!getopts(OPTIONS, \%options)) {
HELP_MESSAGE(*STDERR);
@ -335,10 +357,24 @@ if ($options{'V'}) {
exit 0;
}
$verbose = $options{'v'};
$selected_mac = $options{'m'};
$verbose = $options{'v'};
$new_coordinates = $options{'c'};
$selected_mac = $options{'m'};
if ($options{'i'}) {
if (@ARGV != 1) {
die "One and only one file name must be provided when using -i";
}
$output_file = $ARGV[0];
($output_handle, $tmp_output_file) =
tempfile(
".owlps-aggsetcoord-XXXXXXX",
SUFFIX => ".agg",
DIR => dirname($output_file),
UNLINK => 1
);
}
if (defined($new_coordinates)) {
($new_x, $new_y, $new_z) = split_point_3d($new_coordinates);
}
@ -360,7 +396,7 @@ while ($cur_line = <>) {
# The current line is empty
if ($cur_line eq "\n") {
# If we don't have previous lines, we print it; if we do, we store it
if (@prev_lines == 0) { print "\n" }
if (@prev_lines == 0) { output("\n") }
else { push @prev_lines, "\n" }
next;
}
@ -394,7 +430,7 @@ while ($cur_line = <>) {
trace("Non-positioning request: line skipped.\n");
# If we have no lines in memory, we can just print the line and jump to
# the next one, otherwise we have to store the line
if (@prev_lines == 0) { print $cur_line }
if (@prev_lines == 0) { output($cur_line) }
else { push @prev_lines, $cur_line }
next;
}
@ -405,7 +441,7 @@ while ($cur_line = <>) {
trace( "Transmitter's MAC address ($mac) doesn't match the selected"
. " transmiter's MAC address ($selected_mac): line skipped.\n");
# Print or store the line
if (@prev_lines == 0) { print $cur_line }
if (@prev_lines == 0) { output($cur_line) }
else { push @prev_lines, $cur_line }
next;
}
@ -418,28 +454,29 @@ while ($cur_line = <>) {
# Skip the line if it is not part of the selected lines
if (%selected_lines and !$selected_lines{$line_nb}) {
trace("Line not selected: skipped.\n");
print $cur_line;
output($cur_line);
next;
}
# If the current line is fully incomplete, we reconstitute it with the
# new coordinates
if (is_blank($x, $y, $z)) {
print($csv_format, ";",
$mac, ";",
$type, ";",
$nb_pkt, ";",
$timestamp, ";",
$new_x, ";",
$new_y, ";",
$new_z, ";",
$end_line
output(
$csv_format, ";",
$mac, ";",
$type, ";",
$nb_pkt, ";",
$timestamp, ";",
$new_x, ";",
$new_y, ";",
$new_z, ";",
$end_line
);
}
# If the current line has at least one of its coordinates to a
# non-default value, just print it
else {
print $cur_line;
output($cur_line);
}
# In either case, jump to the next line
@ -454,7 +491,7 @@ while ($cur_line = <>) {
# later interpolation
if (is_complete($x, $y, $z)) {
# Print current line
print $cur_line;
output($cur_line);
# Store current values
$last_x = $x;
$last_y = $y;
@ -471,7 +508,7 @@ while ($cur_line = <>) {
# the line since we won't be able to interpolate anything anyway
if (is_blank($x, $y, $z) && is_blank($last_x, $last_y, $last_z)) {
print_warning("No previous X, Y and Z values to interpolate!");
print $cur_line;
output($cur_line);
next;
}
}
@ -581,9 +618,27 @@ while ($cur_line = <>) {
if (@prev_lines) {
trace("Printing " . scalar(@prev_lines) . " lines left in memory...\n");
print foreach (@prev_lines);
output($_) foreach (@prev_lines);
}
trace("The end.\n");
## Write the output file if needed ##
if (defined($output_file)) {
# Close the output handle
close $output_handle
or die "Can't close the output file handle: $!";
# Backup the original file
my $newname = "$output_file.orig";
move($output_file, $newname)
or die "Can't move \"$output_file\" to \"$newname\": $!";
# Move the temporary file to the new file
move($tmp_output_file, $output_file)
or die "Can't move the temporary file to \"$output_file\": $!";
}
# vim: tabstop=4:shiftwidth=4:expandtab:textwidth=80