Skip to content

Instantly share code, notes, and snippets.

@yoshiki
Created February 8, 2011 15:41
Show Gist options
  • Save yoshiki/816605 to your computer and use it in GitHub Desktop.
Save yoshiki/816605 to your computer and use it in GitHub Desktop.
fetch app stats from appstore
#!/usr/bin/perl
#
# Product Type Identifier Category Description
# 1 Free or Paid Apps iPhone and iPod Touch
# 7 Updates iPhone and iPod Touch
# IA1 In Apps In-App Purchase
# IA9 In Apps In-App Subscription
# 1F Free or Paid Apps Universal Apps
# 7F Updates Universal Apps
# 1T Free or Paid Apps iPad App
# 7T Updates iPad App
use strict;
use warnings;
use Config::Pit;
use WWW::Mechanize;
use DateTime;
use Data::Dumper;
my $ITTS_BASE = 'https://itunesconnect.apple.com';
my $RPT_BASE = 'https://reportingitc.apple.com';
my $UA = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5';
my $date = DateTime->now( time_zone => 'UTC' );
my $yest = $date->clone->subtract( days => 1 );
my $sund = $date->clone->subtract( days => $date->day_of_week );
my $c = pit_get( 'developer.apple.com' );
my $mech = WWW::Mechanize->new;
$mech->agent( $UA );
$mech->cookie_jar( {} );
warn 'login';
$mech->get( "$ITTS_BASE/WebObjects/iTunesConnect.woa" );
$mech->submit_form(
form_name => 'appleConnectForm',
fields => {
theAccountName => $c->{ username },
theAccountPW => $c->{ password },
theAuxValue => undef,
'1.Continue.x' => 0,
'1.Continue.y' => 0,
},
);
warn 'defaultVendorPage';
$mech->get( $RPT_BASE );
my ( $vendor_tag_id )
= $mech->content =~ /<script id="(defaultVendorPage:j_id_jsp_[0-9]+_2)"/;
my $ajax_name = $vendor_tag_id =~ /defaultVendorPage:(j_id_jsp_[0-9]+_2)/;
$ajax_name =~ s/_2$/_0/;
my ( $view_state )
= $mech->content =~ /id="javax\.faces\.ViewState" value="(j_id[0-9]{5}:j_id[0-9]{5})"/;
$mech->post( "$RPT_BASE/vendor_default.faces", {
AJAXREQUEST => $ajax_name,
defaultVendorPage => 'defaultVendorPage',
$vendor_tag_id => $vendor_tag_id,
'javax.faces.ViewState' => $view_state,
} );
warn 'get dates';
$mech->get( "$RPT_BASE/sales.faces" );
my $re = qr{<option value="(\d{2}/\d{2}/\d{4})">[A-Za-z]{3} \d{2}, \d{4}</option>};
my $sales_content = $mech->content;
my @dates;
while ( $sales_content =~ m/$re/sg ) {
push @dates, $1;
}
( $view_state )
= $mech->content =~ /id="javax\.faces\.ViewState" value="(j_id[0-9]{5}:j_id[0-9]{5})"/;
my ( $daily_name )
= $mech->content =~ /<script id="(theForm:j_id_jsp_[0-9]+_6)"/;
( $ajax_name = $daily_name ) =~ s/_6$/_2/;
( my $date_name = $daily_name ) =~ s/_6$/_8/;
( my $select_name = $daily_name ) =~ s/_6$/_32/;
warn 'establish the initial date';
$mech->post( "$RPT_BASE/sales.faces", {
AJAXREQUEST => $ajax_name,
theForm => 'theForm',
'theForm:xyz' => 'notnormal',
'theForm:vendorType' => 'Y',
'theForm:datePickerSourceSelectElementSales' => $yest->strftime( '%m/%d/%Y' ),
'theForm:weekPickerSourceSelectElement' => $sund->strftime( '%m/%d/%Y' ),
'javax.faces.ViewState' => $view_state,
$date_name => $date_name,
} );
warn 'specify that we want daily reports';
$mech->post( "$RPT_BASE/sales.faces", {
AJAXREQUEST => $ajax_name,
theForm => 'theForm',
'theForm:xyz' => 'notnormal',
'theForm:vendorType' => 'Y',
'theForm:datePickerSourceSelectElementSales' => $yest->strftime( '%m/%d/%Y' ),
'theForm:weekPickerSourceSelectElement' => $sund->strftime( '%m/%d/%Y' ),
'javax.faces.ViewState' => $view_state,
$daily_name => $daily_name,
} );
for my $date ( @dates ) {
warn "getting data for $date";
$mech->post( "$RPT_BASE/sales.faces", {
AJAXREQUEST => $ajax_name,
theForm => 'theForm',
'theForm:xyz' => 'notnormal',
'theForm:vendorType' => 'Y',
'theForm:datePickerSourceSelectElementSales' => $date,
'theForm:weekPickerSourceSelectElement' => $sund->strftime( '%m/%d/%Y' ),
'javax.faces.ViewState' => $view_state,
$select_name => $select_name,
} );
( $view_state )
= $mech->content =~ /id="javax\.faces\.ViewState" value="(j_id[0-9]{5}:j_id[0-9]{5})"/;
$mech->post( "$RPT_BASE/sales.faces", {
theForm => 'theForm',
'theForm:xyz' => 'notnormal',
'theForm:vendorType' => 'Y',
'theForm:datePickerSourceSelectElementSales' => $date,
'theForm:weekPickerSourceSelectElement' => $sund->strftime( '%m/%d/%Y' ),
'javax.faces.ViewState' => $view_state,
'theForm:downloadLabel2' => 'theForm:downloadLabel2',
$select_name => $select_name,
} );
print $mech->content; # gziped
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment