This repository was archived by the owner on Oct 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAPI.java
More file actions
151 lines (142 loc) · 4.81 KB
/
API.java
File metadata and controls
151 lines (142 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package space.nasa.spaceapi.utilities;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import space.nasa.spaceapi.models.APOD;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.TreeSet;
/**
* Used to call NASA's APOD API
*/
public class API{
private static final Gson gson = new Gson();
private static final HttpClient client = HttpClient.newHttpClient();
private static final String uri = "https://api.nasa.gov/planetary/apod?thumbs=true&api_key=1rp568Tl7gR9976UiFzaPbedFvxnBFFYbdqxXazV";
private static float progress = 0.00F;
/**
* Returns an {@link APOD} of today's A.P.O.D.
*
* @return today's A.P.O.D.
*/
public static APOD getAPOD(){
return getAPOD(uri);
}
private static APOD getAPOD(String uri){
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri)).build();
try
{
String response = client.send(request, HttpResponse.BodyHandlers.ofString()).body();
return gson.fromJson(response, APOD.class);
}
catch(JsonSyntaxException | IOException | InterruptedException e)
{
e.printStackTrace();
return new APOD();
}
}
/**
* Call APOD API to get the specified date's A.P.O.D.
*
* @param date a {@link LocalDate} of desired A.P.O.D.
*
* @return the {@link APOD} of the given date
*/
public static APOD getAPOD(LocalDate date){
return getAPOD(uri + "&date=" + date);
}
/**
* Get the curent progress of the current or previous API call
* <ul>
* <li>
* returns 0 if the API call has not returned any elements
* </li>
* <li>
* returns >=1 if the API call has been completed and a {@link APOD} has been returned
* </li>>
* <li>
* returns between 0 and 1 if the query has not finished returning all the {@link APOD} elements
* </li>
* </ul>
*
* @return the progress of the API call as decimal (percent value)
*/
public static float getProgress(){
return progress;
}
/**
* Set the progress to given {@code float} Best used if chaining together multiple singular API calls of one A.P.O.D.
*
* @param progress the {@code float} to set the API progress to
*/
public static void setProgress(float progress){
API.progress = progress;
}
/**
* Call APOD API to get multiple A.P.O.D.s between the {@code start} and {@code end} date; inclusive.
* <p>
* If the start date is after the end date null will be returned. Furthermore if either the start or end date is outside the bounds of the {@link
* APOD#minDate} and {@link APOD#maxDate} respectively, null will be returned
* </p>
* <p>
* if more than 50 A.P.O.D.s are requested the call will be divided to multiple calls the progress of the overall call can be monitored with {@link
* API#getProgress()}
* </p>
*
* @param start the beginning {@link LocalDate} to search between for A.P.O.D.s must be after {@link APOD#minDate} (inclusive)
* @param end the last {@link LocalDate} to search between for A.P.O.D.s before {@link APOD#maxDate} (inclusive)
*
* @return returns a {@link TreeSet<APOD>} of all the {@link APOD}s or null if the either dates conditions aren't met or request is interrupted or
* could not be made
*/
public static TreeSet<APOD> getAPODs(LocalDate start, LocalDate end){
if(start.isAfter(end) || start.isBefore(APOD.minDate) || end.isAfter(APOD.maxDate))
return null;
Type typeOf = new TypeToken<TreeSet<APOD>>(){}.getType();
//break up requests for many apods
long days = ChronoUnit.DAYS.between(start, end);
if(days > 50)
{
progress = 0;
TreeSet<APOD> apods = new TreeSet<>();
for(long i = 0; i < ((days / 50) + 1); i++)
{
//access the start date, must be final, so it doesn't change when accessed by thread
final LocalDate threadStart = start.plusDays(50 * i);
//async thread to call numbered amount of APODs query
Thread query = new Thread(() -> {
if(threadStart.isAfter(end))
apods.add(getAPOD(end));
else
apods.addAll(getAPODs(threadStart, threadStart.plusDays(50)));
progress = (float) apods.size() / days;
});
query.start();
//wait for the query to complete
try {query.join();}
catch(InterruptedException e) {return null;}
}
return apods;
}
else
{
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(uri + "&start_date=" + start + "&end_date=" + end)).build();
try
{
String response = client.send(request, HttpResponse.BodyHandlers.ofString()).body();
return gson.fromJson(response, typeOf);
}
catch(JsonSyntaxException | IOException | InterruptedException e)
{
e.printStackTrace();
return null;
}
}
}
}