Skip to content

Instantly share code, notes, and snippets.

@pepl
Created February 2, 2022 08:33
Show Gist options
  • Save pepl/eb3f49f7749f4865e20e429231d86cc0 to your computer and use it in GitHub Desktop.
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)
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