summaryrefslogtreecommitdiffstats
path: root/rust/fatcat-cli/src/api.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/fatcat-cli/src/api.rs')
-rw-r--r--rust/fatcat-cli/src/api.rs365
1 files changed, 300 insertions, 65 deletions
diff --git a/rust/fatcat-cli/src/api.rs b/rust/fatcat-cli/src/api.rs
index 41718ea..3fa67e9 100644
--- a/rust/fatcat-cli/src/api.rs
+++ b/rust/fatcat-cli/src/api.rs
@@ -1,14 +1,18 @@
-
-use hyper::client::ResponseFuture;
-use fatcat_openapi::{ApiNoContext, ContextWrapperExt};
+use crate::{parse_macaroon_editor_id, ClientStatus, EntityType, Specifier};
+use anyhow::{anyhow, Context, Result};
use fatcat_openapi::client::Client;
use fatcat_openapi::models;
-use swagger::{AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString, auth};
-use anyhow::{Result, anyhow, Context};
-use crate::{ClientStatus,parse_macaroon_editor_id,Specifier, EntityType};
+use fatcat_openapi::{ApiNoContext, ContextWrapperExt};
+use hyper::client::ResponseFuture;
+use swagger::{auth, AuthData, ContextBuilder, EmptyContext, Push, XSpanIdString};
use tokio::runtime::current_thread::Runtime;
-type FatcatApiContextType = swagger::make_context_ty!( ContextBuilder, EmptyContext, Option<AuthData>, XSpanIdString);
+type FatcatApiContextType = swagger::make_context_ty!(
+ ContextBuilder,
+ EmptyContext,
+ Option<AuthData>,
+ XSpanIdString
+);
pub struct FatcatApiClient<'a> {
pub api: fatcat_openapi::ContextWrapper<'a, Client<ResponseFuture>, FatcatApiContextType>,
@@ -19,11 +23,15 @@ pub struct FatcatApiClient<'a> {
}
impl<'a> FatcatApiClient<'a> {
-
- pub fn new(client: &'a fatcat_openapi::client::Client<ResponseFuture>, api_host: String, api_token: Option<String>) -> Result<Self> {
-
+ pub fn new(
+ client: &'a fatcat_openapi::client::Client<ResponseFuture>,
+ api_host: String,
+ api_token: Option<String>,
+ ) -> Result<Self> {
let auth_data = match api_token {
- Some(ref token) => Some(AuthData::Bearer(auth::Bearer{ token: token.clone() })),
+ Some(ref token) => Some(AuthData::Bearer(auth::Bearer {
+ token: token.clone(),
+ })),
None => None,
};
//info!("{:?}", auth_data);
@@ -34,14 +42,19 @@ impl<'a> FatcatApiClient<'a> {
XSpanIdString::default()
);
- let wrapped_client: fatcat_openapi::ContextWrapper<Client<ResponseFuture>, FatcatApiContextType> = client.with_context(context);
+ let wrapped_client: fatcat_openapi::ContextWrapper<
+ Client<ResponseFuture>,
+ FatcatApiContextType,
+ > = client.with_context(context);
let rt: Runtime = Runtime::new().expect("create tokio runtime");
let editor_id = match api_token {
- Some(ref token) => Some(parse_macaroon_editor_id(token).context("parse API auth token")?),
+ Some(ref token) => {
+ Some(parse_macaroon_editor_id(token).context("parse API auth token")?)
+ }
None => None,
};
-
+
Ok(FatcatApiClient {
api: wrapped_client,
rt,
@@ -53,20 +66,40 @@ impl<'a> FatcatApiClient<'a> {
pub fn status(&mut self) -> Result<ClientStatus> {
let last_changelog = match self.rt.block_on(self.api.get_changelog(Some(1))) {
- Ok(fatcat_openapi::GetChangelogResponse::Success(entry_vec)) => Some(entry_vec[0].index),
+ Ok(fatcat_openapi::GetChangelogResponse::Success(entry_vec)) => {
+ Some(entry_vec[0].index)
+ }
Ok(_) | Err(_) => None,
};
let has_api_token = self.api_token.is_some();
let account: Option<models::Editor> = if has_api_token && last_changelog.is_some() {
- match self.rt.block_on(self.api.auth_check(None)).context("check auth token")? {
+ match self
+ .rt
+ .block_on(self.api.auth_check(None))
+ .context("check auth token")?
+ {
fatcat_openapi::AuthCheckResponse::Success(_) => Ok(()),
- fatcat_openapi::AuthCheckResponse::Forbidden(err) => Err(anyhow!("Forbidden ({}): {}", err.error, err.message)),
- fatcat_openapi::AuthCheckResponse::NotAuthorized{body: err, ..} => Err(anyhow!("Bad Request ({}): {}", err.error, err.message)),
+ fatcat_openapi::AuthCheckResponse::Forbidden(err) => {
+ Err(anyhow!("Forbidden ({}): {}", err.error, err.message))
+ }
+ fatcat_openapi::AuthCheckResponse::NotAuthorized { body: err, .. } => {
+ Err(anyhow!("Bad Request ({}): {}", err.error, err.message))
+ }
resp => return Err(anyhow!("{:?}", resp)).context("auth check failed"),
- }.context("check auth token")?;
- match self.rt.block_on(self.api.get_editor(self.editor_id.as_ref().unwrap().to_string())).context("fetching editor account info")? {
+ }
+ .context("check auth token")?;
+ match self
+ .rt
+ .block_on(
+ self.api
+ .get_editor(self.editor_id.as_ref().unwrap().to_string()),
+ )
+ .context("fetching editor account info")?
+ {
fatcat_openapi::GetEditorResponse::Found(editor) => Some(editor),
- fatcat_openapi::GetEditorResponse::NotFound(err) => return Err(anyhow!("Not Found: {}", err.message)),
+ fatcat_openapi::GetEditorResponse::NotFound(err) => {
+ return Err(anyhow!("Not Found: {}", err.message))
+ }
resp => return Err(anyhow!("{:?}", resp)).context("editor fetch failed"),
}
} else {
@@ -80,18 +113,29 @@ impl<'a> FatcatApiClient<'a> {
})
}
- pub fn update_editgroup_submit(&mut self, editgroup_id: String, submit: bool) -> Result<models::Editgroup> {
- let result = self.rt.block_on(
- self.api.get_editgroup(editgroup_id.clone())
- ).context("fetch editgroups")?;
+ pub fn update_editgroup_submit(
+ &mut self,
+ editgroup_id: String,
+ submit: bool,
+ ) -> Result<models::Editgroup> {
+ let result = self
+ .rt
+ .block_on(self.api.get_editgroup(editgroup_id.clone()))
+ .context("fetch editgroups")?;
let eg = match result {
fatcat_openapi::GetEditgroupResponse::Found(eg) => eg,
- other => return Err(anyhow!("{:?}", other))
- .with_context(|| format!("failed to fetch editgroup {}", editgroup_id)),
+ other => {
+ return Err(anyhow!("{:?}", other))
+ .with_context(|| format!("failed to fetch editgroup {}", editgroup_id))
+ }
};
- let result = self.rt.block_on(
- self.api.update_editgroup(editgroup_id.clone(), eg, Some(submit))
- ).context("submit editgroup")?;
+ let result = self
+ .rt
+ .block_on(
+ self.api
+ .update_editgroup(editgroup_id.clone(), eg, Some(submit)),
+ )
+ .context("submit editgroup")?;
match result {
fatcat_openapi::UpdateEditgroupResponse::UpdatedEditgroup(eg) => Ok(eg),
other => Err(anyhow!("{:?}", other))
@@ -99,11 +143,18 @@ impl<'a> FatcatApiClient<'a> {
}
}
- pub fn delete_entity(&mut self, specifier: Specifier, editgroup_id: String) -> Result<models::EntityEdit> {
+ pub fn delete_entity(
+ &mut self,
+ specifier: Specifier,
+ editgroup_id: String,
+ ) -> Result<models::EntityEdit> {
use Specifier::*;
let specifier = specifier.into_entity_specifier(self)?;
match specifier.clone() {
- Release(fcid) => match self.rt.block_on(self.api.delete_release(editgroup_id, fcid))? {
+ Release(fcid) => match self
+ .rt
+ .block_on(self.api.delete_release(editgroup_id, fcid))?
+ {
fatcat_openapi::DeleteReleaseResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
@@ -111,11 +162,17 @@ impl<'a> FatcatApiClient<'a> {
fatcat_openapi::DeleteWorkResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- Container(fcid) => match self.rt.block_on(self.api.delete_container(editgroup_id, fcid))? {
+ Container(fcid) => match self
+ .rt
+ .block_on(self.api.delete_container(editgroup_id, fcid))?
+ {
fatcat_openapi::DeleteContainerResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- Creator(fcid) => match self.rt.block_on(self.api.delete_creator(editgroup_id, fcid))? {
+ Creator(fcid) => match self
+ .rt
+ .block_on(self.api.delete_creator(editgroup_id, fcid))?
+ {
fatcat_openapi::DeleteCreatorResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
@@ -123,104 +180,282 @@ impl<'a> FatcatApiClient<'a> {
fatcat_openapi::DeleteFileResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- FileSet(fcid) => match self.rt.block_on(self.api.delete_fileset(editgroup_id, fcid))? {
+ FileSet(fcid) => match self
+ .rt
+ .block_on(self.api.delete_fileset(editgroup_id, fcid))?
+ {
fatcat_openapi::DeleteFilesetResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- WebCapture(fcid) => match self.rt.block_on(self.api.delete_webcapture(editgroup_id, fcid))? {
+ WebCapture(fcid) => match self
+ .rt
+ .block_on(self.api.delete_webcapture(editgroup_id, fcid))?
+ {
fatcat_openapi::DeleteWebcaptureResponse::DeletedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
Editgroup(..) | Editor(..) => unimplemented!("deletion for this entity type"),
Changelog(..) => return Err(anyhow!("mutating this entity type doesn't make sense")),
- EditorUsername(..) | ReleaseLookup(..) | ContainerLookup(..) | FileLookup(..) | CreatorLookup(..) =>
- return Err(anyhow!("into_entity_specifier() didn't work?")),
- }.with_context(|| format!("failed to delete {:?}", specifier))
+ EditorUsername(..) | ReleaseLookup(..) | ContainerLookup(..) | FileLookup(..)
+ | CreatorLookup(..) => return Err(anyhow!("into_entity_specifier() didn't work?")),
+ }
+ .with_context(|| format!("failed to delete {:?}", specifier))
}
- pub fn create_entity_from_json(&mut self, entity_type: EntityType, json_str: &str, editgroup_id: String) -> Result<models::EntityEdit> {
+ pub fn create_entity_from_json(
+ &mut self,
+ entity_type: EntityType,
+ json_str: &str,
+ editgroup_id: String,
+ ) -> Result<models::EntityEdit> {
match entity_type {
EntityType::Release => {
- match self.rt.block_on(self.api.create_release(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_release(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateReleaseResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
- },
+ }
EntityType::Work => {
- match self.rt.block_on(self.api.create_work(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_work(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateWorkResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
- },
+ }
EntityType::Creator => {
- match self.rt.block_on(self.api.create_creator(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_creator(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateCreatorResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
- },
+ }
EntityType::Container => {
- match self.rt.block_on(self.api.create_container(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_container(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateContainerResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
- },
+ }
EntityType::File => {
- match self.rt.block_on(self.api.create_file(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_file(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateFileResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
- },
+ }
EntityType::FileSet => {
- match self.rt.block_on(self.api.create_fileset(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_fileset(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateFilesetResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
- },
+ }
EntityType::WebCapture => {
- match self.rt.block_on(self.api.create_webcapture(editgroup_id, serde_json::from_str(&json_str)?))? {
+ match self.rt.block_on(
+ self.api
+ .create_webcapture(editgroup_id, serde_json::from_str(&json_str)?),
+ )? {
fatcat_openapi::CreateWebcaptureResponse::CreatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
}
+ }
+ }
+ .with_context(|| format!("parsing and creating {:?} entity", entity_type))
+ }
+
+ pub fn existing_edit_in_editgroup(
+ &mut self,
+ editgroup: &models::Editgroup,
+ specifier: &Specifier,
+ ) -> Option<models::EntityEdit> {
+ use Specifier::*;
+ let (fcid, edit_list) = match specifier.clone() {
+ Release(fcid) => (fcid, editgroup.edits.as_ref().unwrap().releases.clone()),
+ Work(fcid) => (fcid, editgroup.edits.as_ref().unwrap().works.clone()),
+ Container(fcid) => (fcid, editgroup.edits.as_ref().unwrap().containers.clone()),
+ Creator(fcid) => (fcid, editgroup.edits.as_ref().unwrap().creators.clone()),
+ File(fcid) => (fcid, editgroup.edits.as_ref().unwrap().files.clone()),
+ FileSet(fcid) => (fcid, editgroup.edits.as_ref().unwrap().filesets.clone()),
+ WebCapture(fcid) => (fcid, editgroup.edits.as_ref().unwrap().webcaptures.clone()),
+ EditorUsername(..) | ReleaseLookup(..) | ContainerLookup(..) | FileLookup(..)
+ | CreatorLookup(..) | Editgroup(..) | Editor(..) | Changelog(..) => {
+ panic!("this entity type doesn't exist in editgroups")
+ }
+ };
+ for entity_edit in edit_list.unwrap() {
+ if entity_edit.ident == fcid {
+ return Some(entity_edit);
+ }
+ }
+ None
+ }
+
+ pub fn delete_editgroup_edit(
+ &mut self,
+ editgroup: &models::Editgroup,
+ specifier: &Specifier,
+ edit: &models::EntityEdit,
+ ) -> Result<()> {
+ use Specifier::*;
+ let editgroup_id = editgroup.editgroup_id.clone().unwrap();
+ let edit_id = edit.edit_id.clone();
+ match specifier.clone() {
+ Release(..) => match self
+ .rt
+ .block_on(self.api.delete_release_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteReleaseEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
+ },
+ Work(..) => match self
+ .rt
+ .block_on(self.api.delete_work_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteWorkEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
+ },
+ Container(..) => match self
+ .rt
+ .block_on(self.api.delete_container_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteContainerEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
+ },
+ Creator(..) => match self
+ .rt
+ .block_on(self.api.delete_creator_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteCreatorEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
+ },
+ File(..) => match self
+ .rt
+ .block_on(self.api.delete_file_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteFileEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
+ },
+ FileSet(..) => match self
+ .rt
+ .block_on(self.api.delete_fileset_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteFilesetEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
},
- }.with_context(|| format!("parsing and creating {:?} entity", entity_type))
+ WebCapture(..) => match self
+ .rt
+ .block_on(self.api.delete_webcapture_edit(editgroup_id, edit_id))?
+ {
+ fatcat_openapi::DeleteWebcaptureEditResponse::DeletedEdit(..) => Ok(()),
+ other => Err(anyhow!("{:?}", other)),
+ },
+ EditorUsername(..) | ReleaseLookup(..) | ContainerLookup(..) | FileLookup(..)
+ | CreatorLookup(..) | Editgroup(..) | Editor(..) | Changelog(..) => {
+ panic!("this entity type doesn't exist in editgroups")
+ }
+ }
}
- pub fn update_entity_from_json(&mut self, specifier: Specifier, json_str: &str, editgroup_id: String) -> Result<models::EntityEdit> {
+ pub fn update_entity_from_json(
+ &mut self,
+ specifier: Specifier,
+ json_str: &str,
+ editgroup_id: String,
+ ) -> Result<models::EntityEdit> {
use Specifier::*;
let specifier = specifier.into_entity_specifier(self)?;
+ let eg = match self
+ .rt
+ .block_on(self.api.get_editgroup(editgroup_id.clone()))?
+ {
+ fatcat_openapi::GetEditgroupResponse::Found(model) => Ok(model),
+ fatcat_openapi::GetEditgroupResponse::BadRequest(err) => {
+ Err(anyhow!("Bad Request ({}): {}", err.error, err.message))
+ }
+ fatcat_openapi::GetEditgroupResponse::NotFound(err) => {
+ Err(anyhow!("Not Found: {}", err.message))
+ }
+ resp => Err(anyhow!("{:?}", resp))
+ .with_context(|| format!("API GET failed: editgroup_{:?}", editgroup_id)),
+ }?;
+ if let Some(entity_edit) = self.existing_edit_in_editgroup(&eg, &specifier) {
+ self.delete_editgroup_edit(&eg, &specifier, &entity_edit)?;
+ };
match specifier.clone() {
- Release(fcid) => match self.rt.block_on(self.api.update_release(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ Release(fcid) => match self.rt.block_on(self.api.update_release(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateReleaseResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- Work(fcid) => match self.rt.block_on(self.api.update_work(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ Work(fcid) => match self.rt.block_on(self.api.update_work(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateWorkResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- Container(fcid) => match self.rt.block_on(self.api.update_container(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ Container(fcid) => match self.rt.block_on(self.api.update_container(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateContainerResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- Creator(fcid) => match self.rt.block_on(self.api.update_creator(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ Creator(fcid) => match self.rt.block_on(self.api.update_creator(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateCreatorResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- File(fcid) => match self.rt.block_on(self.api.update_file(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ File(fcid) => match self.rt.block_on(self.api.update_file(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateFileResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- FileSet(fcid) => match self.rt.block_on(self.api.update_fileset(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ FileSet(fcid) => match self.rt.block_on(self.api.update_fileset(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateFilesetResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
- WebCapture(fcid) => match self.rt.block_on(self.api.update_webcapture(editgroup_id, fcid, serde_json::from_str(&json_str)?))? {
+ WebCapture(fcid) => match self.rt.block_on(self.api.update_webcapture(
+ editgroup_id,
+ fcid,
+ serde_json::from_str(&json_str)?,
+ ))? {
fatcat_openapi::UpdateWebcaptureResponse::UpdatedEntity(ee) => Ok(ee),
other => Err(anyhow!("{:?}", other)),
},
Editgroup(..) | Editor(..) => unimplemented!("updates for this entity type"),
Changelog(..) => return Err(anyhow!("deleting this entity type doesn't make sense")),
- EditorUsername(..) | ReleaseLookup(..) | ContainerLookup(..) | FileLookup(..) | CreatorLookup(..) =>
- return Err(anyhow!("into_entity_specifier() didn't work?")),
- }.with_context(|| format!("failed to update {:?}", specifier))
+ EditorUsername(..) | ReleaseLookup(..) | ContainerLookup(..) | FileLookup(..)
+ | CreatorLookup(..) => return Err(anyhow!("into_entity_specifier() didn't work?")),
+ }
+ .with_context(|| format!("failed to update {:?}", specifier))
}
}