Created
February 2, 2022 08:33
-
-
Save pepl/eb3f49f7749f4865e20e429231d86cc0 to your computer and use it in GitHub Desktop.
Initial version from 2016 (before Strava API data has been significantly restricted for privacy reasons)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use warnings; | |
use Cpanel::JSON::XS; | |
use Text::CSV_XS; | |
use DateTime; | |
use DateTime::Format::ISO8601; | |
use WebService::Strava; | |
use Net::Google::Drive::Simple; | |
binmode STDOUT, ":utf8"; | |
binmode STDERR, ":utf8"; | |
my $json = Cpanel::JSON::XS->new; | |
my $strava = WebService::Strava->new(); | |
my $racingdivision_club = 180386; | |
my $vicc_club = 75500; | |
my $requested_club; | |
foreach my $club ( @{$strava->clubs()} ) { | |
if ( $club->id == $racingdivision_club ) { | |
$requested_club = $club; | |
last; | |
} | |
} | |
my $last_sunday = DateTime->now( time_zone => 'Europe/Vienna' ); | |
while ( $last_sunday->day_of_week != 7 ) { | |
$last_sunday->subtract( days => 1 ); | |
} | |
$last_sunday->set_hour(0); | |
$last_sunday->set_minute(0); | |
$last_sunday->set_second(0); | |
my $last_saturday = $last_sunday->clone->subtract( days => 1 ); | |
#my $club_activies = $strava->auth->get_api(sprintf("/clubs/%d/leaderboard", $requested_club->id)); | |
my $club_activies = $strava->auth->get_api(sprintf("/clubs/%d/activities?per_page=200", $requested_club->id)); | |
#my $club_activies = $strava->auth->get_api("/athlete/activities?after=" . (DateTime->now( time_zone => 'Europe/Vienna' )->epoch - 7200)); | |
# No longer supported by the API | |
#my $club_activies = $strava->auth->get_api("/activities/6616586912/related"); | |
my $club_activies = $strava->auth->get_api(sprintf("/clubs/%d/activities?before=%d", $requested_club->id, $d->epoch)); | |
push (@$club_activies, @{ $strava->auth->get_api(sprintf("/clubs/%d/activities?week_offset=1", $requested_club->id)) }); | |
my @vicc_standard_group_rides = ( | |
[ 'west', qr/\bwest\b/i, ], | |
[ 'east', qr/\beast\b/i, ], | |
[ 'south', qr/\bsouth\b/i, ], | |
[ 'vicc_loop', qr/\bvicc loop\b/i, ], | |
[ 'beginner', qr/\bbeginner\b/i, ], | |
[ 'sundayfunday', qr/\bsundayfunday\b/i, ], | |
[ 'group 3', qr/\bgroup 3\b/i, ], | |
); | |
my %seen_group_rides; | |
my %last_weekend_activities; | |
my $iso8601 = DateTime::Format::ISO8601->new(); | |
foreach my $activity ( @$club_activies ) { | |
my $start_date_local = $iso8601->parse_datetime( $activity->{start_date_local} ); | |
next unless | |
($start_date_local->ymd eq $last_sunday->ymd | |
or $start_date_local->ymd eq $last_saturday->ymd); | |
foreach my $group_ride ( @vicc_standard_group_rides ) { | |
if ( $activity->{name} =~ /$group_ride->[1]/ ) { | |
next if exists $seen_group_rides{$group_ride->[0]}->{$start_date_local->ymd}->{$activity->{id}}; | |
$last_weekend_activities{$group_ride->[0]}->{$start_date_local->ymd}->{$activity->{id}} = [$activity]; | |
my $related_activites = $strava->auth->get_api(sprintf("/activities/%d/related?per_page=200", $activity->{id})); | |
push( @{$last_weekend_activities{$group_ride->[0]}->{$start_date_local->ymd}->{$activity->{id}}}, @$related_activites); | |
foreach my $act ( $activity, @$related_activites ) { | |
$seen_group_rides{$group_ride->[0]}->{$start_date_local->ymd}->{$act->{id}} = 1; | |
} | |
} | |
} | |
} | |
my @files_to_be_uploaded; | |
my $csv = Text::CSV_XS->new(); | |
foreach my $group_ride_key ( keys %last_weekend_activities ) { | |
foreach my $day ( keys %{$last_weekend_activities{$group_ride_key}} ) { | |
foreach my $base_activity_id ( keys %{$last_weekend_activities{$group_ride_key}->{$day}} ) { | |
my $filename = sprintf('%s_%s-%s.csv', $day, $group_ride_key, $base_activity_id); | |
open my $fh, ">:encoding(utf8)", $filename or die "$filename: $!"; | |
my @rows; | |
foreach my $activity ( @{$last_weekend_activities{$group_ride_key}->{$day}->{$base_activity_id}} ) { | |
push(@rows, activity_to_row($base_activity_id, $activity)); | |
} | |
$csv->say($fh, $_) for activity_header_row(); | |
$csv->say($fh, $_) for @rows; | |
warn sprintf("[%s][%s] Got %d activities for base id %d\n", $day, $group_ride_key, scalar @rows, $base_activity_id); | |
close $fh or die "$filename: $!"; | |
warn "Wrote $filename\n"; | |
push(@files_to_be_uploaded, $filename); | |
} | |
} | |
} | |
my $filename = sprintf('%s-%s_club_%s_activities.json', $last_saturday->ymd, $last_sunday->ymd, $requested_club->id); | |
open my $fh, ">:encoding(utf8)", $filename or die "$filename: $!"; | |
print $fh $json->encode(\%last_weekend_activities); | |
close $fh; | |
warn "Wrote $filename\n"; | |
push(@files_to_be_uploaded, $filename); | |
my $gd = Net::Google::Drive::Simple->new(); | |
my $this_weeks_dir_id = $gd->folder_create( $last_saturday->ymd . '_' . $last_sunday->ymd, '0B0g5W8yNYm0XSHJvOHZ4YmdSUm8' ); | |
foreach my $filename ( @files_to_be_uploaded ) { | |
if ( my $file_id = $gd->file_upload( $filename, $this_weeks_dir_id ) ) { | |
warn "Uploaded $filename as $file_id to folder " . $last_saturday->ymd . '_' . $last_sunday->ymd . "\n"; | |
} | |
else { | |
warn "Could not upload $filename\n"; | |
} | |
} | |
sub activity_header_row { | |
return [qw( | |
base_activity_id | |
name athlete_name sex max_heartrate | |
average_heartrate total_elevation_gain average_temp | |
achievement_count max_speed kilojoules suffer_score | |
average_watts moving_time elapsed_time distance average_speed | |
)]; | |
} | |
sub activity_to_row { | |
my ($base_activity_id, $activity) = @_; | |
return [ | |
$base_activity_id, | |
$activity->{name}, | |
$activity->{athlete}->{firstname} . ' ' . $activity->{athlete}->{lastname}, | |
$activity->{athlete}->{sex}, | |
$activity->{max_heartrate}, | |
$activity->{average_heartrate}, | |
$activity->{total_elevation_gain}, | |
$activity->{average_temp}, | |
$activity->{achievement_count}, | |
$activity->{max_speed} * 3.6, | |
$activity->{kilojoules}, | |
$activity->{suffer_score}, | |
$activity->{average_watts}, | |
$activity->{moving_time}, | |
$activity->{elapsed_time}, | |
$activity->{distance}, | |
$activity->{average_speed} * 3.6, | |
]; | |
} | |
# Monkeypatch to support CSV-Google Spreadsheet conversion | |
sub Net::Google::Drive::Simple::file_mime_type { | |
my( $self, $file ) = @_; | |
return 'application/vnd.google-apps.spreadsheet' if $file =~ /\.csv$/; | |
if( !$self->{ magic } ) { | |
$self->{ magic } = File::MMagic->new(); | |
} | |
return $self->{ magic }->checktype_filename( $file ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment