Jump to content

Import script, Strava Importer


SiNNuT
 Share

Recommended Posts

 Disclaimer   

This is not a step by step tutorial, but the script posted serves as an example of how easy it is to bootstrap ProcessWire(PW), query an external API (in this case, Strava) and import stuff into PW pages using the PW API.

To the import!

So i wanted a quick, easy and automated way to import someones Strava activities into his/her own 'activity feed' on a certain PW website.

Strava has an API which you can use to -amongst other things- get your own activity data. After setting up my Strava app i had access to the API. Next step was to import the JSON data i wanted into PW pages.

This was as easy as creating a PW bootstrapped script (see code below) and using the PW API to import the data into Pages. For convenience in talking to the Strava API i used a library that is available on Github. To keep track of what was happening i decided it would be nice to log the import results to a log file. Luckily, PW had me covered by using the WireLog class (/wire/core/WireLog.php).

Result

With some googling on Strava and a (very) basic knowledge of PHP and the PW API i was able to get things working in no-time. With no other CMS i've worked with -and i've had dealings with quite a few- it would have been so easy to get the desired result.

Some notes about the script:

  1. PW version used: 2.4.12, but should work in earlier versions as well.
  2. It does not create templates, fields and pages for you. If you would want to use it (maybe as a starting point), create templates, fields and pages for your own needs and adjust the script accordingly. Also remember to adjust script paths.
  3. In the posted example i don't do any sanitizing on the Strava data. You maybe should :)
  4. In production you would maybe call these kind of importers via a cronjob, and make it non-accessible from the outside.
  5. It served my purposes. There might be better ways of handling this stuff. All suggestions and/or questions are welcome. 

In this case the script was/is called importer_strava.php , located at mydomain/importer/importer_strava.php and requested manually. See notes above, number 3.

<?php 

/**
 * Strava Importer 
 *
 * This crude script will import your own Strava activities into newly created
 * PW pages under a given parent page. The import result will be logged in:
 * /site/assets/logs/importer_strava.txt, using the WireLog class.
 * 
 * For this to work you first need to create an app via http://www.strava.com/developers
 * Strava API reference: http://strava.github.io/api/
 *
 * The PHP library used for working with the Strava v3 API can be found at:
 * https://github.com/iamstuartwilson/strava
 *
 */

// Bootstrap Processwire
include __DIR__ . '/../index.php';

// Include the PHP Library for working with the Strava v3 API 
include __DIR__ . '/StravaApi.php';

// Strava credentials (you can get these from the Strava app page you've created)
$clientId = "Your clientId";
$clientSecret = "Your clientSecret";
$accessToken = "Your accessToken";

// Connect to Strava
$api = new StravaApi( $clientId, $clientSecret );

// Set the parent where activities will be stored as child pages
$activity_parent = wire('pages')->get("/activities/");

// Get new activities
$results = $api->get( 'athlete/activities', $accessToken, array( 'after' => $activity_parent->strava_last_checked ) );

// Uncomment if you want to inspect the $results response onscreen
// echo "<pre>";
// print_r($results);
// echo "</pre>";

// Import new Strava activities to PW Pages
if (empty($results)) {
    // Log that no activities have been imported
    $text = "No new activities have been imported";
    $options = array('showUser' => false, 'showPage' => false); 
    wire('log')->save('importer_strava', $text, $options); 
} else {
    $numImportedPages = 0; // Start counter for number of imported pages

    foreach ($results as $result) {
        $p = new Page(); // Create new page object
        $p->template = 'activity'; // Set template
        $p->parent = $activity_parent; // Set the parent

        // Assign $result data to the corresponding Page fields
        $p->name = $result->id;
        $p->title = $result->name;
        $p->act_distance = $result->distance;
        $p->act_moving_time = $result->moving_time;
        $p->act_elapsed_time = $result->elapsed_time;
        $p->act_total_elevation_gain = $result->total_elevation_gain;
        $p->act_type = $result->type;
        $p->act_start_date = substr($result->start_date_local, 0, 10);
        $p->act_average_speed = $result->average_speed;
        $p->act_start_lat = $result->start_latlng[0];
        $p->act_start_long = $result->start_latlng[1];
        $p->act_end_lat = $result->end_latlng[0];
        $p->act_end_long = $result->end_latlng[1];
        $map = $result->map;
        $p->act_map_polyline = $map->summary_polyline;

        $p->save(); // Save the Page object

        $numImportedPages++; // Increment counter
    }

    // Log the number of activities that have been imported
    $text = ($numImportedPages == 1) ? "$numImportedPages new activity imported" : "$numImportedPages new activities imported";
    $options = array('showUser' => false, 'showPage' => false); 
    wire('log')->save('importer_strava', $text, $options); 

    // After the import, update Field 'strava_last_checked' to current Unix timestamp
    // This could also be placed outside of the 'else' to update on each script run
    $timestamp = $activity_parent;
    $timestamp->of(false); // Turn off output formatting before saving things
    $timestamp->strava_last_checked = time();
    $timestamp->save('strava_last_checked');
}

  • Like 12
Link to comment
Share on other sites

Thanks for sharing this! Looks like a very good example of dealing with externals services.

You might want to consider taking advantage of __DIR__ (PHP 5.3.0+) or dirname(__FILE__) for includes: include __DIR__ . '/../index.php'. This way it's enough to know what's the relative location of, say, ProcessWire's index.php compared to it, instead of having to hard-code the paths in the file if you use it from multiple locations (php importer_strava.php, php mydomain/importer/importer_strava.php, cron etc.)

Strava looks interesting, too -- I've been using SportsTracker for similar purposes, but they don't seem to offer any kind of API for their service. Not sure yet if this is enough of a reason to switch platform, but you've given me some incentive to check out the alternatives ;)

Link to comment
Share on other sites

Thanks teppo,

Good tip on the include part. Updated the posted script with  __DIR__  because i really don't want to encourage taking anything < PHP 5.3 into consideration :)

Hell, even PHP 5.3 is already nearing end of life ( http://php.net/archive/2014.php#id2014-08-14-1 )

About Strava;

There are a lot of activity trackers out there that do the basics right. In the past i've also briefly used Endomondo and Runkeeper and they are fine too.

What i like about Strava:

  • The non-intrusive social features; making friends, following, creating clubs etcetera.
  • The famous Strava segments, where one can become "King of the Mountain". This should not be taken too seriously but me and my cycling buddies have been in serious competition with each other on our 'home' segments and having a lot of fun while doing so.
  • There are quite a lot of Pro's on Strava, which can be nice to follow, if you're into that.
  • It has a nice platform for developers.
  • It just feels like it has some momentum going.

What could be considered a downside is that they don't have an official Windows Phone app. So if you wanted to use your Windows Phone to do the tracking you are left out in the cold. Of course, there are ways around this with very decent third party apps, that allow to sync activities to Strava, but then you do miss some of the features. But you could always use the Strava website to fill in those gaps.

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...