You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
9.5 KiB
337 lines
9.5 KiB
package export;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.BufferedWriter;
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.FileWriter;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.Reader;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.URL;
|
|
import java.nio.charset.Charset;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipOutputStream;
|
|
|
|
import javax.net.ssl.HttpsURLConnection;
|
|
|
|
import org.json.simple.JSONArray;
|
|
import org.json.simple.JSONObject;
|
|
import org.json.simple.parser.JSONParser;
|
|
import org.json.simple.parser.ParseException;
|
|
|
|
public class Main
|
|
{
|
|
public static final String baseUrl = "https://www.strava.com/api/v3/";
|
|
private static int athleteId = 0;
|
|
private static JSONParser parser = new JSONParser();
|
|
|
|
/**
|
|
*
|
|
* @param token
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
static void oneAthlete(String token)
|
|
{
|
|
Map<String, File> athletesTempFiles = new HashMap<String, File>();
|
|
// get general information
|
|
athletesTempFiles.put("general_information.json", saveGeneralInformation(token));
|
|
|
|
// get Activities
|
|
Map<String, JSONObject> activities = getActivities(token);
|
|
|
|
// for each activity: save streams
|
|
int simpleActivityId=0;
|
|
for (String id: activities.keySet())
|
|
{
|
|
JSONObject data = addStreams(id, activities.get(id), token);
|
|
data.put("activity_id", simpleActivityId);
|
|
|
|
try
|
|
{
|
|
File temp = File.createTempFile("activity_" +simpleActivityId , ".json");
|
|
temp.deleteOnExit();
|
|
BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
|
|
bw.write(data.toString());
|
|
bw.close();
|
|
athletesTempFiles.put(""+simpleActivityId, temp);
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
//Temp File coldnt be created
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
|
|
simpleActivityId++;
|
|
}
|
|
|
|
try
|
|
{
|
|
zipAllFiles(athletesTempFiles);
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
//Problem zipping
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds the streams to the given activity
|
|
* @param id Strava id of the activity
|
|
* @param data general information of the activity
|
|
* @param token Identifier / authorization token of the athlete
|
|
* @return The data with the added streams
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
static JSONObject addStreams(String id, JSONObject data, String token)
|
|
{
|
|
//TODO: das könnte mit dem Array Probleme geben....
|
|
String requestUrlExtension = "activities/"+id+"/streams?keys=[time, distance, latlng, altitude, "
|
|
+ "velocity_smooth, heartrate, cadence, watts, temp, moving, grade_smooth]&key_by_type=";
|
|
String json = makeOneRequest(requestUrlExtension, token);
|
|
String type = "type";
|
|
|
|
Object obj;
|
|
try
|
|
{
|
|
obj = parser.parse(json);
|
|
JSONArray listOfStreams = (JSONArray) obj;
|
|
for (int i=0; i<listOfStreams.size(); i++)
|
|
{
|
|
JSONObject oneStream = (JSONObject) listOfStreams.get(i);
|
|
//TODO: hier null etc. abfangen
|
|
data.put("stream_"+oneStream.get(type).toString(), oneStream);
|
|
}
|
|
}
|
|
catch (ParseException e)
|
|
{
|
|
//Problem parsing json
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
|
|
// call by reference / value pruefen
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Gathers all activities of a user, extracts the general information and the ids.
|
|
* @param token Identifier / authorization token of the athlete
|
|
* @return A Map with key = Strava Id of an activity and value = JSONObject with the general information of the activity
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
static Map<String, JSONObject> getActivities(String token)
|
|
{
|
|
Map<String, JSONObject> result = new HashMap<>();
|
|
/*
|
|
* Possible values = AlpineSki, BackcountrySki, Canoeing, Crossfit, EBikeRide, Elliptical, Golf,
|
|
* Handcycle, Hike, IceSkate, InlineSkate, Kayaking, Kitesurf, NordicSki, Ride, RockClimbing,
|
|
* RollerSki, Rowing, Run, Sail, Skateboard, Snowboard, Snowshoe, Soccer, StairStepper,
|
|
* StandUpPaddling, Surfing, Swim, Velomobile, VirtualRide, VirtualRun, Walk, WeightTraining,
|
|
* Wheelchair, Windsurf, Workout, Yoga
|
|
*/
|
|
String type = "type";
|
|
String timezone = "timezone";
|
|
String start = "start_date_local"; //Start date measured in users time zone
|
|
String id = "id";
|
|
|
|
int pageIndex = 1;
|
|
while(true)
|
|
{
|
|
String requestExtension = "athlete/activities?before=&after=&page="+pageIndex+"&per_page=";
|
|
String json = makeOneRequest(requestExtension, token);
|
|
if (json.isEmpty()||json.isBlank()||json.equals("")) //don't know where the last page is...
|
|
{
|
|
break;
|
|
}
|
|
|
|
Object obj;
|
|
try
|
|
{
|
|
obj = parser.parse(json);
|
|
JSONArray listOfActivites = (JSONArray) obj;
|
|
for (int i=0; i<listOfActivites.size(); i++)
|
|
{
|
|
JSONObject oneActivity = (JSONObject) listOfActivites.get(i);
|
|
|
|
JSONObject toSave = new JSONObject();
|
|
toSave.put(type, oneActivity.get(type));
|
|
toSave.put(timezone, oneActivity.get(timezone));
|
|
toSave.put(start, oneActivity.get(start));
|
|
toSave.put("athlete_id", athleteId);
|
|
|
|
|
|
//TODO: hier null etc. abfangen
|
|
result.put(oneActivity.get(id).toString(), toSave);
|
|
}
|
|
}
|
|
catch (ParseException e)
|
|
{
|
|
//Problem parsing json
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
}
|
|
|
|
pageIndex++;
|
|
}
|
|
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extracts an athletes general information and writes the information to a temp file.
|
|
* @param token Identifier / authorization token of the athlete
|
|
* @return Created temp file or {@code null} if there was an error.
|
|
*/
|
|
@SuppressWarnings("unchecked")
|
|
static File saveGeneralInformation(String token)
|
|
{
|
|
//TODO: auf fehlende WErte vorbereiten
|
|
|
|
String sex = "sex"; //Possible values = M, F
|
|
String country = "country";
|
|
String date_pref = "date_preference";
|
|
String meas_pref = "measurement_preference"; //Possible values = feet, meters
|
|
String weight = "weight";
|
|
|
|
String json = makeOneRequest("athlete", token);
|
|
|
|
JSONObject toSave = new JSONObject();
|
|
try
|
|
{
|
|
Object obj = parser.parse(json);
|
|
JSONObject data = (JSONObject) obj;
|
|
toSave.put(sex, data.get(sex));
|
|
toSave.put(country, data.get(country));
|
|
toSave.put(date_pref, data.get(date_pref));
|
|
toSave.put(meas_pref, data.get(meas_pref));
|
|
toSave.put(weight, data.get(weight));
|
|
toSave.put("id", athleteId);
|
|
|
|
File temp = File.createTempFile("general_" +athleteId , ".json");
|
|
temp.deleteOnExit();
|
|
BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
|
|
bw.write(toSave.toString());
|
|
bw.close();
|
|
|
|
return temp;
|
|
}
|
|
catch (ParseException e)
|
|
{
|
|
//sonst ganze Datei abspeichern, nicht schön, aber evtl sinnvoll
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
return null;
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
//Fehler beim Schreiben als Temp-File
|
|
// TODO Auto-generated catch block
|
|
e.printStackTrace();
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Zip a list of files in one .zip file.
|
|
* @param files HasMap of <intended Filename, File> which should be zipped
|
|
* @throws IOException If there was an error zipping
|
|
*/
|
|
static void zipAllFiles(Map<String,File> files) throws IOException
|
|
{
|
|
//TODO: checken, ob hier an den richtigen Ort gespeichert wird.
|
|
//TODO: evtl. alles nochmal zippen
|
|
FileOutputStream fos = new FileOutputStream("athlete_"+athleteId+".zip");
|
|
ZipOutputStream zipOut = new ZipOutputStream(fos);
|
|
for (String key : files.keySet())
|
|
{
|
|
File fileToZip = files.get(key);
|
|
FileInputStream fis = new FileInputStream(fileToZip);
|
|
ZipEntry zipEntry = new ZipEntry(key);
|
|
zipOut.putNextEntry(zipEntry);
|
|
|
|
byte[] bytes = new byte[1024];
|
|
int length;
|
|
while((length = fis.read(bytes)) >= 0) {
|
|
zipOut.write(bytes, 0, length);
|
|
}
|
|
fis.close();
|
|
}
|
|
zipOut.close();
|
|
fos.close();
|
|
}
|
|
|
|
/**
|
|
* Handles one request to the API
|
|
* @param requestUrlExtension Extension for the baseUrl (without '/')
|
|
* @param token Identification / authorization token of the athlete
|
|
* @return The response as a String, an empty String in case of error.
|
|
*/
|
|
static String makeOneRequest(String requestUrlExtension, String token)
|
|
{
|
|
HttpURLConnection connection = null;
|
|
StringBuilder result = new StringBuilder();
|
|
try
|
|
{
|
|
//Create connection
|
|
URL url = new URL(baseUrl+requestUrlExtension);
|
|
connection = (HttpsURLConnection) url.openConnection();
|
|
connection.setRequestMethod("GET");
|
|
connection.setRequestProperty("Authorization", "Bearer [["+token+"]]");
|
|
|
|
int responseCode = connection.getResponseCode();
|
|
|
|
if (responseCode != HttpURLConnection.HTTP_OK)
|
|
{
|
|
//TODO: mehr auf response codes achten
|
|
return "";
|
|
}
|
|
|
|
InputStream inputStream = connection.getInputStream();
|
|
|
|
try (Reader reader = new BufferedReader(
|
|
new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name()))))
|
|
{
|
|
int c = reader.read();
|
|
while (c != -1)
|
|
{
|
|
result.append((char) c);
|
|
c = reader.read();
|
|
}
|
|
}
|
|
|
|
}
|
|
catch(IOException e)
|
|
{
|
|
//TODO: was tun bei error
|
|
return "";
|
|
}
|
|
return result.toString();
|
|
}
|
|
|
|
public static void main(String[] args)
|
|
{
|
|
List<String> tokens = new ArrayList<>();
|
|
//TODO: tokens befüllen
|
|
|
|
for (String token : tokens)
|
|
{
|
|
oneAthlete(token);
|
|
athleteId++;
|
|
}
|
|
//TODO: alles nochmal zippen
|
|
}
|
|
|
|
}
|