diff options
| author | Bryan Newbold <bnewbold@robocracy.org> | 2018-07-25 14:39:58 -0700 | 
|---|---|---|
| committer | Bryan Newbold <bnewbold@robocracy.org> | 2018-07-25 14:39:58 -0700 | 
| commit | 828deb42b6dbdb2d11527e073d96bde26d8fb979 (patch) | |
| tree | 5f341922cff5e6b42cf0faf70227244584e4fe05 /rust | |
| parent | 46dbe1f8ee119aa5c7b200b943dd9f46e4d5fbcb (diff) | |
| download | fatcat-828deb42b6dbdb2d11527e073d96bde26d8fb979.tar.gz fatcat-828deb42b6dbdb2d11527e073d96bde26d8fb979.zip | |
abstracts; more tests
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/src/api_helpers.rs | 55 | ||||
| -rw-r--r-- | rust/src/api_server.rs | 66 | ||||
| -rw-r--r-- | rust/src/database_models.rs | 11 | ||||
| -rw-r--r-- | rust/src/database_schema.rs | 2 | ||||
| -rw-r--r-- | rust/tests/test_api_server.rs | 55 | 
5 files changed, 142 insertions, 47 deletions
| diff --git a/rust/src/api_helpers.rs b/rust/src/api_helpers.rs index ef07ee55..91c6200d 100644 --- a/rust/src/api_helpers.rs +++ b/rust/src/api_helpers.rs @@ -4,9 +4,8 @@ use database_schema::*;  use diesel;  use diesel::prelude::*;  use errors::*; -use uuid::Uuid;  use regex::Regex; - +use uuid::Uuid;  pub fn get_or_create_editgroup(editor_id: Uuid, conn: &PgConnection) -> Result<Uuid> {      // check for current active @@ -119,74 +118,80 @@ pub fn check_pmcid(raw: &str) -> Result<()> {      if RE.is_match(raw) {          Ok(())      } else { -        Err(ErrorKind::MalformedExternalId( -            format!("not a valid PubMed Central ID (PMCID): '{}' (expected, eg, 'PMC12345')", raw) -        ).into()) +        Err(ErrorKind::MalformedExternalId(format!( +            "not a valid PubMed Central ID (PMCID): '{}' (expected, eg, 'PMC12345')", +            raw +        )).into())      }  }  pub fn check_pmid(raw: &str) -> Result<()> {      lazy_static! { -        static ref RE: Regex  = Regex::new(r"^\d+$").unwrap(); +        static ref RE: Regex = Regex::new(r"^\d+$").unwrap();      }      if RE.is_match(raw) {          Ok(())      } else { -        Err(ErrorKind::MalformedExternalId( -            format!("not a valid PubMed ID (PMID): '{}' (expected, eg, '1234')", raw) -        ).into()) +        Err(ErrorKind::MalformedExternalId(format!( +            "not a valid PubMed ID (PMID): '{}' (expected, eg, '1234')", +            raw +        )).into())      }  }  pub fn check_wikidata_qid(raw: &str) -> Result<()> {      lazy_static! { -        static ref RE: Regex  = Regex::new(r"^Q\d+$").unwrap(); +        static ref RE: Regex = Regex::new(r"^Q\d+$").unwrap();      }      if RE.is_match(raw) {          Ok(())      } else { -        Err(ErrorKind::MalformedExternalId( -            format!("not a valid Wikidata QID: '{}' (expected, eg, 'Q1234')", raw) -        ).into()) +        Err(ErrorKind::MalformedExternalId(format!( +            "not a valid Wikidata QID: '{}' (expected, eg, 'Q1234')", +            raw +        )).into())      }  }  pub fn check_doi(raw: &str) -> Result<()> {      lazy_static! { -        static ref RE: Regex  = Regex::new(r"^10.\d{3,6}/.+$").unwrap(); +        static ref RE: Regex = Regex::new(r"^10.\d{3,6}/.+$").unwrap();      }      if RE.is_match(raw) {          Ok(())      } else { -        Err(ErrorKind::MalformedExternalId( -            format!("not a valid DOI: '{}' (expected, eg, '10.1234/aksjdfh')", raw) -        ).into()) +        Err(ErrorKind::MalformedExternalId(format!( +            "not a valid DOI: '{}' (expected, eg, '10.1234/aksjdfh')", +            raw +        )).into())      }  }  pub fn check_issn(raw: &str) -> Result<()> {      lazy_static! { -        static ref RE: Regex  = Regex::new(r"^\d{4}-\d{3}[0-9X]$").unwrap(); +        static ref RE: Regex = Regex::new(r"^\d{4}-\d{3}[0-9X]$").unwrap();      }      if RE.is_match(raw) {          Ok(())      } else { -        Err(ErrorKind::MalformedExternalId( -            format!("not a valid ISSN: '{}' (expected, eg, '1234-5678')", raw) -        ).into()) +        Err(ErrorKind::MalformedExternalId(format!( +            "not a valid ISSN: '{}' (expected, eg, '1234-5678')", +            raw +        )).into())      }  }  pub fn check_orcid(raw: &str) -> Result<()> {      lazy_static! { -        static ref RE: Regex  = Regex::new(r"^\d{4}-\d{4}-\d{4}-\d{4}$").unwrap(); +        static ref RE: Regex = Regex::new(r"^\d{4}-\d{4}-\d{4}-\d{4}$").unwrap();      }      if RE.is_match(raw) {          Ok(())      } else { -        Err(ErrorKind::MalformedExternalId( -            format!("not a valid ORCID: '{}' (expected, eg, '0123-4567-3456-6789')", raw) -        ).into()) +        Err(ErrorKind::MalformedExternalId(format!( +            "not a valid ORCID: '{}' (expected, eg, '0123-4567-3456-6789')", +            raw +        )).into())      }  } diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index 64c028be..d172cb16 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -4,16 +4,17 @@ use api_helpers::*;  use chrono;  use database_models::*;  use database_schema::{ -    changelog, container_edit, container_ident, container_rev, creator_edit, creator_ident, -    creator_rev, editgroup, editor, file_edit, file_ident, file_release, file_rev, file_rev_url, -    release_contrib, release_edit, release_ident, release_ref, release_rev, release_rev_abstract, -    work_edit, work_ident, work_rev, +    abstracts, changelog, container_edit, container_ident, container_rev, creator_edit, +    creator_ident, creator_rev, editgroup, editor, file_edit, file_ident, file_release, file_rev, +    file_rev_url, release_contrib, release_edit, release_ident, release_ref, release_rev, +    release_rev_abstract, work_edit, work_ident, work_rev,  };  use diesel::prelude::*;  use diesel::{self, insert_into};  use errors::*;  use fatcat_api::models;  use fatcat_api::models::*; +use sha1::Sha1;  use uuid::Uuid;  use ConnectionPool; @@ -221,24 +222,26 @@ fn release_row2entity(          .into_iter()          .map(|c: ReleaseContribRow| ReleaseContrib {              index: c.index, -            raw: c.raw, +            raw_name: c.raw_name,              role: c.role,              extra: c.extra_json,              creator_id: c.creator_ident_id.map(|v| uuid2fcid(&v)),          })          .collect(); -    // XXX: join abstracts table      let abstracts: Vec<ReleaseEntityAbstracts> = release_rev_abstract::table +        .inner_join(abstracts::table)          .filter(release_rev_abstract::release_rev.eq(rev.id))          .get_results(conn)?          .into_iter() -        .map(|r: ReleaseRevAbstractRow| ReleaseEntityAbstracts { -            sha1: Some(r.abstract_sha1), -            mimetype: r.mimetype, -            lang: r.lang, -            content: None, -        }) +        .map( +            |r: (ReleaseRevAbstractRow, AbstractsRow)| ReleaseEntityAbstracts { +                sha1: Some(r.0.abstract_sha1), +                mimetype: r.0.mimetype, +                lang: r.0.lang, +                content: Some(r.1.content), +            }, +        )          .collect();      Ok(ReleaseEntity { @@ -767,6 +770,7 @@ impl Server {                  if contrib_list.is_empty() {                      Some(vec![])                  } else { +                    println!("{:#?}", contrib_list);                      let contrib_rows: Vec<ReleaseContribNewRow> = contrib_list                          .iter()                          .map(|c| ReleaseContribNewRow { @@ -774,7 +778,7 @@ impl Server {                              creator_ident_id: c.creator_id                                  .clone()                                  .map(|v| fcid2uuid(&v).expect("valid fatcat identifier")), -                            raw: c.raw.clone(), +                            raw_name: c.raw_name.clone(),                              index: c.index,                              role: c.role.clone(),                              extra_json: c.extra.clone(), @@ -789,6 +793,42 @@ impl Server {              }          }; +        if let Some(abstract_list) = entity.abstracts { +            // For rows that specify content, we need to insert the abstract if it doesn't exist +            // already +            let new_abstracts: Vec<AbstractsRow> = abstract_list +                .iter() +                .filter(|ea| ea.content.is_some()) +                .map(|c| AbstractsRow { +                    sha1: Sha1::from(c.content.clone().unwrap()).hexdigest(), +                    content: c.content.clone().unwrap(), +                }) +                .collect(); +            if !new_abstracts.is_empty() { +                // Sort of an "upsert"; only inserts new abstract rows if they don't already exist +                insert_into(abstracts::table) +                    .values(new_abstracts) +                    //.on_conflict(abstracts::sha1) +                    //.do_nothing() +                    .execute(conn)?; +            } +            let release_abstract_rows: Vec<ReleaseRevAbstractNewRow> = abstract_list +                .into_iter() +                .map(|c| ReleaseRevAbstractNewRow { +                    release_rev: edit.rev_id.unwrap(), +                    abstract_sha1: match c.content { +                        Some(ref content) => Sha1::from(content).hexdigest(), +                        None => c.sha1.expect("either abstract_sha1 or content is required"), +                    }, +                    lang: c.lang, +                    mimetype: c.mimetype, +                }) +                .collect(); +            insert_into(release_rev_abstract::table) +                .values(release_abstract_rows) +                .execute(conn)?; +        } +          edit.into_model()      } diff --git a/rust/src/database_models.rs b/rust/src/database_models.rs index f875b492..50176f5f 100644 --- a/rust/src/database_models.rs +++ b/rust/src/database_models.rs @@ -225,7 +225,7 @@ pub struct ReleaseContribRow {      pub id: i64,      pub release_rev: Uuid,      pub creator_ident_id: Option<Uuid>, -    pub raw: Option<String>, +    pub raw_name: Option<String>,      pub role: Option<String>,      pub index: Option<i64>,      pub extra_json: Option<serde_json::Value>, @@ -236,7 +236,7 @@ pub struct ReleaseContribRow {  pub struct ReleaseContribNewRow {      pub release_rev: Uuid,      pub creator_ident_id: Option<Uuid>, -    pub raw: Option<String>, +    pub raw_name: Option<String>,      pub role: Option<String>,      pub index: Option<i64>,      pub extra_json: Option<serde_json::Value>, @@ -278,6 +278,13 @@ pub struct FileReleaseRow {      pub target_release_ident_id: Uuid,  } +#[derive(Debug, Queryable, Insertable, Associations, AsChangeset)] +#[table_name = "abstracts"] +pub struct AbstractsRow { +    pub sha1: String, +    pub content: String, +} +  #[derive(Debug, Queryable, Identifiable, Associations, AsChangeset)]  #[table_name = "editgroup"]  pub struct EditgroupRow { diff --git a/rust/src/database_schema.rs b/rust/src/database_schema.rs index c23e3f83..f935302a 100644 --- a/rust/src/database_schema.rs +++ b/rust/src/database_schema.rs @@ -157,7 +157,7 @@ table! {          id -> Int8,          release_rev -> Uuid,          creator_ident_id -> Nullable<Uuid>, -        raw -> Nullable<Text>, +        raw_name -> Nullable<Text>,          role -> Nullable<Text>,          index -> Nullable<Int8>,          extra_json -> Nullable<Json>, diff --git a/rust/tests/test_api_server.rs b/rust/tests/test_api_server.rs index b9880ba1..f43101c0 100644 --- a/rust/tests/test_api_server.rs +++ b/rust/tests/test_api_server.rs @@ -422,11 +422,11 @@ fn test_post_release() {                      }],                  "contribs": [{                          "index": 1, -                        "raw": "textual description of contributor (aka, name)", +                        "raw_name": "textual description of contributor (aka, name)",                          "creator_id": "aaaaaaaaaaaaaircaaaaaaaaae",                          "contrib_type": "author"                      },{ -                        "raw": "shorter" +                        "raw_name": "shorter"                      }],                  "extra": { "source": "speculation" }                  }"#, @@ -620,11 +620,11 @@ fn test_400() {                      }],                  "contribs": [{                          "index": 1, -                        "raw": "textual description of contributor (aka, name)", +                        "raw_name": "textual description of contributor (aka, name)",                          "creator_id": "aaaaaaaaaaaaaircaaaaaaaaae",                          "contrib_type": "author"                      },{ -                        "raw": "shorter" +                        "raw_name": "shorter"                      }],                  "extra": { "source": "speculation" }                  }"#, @@ -820,8 +820,8 @@ fn test_abstracts() {              &router,          ),          status::Ok, -        // SHA-1 of first abstract string -        Some("4e30ded694c6a7775b9e7b019dfda6be0dd60944"), +        // SHA-1 of first abstract string (with no trailing newline) +        Some("65c171bd8c968e12ede25ad95f02cd4b2ce9db52"),      );      check_response(          request::get( @@ -842,3 +842,46 @@ fn test_abstracts() {          Some("24iu3i25u2"),      );  } + +#[test] +fn test_contribs() { +    let (headers, router, conn) = setup(); + +    check_response( +        request::post( +            "http://localhost:9411/v0/release", +            headers.clone(), +            r#"{"title": "some paper", +                "doi": "10.1234/iiiiiii", +                "contribs": [{ +                        "index": 1, +                        "raw_name": "textual description of contributor (aka, name)", +                        "creator_id": "aaaaaaaaaaaaaircaaaaaaaaae", +                        "contrib_type": "author", +                        "extra": {"key": "value 28328424942"} +                    },{ +                        "raw_name": "shorter" +                    }] +                }"#, +            &router, +        ), +        status::Created, +        None, +    ); + +    let editor_id = Uuid::parse_str("00000000-0000-0000-AAAA-000000000001").unwrap(); +    let editgroup_id = get_or_create_editgroup(editor_id, &conn).unwrap(); +    check_response( +        request::post( +            &format!( +                "http://localhost:9411/v0/editgroup/{}/accept", +                uuid2fcid(&editgroup_id) +            ), +            headers.clone(), +            "", +            &router, +        ), +        status::Ok, +        None, +    ); +} | 
