Skip to content

Commit

Permalink
Merge with genehack
Browse files Browse the repository at this point in the history
  • Loading branch information
ericblue committed Jul 8, 2010
2 parents 8536451 + f481017 commit 76668c9
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 45 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
log
21 changes: 21 additions & 0 deletions Makefile.PL
@@ -0,0 +1,21 @@
#! /usr/bin/env perl

use inc::Module::Install;

name 'WWW-Fitbit-API';
all_from 'lib/WWW/Fitbit/API.pm';

requires 'Carp';

requires 'Data::Dumper';
requires 'Date::Parse';
requires 'HTTP::Cookies';
requires 'HTTP::Request';
requires 'LWP::UserAgent';
requires 'Log::Log4perl';
requires 'POSIX';
requires 'XML::Simple';

install_script glob('script/*.pl');
auto_install;
WriteAll;
73 changes: 36 additions & 37 deletions FitbitClient.pm → lib/WWW/Fitbit/API.pm 100644 → 100755
@@ -1,31 +1,30 @@
#!/usr/bin/perl
package WWW::Fitbit::API;

#
# Author: Eric Blue - ericblue76@gmail.com
# Project: Perl Fitbit API
# Url: http://eric-blue.com/projects/fitbit
#

package FitbitClient;
use strict;
use warnings;

use LWP::UserAgent;
use HTTP::Request;
use HTTP::Cookies;
use Date::Parse;
use Carp;
use Data::Dumper;
use XML::Simple;
use Date::Parse;
use HTTP::Cookies;
use HTTP::Request;
use LWP::UserAgent;
use Log::Log4perl qw(:easy);

use POSIX;
use Carp;
use strict;
use vars qw( $VERSION );
use XML::Simple;

use vars qw( $VERSION );
$VERSION = '0.1';

#################################################################
# Title : new (public)
# Usage : my $fb = new FitbitClient();
# Usage : my $fb = WWW::Fitbit::API->new();
# Purpose : Constructor
# Parameters : user_id (url profile), uid, uis, sid (cookies)
# Returns : Blessed class
Expand Down Expand Up @@ -55,7 +54,7 @@ sub new {
else {
my @required_params = qw[uis uid sid user_id];
foreach (@required_params) {
croak "$_ is a required parameter!"
confess "$_ is a required parameter!"
if !defined $params{$_};
}
$self->{_uis} = $params{'uis'};
Expand All @@ -82,12 +81,12 @@ sub _load_fitbit_config {
my ($filename) = @_;

$/ = "";
open( CONFIG, "$filename" ) or die "Can't open config $filename!";
open( CONFIG, "$filename" ) or confess "Can't open config $filename!";
my $config_file = <CONFIG>;
close(CONFIG);
undef $/;

my $config = eval($config_file) or die "Invalid config file format!";
my $config = eval($config_file) or confess "Invalid config file format!";

return $config;

Expand Down Expand Up @@ -288,7 +287,7 @@ sub total_sleep_time {
# Usage : $self->_check_date_format($date)
# Purpose : Verify valid date format is supplied
# Parameters : date
# Returns : 1 (true) ; croak on error
# Returns : 1 (true) ; confess on error

sub _check_date_format {

Expand All @@ -297,7 +296,7 @@ sub _check_date_format {

# Very basic regex to check date format
if ( $date !~ /(\d{4})-(\d{2})-(\d{2})/ ) {
croak "Invalid date format [$date]. Expected (YYYY-MM-DD)";
confess "Invalid date format [$date]. Expected (YYYY-MM-DD)";
}

return 1;
Expand Down Expand Up @@ -360,13 +359,13 @@ sub _request_http {
$self->{_logger}->debug("URL = $url");

# Note that user agent also uses cookie jar created on initialization
my $request = new HTTP::Request 'GET', $url;
my $request = HTTP::Request->new('GET', $url);
my $response = $self->{_ua}->request($request);

if ( !$response->is_success ) {
$self->{_logger}
->info( "HTTP status = ", Dumper( $response->status_line ) );
die "Couldn't get graph data; reason = HTTP status ($response->{_rc})!";
confess "Couldn't get graph data; reason = HTTP status ($response->{_rc})!";
}

return $response->content;
Expand Down Expand Up @@ -405,15 +404,15 @@ sub _request_graph_xml {
};

if ( !defined $type_map->{$graph_type} ) {
croak "$graph_type is not a valid graph type!";
confess "$graph_type is not a valid graph type!";
}

# TODO Add methods for sleep; need to solve day-boundary problem (see python code)

# TODO Add second parameter (duration in days) to fetch multiple days worth of data
# in a single request (avoiding multiple HTTP Requests). This would change duration
# from 1d to 1m

# TODO Add support for getting weight info

my $base_params = {
Expand Down Expand Up @@ -465,7 +464,7 @@ sub _parse_graph_xml {

eval { $graph_data = XMLin( $xml, keyattr => [] ); };
if ($@) {
die "$$: XMLin() died: $@\n";
confess "$$: XMLin() died: $@\n";
}

my @entries;
Expand Down Expand Up @@ -608,43 +607,43 @@ __END__
=head1 NAME
FitbitClient - OO Perl API used to fetch fitness data from fitbit.com
WWW::Fitbit::API - OO Perl API used to fetch fitness data from fitbit.com
=head1 SYNOPSIS
Sample Usage:
use FitbitClient;
my $fb = new FitbitClient(
use WWW::Fitbit::API;
my $fb = WWW::Fitbit::API->new(
# Available from fitbit profile URL
user_id => "XXXNSD",
# Populated by cookie
sid => "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
uid => "12345",
uis => "XXX%3D"
);
OR
my $fb = new FitbitClient(config => 'conf/fitbit.conf');
my $fb = WWW::Fitbit::API->new(config => 'conf/fitbit.conf');
# No date defaults to today
my @log = $fb->get_calories_log();
foreach (@log) {
print "time = $_->{time} : calories = $_->{value}\n";
}
print "calories = " . $fb->total_calories("2010-05-03") . "\n";
print "activescore = " . $fb->total_active_score("2010-05-03") . "\n";
print "steps = " . $fb->total_steps("2010-05-03") . "\n";
=head1 DESCRIPTION
C<FitbitClient> provides an OO API for fetching fitness data from fitbit.com.
C<WWW::Fitbit::API> provides an OO API for fetching fitness data from fitbit.com.
Currently there is no official API, however data is retrieved using XML feeds
that populate the flash-based charts.
that populate the flash-based charts.
Intraday (5min and 1min intervals) logs are provide for:
Expand Down Expand Up @@ -678,15 +677,15 @@ See test_client.pl and dump_csv.pl
At this time, if you attempt to tally the intraday (5min) logs for
the total daily number, this number will NOT match the number from
the total_*_ API call. This is due to the way that FitBit feeds the
intraday values via XML to the flash-graph chart. All numbers are
intraday values via XML to the flash-graph chart. All numbers are
whole numbers, and this rounding issue causes the detailed log
tally to be between 10-100 points higher.
For example:
# Calling total = 2122
print "Total calories burned = " . $fb->total_calories()->{burned} . "\n";
# Tallying total from log entries = 2157
my $total = 0;
$total += $_->{value} foreach ( $fb->get_calories_log($date) );
Expand Down
3 changes: 0 additions & 3 deletions log/debug.log
@@ -1,4 +1 @@
2010/05/11 20:48:06 INFO> FitbitClient.pm:462 FitbitClient::_parse_graph_xml - Getting calories burned for date 2010-05-11
2010/07/07 16:35:27 INFO> FitbitClient.pm:462 FitbitClient::_parse_graph_xml - Getting calories burned for date 2010-07-07
2010/07/07 16:35:28 INFO> FitbitClient.pm:368 FitbitClient::_request_http - HTTP status = $VAR1 = '500 Internal Server Error';

9 changes: 6 additions & 3 deletions dump_csv.pl → script/dump_csv.pl 100644 → 100755
@@ -1,15 +1,18 @@
#!/usr/bin/perl

use strict;
use warnings;

#
# Author: Eric Blue - ericblue76@gmail.com
# Project: Perl Fitbit API - CSV export
# Url: http://eric-blue.com/projects/fitbit
#

use FitbitClient;
use WWW::Fitbit::API;
use POSIX;

my $fb = new FitbitClient( config => 'conf/fitbit.conf' );
my $fb = WWW::Fitbit::API->new( config => 'conf/fitbit.conf' );

my $day = 86400; # 1 day
my $total_days = 7;
Expand All @@ -23,7 +26,7 @@
print TOTALS_CSV "\n";

for ( my $i = 0 ; $i < $total_days ; $i++ ) {
$previous_day = strftime( "%F", localtime( time - $day ) );
my $previous_day = strftime( "%F", localtime( time - $day ) );
print "Getting data for $previous_day ...\n";

print TOTALS_CSV $previous_day . ",";
Expand Down
7 changes: 5 additions & 2 deletions test_client.pl → script/test_client.pl 100644 → 100755
@@ -1,14 +1,17 @@
#!/usr/bin/perl

use strict;
use warnings;

#
# Author: Eric Blue - ericblue76@gmail.com
# Project: Perl Fitbit API - client test script
# Url: http://eric-blue.com/projects/fitbit
#

use FitbitClient;
use WWW::Fitbit::API;

my $fb = new FitbitClient( config => 'conf/fitbit.conf' );
my $fb = WWW::Fitbit::API->new( config => 'conf/fitbit.conf' );

print "Total calories burned = " . $fb->total_calories()->{burned} . "\n";
print "Total calories consumed = " . $fb->total_calories()->{consumed} . "\n";
Expand Down
12 changes: 12 additions & 0 deletions t/00-load.t
@@ -0,0 +1,12 @@
#! perl

use Test::More;

BEGIN {
use_ok 'WWW::Fitbit::API'
or BAIL_OUT( "main module can't compile?!" )
}

diag "Testing WWW::Fitbit::API version $WWW::Fitbit::API::VERSION";

done_testing(1);
9 changes: 9 additions & 0 deletions t/config.t
@@ -0,0 +1,9 @@
#! perl

use Test::More;
use Test::Exception;
use WWW::Fitbit::API;

dies_ok { WWW::Fitbit::API->new() } 'new() without config throws exception';

done_testing(1);

0 comments on commit 76668c9

Please sign in to comment.