Pages

14 March 2011

brokyplo.pl


#!/usr/bin/perl

use strict;
use warnings;

use LWP::UserAgent;
use Getopt::Long;
use File::Slurp;
use Term::ANSIColor;
use Env;

my $script_version = '0.3.4';

# Set the main folder which contains all the saved data.

my $main_folder = "$HOME/.brokyplo/";

# This variable will contain the name of the company, for example
# Google Inc, Apple Inc, etc. $company_name_parsed will contain
# instead the full name of the company, parsed by a regexp.
# $company_description_parsed, is used when the option --info is called;
# It will contain all the information of the company.

my $company_name               = '';
my $company_name_parsed        = '';
my $company_description_parsed = '';

# $price_to_color, will be used in the sub function color_price() at the
# line 342, to color the name of the stock market quotes (in order to
# make it more readable data visualization). $file_content will be used
# instead, to contain the content of the file dot brk saved.

my $price_to_color = '';
my $file_content   = '';

# The following group of scalars belong, to the function GetOptions().
# Each of them is used for the parameter which will be passed from
# command line.

my $parameter_show_info;
my $parameter_delete_item;
my $parameter_save_item;
my $parameter_read_item;
my $parameter_cleans_folder;
my $parameter_help;

# LWP::UserAgent scalars, which will compose the requests and the
# responses. At the end the $lwp_content will contain the page content.

my ( $lwp_useragent, $lwp_response, $lwp_content ) = ( '', '', '' );

# The following scalars, will be used to record the precise time when
# the stock quotes are saved in the database.

my $log_minutes = (localtime)[1];
my $log_hours   = (localtime)[2];
my $log_day     = (localtime)[3];
my $log_month   = (localtime)[4];
my $log_year    = 1900 + (localtime)[5];

# $price_id and $price_ch, will contain the information to show
# if the currency is in decline or is on the rise.

my ( $price_id, $price_ch ) = ( '', '' );

my $FILEHANDLE;
my $DIRHANDLE;

# This vector will be used to show all the information on the
# stock quotes, during the final iteration.

my @regular_expression_keys = (
    'Range',   '52 week', 'Open',      'Vol / Avg.',
    'Mkt cap', 'P/E',     'Div/yield', 'EPS',
    'Shares',  'Beta',    'Inst. own',
);

# @regular_expression_values, will contain the regexp to parse in the
# final iteration except the value eleven.

my @regular_expression_values = (
    'Range
(.*?)',
'52 week
(.*?)',
    'Open
(.*?)',
'Vol / Avg.
(.*?)',
'Mkt cap
(.*?)',
    'P/E
(.*?)',
'Div/yield
(.*?)',
    'EPS
(.*?)',
    'Shares
(.*?)',
    'Beta
(.*?)',
'Inst. own
(.*?)',

    '
(.*?) <', ); # Creates the main directory which will contain all the file dot brk. # The file dot brk will contain expecially the stock quotes info # existing in the @regular_expression_keys and catched by # @regular_expression_values. mkdir "$HOME/.brokyplo" unless ( -d $main_folder ); GetOptions( 'help' => \$parameter_help, 'info' => \$parameter_show_info, 'remove' => \$parameter_delete_item, 'read' => \$parameter_read_item, 'save' => \$parameter_save_item, 'clear' => \$parameter_cleans_folder, ); if ( defined($parameter_help) ) { print color('green'), q { Brokyplo }, color('reset'), $script_version, q { Usage: perl }, $0, q { [--options] --info: show information about a company; --save: save the reasults in the main folder; --read: read a company saved in the past; --remove: remove a specific company from the database; --clear: clear the main directory which contains the stock quotes; --help: show this help. SEE THE PERLDOC (perldoc }, $0, q {) FOR MORE INFORMATION }; exit; } if ( defined($parameter_cleans_folder) ) { if ( -d $main_folder ) { opendir $DIRHANDLE, $main_folder or die "Can't open the directory: $!\n"; while ( glob( $main_folder . '*' ) ) { $FILEHANDLE = glob( $main_folder . '*' ); unlink $FILEHANDLE; } close $DIRHANDLE; die "\n", color('green'), 'Stock quotes successfully removed!', color('reset'), "\n\n"; } else { die "\n", color('red'), 'Main directory doesn\'t exists!', color('reset'), "\n\n"; } } # Asks the company name via INPUT and makes lowercase # characters in input. do { print q { , , )\\___/( \{(@)v(@)\} \{|~~~|\} \{|~~~|\} \{/^^^\\\} =======`m-m`====\ Please enter the company name: }; chomp( $company_name = <> ); } while ( $company_name eq '' ); $company_name = lc($company_name); # Checks if the user wants to read or remove something from the database read_database($company_name) if ( defined($parameter_read_item) ); remove_database($company_name) if ( defined($parameter_delete_item) ); $lwp_useragent = LWP::UserAgent->new; $lwp_useragent->agent('Mozilla/5.0'); $lwp_response = $lwp_useragent->get( 'http://www.google.com/finance?q=' . $company_name ); die "\n", color('red'), 'Error during extablishing the connection with the remote host...', color('reset'), "\n\n" unless ( $lwp_response->is_success ); $lwp_content = $lwp_response->content; # Checks if company exists in the Google Finance database die "\n", color('red'), 'Company name doesn\'t exists', color('reset'), ', please be more precise...', "\n\n" if ( $lwp_content =~ m{produced no matches}i or $lwp_content =~ m{Results 1}i ); # Starts parsing the company name and prints the results. if ( $lwp_content =~ m{class="g-unit g-first">

(.*?) 

}i ) { $company_name_parsed = $1; print "\n", $company_name_parsed, ' '; } print $1, "\n\n" if ( $lwp_content =~ m{(.*?)  }i ); # Checks if the user just wants to view the information about the company # if true, is called the sub function show_info() on the line 299. if ( defined($parameter_show_info) ) { show_info($1) if ( $lwp_content =~ m{$regular_expression_values[11]}i ); } # Starts parsing the price and the currency. Well, honestly I don't like # so much this kind of solution... but I had to do it! If you have any # advices about this block of code let me know! $price_id = $1 if ( $lwp_content =~ m{}i ); $price_ch = $1 if ( $lwp_content =~ m{ print 'Price: ', $1, ' ' if ( $lwp_content =~ m{(.*?)}i ); print color_price( $1, $price_ch ), ' ' if ( $lwp_content =~ m{(.*?)}i ); print color_price( $1, $price_ch ), "\n\n" if ( $lwp_content =~ m{(.*?)}i ); # Checks if the user wants to save the statistics in the database. The # statistics files will be saved in dot brk. if ( defined($parameter_save_item) ) { open $FILEHANDLE, '>>', $main_folder . $company_name . '.brk' or die "Can't open file handle: $!\n"; # Checks if the file doesn't contains the banner, if true, writes the # banner with the program version and the full company name. $file_content = read_file( $main_folder . $company_name . '.brk' ); print {$FILEHANDLE} "\n", 'Brokyplo version: ', $script_version, "\n\n", 'Company name: ', $company_name_parsed, "\n" if ( $file_content !~ m{Brokyplo version:}i ); print {$FILEHANDLE} "\n", '---', $log_hours, ':', $log_minutes, '---', $log_month, '/', $log_day, '/', $log_year, '---', "\n\n"; } # Parse the rest of the body of the Google Finance page and shows the # various information about the stock quotes. $lwp_content =~ s/\*/\*/g if ( $lwp_content =~ m{\*}i ); $lwp_content =~ s/    -/-/g; for my $index ( 0 .. 10 ) { if ( $lwp_content =~ m{$regular_expression_values[$index]}i ) { defined($parameter_save_item) ? print {$FILEHANDLE} $regular_expression_keys[$index], ': ', $1, "\n" : print $regular_expression_keys[$index], ': ', color('blue'), $1, color('reset'), "\n"; } } # Makes the final check, to control if the file was successfully saved, # and closes the file-handle. if ( defined($parameter_save_item) ) { print 'Stock quotes for ', color('blue'), $company_name_parsed, color('reset'), ' successfully saved!', "\n\n" if ( -e $main_folder . $company_name . '.brk' ); close $FILEHANDLE; } # Various sub functions sub show_info { $company_description_parsed = shift; print $company_description_parsed, "\n\n"; exit; } sub remove_database { $company_name = shift; if ( -e $main_folder . $company_name . '.brk' ) { unlink( $main_folder . $company_name . '.brk' ); print "\n", color('blue'), $company_name, color('reset'), color('green'), '.brk, successfully removed from database!', color('reset'), "\n\n"; exit; } else { die "\n", color('red'), 'The company doesn\'t exists in the database!', color('reset'), "\n\n"; } } sub read_database { $company_name = shift; if ( -e $main_folder . $company_name . '.brk' ) { print read_file( $main_folder . $company_name . '.brk' ), "\n"; exit; } else { die "\n", color('red'), 'The company doesn\'t exists in the database!', color('reset'), "\n\n"; } } sub color_price { $price_to_color = shift; $price_ch = shift; $price_ch eq 'chg' ? return color('green'), $price_to_color, color('reset') : return color('red'), $price_to_color, color('reset'); } __END__ =head1 NAME Brokyplo =head1 SYNOPSIS perl brokyplo.pl [--options] --info: show information about a company; --save: save the reasults in the main folder; --read: read a company saved in the past; --remove: remove a specific company from the database; --clear: clear the main directory which contains the stock quotes; --help: show this help. =head1 EXAMPLES Please enter the company name: Google Google Inc. (Public, NASDAQ:GOOG) Price: 600.62 -8.94 (-1.47%) Stock quotes for Google Inc. successfully saved! =head1 DESCRIPTION Thanks to Google Finance, (www.google.com/finance), Brokyplo, can parse some of the information of a company for example the stock quotes, the currency and something else, and save it on a flat database. This script works without any graphic interface, but only from a command line, perfect for minimal desktop environments. If you want, you can save something in the main folder, you can also remove these files saved as dot brk, or read them simply from the command line with the relative ARGV options. =head1 SEE ALSO http://www.google.com/finance Env ~ http://search.cpan.org/~rjbs/perl-5.12.3/lib/Env.pm Getopt::Long ~ http://search.cpan.org/~enrys/POD2-IT-Getopt-Long/lib/POD2/IT/Getopt/Long.pm LWP::UserAgent ~ http://search.cpan.org/~gaas/libwww-perl-5.837/lib/LWP/UserAgent.pm File::Slurp ~ http://search.cpan.org/~drolsky/File-Slurp-9999.13/lib/File/Slurp.pm See the FAQ about Term modules at http://perldoc.perl.org/perlfaq8.html =head1 COPYRIGHT Copyright (C) 2010 by sysxash This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-3. =head1 AUTHOR sysxash with his mind - =head1 THANKS Thanks to perl.it irc channel @ irc.freenode.net =cut

0 comments: