1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
#[macro_use] extern crate failure; extern crate futures; extern crate hyper; extern crate hyper_tls; #[macro_use] extern crate serde_derive; extern crate serde_json; extern crate tokio_core; mod models; use std::vec::Vec; use failure::Error; use futures::Stream; use futures::future::{err, Future}; use hyper::{Client, Method, Request, StatusCode}; use hyper::header::{Authorization, ContentLength, ContentType}; use hyper_tls::HttpsConnector; use tokio_core::reactor::Handle; use models::{App, Category, NewRelease}; pub fn get_categories(handle: &Handle) -> Box<Future<Item = Vec<Category>, Error = Error>> { let uri = match "https://apps.nextcloud.com/api/v1/categories.json".parse() { Ok(u) => u, Err(e) => return Box::new(err(Error::from(e))), }; let client = Client::configure() .connector(HttpsConnector::new(4, handle).unwrap()) .build(handle); let work = client .get(uri) .and_then(|res| { res.body().concat2().and_then(move |body| { let apps: Vec<Category> = serde_json::from_slice(&body).unwrap(); Ok(apps) }) }) .map_err(|err| err.into()); Box::new(work) } pub fn get_apps_and_releases(handle: &Handle, version: &String) -> Box<Future<Item = Vec<App>, Error = Error>> { let raw_uri = format!("https://apps.nextcloud.com/api/v1/platform/{}/apps.json", version); let uri = match raw_uri.parse() { Ok(u) => u, Err(e) => return Box::new(err(Error::from(e))), }; let client = Client::configure() .connector(HttpsConnector::new(4, handle).unwrap()) .build(handle); let work = client .get(uri) .and_then(|res| { res.body().concat2().and_then(move |body| { let apps: Vec<App> = serde_json::from_slice(&body).unwrap(); Ok(apps) }) }) .map_err(|err| Error::from(err)); Box::new(work) } pub fn publish_app(handle: &Handle, url: &String, is_nightly: bool, signature: &String, api_token: &String) -> Box<Future<Item = (), Error = Error>> { let uri = match "https://apps.nextcloud.com/api/v1/apps/releases".parse() { Ok(u) => u, Err(e) => return Box::new(err(Error::from(e))), }; let release = NewRelease { download: url.to_owned(), signature: signature.to_owned(), nightly: is_nightly, }; let release_json = serde_json::to_string(&release).unwrap(); let client = Client::configure() .connector(HttpsConnector::new(4, handle).unwrap()) .build(handle); let mut req = Request::new(Method::Post, uri); req.headers_mut() .set(Authorization(format!("Token {}", api_token))); req.headers_mut().set(ContentType::json()); req.headers_mut() .set(ContentLength(release_json.len() as u64)); req.set_body(release_json); let work = client .request(req) .map_err(|err| Error::from(err)) .and_then(|res| match res.status() { StatusCode::Ok => Ok(()), StatusCode::Created => Ok(()), _ => { Err(format_err!("error uploading release, got HTTP status {}", res.status())) } }); Box::new(work) }