jonasoreland / runnerup

A open source run tracker
GNU General Public License v3.0
742 stars 274 forks source link

runtastic import #89

Closed dhiltonp closed 10 years ago

dhiltonp commented 10 years ago

I've done some preliminary looking into runtastic imports (manually uploading an exported tcx and gpx), and the tcx data successfully imported pauses, while the gpx file didn't.

After authentication, the file is uploaded here: https://www.runtastic.com/import/upload_session (I get {"error":"Uploading failed"} when accessing the url directly)

jonasoreland commented 10 years ago

is there any API documentation ?

/Jonas

On Tue, Aug 5, 2014 at 2:14 AM, David Hilton notifications@github.com wrote:

I've done some preliminary looking into runtastic imports (manually uploading an exported tcx and gpx), and the tcx data successfully imported pauses, while the gpx file didn't.

After authentication, the file is uploaded here: https://www.runtastic.com/import/upload_session (I get {"error":"Uploading failed"} when accessing the url directly)

— Reply to this email directly or view it on GitHub https://github.com/jonasoreland/runnerup/issues/89.

dhiltonp commented 10 years ago

Web programming isn't exactly my thing, but I would like to see this feature added :). I haven't found any public documentation; here's what I have so far for authentication:

    Authenticatation methods:

    <div class='fb_login'>
    <a href="/auth/facebook" class="link_as_button" data-gaq-action="facebook" data-gaq-category="login" id="fb_login_button"><div class='bttn fb_style'>
    <div class='icon'></div>
    <span>Facebook</span>
    </div>
    </a>
    </div>

    <div class='g_plus_login'>
    <div class='bttn g_plus_style g_signin '>
    <div class='icon'></div>
    <span>Google</span>
    </div>

    <form accept-charset="UTF-8" action="/en/d/users/sign_in.json" class="formtastic user" id="login_form" method="post">
        <div style="margin:0;padding:0;display:inline">
            <input name="utf8" type="hidden" value="&#x2713;" />
            <input name="authenticity_token" type="hidden" value="+BO8WnBoGno0ea+2AzF1ODQ9QyAO9bpEajtMMwdsIP0=" />
        </div>
        <fieldset class="inputs">
            <ol>
                <li class="string optional" id="user_email_input">
                    <label for="user_email">Email</label>
                    <input id="user_email" maxlength="255" name="user[email]" tabindex="10" type="text" />
                </li>
                <p class='forgot_password'><a href="/en/d/users/password/new">Forgot your password?</a>
                </p>
                <li class="password optional" id="user_password_input">
                    <label for="user_password">Password</label>
                    <input id="user_password" name="user[password]" tabindex="11" type="password" />
                </li>
            </ol>
        </fieldset>
        <fieldset class="buttons">
            <ol>
                <li class="commit">
                    <input class="bttn create" name="commit" tabindex="13" type="submit" value="Log in" />
                </li>

    Current login attempt:
    curl -L -k -c cookiejar https://runtastic.com > index.html
    grep sign_in.json index.html  # get authenticity token
    curl -c cookiejar -L -k --data-urlencode "authenticity_token=$FROM_INDEX&user_password=$PASSWORD&user_email=$EMAIL&submit=login_form" https://runtastic.com/en/d/users/sign_in.json > login_done.html

I'm botching the form submission somehow.

dhiltonp commented 10 years ago

post for authentication: url: https://www.runtastic.com/en/d/users/sign_in.json post data: authenticity_token=76jIR8ttjXNRl7Dp62aRZ0cln4lP%2FjMm0vzBmACc6bc%3D&user%5Bemail%5D=someone%40example.com&user%5Bpassword%5D=URLENCODEDPASSWORD

post for activity submission: url: https://www.runtastic.com/import/upload_session?authenticity_token=76jIR8ttjXNRl7Dp62aRZ0cln4lP%2FjMm0vzBmACc6bc%3D&qqfile=activity.tcx post data: the raw tcx file contents.

dhiltonp commented 10 years ago

There are 2 additional authentication methods; facebook and google oath2.

jonasoreland commented 10 years ago

Hi!

Great work!!

I'm currently experimenting with it and I get the authentication to work fine. But when I try to upload I get {"error":"undefined method `read' for \"activity.tcx\":String"}

I do "curl -v -v https://www.runtastic.com/import/upload_session?authenticity_token=${TOKEN}&qqfile=activity.tcx -d @activity.tcx"

Have you seen this ?

/Jonas

ps. currently only experimenting with curl...once that works I'll do it in java

On Wed, Aug 13, 2014 at 5:01 PM, David Hilton notifications@github.com wrote:

There are 2 additional authentication methods; facebook and google oath2.

— Reply to this email directly or view it on GitHub https://github.com/jonasoreland/runnerup/issues/89#issuecomment-52060452 .

dhiltonp commented 10 years ago

I was also using curl, but then figured out firebug a bit better; I've not replicated what they do... could you post the curl you're using to login as well?

I think the issue may involve cookies; 'curl -c cookiejar -b cookiejar ....' might work... We could also try sending the file with --data-binary or --data-urlencode...

jonasoreland commented 10 years ago

i've tried a bunch of different variants without getting it to work... including using cookies...

have you gotten it to work somehow ? how did you otherwise get these URL endpoints ?

/Jonas

On Wed, Aug 20, 2014 at 6:52 PM, David Hilton notifications@github.com wrote:

I was also using curl, but then figured out firebug a bit better; I've not replicated what they do... could you post the curl you're using to login as well?

I think the issue may involve cookies; 'curl -c cookiejar -b cookiejar ....' might work... We could also try sending the file with --data-binary or --data-urlencode...

— Reply to this email directly or view it on GitHub https://github.com/jonasoreland/runnerup/issues/89#issuecomment-52807174 .

dhiltonp commented 10 years ago

I learned how to get the info from firebug: https://www.dropbox.com/s/fefqhhlkx83nx9v/runtastic%20import.png?dl=0

jonasoreland commented 10 years ago

Ok, got one step further:

URL="https://www.runtastic.com/import/upload_session?authenticity_token=${TOKEN}" curl -v -v -c cookie.jar "$URL" -X POST -F qqfile=@activity.tcx

Now I get back success, but I need to choose sport to... Can you do that firebug thing to see how that's done too ?

/Jonas

dhiltonp commented 10 years ago

upload_session will return json:

{success = true,
 content = "<tr name='4053367'> <td> <select class="sport_type" id="data_imports_sport_type_4053367" name="data_imports[sport_type_4053367]"><option value="67">American Football</option> <option value="53">Back Country Skiing</option> <option value="24">Badminton</option> <option value="68">Baseball</option> <option value="45">Basketball</option> <option value="60">Biathlon</option> <option value="32">Climbing</option> <option value="8">Cross Country Skiing</option> <option value="69">Crossfit</option> <option value="37">Cross Skating</option> <option value="58">Curling</option> <option value="3">Cycling</option> <option value="50">Diving</option> <option value="12">Driving</option> <option value="49">Freecrossen</option> <option value="33">Frisbee</option> <option value="21">Golfing</option> <option value="36">Handbike</option> <option value="7">Hiking</option> <option value="71">Ice Hockey</option> <option value="54">Ice Skating</option> <option value="59">Ice Stock</option> <option value="44">Kayaking</option> <option value="61">Kite Skiing</option> <option value="43">Kite Surfing</option> <option value="11">Motorbiking</option> <option value="4">Mountain Biking</option> <option value="2">Nordic Walking</option> <option value="5">Other</option> <option value="47">Paragliding</option> <option value="22">Race Cycling</option> <option value="20">Riding</option> <option value="17">Rowing</option> <option value="75">Rugby</option> <option value="1" selected="selected">Running</option> <option value="29">Sailing</option> <option value="72">Skateboarding</option> <option value="6">Skating</option> <option value="9">Skiing</option> <option value="41">Nordic Cross Skating</option> <option value="55">Sledding</option> <option value="39">Smovey Walking</option> <option value="57">Snowball Fight</option> <option value="10">Snow Boarding</option> <option value="56">Snowman Building</option> <option value="13">Snowshoeing</option> <option value="38">Soccer</option> <option value="62">Speed Skiing</option> <option value="76">Standup Paddling</option> <option value="19">Walking</option> <option value="42">Surfing</option> <option value="18">Swimming</option> <option value="23">Tennis</option> <option value="35">Volleyball</option> <option value="48">Wake Boarding</option> <option value="30">Windsurfing</option></select> </td> <td> --- </td> <td> activity(3).tcx </td> <td> --- </td> <td class='status'> new </td> <td class='delete'> <div class='general_delete_icon'></div> </td> <td class='show'> </td> </tr> "}

sport_type 1 is Running, 3 is Cycling (19 is Walking).

POST to: https://www.runtastic.com/import/update_sport_type

authenticity_token=$TOKEN data_import_id =$FROM_CONTENT_TR_NAME sport_type_id=1 user_id=$EIGHT_DIGITS, I'm not sure the best place to get this from... it's part of the URL of my avatar, and but you may have a better way of getting it.

dhiltonp commented 10 years ago

It would be good to also run the 'refine elevation command', something like: GET: https://www.runtastic.com/en/users/david-hilton-15/sport-sessions/309721576/refine?user_id=$EIGHT_DIGITS

jonasoreland commented 10 years ago

hmm...don't know where to get the user_id otherwise it looks ok i think...

jl1990 commented 10 years ago

You can get it here:

"https://www.runtastic.com/en/users/"+ slug+"/import"

In the source code of the page there is an array like this:

var user = {"id":XXXXXXXX, ...}

I'm currently finishing my master thesis which is based on syncing sport data between different servers. About Runtastic, currently I can log in and get all the user data, but file uploading doesn't work for me. The server responds with "success" but it just doesn't upload the file.

I'm developing it in Android, but right now I'm testing it in Java with Apache HttpClient library, so I have all the functions if you need some help.

PS: About Endomondo, I can remove Workouts from the server if you need it.

Maybe we can work together on this.

jonasoreland commented 10 years ago

Hi jl1990

Thx for hint, I'll look into to that method... In general, you are most welcome to look at the 12 uploaders that's present in RunnerUp. And you are ofcourse also most welcome to contribute code or ideas.

/Jonas

jonasoreland commented 10 years ago

Hi again,

I've just tried this: GET on "https://www.runtastic.com/en/users/import?authenticity_token=${TOKEN}" But...no matter what TOKEN I put there I get back details for a Konstantin Neznamov. I have NO IDEA WHY ?? I get the token from the signin (without a token...)

jl1990 commented 10 years ago

Ok, I got it working some days ago. I just uploaded the code to github. Take a look at this class:

https://github.com/jl1990/Android_Sport_Share/blob/master/src/com/droidlogic/others/RuntasticFunctions.java

Edit: I finally decided to use Apache HttpClient library. It just simplify the work too much.

jonasoreland commented 10 years ago

Great!

A question: are all the arguments really needed ?? Sending User-agent: Mozilla/5.0 seems a bit silly. Have you tried to remove them one by one, to see when it stops working ??

/Jonas

jl1990 commented 10 years ago

No, just some of them are mandatory. But I didn't try to remove any of them. As it didn't work in the beginning (I think it was X-NewRelicID or some non-typical HTTP parameter), I tried to mimic the web navigator response to make it work, and it did.

jonasoreland commented 10 years ago

Update: committed runtastic uploader. It doesn't work however :-(

After my upload_session i get success back...back nothing shows on the site. To enable code, change DBHelper.VERSION to 26

jl1990 commented 10 years ago

Check cookies too, you have to mantain the session. I used Apache HttpClient because of that. You must mimic almost exactly the behaviour of a web browser or it won't work.

Hope it helps

edit: My code is working, if you have any doubt just ask (I know my code needs some cleaning but... I had to make it work and it wasn't easy).

jonasoreland commented 10 years ago

indeed! with cookie it actually worked!! thx closing this, runtastic will be in next release

dhiltonp commented 10 years ago

Sports type is always set to running (1); we should set this to biking (3), when appropriate.

jonasoreland commented 10 years ago

correct!! (i forgot)...

so I did this. 1) I wrote code to fix it. It of course didn't work :( 2) I ignored this and published anyway 3) We should file a new bug for that aspect.

On Sat, Oct 11, 2014 at 12:31 AM, David Hilton notifications@github.com wrote:

Sports type is always set to running (1); we should set this to biking (3), when appropriate.

— Reply to this email directly or view it on GitHub https://github.com/jonasoreland/runnerup/issues/89#issuecomment-58724357 .

fourlightyears commented 1 year ago

I tried to export an activity from Runnerup running on my old phone (using share/export or something) and then import it in my new phone (by using 'open with Runnerup from the file manager), in both gpx and tcx file formats, but in both cases the app said 'failed to import'. Is this related to the issue here?

I am using v2.6.0.2, which is the latest version.

I remember I was able to do it once before in what is probably an older version. Has something broken in the new version, or am I simply doing it wrong?

gerhardol commented 1 year ago

There has been very minimal changes to .tcx and no changes I can think of for .gpx the last two years or so. So it is likely something on the Runtastic side.

Compare to #1161 where Strava requires their own format to support importing cadence.

gerhardol commented 1 year ago

And the built-in uploader to Runtastic was removed some years ago, Runtastic removed support.

fourlightyears commented 1 year ago

Okay, sorry, I didn't even know what runtastic was until now, I should have googled it before posting. I thought it might have been the old name for Runnerup (Google Bard mislead me).

I'm not using any third party apps. My problem is exporting from Runnerup and importing back to Runnerup. It's giving import failed regardless of whether it's done on the same phone or a different one.

gerhardol commented 1 year ago

Maintenance Export and import database

RU can import workouts, not activities

fourlightyears commented 1 year ago

I already tried export and import database, but how do I copy the sqlite file into my other phone? It stores into an area that cannot be accessed i.e /Android/data/* , at least not without root.

gerhardol commented 1 year ago

Android have scooped storage, so this is what normal apps can access. A file manager like Solid or Amaze has such privileges. adb should work too.

fourlightyears commented 1 year ago

Thanks, I got Amaze from F-droid, and I can access the database.

I'm wondering if it's possible to do a sync with WebDAV connection as well? I logged into my Nextcloud with Runnerup on both phones, and didn't see anything getting synced in history.

PS: I had a look at the wiki, and saw upload 'OK' and Download blank for WebDAV, so assume it won't work ( https://github.com/jonasoreland/runnerup/wiki/Synchronization-with-external-providers ). Is this a feature that is planned at all?

gerhardol commented 1 year ago

I'm wondering if it's possible to do a sync with WebDAV connection as well? I logged into my Nextcloud with Runnerup on both phones, and didn't see anything getting synced in history.

You can upload gpx/tcx to WebDAV (sync can be done automatically or on request per activity).

PS: I had a look at the wiki, and saw upload 'OK' and Download blank for WebDAV, so assume it won't work ( https://github.com/jonasoreland/runnerup/wiki/Synchronization-with-external-providers ). Is this a feature that is planned at all?

Download is not planned (by me, but someone else may contribute it). Download would require parsing of activities as well which there is no support for. There were some previous formats that had implemented this, but here it would be tcx/gpx which is quite generic and it will be a lot of work to support expected formats..