Skip to content
Browse files

Merge branch 'master' of https://github.com/pmyteh/TagTime

  • Loading branch information...
2 parents c53846a + 9bc2f0c commit 011d268ac93388470051f83db89937c992cbfd63 Tom Nicholls committed
Showing with 122 additions and 0 deletions.
  1. +122 −0 script/ttlogmerge.pl
View
122 script/ttlogmerge.pl
@@ -0,0 +1,122 @@
+#!/usr/bin/perl
+
+# Syntax: ttlogmerge.pl logfile1 logfile2 outputlogfile
+#
+# A helper script for the Unison file synchroniser. One option for Unison is to
+# use an external program to merge two files which have been change in both
+# roots. This script uses this feature to merge two TagTime log files which
+# have been created on different machines.
+#
+# In principle, this allows you to run TagTime on multiple computers and, as
+# long as they have the same period and random seeds, create a merged file
+# which tracks what you were doing on all your machines.
+#
+# If a ping only exists in one file, use it.
+# If a ping exists in both files but one is tagged "RETRO", use the other.
+# If a ping exists in both files and both or neither are tagged "RETRO",
+# then use the one with the most tags entered.
+# Note that it is assumed that both files have timestamps in ascending order.
+#
+# This is best used by adding something like the following to your Unison
+# preferences file:
+#
+# merge = Path path/to/tagtime/*.log -> /path/to/ttlogmerge.pl CURRENT1 CURRENT2 NEW
+
+use strict;
+use warnings;
+
+sub longer
+{
+ (length($_[0]) >= length($_[1])) ? $_[0] : $_[1];
+}
+
+sub parse
+# Returns the initial timestamp and tag set
+{
+ my $s = $_[0];
+ my @tokens = split(/\s+/, $s);
+ for my $i (1..3) { pop(@tokens) } # Discard date string
+# print "parse: ", $_[0], @tokens;
+ return @tokens;
+}
+
+sub parse_timestamp
+# Returns just the initial timestamp from a line
+{
+ my $s = $_[0];
+ my @tokens = split(/\s+/, $s);
+ print "parse_timestamp: ", $tokens[0];
+ return $tokens[0];
+}
+
+open(my $f1, "<", $ARGV[0]) or die;
+open(my $f2, "<", $ARGV[1]) or die;
+open(my $fo, ">", $ARGV[2]) or die;
+
+# Read initial lines from files
+my $l1 = <$f1>;
+my $l2 = <$f2>;
+
+# If one file is present but empty, this will be skipped, and the other file
+# will be copied into the output file by the second loop.
+while (defined $l1 and defined $l2) {
+ my @l1a = &parse($l1);
+ my @l2a = &parse($l2);
+ if (not defined $l1a[0] or not defined $l2a[0])
+ {
+ last; # Spurious blank line
+ }
+ if ($l1a[0] < $l2a[0]) {
+ # f1 has ping not in f2
+ print $fo $l1;
+ $l1 = <$f1>;
+ } elsif ($l1a[0] > $l2a[0]) {
+ # f2 has ping not in f1
+ print $fo $l2;
+ $l2 = <$f2>;
+ } else {
+ # both f1 and f2 have a ping
+ if ($l1 eq $l2) {
+ # Identical. Print one copy and get new data
+ print $fo $l1;
+ $l1 = <$f1>;
+ $l2 = <$f2>;
+ } else {
+ # Different content.
+ if (index($l1, " RETRO ") != -1) {
+ if (index($l2, " RETRO ") != -1) {
+ # Both RETRO - print longer
+ print $fo &longer($l1, $l2);
+ } else {
+ # 1 RETRO, 2 not
+ print $fo $l2;
+ }
+ } elsif (index($l2, "RETRO") != -1) {
+ # 2 RETRO, 1 not
+ print $fo $l1;
+ } else {
+ # Both non-RETRO (shouldn't really happen)
+ print $fo &longer($l1, $l2);
+ }
+ # Get new lines from both files
+ $l1 = <$f1>;
+ $l2 = <$f2>;
+ }
+ }
+}
+
+# One or both of the files is exhausted and its line undefined.
+# Any non-undefined files have unprocessed data in $lx
+if (defined $l1) {
+ do {
+# print "Extra line in f1. Writing.\n", $l1;
+ print $fo $l1
+ } while ($l1 = <$f1>);
+} elsif (defined $l2) {
+ do {
+# print "Extra line in f2. Writing.\n", $l2;
+ print $fo $l2
+ } while ($l2 = <$f2>);
+}
+
+exit(0);

0 comments on commit 011d268

Please sign in to comment.
Something went wrong with that request. Please try again.