Can we play log files

Linas Vepstas linas@linas.org
Thu, 17 May 2001 12:02:46 -0500


--fdj2RfSjLxBAspz7
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Thu, May 17, 2001 at 12:05:44AM +0200, Fran?ois Jan was heard to remark:
> Hi everybody,
>=20
> I use gnucash for a while and I just lost two hours of work. I closed it
> without saving my changes. So the question is : can I play the .log file
> in order to build the missing .xac one from the last .xac file ?

Yes.  The perl script below should do the trick, although
it has not been widely tested.

--=20
Linas Vepstas -- linas@gnumatic.com -- http://www.gnumatic.com/


#! /usr/bin/perl
#
# FUNCTION:
# restore gnucash transactions from a gnucash log file.
#
# Usage: cat <logfile> | gnc-restore.pl <gnucash-filename>
#
# Warning! this script probably does the wrong thing,=20
# and has never been tested!!
# It will probably destroy your data!  Use at your own risk!
#

# hack alert -- fix the paths
# set the path below to where your gnucash.pm is located
use lib '/usr/local/gnucash-1.4/lib/gnucash/perl';
use lib '/usr/local/gnucash-1.4/share/gnucash/perl';
use gnucash;

 =20
die "Usage: cat <logfile> | $0 <gnucash-filename>" if $#ARGV < 0;
 =20
# open the file
print "Opening file $ARGV[0]\n";
$sess =3D gnucash::xaccMallocSession ();
$grp =3D gnucash::xaccSessionBeginFile ($sess,$ARGV[0]);

die "failed to read file $ARGV[0], maybe its locked? " if (! $grp);

$got_data =3D 0;
$nsplit =3D 0;

# --------------------------------------------------
while (<STDIN>) {

  # start of transaction
  if (/^=3D=3D=3D=3D=3D START/) {=20
     $nsplit =3D 0;
     next;=20
  }

  # end of transaction
  if (/^=3D=3D=3D=3D=3D END/) {=20
     if ($got_data =3D=3D 1) {
        gnucash::xaccTransCommitEdit ($trans);
     }
     $got_data =3D 0;
     next;=20
  }
 =20
  # ignore 'begin' lines
  if (/^B/) { next; }
  if (/^D/) {=20
    print "WARNING: deletes not handled, you will have to manually delete\n=
";
    next;=20
  }

  # ignore any line that's not a 'commit'
  if (!/^C/) { next; }
 =20
  chop;

  # get journal entry
  ($mod, $id, $time_now, $date_entered, $date_posted,
   $account, $num, $description, $memo, $action,=20
   $reconciled, $amount, $price, $date_reconciled)
    =3D split (/	/);

  # parse amount & price=20
  # gnucash-1.4.x : float point;  gnucash-1.5.x: fractional ratio
  ($anum, $adeno) =3D split (/\//, $amount);
  if (0 !=3D $adeno) {
     $amount =3D $anum / $adeno;
  }
   =20
  ($pnum, $pdeno) =3D split (/\//, $price);
  if (0 !=3D $pdeno) {
     $price =3D $pnum / $pdeno;
     # value, not price in gnucash-1.5.x
     if (0 !=3D $amount) {
        $price =3D $price/$amount;
     }
  }

  $dyear =3D int($date_posted/10000000000);
  $dmonth =3D int($date_posted/100000000) - 100*$dyear;
  $dday =3D int($date_posted/1000000) - 10000*$dyear - 100*$dmonth;
 =20
  $dpost =3D $dmonth . "/" . $dday . "/" . $dyear;

  # do a 'commit'
  if ($mod =3D=3D C) {=20
     print "restoring '$account' $dpost '$description' for $amount at price=
 $price\n";
    =20
     if ($got_data =3D=3D 0) {
        $trans =3D gnucash::xaccMallocTransaction();
        gnucash::xaccTransBeginEdit( $trans, 1);
        $got_data =3D 1;
     }

     gnucash::xaccTransSetDescription( $trans, $description);
     gnucash::xaccTransSetDateStr ($trans, $dpost);
     gnucash::xaccTransSetNum ($trans, $num);

     if ($nsplit =3D=3D 0) {
        $split =3D gnucash::xaccTransGetSplit ($trans, $nsplit);
     } else {
        $split =3D gnucash::xaccMallocSplit();
	gnucash::xaccTransAppendSplit($trans, $split);
     }
     gnucash::xaccSplitSetAction ($split, $action);
     gnucash::xaccSplitSetMemo ($split, $memo);
     gnucash::xaccSplitSetReconcile ($split, $reconciled);

     # hack alert -- fixme: the reconcile date is not set ...
     # need to convert date_reconciled to 'seconds' ...=20
     # gnucash::xaccSplitSetDateReconciled ($split, $date_reconciled);
     gnucash::xaccSplitSetSharePriceAndAmount($split, $price, $amount);

     $acct =3D gnucash::xaccGetAccountFromName ($grp,$account);
     gnucash::xaccAccountBeginEdit ($acct, 1);
     gnucash::xaccAccountInsertSplit ($acct, $split);
     gnucash::xaccAccountCommitEdit ($acct);
 =20
     $nsplit ++;
  }

}

gnucash::xaccSessionSave ($sess);
gnucash::xaccSessionEnd ($sess);



--fdj2RfSjLxBAspz7
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.5 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE7BAQ2ZKmaggEEWTMRAqV4AJ966tLi5njxfDnulQIoZYBIAlrzwQCfdWPx
IXINplnEiL7ecE1qeU+cWOY=
=0wb7
-----END PGP SIGNATURE-----

--fdj2RfSjLxBAspz7--