One small correction - there should be a line break in the following statement: # Extract first table. my $te = HTML::TableExtract->new( headers => [qw(Date Price)] );
... so it's actually # Extract first table. my $te = HTML::TableExtract->new( headers => [qw(Date Price)] ); On Monday, November 18, 2019, 11:17:20 AM EST, Derek Robinson via gnucash-user <gnucash-user@gnucash.org> wrote: Apologies - I don't know why the linebreaks didn't work in my last message. Please disregard that (unreadable) version. New to the list - please direct me to previous posts if I've missed something that will explain what's happening. I wrote a custom F::Q module to extract daily "prices" from Vanguard 529 plan portfolios that are not traded on exchanges. I believe I've done that correctly. When I run gnc-fq-dump, I get return values that make sense and appear to be the same returns I would get from using an existing module (say yahoo_json) to query for a traded security (say CSCO). However, when I configure one of my securities in Gnucash (build 3.7+, F::Q version 1.49) the program crashes. There is no log output in gnucash.trace.xxxxxx.log (the file exists, but it's blank) and no useful information from gdb. I may have installed gdb incorrectly, or maybe I'm using it incorrectly. All I get is "Inferior 1 (process xxxx) exited with code 01" and "No stack" after using bt. I'd appreciate any guidance an experienced user can provide. Thanks! Derek package Finance::Quote::VanguardPortfolios529; require 5.005; our $VERSION = '1.49'; # VERSION use strict; use HTTP::Request::Common; use HTML::TableExtract; use HTML::TreeBuilder; use Text::Template; use Encode qw(decode); use Time::Piece; sub methods { return ( vanguardportfolios529 => \&vanguardportfolios529 ); } my @labels = qw/date isodate nav/; sub labels { return ( iexcloud => \@labels, ); } sub vanguardportfolios529 { my $quoter = shift; my @portfolios = @_; my (%info, $symbol, $url, $reply, $code, $desc, $body); my $ua = $quoter->user_agent(); my $quantity = @portfolios; foreach my $symbol (@portfolios) { my $t = localtime; my $t2 = $t - 7*86400; my $URL = Text::Template->new(TYPE => 'STRING', SOURCE => 'https://personal.vanguard.com/us/funds/tools/pricehistorysearch?radio=1&results=get&FundType=529Plans&FundIntExt=INT&FundId={$symbol}&fundName={$symbol}&radiobutton2=1&beginDate='.$t2->mon.'%2F'.$t2->mday.'%2F'.$t2->year.'&endDate='.$t->mon.'%2F'.$t->mday.'%2F'.$t->year.'&year=#res'); # Vanguard price history doesn't like invalid dates, so we pass a date range from a week ago through today - this range will always return SOME valid data, unless markets close for several days. # Get the web page $url = $URL->fill_in(HASH => {symbol => $symbol}); $reply = $ua->request( GET $url); $code = $reply->code; $desc = HTTP::Status::status_message($code); $body = decode('UTF-8', $reply->content); if ($code != 200) { $info{ $symbol, 'success' } = 0; $info{ $symbol, 'errormsg' } = $desc; next; } # Extract first table. my $te = HTML::TableExtract->new( headers => [qw(Date Price)] ); $te->parse($body); my $ts = $te->first_table_found(); # It's a simple table - just dates and prices. my $currprice; my $currdate; # Iterate over table. We will end up passing the last row (most current price) to the constructor below. foreach my $row ($ts->rows) { $currprice = @$row[1]; $currdate = @$row[0]; } eval { $info{$symbol, 'symbol'} = $symbol; $info{$symbol, 'method'} = 'vanguardportfolios529'; $info{$symbol, 'nav'} = $currprice =~ s/[\$,]//g ? $currprice : die('failed to parse last price'); $info{$symbol, 'currency'} = 'USD'; $info{$symbol, 'success'} = 1; $quoter->store_date( \%info, $symbol, { usdate => $currdate } ); } or do { $info{$symbol, 'errormsg'} = $@; $info{$symbol, 'success'} = 0; } } return wantarray() ? %info : \%info; } 1; gnc-fq-dump output C:\Program Files (x86)\gnucash\bin>perl gnc-fq-dump vanguardportfolios529 4517 Finance::Quote fields Gnucash uses: symbol: 4517 <=== required date: 11/15/2019 <=== recommended currency: USD <=== required last: <=\ nav: 51.22 <=== one of these price: <=/ timezone: <=== optional _______________________________________________ gnucash-user mailing list gnucash-user@gnucash.org To update your subscription preferences or to unsubscribe: https://lists.gnucash.org/mailman/listinfo/gnucash-user If you are using Nabble or Gmane, please see https://wiki.gnucash.org/wiki/Mailing_Lists for more information. ----- Please remember to CC this list on all your replies. You can do this by using Reply-To-List or Reply-All. _______________________________________________ gnucash-user mailing list gnucash-user@gnucash.org To update your subscription preferences or to unsubscribe: https://lists.gnucash.org/mailman/listinfo/gnucash-user If you are using Nabble or Gmane, please see https://wiki.gnucash.org/wiki/Mailing_Lists for more information. ----- Please remember to CC this list on all your replies. You can do this by using Reply-To-List or Reply-All.