1mod entities;
2mod error;
3
4pub use entities::access::{
6 EphemerisPoint, EphemerisRequest, EphemerisResponse, FOVAccessRequest, FOVAccessResponse,
7 GeoAccessQuery, GeoAccessResult, GroundStationAccessToSatelliteRequest, HorizonAccess,
8 LocationAccess, LocationWaypoint, SatelliteAccessToGroundstationRequest,
9 SatellitesToLocationRequest, SensorFrame, TrackingParameters,
10};
11pub use entities::account::{
12 AddGroupMemberRequest, GroupMember, UpdatePreferencesRequest, UserAccount, UserPreferences,
13};
14pub use entities::alert_subscription::{
15 AlertSubscription, AlertType, CreateAlertSubscriptionRequest, TargetType,
16 UpdateAlertSubscriptionRequest,
17};
18pub use entities::antenna::Antenna;
19pub use entities::auth::{
20 CreatePersonalAccessTokenRequest, CreatePersonalAccessTokenResponse, PersonalAccessToken,
21 PersonalAccessTokenListResponse,
22};
23pub use entities::collection_request::{
24 CollectionRequest, CollectionRequestType, CreateCollectionRequestRequest,
25};
26pub use entities::elset::{
27 CreateElsetRequest, Elset, ElsetCount, ElsetHistoryQuery, GeoScatterPoint, LeoScatterPoint,
28};
29pub use entities::filter::{Filter, FilterExpandRequest, FilterExpandResponse};
30pub use entities::groundstation::{Groundstation, GroundstationCreateRequest};
31pub use entities::image::{
32 ImageData, ImageDataRequest, ImageListQuery, ImageStatus, ImageUploadRequest,
33 ImageUploadResponse,
34};
35pub use entities::maneuver::{
36 CreateManeuverRequest, Maneuver, ManeuverListQuery, UpdateManeuverRequest,
37};
38pub use entities::observation::{
39 CreateOpticalObservationRequest, ObservationCount, ObservationQuery, OpticalObservation,
40};
41pub use entities::orbit_determination::{ODObservation, ODRequest, ODResult};
42pub use entities::rf_observation::{CreateRFCaptureRequest, RFCapture, RFCaptureSummary};
43pub use entities::satellite::{
44 CloseApproach, CountryCount, GroundTrackPoint, ObservationBounds, ObservationResidual,
45 OrbitalElements, RelativeState, ResidualResult, ResidualsRequest, Satellite, SatelliteListQuery,
46 SatelliteOverview, SatellitePageResponse, SatellitePaginatedResponse,
47};
48pub use entities::satellite_group::{
49 CreateSatelliteGroupRequest, SatelliteGroup, SatelliteGroupMembersRequest,
50 UpdateSatelliteGroupRequest,
51};
52pub use entities::task::{CreateTaskRequest, Task, TaskStatus, TaskUpdateRequest};
53pub use entities::telescope::Telescope;
54pub use entities::weather::{
55 CurrentWeather, MinutelyForecast, WeatherCondition, WeatherQuery, WeatherResponse,
56};
57pub use error::LemonaidError;
58
59pub struct CitraClient {
60 base_url: String,
61 api_key: String,
62 client: reqwest::Client,
63}
64
65impl CitraClient {
66 pub fn new(api_key: &str, dev: bool) -> Self {
67 if !dev {
68 return CitraClient {
69 base_url: "https://api.citra.space/".to_string(),
70 api_key: api_key.to_string(),
71 client: reqwest::Client::new(),
72 };
73 }
74 CitraClient {
75 base_url: "https://dev.api.citra.space/".to_string(),
76 api_key: api_key.to_string(),
77 client: reqwest::Client::new(),
78 }
79 }
80
81 async fn check_response(
83 &self,
84 response: reqwest::Response,
85 ) -> Result<reqwest::Response, LemonaidError> {
86 let status = response.status();
87 if status.is_success() {
88 Ok(response)
89 } else {
90 let message = response
91 .text()
92 .await
93 .unwrap_or_else(|_| "Unknown error".to_string());
94 Err(LemonaidError::Api { status, message })
95 }
96 }
97
98 pub async fn get_telescope(&self, telescope_id: &str) -> Result<Telescope, LemonaidError> {
101 let url = format!("{}telescopes/{}", self.base_url, telescope_id);
102 let response = self
103 .client
104 .get(&url)
105 .header("Authorization", format!("Bearer {}", self.api_key))
106 .send()
107 .await?;
108 let response = self.check_response(response).await?;
109 let telescope = response.json::<Telescope>().await?;
110 Ok(telescope)
111 }
112
113 pub async fn list_telescopes(&self) -> Result<Vec<Telescope>, LemonaidError> {
114 let url = format!("{}telescopes", self.base_url);
115 let response = self
116 .client
117 .get(&url)
118 .header("Authorization", format!("Bearer {}", self.api_key))
119 .send()
120 .await?;
121 let response = self.check_response(response).await?;
122 let telescopes = response.json::<Vec<Telescope>>().await?;
123 Ok(telescopes)
124 }
125
126 pub async fn list_my_telescopes(&self) -> Result<Vec<Telescope>, LemonaidError> {
127 let url = format!("{}my/telescopes", self.base_url);
128 let response = self
129 .client
130 .get(&url)
131 .header("Authorization", format!("Bearer {}", self.api_key))
132 .send()
133 .await?;
134 let response = self.check_response(response).await?;
135 let telescopes = response.json::<Vec<Telescope>>().await?;
136 Ok(telescopes)
137 }
138
139 pub async fn create_telescope(
140 &self,
141 telescope: &Telescope,
142 ) -> Result<Telescope, LemonaidError> {
143 let url = format!("{}telescopes", self.base_url);
144 let response = self
145 .client
146 .post(&url)
147 .header("Authorization", format!("Bearer {}", self.api_key))
148 .json(&vec![telescope])
149 .send()
150 .await?;
151 let response = self.check_response(response).await?;
152 let telescopes = response.json::<Vec<Telescope>>().await?;
153 Ok(telescopes.into_iter().next().unwrap())
154 }
155
156 pub async fn delete_telescope(&self, telescope_id: &str) -> Result<(), LemonaidError> {
157 let url = format!("{}telescopes", self.base_url);
158 let response = self
159 .client
160 .delete(&url)
161 .header("Authorization", format!("Bearer {}", self.api_key))
162 .json(&vec![telescope_id])
163 .send()
164 .await?;
165 self.check_response(response).await?;
166 Ok(())
167 }
168
169 pub async fn update_telescope(
170 &self,
171 telescope: &Telescope,
172 ) -> Result<Telescope, LemonaidError> {
173 let url = format!("{}telescopes", self.base_url);
174 let response = self
175 .client
176 .put(&url)
177 .header("Authorization", format!("Bearer {}", self.api_key))
178 .json(&vec![telescope])
179 .send()
180 .await?;
181 let response = self.check_response(response).await?;
182 let telescopes = response.json::<Vec<Telescope>>().await?;
183 Ok(telescopes.into_iter().next().unwrap())
184 }
185
186 pub async fn list_tasks_for_telescope(
187 &self,
188 telescope_id: &str,
189 ) -> Result<Vec<Task>, LemonaidError> {
190 let url = format!("{}telescopes/{}/tasks", self.base_url, telescope_id);
191 let response = self
192 .client
193 .get(&url)
194 .header("Authorization", format!("Bearer {}", self.api_key))
195 .send()
196 .await?;
197 let response = self.check_response(response).await?;
198 let tasks = response.json::<Vec<Task>>().await?;
199 Ok(tasks)
200 }
201
202 pub async fn get_telescope_tasks_by_status(
203 &self,
204 telescope_id: &str,
205 statuses: Vec<TaskStatus>,
206 ) -> Result<Vec<Task>, LemonaidError> {
207 let status_params: Vec<String> = statuses
208 .iter()
209 .map(|s| format!("statuses={:?}", s))
210 .collect();
211 let query_string = status_params.join("&");
212 let url = format!(
213 "{}telescopes/{}/tasks?{}",
214 self.base_url, telescope_id, query_string
215 );
216 let response = self
217 .client
218 .get(&url)
219 .header("Authorization", format!("Bearer {}", self.api_key))
220 .send()
221 .await?;
222 let response = self.check_response(response).await?;
223 let tasks = response.json::<Vec<Task>>().await?;
224 Ok(tasks)
225 }
226
227 pub async fn list_images_for_telescope(
228 &self,
229 telescope_id: &str,
230 query: Option<&ImageListQuery>,
231 ) -> Result<Vec<ImageStatus>, LemonaidError> {
232 let mut url = format!("{}telescopes/{}/images", self.base_url, telescope_id);
233 if let Some(q) = query {
234 let mut params = Vec::new();
235 if let Some(offset) = q.offset {
236 params.push(format!("offset={}", offset));
237 }
238 if let Some(limit) = q.limit {
239 params.push(format!("limit={}", limit));
240 }
241 if let Some(ref status) = q.status {
242 params.push(format!("status={}", status));
243 }
244 if !params.is_empty() {
245 url = format!("{}?{}", url, params.join("&"));
246 }
247 }
248 let response = self
249 .client
250 .get(&url)
251 .header("Authorization", format!("Bearer {}", self.api_key))
252 .send()
253 .await?;
254 let response = self.check_response(response).await?;
255 let images = response.json::<Vec<ImageStatus>>().await?;
256 Ok(images)
257 }
258
259 pub async fn get_groundstation(
262 &self,
263 groundstation_id: &str,
264 ) -> Result<Groundstation, LemonaidError> {
265 let url = format!("{}ground-stations/{}", self.base_url, groundstation_id);
266 let response = self
267 .client
268 .get(&url)
269 .header("Authorization", format!("Bearer {}", self.api_key))
270 .send()
271 .await?;
272 let response = self.check_response(response).await?;
273 let groundstation = response.json::<Groundstation>().await?;
274 Ok(groundstation)
275 }
276
277 pub async fn list_groundstations(&self) -> Result<Vec<Groundstation>, LemonaidError> {
278 let url = format!("{}ground-stations", self.base_url);
279 let response = self
280 .client
281 .get(&url)
282 .header("Authorization", format!("Bearer {}", self.api_key))
283 .send()
284 .await?;
285 let response = self.check_response(response).await?;
286 let list_response = response
287 .json::<entities::groundstation::GroundstationListResponse>()
288 .await?;
289 Ok(list_response.ground_stations)
290 }
291
292 pub async fn list_my_groundstations(&self) -> Result<Vec<Groundstation>, LemonaidError> {
293 let url = format!("{}my/ground-stations", self.base_url);
294 let response = self
295 .client
296 .get(&url)
297 .header("Authorization", format!("Bearer {}", self.api_key))
298 .send()
299 .await?;
300 let response = self.check_response(response).await?;
301 let list_response = response
302 .json::<entities::groundstation::GroundstationListResponse>()
303 .await?;
304 Ok(list_response.ground_stations)
305 }
306
307 pub async fn create_groundstation(
308 &self,
309 groundstation: &GroundstationCreateRequest,
310 ) -> Result<Groundstation, LemonaidError> {
311 let url = format!("{}ground-stations", self.base_url);
312 let response = self
313 .client
314 .post(&url)
315 .header("Authorization", format!("Bearer {}", self.api_key))
316 .json(groundstation)
317 .send()
318 .await?;
319 let response = self.check_response(response).await?;
320 let created = response.json::<Groundstation>().await?;
321 Ok(created)
322 }
323
324 pub async fn delete_groundstation(&self, groundstation_id: &str) -> Result<(), LemonaidError> {
325 let url = format!("{}ground-stations/{}", self.base_url, groundstation_id);
326 let response = self
327 .client
328 .delete(&url)
329 .header("Authorization", format!("Bearer {}", self.api_key))
330 .send()
331 .await?;
332 self.check_response(response).await?;
333 Ok(())
334 }
335
336 pub async fn update_groundstation(
337 &self,
338 groundstation_id: &str,
339 groundstation: &GroundstationCreateRequest,
340 ) -> Result<Groundstation, LemonaidError> {
341 let url = format!("{}ground-stations/{}", self.base_url, groundstation_id);
342 let response = self
343 .client
344 .put(&url)
345 .header("Authorization", format!("Bearer {}", self.api_key))
346 .json(groundstation)
347 .send()
348 .await?;
349 let response = self.check_response(response).await?;
350 let groundstation = response.json::<Groundstation>().await?;
351 Ok(groundstation)
352 }
353
354 pub async fn list_telescopes_for_groundstation(
355 &self,
356 groundstation_id: &str,
357 ) -> Result<Vec<Telescope>, LemonaidError> {
358 let url = format!(
359 "{}ground-stations/{}/telescopes",
360 self.base_url, groundstation_id
361 );
362 let response = self
363 .client
364 .get(&url)
365 .header("Authorization", format!("Bearer {}", self.api_key))
366 .send()
367 .await?;
368 let response = self.check_response(response).await?;
369 let telescopes = response.json::<Vec<Telescope>>().await?;
370 Ok(telescopes)
371 }
372
373 pub async fn list_antennas_for_groundstation(
374 &self,
375 groundstation_id: &str,
376 ) -> Result<Vec<Antenna>, LemonaidError> {
377 let url = format!(
378 "{}ground-stations/{}/antennas",
379 self.base_url, groundstation_id
380 );
381 let response = self
382 .client
383 .get(&url)
384 .header("Authorization", format!("Bearer {}", self.api_key))
385 .send()
386 .await?;
387 let response = self.check_response(response).await?;
388 let antennas = response.json::<Vec<Antenna>>().await?;
389 Ok(antennas)
390 }
391
392 pub async fn list_antennas(&self) -> Result<Vec<Antenna>, LemonaidError> {
395 let url = format!("{}antennas", self.base_url);
396 let response = self
397 .client
398 .get(&url)
399 .header("Authorization", format!("Bearer {}", self.api_key))
400 .send()
401 .await?;
402 let response = self.check_response(response).await?;
403 let antennas = response.json::<Vec<Antenna>>().await?;
404 Ok(antennas)
405 }
406
407 pub async fn list_my_antennas(&self) -> Result<Vec<Antenna>, LemonaidError> {
408 let url = format!("{}my/antennas", self.base_url);
409 let response = self
410 .client
411 .get(&url)
412 .header("Authorization", format!("Bearer {}", self.api_key))
413 .send()
414 .await?;
415 let response = self.check_response(response).await?;
416 let antennas = response.json::<Vec<Antenna>>().await?;
417 Ok(antennas)
418 }
419
420 pub async fn get_antenna(&self, antenna_id: &str) -> Result<Antenna, LemonaidError> {
421 let url = format!("{}antennas/{}", self.base_url, antenna_id);
422 let response = self
423 .client
424 .get(&url)
425 .header("Authorization", format!("Bearer {}", self.api_key))
426 .send()
427 .await?;
428 let response = self.check_response(response).await?;
429 let antenna = response.json::<Antenna>().await?;
430 Ok(antenna)
431 }
432
433 pub async fn create_antenna(&self, antenna: &Antenna) -> Result<Antenna, LemonaidError> {
434 let url = format!("{}antennas", self.base_url);
435 let response = self
436 .client
437 .post(&url)
438 .header("Authorization", format!("Bearer {}", self.api_key))
439 .json(&vec![antenna])
440 .send()
441 .await?;
442 let response = self.check_response(response).await?;
443 let antennas = response.json::<Vec<Antenna>>().await?;
444 Ok(antennas.into_iter().next().unwrap())
445 }
446
447 pub async fn delete_antenna(&self, antenna_id: &str) -> Result<(), LemonaidError> {
448 let url = format!("{}antennas", self.base_url);
449 let response = self
450 .client
451 .delete(&url)
452 .header("Authorization", format!("Bearer {}", self.api_key))
453 .json(&vec![antenna_id])
454 .send()
455 .await?;
456 self.check_response(response).await?;
457 Ok(())
458 }
459
460 pub async fn update_antenna(&self, antenna: &Antenna) -> Result<Antenna, LemonaidError> {
461 let url = format!("{}antennas", self.base_url);
462 let response = self
463 .client
464 .put(&url)
465 .header("Authorization", format!("Bearer {}", self.api_key))
466 .json(&vec![antenna])
467 .send()
468 .await?;
469 let response = self.check_response(response).await?;
470 let antennas = response.json::<Vec<Antenna>>().await?;
471 Ok(antennas.into_iter().next().unwrap())
472 }
473
474 pub async fn list_tasks_for_antenna(
475 &self,
476 antenna_id: &str,
477 ) -> Result<Vec<Task>, LemonaidError> {
478 let url = format!("{}antennas/{}/tasks", self.base_url, antenna_id);
479 let response = self
480 .client
481 .get(&url)
482 .header("Authorization", format!("Bearer {}", self.api_key))
483 .send()
484 .await?;
485 let response = self.check_response(response).await?;
486 let tasks = response.json::<Vec<Task>>().await?;
487 Ok(tasks)
488 }
489
490 pub async fn get_antenna_tasks_by_status(
491 &self,
492 antenna_id: &str,
493 statuses: Vec<TaskStatus>,
494 ) -> Result<Vec<Task>, LemonaidError> {
495 let status_params: Vec<String> = statuses
496 .iter()
497 .map(|s| format!("statuses={:?}", s))
498 .collect();
499 let query_string = status_params.join("&");
500 let url = format!(
501 "{}antennas/{}/tasks?{}",
502 self.base_url, antenna_id, query_string
503 );
504 let response = self
505 .client
506 .get(&url)
507 .header("Authorization", format!("Bearer {}", self.api_key))
508 .send()
509 .await?;
510 let response = self.check_response(response).await?;
511 let tasks = response.json::<Vec<Task>>().await?;
512 Ok(tasks)
513 }
514
515 pub async fn create_task(&self, task: &CreateTaskRequest) -> Result<Task, LemonaidError> {
518 let url = format!("{}tasks", self.base_url);
519 let response = self
520 .client
521 .post(&url)
522 .header("Authorization", format!("Bearer {}", self.api_key))
523 .json(task)
524 .send()
525 .await?;
526 let response = self.check_response(response).await?;
527 let created_task = response.json::<Task>().await?;
528 Ok(created_task)
529 }
530
531 pub async fn update_task(&self, task: &TaskUpdateRequest) -> Result<Task, LemonaidError> {
532 let url = format!("{}tasks/{}", self.base_url, task.id);
533 let response = self
534 .client
535 .put(&url)
536 .header("Authorization", format!("Bearer {}", self.api_key))
537 .json(task)
538 .send()
539 .await?;
540 let response = self.check_response(response).await?;
541 let updated_task = response.json::<Task>().await?;
542 Ok(updated_task)
543 }
544
545 pub async fn list_images_for_task(
546 &self,
547 task_id: &str,
548 ) -> Result<Vec<ImageStatus>, LemonaidError> {
549 let url = format!("{}tasks/{}/images", self.base_url, task_id);
550 let response = self
551 .client
552 .get(&url)
553 .header("Authorization", format!("Bearer {}", self.api_key))
554 .send()
555 .await?;
556 let response = self.check_response(response).await?;
557 let images = response.json::<Vec<ImageStatus>>().await?;
558 Ok(images)
559 }
560
561 pub async fn solve_access_for_groundstation(
564 &self,
565 access_request: &SatelliteAccessToGroundstationRequest,
566 ) -> Result<Vec<HorizonAccess>, LemonaidError> {
567 let url = format!(
568 "{}access/window/satellites_to_ground_station",
569 self.base_url
570 );
571 let response = self
572 .client
573 .post(&url)
574 .header("Authorization", format!("Bearer {}", self.api_key))
575 .json(access_request)
576 .send()
577 .await?;
578 let response = self.check_response(response).await?;
579 let accesses = response.json::<Vec<HorizonAccess>>().await?;
580 Ok(accesses)
581 }
582
583 pub async fn solve_access_groundstations_to_satellite(
584 &self,
585 access_request: &GroundStationAccessToSatelliteRequest,
586 ) -> Result<Vec<HorizonAccess>, LemonaidError> {
587 let url = format!(
588 "{}access/window/ground_stations_to_satellite",
589 self.base_url
590 );
591 let response = self
592 .client
593 .post(&url)
594 .header("Authorization", format!("Bearer {}", self.api_key))
595 .json(access_request)
596 .send()
597 .await?;
598 let response = self.check_response(response).await?;
599 let accesses = response.json::<Vec<HorizonAccess>>().await?;
600 Ok(accesses)
601 }
602
603 pub async fn solve_access_satellites_to_location(
604 &self,
605 access_request: &SatellitesToLocationRequest,
606 ) -> Result<Vec<LocationAccess>, LemonaidError> {
607 let url = format!("{}access/window/satellitesToLocation", self.base_url);
608 let response = self
609 .client
610 .post(&url)
611 .header("Authorization", format!("Bearer {}", self.api_key))
612 .json(access_request)
613 .send()
614 .await?;
615 let response = self.check_response(response).await?;
616 let accesses = response.json::<Vec<LocationAccess>>().await?;
617 Ok(accesses)
618 }
619
620 pub async fn solve_fov_access(
621 &self,
622 fov_request: &FOVAccessRequest,
623 ) -> Result<Vec<FOVAccessResponse>, LemonaidError> {
624 let url = format!("{}access/fov", self.base_url);
625 let response = self
626 .client
627 .post(&url)
628 .header("Authorization", format!("Bearer {}", self.api_key))
629 .json(fov_request)
630 .send()
631 .await?;
632 let response = self.check_response(response).await?;
633 let fov_responses = response.json::<Vec<FOVAccessResponse>>().await?;
634 Ok(fov_responses)
635 }
636
637 pub async fn get_geo_access(
638 &self,
639 query: &GeoAccessQuery,
640 ) -> Result<Vec<GeoAccessResult>, LemonaidError> {
641 let mut params = Vec::new();
642 if let Some(min_lon) = query.min_longitude_deg {
643 params.push(format!("minLongitude={}", min_lon));
644 }
645 if let Some(max_lon) = query.max_longitude_deg {
646 params.push(format!("maxLongitude={}", max_lon));
647 }
648 if let Some(min_sma) = query.min_semi_major_axis_km {
649 params.push(format!("minSemiMajorAxis={}", min_sma));
650 }
651 if let Some(max_sma) = query.max_semi_major_axis_km {
652 params.push(format!("maxSemiMajorAxis={}", max_sma));
653 }
654 if let Some(max_inc) = query.max_inclination_deg {
655 params.push(format!("maxInclination={}", max_inc));
656 }
657 let url = if params.is_empty() {
658 format!("{}access/geo", self.base_url)
659 } else {
660 format!("{}access/geo?{}", self.base_url, params.join("&"))
661 };
662 let response = self
663 .client
664 .get(&url)
665 .header("Authorization", format!("Bearer {}", self.api_key))
666 .send()
667 .await?;
668 let response = self.check_response(response).await?;
669 let results = response.json::<Vec<GeoAccessResult>>().await?;
670 Ok(results)
671 }
672
673 pub async fn generate_ephemeris(
674 &self,
675 request: &EphemerisRequest,
676 ) -> Result<EphemerisResponse, LemonaidError> {
677 let url = format!("{}access/ephemeris", self.base_url);
678 let response = self
679 .client
680 .post(&url)
681 .header("Authorization", format!("Bearer {}", self.api_key))
682 .json(request)
683 .send()
684 .await?;
685 let response = self.check_response(response).await?;
686 let ephemeris = response.json::<EphemerisResponse>().await?;
687 Ok(ephemeris)
688 }
689
690 pub async fn create_rf_capture(
693 &self,
694 rf_capture_request: &CreateRFCaptureRequest,
695 ) -> Result<RFCapture, LemonaidError> {
696 let url = format!("{}rf-captures", self.base_url);
697 let response = self
698 .client
699 .post(&url)
700 .header("Authorization", format!("Bearer {}", self.api_key))
701 .json(rf_capture_request)
702 .send()
703 .await?;
704 let response = self.check_response(response).await?;
705 let rf_capture = response.json::<RFCapture>().await?;
706 Ok(rf_capture)
707 }
708
709 pub async fn get_rf_capture(&self, rf_capture_id: &str) -> Result<RFCapture, LemonaidError> {
710 let url = format!("{}rf-captures/{}", self.base_url, rf_capture_id);
711 let response = self
712 .client
713 .get(&url)
714 .header("Authorization", format!("Bearer {}", self.api_key))
715 .send()
716 .await?;
717 let response = self.check_response(response).await?;
718 let rf_capture = response.json::<RFCapture>().await?;
719 Ok(rf_capture)
720 }
721
722 pub async fn list_rf_captures_for_antenna(
723 &self,
724 antenna_id: &str,
725 ) -> Result<Vec<RFCaptureSummary>, LemonaidError> {
726 let url = format!("{}antennas/{}/rf-captures", self.base_url, antenna_id);
727 let response = self
728 .client
729 .get(&url)
730 .header("Authorization", format!("Bearer {}", self.api_key))
731 .send()
732 .await?;
733 let response = self.check_response(response).await?;
734 let rf_captures = response.json::<Vec<RFCaptureSummary>>().await?;
735 Ok(rf_captures)
736 }
737
738 pub async fn list_rf_captures_for_task(
739 &self,
740 task_id: &str,
741 ) -> Result<Vec<RFCaptureSummary>, LemonaidError> {
742 let url = format!("{}tasks/{}/rf-captures", self.base_url, task_id);
743 let response = self
744 .client
745 .get(&url)
746 .header("Authorization", format!("Bearer {}", self.api_key))
747 .send()
748 .await?;
749 let response = self.check_response(response).await?;
750 let rf_captures = response.json::<Vec<RFCaptureSummary>>().await?;
751 Ok(rf_captures)
752 }
753
754 pub async fn list_rf_captures_for_satellite(
755 &self,
756 satellite_id: &str,
757 ) -> Result<Vec<RFCaptureSummary>, LemonaidError> {
758 let url = format!("{}satellites/{}/rf-captures", self.base_url, satellite_id);
759 let response = self
760 .client
761 .get(&url)
762 .header("Authorization", format!("Bearer {}", self.api_key))
763 .send()
764 .await?;
765 let response = self.check_response(response).await?;
766 let rf_captures = response.json::<Vec<RFCaptureSummary>>().await?;
767 Ok(rf_captures)
768 }
769
770 pub async fn list_satellites(
773 &self,
774 query: Option<&SatelliteListQuery>,
775 ) -> Result<SatellitePageResponse, LemonaidError> {
776 let mut url = format!("{}satellites", self.base_url);
777 if let Some(q) = query {
778 let mut params = Vec::new();
779 if let Some(ref ids) = q.ids {
780 for id in ids {
781 params.push(format!("ids={}", id));
782 }
783 }
784 if let Some(ref search) = q.search {
785 params.push(format!("search={}", search));
786 }
787 if let Some(ref country) = q.country {
788 params.push(format!("country={}", country));
789 }
790 if let Some(ref object_type) = q.object_type {
791 params.push(format!("objectType={}", object_type));
792 }
793 if let Some(include_decayed) = q.include_decayed {
794 params.push(format!("includeDecayed={}", include_decayed));
795 }
796 if let Some(ref sort_by) = q.sort_by {
797 params.push(format!("sortBy={}", sort_by));
798 }
799 if let Some(ref sort_order) = q.sort_order {
800 params.push(format!("sortOrder={}", sort_order));
801 }
802 if let Some(offset) = q.offset {
803 params.push(format!("offset={}", offset));
804 }
805 if let Some(limit) = q.limit {
806 params.push(format!("limit={}", limit));
807 }
808 if !params.is_empty() {
809 url = format!("{}?{}", url, params.join("&"));
810 }
811 }
812 let response = self
813 .client
814 .get(&url)
815 .header("Authorization", format!("Bearer {}", self.api_key))
816 .send()
817 .await?;
818 let response = self.check_response(response).await?;
819 let page_response = response.json::<SatellitePageResponse>().await?;
820 Ok(page_response)
821 }
822
823 pub async fn get_satellite(&self, satellite_id: &str) -> Result<Satellite, LemonaidError> {
824 let url = format!("{}satellites/{}", self.base_url, satellite_id);
825 let response = self
826 .client
827 .get(&url)
828 .header("Authorization", format!("Bearer {}", self.api_key))
829 .send()
830 .await?;
831 let response = self.check_response(response).await?;
832 let satellite = response.json::<Satellite>().await?;
833 Ok(satellite)
834 }
835
836 pub async fn get_satellites_overview(&self) -> Result<SatelliteOverview, LemonaidError> {
837 let url = format!("{}satellites/overview", self.base_url);
838 let response = self
839 .client
840 .get(&url)
841 .header("Authorization", format!("Bearer {}", self.api_key))
842 .send()
843 .await?;
844 let response = self.check_response(response).await?;
845 let overview = response.json::<SatelliteOverview>().await?;
846 Ok(overview)
847 }
848
849 pub async fn get_satellite_countries(&self) -> Result<Vec<CountryCount>, LemonaidError> {
850 let url = format!("{}satellites/countries", self.base_url);
851 let response = self
852 .client
853 .get(&url)
854 .header("Authorization", format!("Bearer {}", self.api_key))
855 .send()
856 .await?;
857 let response = self.check_response(response).await?;
858 let countries = response.json::<Vec<CountryCount>>().await?;
859 Ok(countries)
860 }
861
862 pub async fn get_satellites_page(
863 &self,
864 offset: i64,
865 limit: i64,
866 ) -> Result<SatellitePaginatedResponse, LemonaidError> {
867 let url = format!(
868 "{}satellites/page?offset={}&limit={}",
869 self.base_url, offset, limit
870 );
871 let response = self
872 .client
873 .get(&url)
874 .header("Authorization", format!("Bearer {}", self.api_key))
875 .send()
876 .await?;
877 let response = self.check_response(response).await?;
878 let page = response.json::<SatellitePaginatedResponse>().await?;
879 Ok(page)
880 }
881
882 pub async fn list_tasks_for_satellite(
883 &self,
884 satellite_id: &str,
885 ) -> Result<Vec<Task>, LemonaidError> {
886 let url = format!("{}satellites/{}/tasks", self.base_url, satellite_id);
887 let response = self
888 .client
889 .get(&url)
890 .header("Authorization", format!("Bearer {}", self.api_key))
891 .send()
892 .await?;
893 let response = self.check_response(response).await?;
894 let tasks = response.json::<Vec<Task>>().await?;
895 Ok(tasks)
896 }
897
898 pub async fn calculate_residuals(
899 &self,
900 satellite_id: &str,
901 request: &ResidualsRequest,
902 ) -> Result<Vec<ResidualResult>, LemonaidError> {
903 let url = format!("{}satellites/{}/residuals", self.base_url, satellite_id);
904 let response = self
905 .client
906 .post(&url)
907 .header("Authorization", format!("Bearer {}", self.api_key))
908 .json(request)
909 .send()
910 .await?;
911 let response = self.check_response(response).await?;
912 let residuals = response.json::<Vec<ResidualResult>>().await?;
913 Ok(residuals)
914 }
915
916 pub async fn get_close_approaches(
917 &self,
918 satellite_id: &str,
919 ) -> Result<Vec<CloseApproach>, LemonaidError> {
920 let url = format!("{}satellites/{}/close-approaches", self.base_url, satellite_id);
921 let response = self
922 .client
923 .get(&url)
924 .header("Authorization", format!("Bearer {}", self.api_key))
925 .send()
926 .await?;
927 let response = self.check_response(response).await?;
928 let approaches = response.json::<Vec<CloseApproach>>().await?;
929 Ok(approaches)
930 }
931
932 pub async fn get_relative_state(
933 &self,
934 satellite_id: &str,
935 other_satellite_id: &str,
936 ) -> Result<Vec<RelativeState>, LemonaidError> {
937 let url = format!(
938 "{}satellites/{}/relative/{}",
939 self.base_url, satellite_id, other_satellite_id
940 );
941 let response = self
942 .client
943 .get(&url)
944 .header("Authorization", format!("Bearer {}", self.api_key))
945 .send()
946 .await?;
947 let response = self.check_response(response).await?;
948 let states = response.json::<Vec<RelativeState>>().await?;
949 Ok(states)
950 }
951
952 pub async fn get_satellite_ground_track(
953 &self,
954 satellite_id: &str,
955 ) -> Result<Vec<GroundTrackPoint>, LemonaidError> {
956 let url = format!("{}satellites/{}/ground-track", self.base_url, satellite_id);
957 let response = self
958 .client
959 .get(&url)
960 .header("Authorization", format!("Bearer {}", self.api_key))
961 .send()
962 .await?;
963 let response = self.check_response(response).await?;
964 let track = response.json::<Vec<GroundTrackPoint>>().await?;
965 Ok(track)
966 }
967
968 pub async fn get_satellite_observation_bounds(
969 &self,
970 satellite_id: &str,
971 ) -> Result<ObservationBounds, LemonaidError> {
972 let url = format!(
973 "{}satellites/{}/observation-bounds",
974 self.base_url, satellite_id
975 );
976 let response = self
977 .client
978 .get(&url)
979 .header("Authorization", format!("Bearer {}", self.api_key))
980 .send()
981 .await?;
982 let response = self.check_response(response).await?;
983 let bounds = response.json::<ObservationBounds>().await?;
984 Ok(bounds)
985 }
986
987 pub async fn get_satellite_groups_for_satellite(
988 &self,
989 satellite_id: &str,
990 ) -> Result<Vec<SatelliteGroup>, LemonaidError> {
991 let url = format!("{}satellites/{}/groups", self.base_url, satellite_id);
992 let response = self
993 .client
994 .get(&url)
995 .header("Authorization", format!("Bearer {}", self.api_key))
996 .send()
997 .await?;
998 let response = self.check_response(response).await?;
999 let groups = response.json::<Vec<SatelliteGroup>>().await?;
1000 Ok(groups)
1001 }
1002
1003 pub async fn list_images_for_satellite(
1004 &self,
1005 satellite_id: &str,
1006 query: Option<&ImageListQuery>,
1007 ) -> Result<Vec<ImageStatus>, LemonaidError> {
1008 let mut url = format!("{}satellites/{}/images", self.base_url, satellite_id);
1009 if let Some(q) = query {
1010 let mut params = Vec::new();
1011 if let Some(offset) = q.offset {
1012 params.push(format!("offset={}", offset));
1013 }
1014 if let Some(limit) = q.limit {
1015 params.push(format!("limit={}", limit));
1016 }
1017 if !params.is_empty() {
1018 url = format!("{}?{}", url, params.join("&"));
1019 }
1020 }
1021 let response = self
1022 .client
1023 .get(&url)
1024 .header("Authorization", format!("Bearer {}", self.api_key))
1025 .send()
1026 .await?;
1027 let response = self.check_response(response).await?;
1028 let images = response.json::<Vec<ImageStatus>>().await?;
1029 Ok(images)
1030 }
1031
1032 pub async fn list_collection_requests_for_satellite(
1033 &self,
1034 satellite_id: &str,
1035 ) -> Result<Vec<CollectionRequest>, LemonaidError> {
1036 let url = format!(
1037 "{}satellites/{}/collection-requests",
1038 self.base_url, satellite_id
1039 );
1040 let response = self
1041 .client
1042 .get(&url)
1043 .header("Authorization", format!("Bearer {}", self.api_key))
1044 .send()
1045 .await?;
1046 let response = self.check_response(response).await?;
1047 let requests = response.json::<Vec<CollectionRequest>>().await?;
1048 Ok(requests)
1049 }
1050
1051 pub async fn get_satellite_orbital_elements(
1052 &self,
1053 satellite_id: &str,
1054 ) -> Result<Vec<OrbitalElements>, LemonaidError> {
1055 let url = format!(
1056 "{}satellites/{}/orbital-elements",
1057 self.base_url, satellite_id
1058 );
1059 let response = self
1060 .client
1061 .get(&url)
1062 .header("Authorization", format!("Bearer {}", self.api_key))
1063 .send()
1064 .await?;
1065 let response = self.check_response(response).await?;
1066 let elements = response.json::<Vec<OrbitalElements>>().await?;
1067 Ok(elements)
1068 }
1069
1070 pub async fn get_satellite_elsets(
1073 &self,
1074 satellite_id: &str,
1075 ) -> Result<Vec<Elset>, LemonaidError> {
1076 let url = format!("{}satellites/{}/elsets", self.base_url, satellite_id);
1077 let response = self
1078 .client
1079 .get(&url)
1080 .header("Authorization", format!("Bearer {}", self.api_key))
1081 .send()
1082 .await?;
1083 let response = self.check_response(response).await?;
1084 let elsets = response.json::<Vec<Elset>>().await?;
1085 Ok(elsets)
1086 }
1087
1088 pub async fn create_elset(
1089 &self,
1090 satellite_id: &str,
1091 request: &CreateElsetRequest,
1092 ) -> Result<Elset, LemonaidError> {
1093 let url = format!("{}satellites/{}/elsets", self.base_url, satellite_id);
1094 let response = self
1095 .client
1096 .post(&url)
1097 .header("Authorization", format!("Bearer {}", self.api_key))
1098 .json(request)
1099 .send()
1100 .await?;
1101 let response = self.check_response(response).await?;
1102 let elset = response.json::<Elset>().await?;
1103 Ok(elset)
1104 }
1105
1106 pub async fn get_satellite_elset_history(
1107 &self,
1108 satellite_id: &str,
1109 query: Option<&ElsetHistoryQuery>,
1110 ) -> Result<Vec<Elset>, LemonaidError> {
1111 let mut url = format!("{}satellites/{}/elset-history", self.base_url, satellite_id);
1112 if let Some(q) = query {
1113 let mut params = Vec::new();
1114 if let Some(ref start) = q.start {
1115 params.push(format!("start={}", start.to_rfc3339()));
1116 }
1117 if let Some(ref end) = q.end {
1118 params.push(format!("end={}", end.to_rfc3339()));
1119 }
1120 if let Some(ref source) = q.source {
1121 params.push(format!("source={}", source));
1122 }
1123 if let Some(limit) = q.limit {
1124 params.push(format!("limit={}", limit));
1125 }
1126 if !params.is_empty() {
1127 url = format!("{}?{}", url, params.join("&"));
1128 }
1129 }
1130 let response = self
1131 .client
1132 .get(&url)
1133 .header("Authorization", format!("Bearer {}", self.api_key))
1134 .send()
1135 .await?;
1136 let response = self.check_response(response).await?;
1137 let elsets = response.json::<Vec<Elset>>().await?;
1138 Ok(elsets)
1139 }
1140
1141 pub async fn get_latest_elsets(&self, days: Option<i32>) -> Result<Vec<Elset>, LemonaidError> {
1142 let url = match days {
1143 Some(d) => format!("{}elsets/latest?days={}", self.base_url, d),
1144 None => format!("{}elsets/latest", self.base_url),
1145 };
1146 let response = self
1147 .client
1148 .get(&url)
1149 .header("Authorization", format!("Bearer {}", self.api_key))
1150 .send()
1151 .await?;
1152 let response = self.check_response(response).await?;
1153 let elsets = response.json::<Vec<Elset>>().await?;
1154 Ok(elsets)
1155 }
1156
1157 pub async fn get_elset_counts(&self) -> Result<Vec<ElsetCount>, LemonaidError> {
1158 let url = format!("{}elsets/counts", self.base_url);
1159 let response = self
1160 .client
1161 .get(&url)
1162 .header("Authorization", format!("Bearer {}", self.api_key))
1163 .send()
1164 .await?;
1165 let response = self.check_response(response).await?;
1166 let counts = response.json::<Vec<ElsetCount>>().await?;
1167 Ok(counts)
1168 }
1169
1170 pub async fn get_near_geo_scatter(&self) -> Result<Vec<GeoScatterPoint>, LemonaidError> {
1171 let url = format!("{}elsets/near-geo-scatter", self.base_url);
1172 let response = self
1173 .client
1174 .get(&url)
1175 .header("Authorization", format!("Bearer {}", self.api_key))
1176 .send()
1177 .await?;
1178 let response = self.check_response(response).await?;
1179 let scatter = response.json::<Vec<GeoScatterPoint>>().await?;
1180 Ok(scatter)
1181 }
1182
1183 pub async fn get_leo_scatter(
1184 &self,
1185 min_sma_km: Option<f64>,
1186 max_sma_km: Option<f64>,
1187 ) -> Result<Vec<LeoScatterPoint>, LemonaidError> {
1188 let mut params = Vec::new();
1189 if let Some(min) = min_sma_km {
1190 params.push(format!("minSma={}", min));
1191 }
1192 if let Some(max) = max_sma_km {
1193 params.push(format!("maxSma={}", max));
1194 }
1195 let url = if params.is_empty() {
1196 format!("{}elsets/leo-scatter", self.base_url)
1197 } else {
1198 format!("{}elsets/leo-scatter?{}", self.base_url, params.join("&"))
1199 };
1200 let response = self
1201 .client
1202 .get(&url)
1203 .header("Authorization", format!("Bearer {}", self.api_key))
1204 .send()
1205 .await?;
1206 let response = self.check_response(response).await?;
1207 let scatter = response.json::<Vec<LeoScatterPoint>>().await?;
1208 Ok(scatter)
1209 }
1210
1211 pub async fn reject_elset(&self, elset_id: &str) -> Result<(), LemonaidError> {
1212 let url = format!("{}elsets/{}/reject", self.base_url, elset_id);
1213 let response = self
1214 .client
1215 .patch(&url)
1216 .header("Authorization", format!("Bearer {}", self.api_key))
1217 .send()
1218 .await?;
1219 self.check_response(response).await?;
1220 Ok(())
1221 }
1222
1223 pub async fn list_satellite_groups(&self) -> Result<Vec<SatelliteGroup>, LemonaidError> {
1226 let url = format!("{}satellite-groups", self.base_url);
1227 let response = self
1228 .client
1229 .get(&url)
1230 .header("Authorization", format!("Bearer {}", self.api_key))
1231 .send()
1232 .await?;
1233 let response = self.check_response(response).await?;
1234 let groups = response.json::<Vec<SatelliteGroup>>().await?;
1235 Ok(groups)
1236 }
1237
1238 pub async fn list_my_satellite_groups(&self) -> Result<Vec<SatelliteGroup>, LemonaidError> {
1239 let url = format!("{}my/satellite-groups", self.base_url);
1240 let response = self
1241 .client
1242 .get(&url)
1243 .header("Authorization", format!("Bearer {}", self.api_key))
1244 .send()
1245 .await?;
1246 let response = self.check_response(response).await?;
1247 let groups = response.json::<Vec<SatelliteGroup>>().await?;
1248 Ok(groups)
1249 }
1250
1251 pub async fn list_favorite_satellite_groups(
1252 &self,
1253 ) -> Result<Vec<SatelliteGroup>, LemonaidError> {
1254 let url = format!("{}my/satellite-groups/favorites", self.base_url);
1255 let response = self
1256 .client
1257 .get(&url)
1258 .header("Authorization", format!("Bearer {}", self.api_key))
1259 .send()
1260 .await?;
1261 let response = self.check_response(response).await?;
1262 let groups = response.json::<Vec<SatelliteGroup>>().await?;
1263 Ok(groups)
1264 }
1265
1266 pub async fn get_satellite_group(
1267 &self,
1268 group_id: &str,
1269 ) -> Result<SatelliteGroup, LemonaidError> {
1270 let url = format!("{}satellite-groups/{}", self.base_url, group_id);
1271 let response = self
1272 .client
1273 .get(&url)
1274 .header("Authorization", format!("Bearer {}", self.api_key))
1275 .send()
1276 .await?;
1277 let response = self.check_response(response).await?;
1278 let group = response.json::<SatelliteGroup>().await?;
1279 Ok(group)
1280 }
1281
1282 pub async fn create_satellite_group(
1283 &self,
1284 request: &CreateSatelliteGroupRequest,
1285 ) -> Result<String, LemonaidError> {
1286 let url = format!("{}satellite-groups", self.base_url);
1287 let response = self
1288 .client
1289 .post(&url)
1290 .header("Authorization", format!("Bearer {}", self.api_key))
1291 .json(&vec![request])
1292 .send()
1293 .await?;
1294 let response = self.check_response(response).await?;
1295 let ids = response.json::<Vec<String>>().await?;
1296 Ok(ids.into_iter().next().unwrap())
1297 }
1298
1299 pub async fn update_satellite_group(
1300 &self,
1301 request: &UpdateSatelliteGroupRequest,
1302 ) -> Result<String, LemonaidError> {
1303 let url = format!("{}satellite-groups", self.base_url);
1304 let response = self
1305 .client
1306 .put(&url)
1307 .header("Authorization", format!("Bearer {}", self.api_key))
1308 .json(&vec![request])
1309 .send()
1310 .await?;
1311 let response = self.check_response(response).await?;
1312 let ids = response.json::<Vec<String>>().await?;
1313 Ok(ids.into_iter().next().unwrap())
1314 }
1315
1316 pub async fn delete_satellite_group(&self, group_id: &str) -> Result<(), LemonaidError> {
1317 let url = format!("{}satellite-groups/{}", self.base_url, group_id);
1318 let response = self
1319 .client
1320 .delete(&url)
1321 .header("Authorization", format!("Bearer {}", self.api_key))
1322 .send()
1323 .await?;
1324 self.check_response(response).await?;
1325 Ok(())
1326 }
1327
1328 pub async fn get_satellites_in_group(
1329 &self,
1330 group_id: &str,
1331 ) -> Result<Vec<Satellite>, LemonaidError> {
1332 let url = format!("{}satellite-groups/{}/satellites", self.base_url, group_id);
1333 let response = self
1334 .client
1335 .get(&url)
1336 .header("Authorization", format!("Bearer {}", self.api_key))
1337 .send()
1338 .await?;
1339 let response = self.check_response(response).await?;
1340 let satellites = response.json::<Vec<Satellite>>().await?;
1341 Ok(satellites)
1342 }
1343
1344 pub async fn add_satellites_to_group(
1345 &self,
1346 group_id: &str,
1347 request: &SatelliteGroupMembersRequest,
1348 ) -> Result<(), LemonaidError> {
1349 let url = format!("{}satellite-groups/{}/satellites", self.base_url, group_id);
1350 let response = self
1351 .client
1352 .post(&url)
1353 .header("Authorization", format!("Bearer {}", self.api_key))
1354 .json(request)
1355 .send()
1356 .await?;
1357 self.check_response(response).await?;
1358 Ok(())
1359 }
1360
1361 pub async fn remove_satellites_from_group(
1362 &self,
1363 group_id: &str,
1364 request: &SatelliteGroupMembersRequest,
1365 ) -> Result<(), LemonaidError> {
1366 let url = format!("{}satellite-groups/{}/satellites", self.base_url, group_id);
1367 let response = self
1368 .client
1369 .delete(&url)
1370 .header("Authorization", format!("Bearer {}", self.api_key))
1371 .json(request)
1372 .send()
1373 .await?;
1374 self.check_response(response).await?;
1375 Ok(())
1376 }
1377
1378 pub async fn favorite_satellite_group(&self, group_id: &str) -> Result<(), LemonaidError> {
1379 let url = format!("{}satellite-groups/{}/favorite", self.base_url, group_id);
1380 let response = self
1381 .client
1382 .post(&url)
1383 .header("Authorization", format!("Bearer {}", self.api_key))
1384 .send()
1385 .await?;
1386 self.check_response(response).await?;
1387 Ok(())
1388 }
1389
1390 pub async fn unfavorite_satellite_group(&self, group_id: &str) -> Result<(), LemonaidError> {
1391 let url = format!("{}satellite-groups/{}/favorite", self.base_url, group_id);
1392 let response = self
1393 .client
1394 .delete(&url)
1395 .header("Authorization", format!("Bearer {}", self.api_key))
1396 .send()
1397 .await?;
1398 self.check_response(response).await?;
1399 Ok(())
1400 }
1401
1402 pub async fn get_weather(&self, query: &WeatherQuery) -> Result<WeatherResponse, LemonaidError> {
1405 let mut params = vec![
1406 format!("lat={}", query.latitude),
1407 format!("lon={}", query.longitude),
1408 ];
1409 if let Some(ref units) = query.units {
1410 params.push(format!("units={}", units));
1411 }
1412 let url = format!("{}weather?{}", self.base_url, params.join("&"));
1413 let response = self
1414 .client
1415 .get(&url)
1416 .header("Authorization", format!("Bearer {}", self.api_key))
1417 .send()
1418 .await?;
1419 let response = self.check_response(response).await?;
1420 let weather = response.json::<WeatherResponse>().await?;
1421 Ok(weather)
1422 }
1423
1424 pub async fn get_my_account(&self) -> Result<UserAccount, LemonaidError> {
1427 let url = format!("{}my/account", self.base_url);
1428 let response = self
1429 .client
1430 .get(&url)
1431 .header("Authorization", format!("Bearer {}", self.api_key))
1432 .send()
1433 .await?;
1434 let response = self.check_response(response).await?;
1435 let account = response.json::<UserAccount>().await?;
1436 Ok(account)
1437 }
1438
1439 pub async fn update_my_preferences(
1440 &self,
1441 request: &UpdatePreferencesRequest,
1442 ) -> Result<UserPreferences, LemonaidError> {
1443 let url = format!("{}my/preferences", self.base_url);
1444 let response = self
1445 .client
1446 .patch(&url)
1447 .header("Authorization", format!("Bearer {}", self.api_key))
1448 .json(request)
1449 .send()
1450 .await?;
1451 let response = self.check_response(response).await?;
1452 let preferences = response.json::<UserPreferences>().await?;
1453 Ok(preferences)
1454 }
1455
1456 pub async fn list_group_members(&self) -> Result<Vec<GroupMember>, LemonaidError> {
1457 let url = format!("{}my/group/members", self.base_url);
1458 let response = self
1459 .client
1460 .get(&url)
1461 .header("Authorization", format!("Bearer {}", self.api_key))
1462 .send()
1463 .await?;
1464 let response = self.check_response(response).await?;
1465 let members = response.json::<Vec<GroupMember>>().await?;
1466 Ok(members)
1467 }
1468
1469 pub async fn add_group_member(
1470 &self,
1471 request: &AddGroupMemberRequest,
1472 ) -> Result<GroupMember, LemonaidError> {
1473 let url = format!("{}my/group/members", self.base_url);
1474 let response = self
1475 .client
1476 .post(&url)
1477 .header("Authorization", format!("Bearer {}", self.api_key))
1478 .json(request)
1479 .send()
1480 .await?;
1481 let response = self.check_response(response).await?;
1482 let member = response.json::<GroupMember>().await?;
1483 Ok(member)
1484 }
1485
1486 pub async fn remove_group_member(&self, user_id: &str) -> Result<(), LemonaidError> {
1487 let url = format!("{}my/group/members/{}", self.base_url, user_id);
1488 let response = self
1489 .client
1490 .delete(&url)
1491 .header("Authorization", format!("Bearer {}", self.api_key))
1492 .send()
1493 .await?;
1494 self.check_response(response).await?;
1495 Ok(())
1496 }
1497
1498 pub async fn initiate_image_upload(
1501 &self,
1502 request: &ImageUploadRequest,
1503 ) -> Result<ImageUploadResponse, LemonaidError> {
1504 let url = format!("{}my/images", self.base_url);
1505 let response = self
1506 .client
1507 .post(&url)
1508 .header("Authorization", format!("Bearer {}", self.api_key))
1509 .json(request)
1510 .send()
1511 .await?;
1512 let response = self.check_response(response).await?;
1513 let upload = response.json::<ImageUploadResponse>().await?;
1514 Ok(upload)
1515 }
1516
1517 pub async fn list_my_images(
1518 &self,
1519 query: Option<&ImageListQuery>,
1520 ) -> Result<Vec<ImageStatus>, LemonaidError> {
1521 let mut url = format!("{}my/images", self.base_url);
1522 if let Some(q) = query {
1523 let mut params = Vec::new();
1524 if let Some(offset) = q.offset {
1525 params.push(format!("offset={}", offset));
1526 }
1527 if let Some(limit) = q.limit {
1528 params.push(format!("limit={}", limit));
1529 }
1530 if let Some(ref status) = q.status {
1531 params.push(format!("status={}", status));
1532 }
1533 if !params.is_empty() {
1534 url = format!("{}?{}", url, params.join("&"));
1535 }
1536 }
1537 let response = self
1538 .client
1539 .get(&url)
1540 .header("Authorization", format!("Bearer {}", self.api_key))
1541 .send()
1542 .await?;
1543 let response = self.check_response(response).await?;
1544 let images = response.json::<Vec<ImageStatus>>().await?;
1545 Ok(images)
1546 }
1547
1548 pub async fn get_image_status(&self, upload_id: &str) -> Result<ImageStatus, LemonaidError> {
1549 let url = format!("{}my/images/{}", self.base_url, upload_id);
1550 let response = self
1551 .client
1552 .get(&url)
1553 .header("Authorization", format!("Bearer {}", self.api_key))
1554 .send()
1555 .await?;
1556 let response = self.check_response(response).await?;
1557 let status = response.json::<ImageStatus>().await?;
1558 Ok(status)
1559 }
1560
1561 pub async fn delete_image(&self, upload_id: &str) -> Result<(), LemonaidError> {
1562 let url = format!("{}my/images/{}", self.base_url, upload_id);
1563 let response = self
1564 .client
1565 .delete(&url)
1566 .header("Authorization", format!("Bearer {}", self.api_key))
1567 .send()
1568 .await?;
1569 self.check_response(response).await?;
1570 Ok(())
1571 }
1572
1573 pub async fn get_image_data(
1574 &self,
1575 upload_id: &str,
1576 request: Option<&ImageDataRequest>,
1577 ) -> Result<ImageData, LemonaidError> {
1578 let mut url = format!("{}images/{}/data", self.base_url, upload_id);
1579 if let Some(req) = request {
1580 let mut params = Vec::new();
1581 if let Some(binning) = req.binning {
1582 params.push(format!("binning={}", binning));
1583 }
1584 if let Some(ref contrast) = req.contrast {
1585 params.push(format!("contrast={}", contrast));
1586 }
1587 if !params.is_empty() {
1588 url = format!("{}?{}", url, params.join("&"));
1589 }
1590 }
1591 let response = self
1592 .client
1593 .get(&url)
1594 .header("Authorization", format!("Bearer {}", self.api_key))
1595 .send()
1596 .await?;
1597 let response = self.check_response(response).await?;
1598 let data = response.json::<ImageData>().await?;
1599 Ok(data)
1600 }
1601
1602 pub async fn get_optical_observation_counts(
1605 &self,
1606 ) -> Result<Vec<ObservationCount>, LemonaidError> {
1607 let url = format!("{}observations/optical/counts", self.base_url);
1608 let response = self
1609 .client
1610 .get(&url)
1611 .header("Authorization", format!("Bearer {}", self.api_key))
1612 .send()
1613 .await?;
1614 let response = self.check_response(response).await?;
1615 let counts = response.json::<Vec<ObservationCount>>().await?;
1616 Ok(counts)
1617 }
1618
1619 pub async fn upload_optical_observations(
1620 &self,
1621 observations: &[CreateOpticalObservationRequest],
1622 ) -> Result<Vec<OpticalObservation>, LemonaidError> {
1623 let url = format!("{}observations/optical", self.base_url);
1624 let response = self
1625 .client
1626 .post(&url)
1627 .header("Authorization", format!("Bearer {}", self.api_key))
1628 .json(observations)
1629 .send()
1630 .await?;
1631 let response = self.check_response(response).await?;
1632 let created = response.json::<Vec<OpticalObservation>>().await?;
1633 Ok(created)
1634 }
1635
1636 pub async fn query_optical_observations(
1637 &self,
1638 query: &ObservationQuery,
1639 ) -> Result<Vec<OpticalObservation>, LemonaidError> {
1640 let mut params = Vec::new();
1641 if let Some(ref satellite_id) = query.satellite_id {
1642 params.push(format!("satelliteId={}", satellite_id));
1643 }
1644 if let Some(ref telescope_id) = query.telescope_id {
1645 params.push(format!("telescopeId={}", telescope_id));
1646 }
1647 if let Some(ref start) = query.start {
1648 params.push(format!("start={}", start.to_rfc3339()));
1649 }
1650 if let Some(ref end) = query.end {
1651 params.push(format!("end={}", end.to_rfc3339()));
1652 }
1653 if let Some(offset) = query.offset {
1654 params.push(format!("offset={}", offset));
1655 }
1656 if let Some(limit) = query.limit {
1657 params.push(format!("limit={}", limit));
1658 }
1659 let url = if params.is_empty() {
1660 format!("{}observations/optical", self.base_url)
1661 } else {
1662 format!("{}observations/optical?{}", self.base_url, params.join("&"))
1663 };
1664 let response = self
1665 .client
1666 .get(&url)
1667 .header("Authorization", format!("Bearer {}", self.api_key))
1668 .send()
1669 .await?;
1670 let response = self.check_response(response).await?;
1671 let observations = response.json::<Vec<OpticalObservation>>().await?;
1672 Ok(observations)
1673 }
1674
1675 pub async fn create_collection_request(
1678 &self,
1679 request: &CreateCollectionRequestRequest,
1680 ) -> Result<CollectionRequest, LemonaidError> {
1681 let url = format!("{}collection-requests", self.base_url);
1682 let response = self
1683 .client
1684 .post(&url)
1685 .header("Authorization", format!("Bearer {}", self.api_key))
1686 .json(request)
1687 .send()
1688 .await?;
1689 let response = self.check_response(response).await?;
1690 let collection_request = response.json::<CollectionRequest>().await?;
1691 Ok(collection_request)
1692 }
1693
1694 pub async fn list_filters(&self) -> Result<Vec<Filter>, LemonaidError> {
1697 let url = format!("{}filters/list", self.base_url);
1698 let response = self
1699 .client
1700 .get(&url)
1701 .header("Authorization", format!("Bearer {}", self.api_key))
1702 .send()
1703 .await?;
1704 let response = self.check_response(response).await?;
1705 let filters = response.json::<Vec<Filter>>().await?;
1706 Ok(filters)
1707 }
1708
1709 pub async fn expand_filters(
1710 &self,
1711 request: &FilterExpandRequest,
1712 ) -> Result<FilterExpandResponse, LemonaidError> {
1713 let url = format!("{}filters/expand", self.base_url);
1714 let response = self
1715 .client
1716 .post(&url)
1717 .header("Authorization", format!("Bearer {}", self.api_key))
1718 .json(request)
1719 .send()
1720 .await?;
1721 let response = self.check_response(response).await?;
1722 let expanded = response.json::<FilterExpandResponse>().await?;
1723 Ok(expanded)
1724 }
1725
1726 pub async fn list_maneuvers(
1729 &self,
1730 query: Option<&ManeuverListQuery>,
1731 ) -> Result<Vec<Maneuver>, LemonaidError> {
1732 let mut url = format!("{}maneuvers", self.base_url);
1733 if let Some(q) = query {
1734 let mut params = Vec::new();
1735 if let Some(ref satellite_id) = q.satellite_id {
1736 params.push(format!("satelliteId={}", satellite_id));
1737 }
1738 if let Some(ref status) = q.status {
1739 params.push(format!("status={}", status));
1740 }
1741 if let Some(ref start) = q.start {
1742 params.push(format!("start={}", start.to_rfc3339()));
1743 }
1744 if let Some(ref end) = q.end {
1745 params.push(format!("end={}", end.to_rfc3339()));
1746 }
1747 if let Some(offset) = q.offset {
1748 params.push(format!("offset={}", offset));
1749 }
1750 if let Some(limit) = q.limit {
1751 params.push(format!("limit={}", limit));
1752 }
1753 if !params.is_empty() {
1754 url = format!("{}?{}", url, params.join("&"));
1755 }
1756 }
1757 let response = self
1758 .client
1759 .get(&url)
1760 .header("Authorization", format!("Bearer {}", self.api_key))
1761 .send()
1762 .await?;
1763 let response = self.check_response(response).await?;
1764 let maneuvers = response.json::<Vec<Maneuver>>().await?;
1765 Ok(maneuvers)
1766 }
1767
1768 pub async fn get_maneuver(&self, maneuver_id: &str) -> Result<Maneuver, LemonaidError> {
1769 let url = format!("{}maneuvers/{}", self.base_url, maneuver_id);
1770 let response = self
1771 .client
1772 .get(&url)
1773 .header("Authorization", format!("Bearer {}", self.api_key))
1774 .send()
1775 .await?;
1776 let response = self.check_response(response).await?;
1777 let maneuver = response.json::<Maneuver>().await?;
1778 Ok(maneuver)
1779 }
1780
1781 pub async fn create_maneuver(
1782 &self,
1783 request: &CreateManeuverRequest,
1784 ) -> Result<Maneuver, LemonaidError> {
1785 let url = format!("{}maneuvers", self.base_url);
1786 let response = self
1787 .client
1788 .post(&url)
1789 .header("Authorization", format!("Bearer {}", self.api_key))
1790 .json(request)
1791 .send()
1792 .await?;
1793 let response = self.check_response(response).await?;
1794 let maneuver = response.json::<Maneuver>().await?;
1795 Ok(maneuver)
1796 }
1797
1798 pub async fn update_maneuver(
1799 &self,
1800 maneuver_id: &str,
1801 request: &UpdateManeuverRequest,
1802 ) -> Result<Maneuver, LemonaidError> {
1803 let url = format!("{}maneuvers/{}", self.base_url, maneuver_id);
1804 let response = self
1805 .client
1806 .put(&url)
1807 .header("Authorization", format!("Bearer {}", self.api_key))
1808 .json(request)
1809 .send()
1810 .await?;
1811 let response = self.check_response(response).await?;
1812 let maneuver = response.json::<Maneuver>().await?;
1813 Ok(maneuver)
1814 }
1815
1816 pub async fn list_maneuvers_for_satellite(
1817 &self,
1818 satellite_id: &str,
1819 ) -> Result<Vec<Maneuver>, LemonaidError> {
1820 let url = format!("{}satellites/{}/maneuvers", self.base_url, satellite_id);
1821 let response = self
1822 .client
1823 .get(&url)
1824 .header("Authorization", format!("Bearer {}", self.api_key))
1825 .send()
1826 .await?;
1827 let response = self.check_response(response).await?;
1828 let maneuvers = response.json::<Vec<Maneuver>>().await?;
1829 Ok(maneuvers)
1830 }
1831
1832 pub async fn list_alert_subscriptions(
1835 &self,
1836 ) -> Result<Vec<AlertSubscription>, LemonaidError> {
1837 let url = format!("{}my/alert-subscriptions", self.base_url);
1838 let response = self
1839 .client
1840 .get(&url)
1841 .header("Authorization", format!("Bearer {}", self.api_key))
1842 .send()
1843 .await?;
1844 let response = self.check_response(response).await?;
1845 let subscriptions = response.json::<Vec<AlertSubscription>>().await?;
1846 Ok(subscriptions)
1847 }
1848
1849 pub async fn get_alert_subscription(
1850 &self,
1851 subscription_id: &str,
1852 ) -> Result<AlertSubscription, LemonaidError> {
1853 let url = format!(
1854 "{}my/alert-subscriptions/{}",
1855 self.base_url, subscription_id
1856 );
1857 let response = self
1858 .client
1859 .get(&url)
1860 .header("Authorization", format!("Bearer {}", self.api_key))
1861 .send()
1862 .await?;
1863 let response = self.check_response(response).await?;
1864 let subscription = response.json::<AlertSubscription>().await?;
1865 Ok(subscription)
1866 }
1867
1868 pub async fn create_alert_subscription(
1869 &self,
1870 request: &CreateAlertSubscriptionRequest,
1871 ) -> Result<AlertSubscription, LemonaidError> {
1872 let url = format!("{}my/alert-subscriptions", self.base_url);
1873 let response = self
1874 .client
1875 .post(&url)
1876 .header("Authorization", format!("Bearer {}", self.api_key))
1877 .json(request)
1878 .send()
1879 .await?;
1880 let response = self.check_response(response).await?;
1881 let subscription = response.json::<AlertSubscription>().await?;
1882 Ok(subscription)
1883 }
1884
1885 pub async fn update_alert_subscription(
1886 &self,
1887 subscription_id: &str,
1888 request: &UpdateAlertSubscriptionRequest,
1889 ) -> Result<AlertSubscription, LemonaidError> {
1890 let url = format!(
1891 "{}my/alert-subscriptions/{}",
1892 self.base_url, subscription_id
1893 );
1894 let response = self
1895 .client
1896 .put(&url)
1897 .header("Authorization", format!("Bearer {}", self.api_key))
1898 .json(request)
1899 .send()
1900 .await?;
1901 let response = self.check_response(response).await?;
1902 let subscription = response.json::<AlertSubscription>().await?;
1903 Ok(subscription)
1904 }
1905
1906 pub async fn delete_alert_subscription(
1907 &self,
1908 subscription_id: &str,
1909 ) -> Result<(), LemonaidError> {
1910 let url = format!(
1911 "{}my/alert-subscriptions/{}",
1912 self.base_url, subscription_id
1913 );
1914 let response = self
1915 .client
1916 .delete(&url)
1917 .header("Authorization", format!("Bearer {}", self.api_key))
1918 .send()
1919 .await?;
1920 self.check_response(response).await?;
1921 Ok(())
1922 }
1923
1924 pub async fn list_personal_access_tokens(
1927 &self,
1928 ) -> Result<Vec<PersonalAccessToken>, LemonaidError> {
1929 let url = format!("{}auth/personal-access-tokens", self.base_url);
1930 let response = self
1931 .client
1932 .get(&url)
1933 .header("Authorization", format!("Bearer {}", self.api_key))
1934 .send()
1935 .await?;
1936 let response = self.check_response(response).await?;
1937 let wrapper = response.json::<PersonalAccessTokenListResponse>().await?;
1938 Ok(wrapper.tokens)
1939 }
1940
1941 pub async fn delete_personal_access_token(&self, token_id: &str) -> Result<(), LemonaidError> {
1942 let url = format!("{}auth/personal-access-tokens/{}", self.base_url, token_id);
1943 let response = self
1944 .client
1945 .delete(&url)
1946 .header("Authorization", format!("Bearer {}", self.api_key))
1947 .send()
1948 .await?;
1949 self.check_response(response).await?;
1950 Ok(())
1951 }
1952
1953 pub async fn solve_orbit_determination(
1956 &self,
1957 request: &ODRequest,
1958 ) -> Result<ODResult, LemonaidError> {
1959 let url = format!("{}od/", self.base_url);
1960 let response = self
1961 .client
1962 .post(&url)
1963 .header("Authorization", format!("Bearer {}", self.api_key))
1964 .json(request)
1965 .send()
1966 .await?;
1967 let response = self.check_response(response).await?;
1968 let result = response.json::<ODResult>().await?;
1969 Ok(result)
1970 }
1971}