Hello to everyone!

This is my first post here. I have to confess that I was very impressed by 
the features of ledger.
As an avid GNUCash user I was a little disappointed with the absence of 
GNUCash reading capabilities.
I managed to write a perl script to parse and output a ledger-formatted 
file and than I started looking for ways to present my data.

Long story short, I haven't found a way to access this Python interface, my 
intent is to produce a series of scripts to output HMTL5 files with my 
reports on a regular basis (probably a cron-job). How can I do this? Is 
there any way to communicate with Ledger without having to put it in REPL 
mode and creating the interface myself?

Thanks!

On Friday, March 2, 2012 12:06:48 AM UTC-3, John Wiegley wrote:
>
> Hello all,
>
> I think it's time for a primer on using Python to extend your Ledger
> experience.  But first, a word must be said about Ledger's data model, so 
> that
> other things make sense later.
>
>
> ------------------------------------------------------------------------------
> # Basic data traversal
>
> Every interaction with Ledger happens in the context of a Session.  Even if
> you don't create a session manually, one is created for you by the 
> top-level
> interface functions.  The Session is where objects live like the 
> Commodity's
> that Amount's refer to.
>
> The make a Session useful, you must read a Journal into it, using the 
> function
> `read_journal`.  This reads Ledger data from the given file, populates a
> Journal object within the current Session, and returns a reference to that
> Journal object.
>
> Within the Journal live all the Transaction's, Posting's, and other objects
> related to your data.  There are also AutomatedTransaction's and
> PeriodicTransaction's, etc.
>
> Here is how you would traverse all the postings in your data file:
>
>     import ledger
>
>     for xact in ledger.read_journal("sample.dat").xacts:
>         for post in xact.posts:
>             print "Transferring %s to/from %s" % (post.amount, 
> post.account)
>
>
> ------------------------------------------------------------------------------
> # Raw vs. Cooked
>
> Ledger data exists in one of two forms: raw and cooked.  Raw objects are 
> what
> you get from a traversal like the above, and represent exactly what was 
> seen
> in the data file.  Consider this journal:
>
>     = true
>         (Assets:Cash)    $100
>
>     2012-03-01 KFC
>         Expenses:Food    $100
>         Assets:Credit
>
> In this case, the *raw* regular transaction in this file is:
>
>     2012-03-01 KFC
>         Expenses:Food    $100
>         Assets:Credit
>
> While the cooked form is:
>
>     2012-03-01 KFC
>         Expenses:Food    $100
>         Assets:Credit   $-100
>         (Assets:Cash)    $100
>
> So the easy way to think about raw vs. cooked is that raw is the 
> unprocessed
> data, and cooked has had all considerations applied.
>
> When you traverse a Journal by iterating its transactions, you are 
> generally
> looking at raw data.  In order to look at cooked data, you must generate a
> report of some kind by querying the journal:
>
>     for post in ledger.read_journal("sample.dat").query("food"):
>         print "Transferring %s to/from %s" % (post.amount, post.account)
>
> The reason why queries iterate over postings instead of transactions is 
> that
> queries often return only a "slice" of the transactions they apply to.  You
> can always get at a matching posting's transaction by looking at its "xact"
> member:
>
>     last_xact = None
>     for post in ledger.read_journal("sample.dat").query(""):
>         if post.xact != last_xact:
>             for post in post.xact.posts:
>                 print "Transferring %s to/from %s" % (post.amount,
>                 post.account)
>             last_xact = post.xact
>
> This query ends up reporting every cooked posting in the Journal, but does 
> it
> transaction-wise.  It relies on the fact that an unsorted report returns
> postings in the exact order they were parsed from the journal file.
>
>
> ------------------------------------------------------------------------------
> # Queries
>
> The Journal.query() method accepts every argument you can specify on the
> command-line, including --options.
>
> Since a query "cooks" the journal it applies to, only one query may be 
> active
> for that journal at a given time.  Once the query object is gone (after the
> for loop), then the data reverts back to its raw state.
>
>
> ------------------------------------------------------------------------------
> # Embedded Python
>
> Can you embed Python into your data files using the 'python' directive:
>
>     python
>         import so
>         def check_path(path_value):
>             print "%s => %s" % (str(path_value), 
> os.path.isfile(str(path_value)))
>             return os.path.isfile(str(path_value))
>     
>     tag PATH
>         assert check_path(value)
>     
>     2012-02-29 KFC
>         ; PATH: somebogusfile.dat
>         Expenses:Food                $20
>         Assets:Cash
>
> Any Python functions you define this way become immediately available as
> valexpr functions.
>
>
> ------------------------------------------------------------------------------
> # Amounts
>
> When numbers come from Ledger, like post.amount, the type of the value is
> Amount.  It can be used just like an ordinary number, except that addition
> and subtraction are restricted to amounts with the same commodity.  If you
> need to create sums of multiple commodities, use a Balance.  For example:
>
>     total = Balance()
>     for post in ledger.read_journal("sample.dat").query(""):
>         total += post.amount
>     print total
>
> John
>
>

Reply via email to