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

  1. package export;
  2. import java.io.BufferedReader;
  3. import java.io.BufferedWriter;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.FileWriter;
  8. import java.io.IOException;
  9. import java.io.InputStream;
  10. import java.io.InputStreamReader;
  11. import java.io.Reader;
  12. import java.net.HttpURLConnection;
  13. import java.net.URL;
  14. import java.nio.charset.Charset;
  15. import java.nio.charset.StandardCharsets;
  16. import java.util.ArrayList;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.zip.ZipEntry;
  21. import java.util.zip.ZipOutputStream;
  22. import javax.net.ssl.HttpsURLConnection;
  23. import org.json.simple.JSONArray;
  24. import org.json.simple.JSONObject;
  25. import org.json.simple.parser.JSONParser;
  26. import org.json.simple.parser.ParseException;
  27. public class Main
  28. {
  29. public static final String baseUrl = "https://www.strava.com/api/v3/";
  30. private static int athleteId = 0;
  31. private static JSONParser parser = new JSONParser();
  32. /**
  33. *
  34. * @param token
  35. */
  36. @SuppressWarnings("unchecked")
  37. static void oneAthlete(String token)
  38. {
  39. Map<String, File> athletesTempFiles = new HashMap<String, File>();
  40. // get general information
  41. athletesTempFiles.put("general_information.json", saveGeneralInformation(token));
  42. // get Activities
  43. Map<String, JSONObject> activities = getActivities(token);
  44. // for each activity: save streams
  45. int simpleActivityId=0;
  46. for (String id: activities.keySet())
  47. {
  48. JSONObject data = addStreams(id, activities.get(id), token);
  49. data.put("activity_id", simpleActivityId);
  50. try
  51. {
  52. File temp = File.createTempFile("activity_" +simpleActivityId , ".json");
  53. temp.deleteOnExit();
  54. BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
  55. bw.write(data.toString());
  56. bw.close();
  57. athletesTempFiles.put(""+simpleActivityId, temp);
  58. }
  59. catch (IOException e)
  60. {
  61. //Temp File coldnt be created
  62. // TODO Auto-generated catch block
  63. e.printStackTrace();
  64. }
  65. simpleActivityId++;
  66. }
  67. try
  68. {
  69. zipAllFiles(athletesTempFiles);
  70. }
  71. catch (IOException e)
  72. {
  73. //Problem zipping
  74. // TODO Auto-generated catch block
  75. e.printStackTrace();
  76. }
  77. }
  78. /**
  79. * Adds the streams to the given activity
  80. * @param id Strava id of the activity
  81. * @param data general information of the activity
  82. * @param token Identifier / authorization token of the athlete
  83. * @return The data with the added streams
  84. */
  85. @SuppressWarnings("unchecked")
  86. static JSONObject addStreams(String id, JSONObject data, String token)
  87. {
  88. //TODO: das k�nnte mit dem Array Probleme geben....
  89. String requestUrlExtension = "activities/"+id+"/streams?keys=[time, distance, latlng, altitude, "
  90. + "velocity_smooth, heartrate, cadence, watts, temp, moving, grade_smooth]&key_by_type=";
  91. String json = makeOneRequest(requestUrlExtension, token);
  92. String type = "type";
  93. Object obj;
  94. try
  95. {
  96. obj = parser.parse(json);
  97. JSONArray listOfStreams = (JSONArray) obj;
  98. for (int i=0; i<listOfStreams.size(); i++)
  99. {
  100. JSONObject oneStream = (JSONObject) listOfStreams.get(i);
  101. //TODO: hier null etc. abfangen
  102. data.put("stream_"+oneStream.get(type).toString(), oneStream);
  103. }
  104. }
  105. catch (ParseException e)
  106. {
  107. //Problem parsing json
  108. // TODO Auto-generated catch block
  109. e.printStackTrace();
  110. }
  111. // call by reference / value pruefen
  112. return data;
  113. }
  114. /**
  115. * Gathers all activities of a user, extracts the general information and the ids.
  116. * @param token Identifier / authorization token of the athlete
  117. * @return A Map with key = Strava Id of an activity and value = JSONObject with the general information of the activity
  118. */
  119. @SuppressWarnings("unchecked")
  120. static Map<String, JSONObject> getActivities(String token)
  121. {
  122. Map<String, JSONObject> result = new HashMap<>();
  123. /*
  124. * Possible values = AlpineSki, BackcountrySki, Canoeing, Crossfit, EBikeRide, Elliptical, Golf,
  125. * Handcycle, Hike, IceSkate, InlineSkate, Kayaking, Kitesurf, NordicSki, Ride, RockClimbing,
  126. * RollerSki, Rowing, Run, Sail, Skateboard, Snowboard, Snowshoe, Soccer, StairStepper,
  127. * StandUpPaddling, Surfing, Swim, Velomobile, VirtualRide, VirtualRun, Walk, WeightTraining,
  128. * Wheelchair, Windsurf, Workout, Yoga
  129. */
  130. String type = "type";
  131. String timezone = "timezone";
  132. String start = "start_date_local"; //Start date measured in users time zone
  133. String id = "id";
  134. int pageIndex = 1;
  135. while(true)
  136. {
  137. String requestExtension = "athlete/activities?before=&after=&page="+pageIndex+"&per_page=";
  138. String json = makeOneRequest(requestExtension, token);
  139. if (json.isEmpty()||json.isBlank()||json.equals("")) //don't know where the last page is...
  140. {
  141. break;
  142. }
  143. Object obj;
  144. try
  145. {
  146. obj = parser.parse(json);
  147. JSONArray listOfActivites = (JSONArray) obj;
  148. for (int i=0; i<listOfActivites.size(); i++)
  149. {
  150. JSONObject oneActivity = (JSONObject) listOfActivites.get(i);
  151. JSONObject toSave = new JSONObject();
  152. toSave.put(type, oneActivity.get(type));
  153. toSave.put(timezone, oneActivity.get(timezone));
  154. toSave.put(start, oneActivity.get(start));
  155. toSave.put("athlete_id", athleteId);
  156. //TODO: hier null etc. abfangen
  157. result.put(oneActivity.get(id).toString(), toSave);
  158. }
  159. }
  160. catch (ParseException e)
  161. {
  162. //Problem parsing json
  163. // TODO Auto-generated catch block
  164. e.printStackTrace();
  165. }
  166. pageIndex++;
  167. }
  168. return result;
  169. }
  170. /**
  171. * Extracts an athletes general information and writes the information to a temp file.
  172. * @param token Identifier / authorization token of the athlete
  173. * @return Created temp file or {@code null} if there was an error.
  174. */
  175. @SuppressWarnings("unchecked")
  176. static File saveGeneralInformation(String token)
  177. {
  178. //TODO: auf fehlende WErte vorbereiten
  179. String sex = "sex"; //Possible values = M, F
  180. String country = "country";
  181. String date_pref = "date_preference";
  182. String meas_pref = "measurement_preference"; //Possible values = feet, meters
  183. String weight = "weight";
  184. String json = makeOneRequest("athlete", token);
  185. JSONObject toSave = new JSONObject();
  186. try
  187. {
  188. Object obj = parser.parse(json);
  189. JSONObject data = (JSONObject) obj;
  190. toSave.put(sex, data.get(sex));
  191. toSave.put(country, data.get(country));
  192. toSave.put(date_pref, data.get(date_pref));
  193. toSave.put(meas_pref, data.get(meas_pref));
  194. toSave.put(weight, data.get(weight));
  195. toSave.put("id", athleteId);
  196. File temp = File.createTempFile("general_" +athleteId , ".json");
  197. temp.deleteOnExit();
  198. BufferedWriter bw = new BufferedWriter(new FileWriter(temp));
  199. bw.write(toSave.toString());
  200. bw.close();
  201. return temp;
  202. }
  203. catch (ParseException e)
  204. {
  205. //sonst ganze Datei abspeichern, nicht sch�n, aber evtl sinnvoll
  206. // TODO Auto-generated catch block
  207. e.printStackTrace();
  208. return null;
  209. }
  210. catch (IOException e)
  211. {
  212. //Fehler beim Schreiben als Temp-File
  213. // TODO Auto-generated catch block
  214. e.printStackTrace();
  215. return null;
  216. }
  217. }
  218. /**
  219. * Zip a list of files in one .zip file.
  220. * @param files HasMap of <intended Filename, File> which should be zipped
  221. * @throws IOException If there was an error zipping
  222. */
  223. static void zipAllFiles(Map<String,File> files) throws IOException
  224. {
  225. //TODO: checken, ob hier an den richtigen Ort gespeichert wird.
  226. //TODO: evtl. alles nochmal zippen
  227. FileOutputStream fos = new FileOutputStream("athlete_"+athleteId+".zip");
  228. ZipOutputStream zipOut = new ZipOutputStream(fos);
  229. for (String key : files.keySet())
  230. {
  231. File fileToZip = files.get(key);
  232. FileInputStream fis = new FileInputStream(fileToZip);
  233. ZipEntry zipEntry = new ZipEntry(key);
  234. zipOut.putNextEntry(zipEntry);
  235. byte[] bytes = new byte[1024];
  236. int length;
  237. while((length = fis.read(bytes)) >= 0) {
  238. zipOut.write(bytes, 0, length);
  239. }
  240. fis.close();
  241. }
  242. zipOut.close();
  243. fos.close();
  244. }
  245. /**
  246. * Handles one request to the API
  247. * @param requestUrlExtension Extension for the baseUrl (without '/')
  248. * @param token Identification / authorization token of the athlete
  249. * @return The response as a String, an empty String in case of error.
  250. */
  251. static String makeOneRequest(String requestUrlExtension, String token)
  252. {
  253. HttpURLConnection connection = null;
  254. StringBuilder result = new StringBuilder();
  255. try
  256. {
  257. //Create connection
  258. URL url = new URL(baseUrl+requestUrlExtension);
  259. connection = (HttpsURLConnection) url.openConnection();
  260. connection.setRequestMethod("GET");
  261. connection.setRequestProperty("Authorization", "Bearer [["+token+"]]");
  262. int responseCode = connection.getResponseCode();
  263. if (responseCode != HttpURLConnection.HTTP_OK)
  264. {
  265. //TODO: mehr auf response codes achten
  266. return "";
  267. }
  268. InputStream inputStream = connection.getInputStream();
  269. try (Reader reader = new BufferedReader(
  270. new InputStreamReader(inputStream, Charset.forName(StandardCharsets.UTF_8.name()))))
  271. {
  272. int c = reader.read();
  273. while (c != -1)
  274. {
  275. result.append((char) c);
  276. c = reader.read();
  277. }
  278. }
  279. }
  280. catch(IOException e)
  281. {
  282. //TODO: was tun bei error
  283. return "";
  284. }
  285. return result.toString();
  286. }
  287. public static void main(String[] args)
  288. {
  289. List<String> tokens = new ArrayList<>();
  290. //TODO: tokens bef�llen
  291. for (String token : tokens)
  292. {
  293. oneAthlete(token);
  294. athleteId++;
  295. }
  296. //TODO: alles nochmal zippen
  297. }
  298. }