Request for feedback

Bill Gribble grib@linuxdevel.com
11 Nov 2001 07:42:38 -0600


On Sun, 2001-11-11 at 00:00, Anthony W. Juckel wrote:
> Recently I've been mulling over a way to rework the current transaction
> import code to make it a little more generic.  I noticed a comment in
> src/import-export/qif-io-import/qif-objects.scm stating a desire to have
> the code re-worked into GOOPS classes, so I've started with that.

Youy should probably start out by looking at
src/import-export/qif-io-core, which is the "next generation" importer
I've been working on. 

I don't think it's a good idea to depend on GOOPS in the gnucash core
right now.  We made a decision as a group not to use GOOPS because it's
not well supported by the versions of guile that Red Hat users have
available.  I personally would like to start, but I think we should wait
at least until Red Hat ships something other than guile-1.3.4 with their
current release. 

If you're a Red Hat user and are using guile with no problems, maybe
it's time to reconsider. 

> hope is to add a layer of abstraction between the file type and the
> gnc:xtn code to make it relatively easy to add a new import file type.  

I think you're on the wrong track.  Every import format will have very
different limitations and information shortfalls and will need different
GUI front ends, and different processing. I advise against trying to
take the current QIF code and make it a generic importer.

I think it's a good idea to use more generic tools for certain parts of
the import process, such as eliminating duplicate transactions.  In the
qif-io-core code, the major change I made was to convert the QIF
transactions into gnucash transactions as early in the process as
possible, allowing most of the logic about matching with existing
accounts and transactions to be done by reasoning on gnucash
transactions rather than an intermediate form.  That would allow the
same mechanisms to be used by multiple importers. 

b.g.



> 
> I've got some very preliminary stuff going so far, but I'm looking for
> some comments on the direction I'm heading, since I'm very new both to
> GnuCash and scheme.
> 
> Here's what I have envisioned:
> 
> 1)  A list of files is selected for import.
> 2)  A gnc:initialize-xtn-file method selects tests for the appropriate
> file type and returns an instance of the appropriate <xtn-file> subclass
> to parse the file.
> 3)  The <xtn-file> subclass provides methods for inspecting/parsing the
> file, returning a list of gnc:xtns and accounts which are then fed
> through the rest of the import engine (which I'm hoping to swipe from
> the current qif-io-core) and checked for duplicates, etc.
> 
> Questions, comments, and suggestions are encouraged.
> 
> Here's the class choosing code skeleton that I've come up with so far:
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;;;  xtn-objects.scm
> ;;;  Initial object system for reading transactions from files
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (use-modules (oop goops))
> 
> (define-class <xtn-file> ()
>   ;; slots yet to be defined
>   (xtn-file-alist #:allocation #:class )
>   )
> 
> ;; I don't know how else to do this...
> ;;  Maybe this is the correct way?
> (class-slot-set! <xtn-file> 'xtn-file-alist ())
> 
> (define-method (gnc:xtn-file-parse (f <xtn-file>))
>   (error "Must be defined by a subclass"))
> (define-method (gnc:xtn-file-next-xtn (f <xtn-file>))
>   (error "Must be defined by a subclass"))
> ;; More methods for inspecting/parsing the input file
> 
> ;; A method to register (file-test . <class>) pairs
> ;; with the system.
> (define-method (gnc:xtn-file-register-test (c <class>) f)
>   (class-slot-set! <xtn-file> 'xtn-file-alist
> 	     (cons (cons f c) (class-slot-ref <xtn-file> 'xtn-file-alist))))
> 
> ;; Skeleton for two different input file types
> ;; class needs to be fleshed out with slots/method
> ;; definitions, etc, and the qif-file procedure would
> ;; actually read the file f to check whether or not it
> ;; was a qif file, returning #t or #f
> (define-class <gnc:qif-file> (<xtn-file>))
> (define-method (gnc:xtn-file-parse (f <qif-file>))
>   (display "Importing QIF"))
> (define (qif-file f) #f)
> (gnc:xtn-file-register-test <gnc:qif-file> qif-file)
> 
> ;; Same as above, except this would define how to read an xml file
> (define-class <gnc:xml-file> (<xtn-file>))
> (define-method (gnc:xtn-file-parse (f <gnc:xml-file>))
>   (display "Importing XML"))
> (define (xml-file f) #f)
> (gnc:xtn-file-register-test <gnc:xml-file> xml-file)
> 
> ;; A factory-type method that returns a <xtn-file> subclass suitable for
> ;; importing file f (I'm not quite sure how to pass filehandles around
> ;; yet...).  Basically, it returns an instance of the first class for
> ;; whose file test operator returns true.
> 
> (define-method (initialize-xtn-file f)
>   (let init ((t (caar (class-slot-ref <xtn-file> 'xtn-file-alist)))
> 	     (c (cdar (class-slot-ref <xtn-file> 'xtn-file-alist)))
> 	     (l (class-slot-ref <xtn-file> 'xtn-file-alist)))
>     (if (t f)
>        (make c)
>        (if (= (length l) 0 )
> 	   (error "No matching files registered")
> 	   (init (caadr l) (cdadr l) (cdr l)))))) 
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ;;;  EOF
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> Anthony W. Juckel
> 
> _______________________________________________
> gnucash-devel mailing list
> gnucash-devel@lists.gnumatic.com
> http://www.gnumatic.com/cgi-bin/mailman/listinfo/gnucash-devel