Compare commits

..

No commits in common. "main" and "007-comments" have entirely different histories.

3 changed files with 16 additions and 36 deletions

13
LICENSE
View file

@ -1,13 +0,0 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

View file

@ -1,5 +0,0 @@
### publicise-rs
_Publicise_ is an application which traverses a Nextcloud folder and creates a public share for each file.
The application was originally devised as a way to share photos with people without Instagram accounts, and as an exploration of Rust.

View file

@ -1,6 +1,6 @@
extern crate xdg; extern crate xdg;
use env_logger::Env; use env_logger::{Env, Target};
use log::debug; use log::debug;
use reqwest; use reqwest;
use serde::Deserialize; use serde::Deserialize;
@ -109,12 +109,10 @@ pub struct Collection {
} }
fn init() -> Result<Config, Box<dyn std::error::Error>> { fn init() -> Result<Config, Box<dyn std::error::Error>> {
debug!("[init] Entering function...");
let xdg_dirs = xdg::BaseDirectories::with_prefix("publicise-rs").unwrap(); let xdg_dirs = xdg::BaseDirectories::with_prefix("publicise-rs").unwrap();
let config_path = xdg_dirs.find_config_file("config.toml").unwrap(); let config_path = xdg_dirs.find_config_file("config.toml").unwrap();
let config_file_contents = fs::read_to_string(config_path).unwrap(); let config_file_contents = fs::read_to_string(config_path).unwrap();
let config: Config = toml::from_str(&config_file_contents).unwrap(); let config: Config = toml::from_str(&config_file_contents).unwrap();
debug!("[init] config: {:?}", config);
return Ok(config); return Ok(config);
} }
@ -141,7 +139,7 @@ async fn get_folder_contents(url_tail: &str, config: &Config) -> Result<String,
); );
let response_text = client let response_text = client
.request(method, url) .request(method, url)
.basic_auth(config.credentials.username.as_str(), config.credentials.password.as_ref()) .basic_auth("adam", config.credentials.password.as_ref())
.body(body) .body(body)
.send() .send()
.await? .await?
@ -151,10 +149,9 @@ async fn get_folder_contents(url_tail: &str, config: &Config) -> Result<String,
Ok(response_text) Ok(response_text)
} }
async fn publicise_it(path: &str, config: &Config) -> Result<bool, Box<dyn std::error::Error>> { async fn publicise_it(path: &str, password: &str) -> Result<bool, Box<dyn std::error::Error>> {
debug!("[publicise_it] Entering function..."); debug!("[publicise_it] Entering function...");
let base_url = Url::parse(config.paths.root.as_str())?; let url = "https://cloud.theadamcooper.com/ocs/v2.php/apps/files_sharing/api/v1/shares";
let url = base_url.join("ocs/v2.php/apps/files_sharing/api/v1/shares")?;
let method = reqwest::Method::POST; let method = reqwest::Method::POST;
let client = reqwest::Client::new(); let client = reqwest::Client::new();
let params = [("path", path), ("shareType", "3")]; let params = [("path", path), ("shareType", "3")];
@ -162,7 +159,7 @@ async fn publicise_it(path: &str, config: &Config) -> Result<bool, Box<dyn std::
debug!("[publicise_it] params: {:?}", params); debug!("[publicise_it] params: {:?}", params);
let response_text = client let response_text = client
.request(method, url) .request(method, url)
.basic_auth(config.credentials.username.as_str(), config.credentials.password.as_ref()) .basic_auth("adam", Some(password))
.header("OCS-APIRequest", "true") .header("OCS-APIRequest", "true")
.form(&params) .form(&params)
.send() .send()
@ -203,13 +200,13 @@ async fn traverse(mut result: Multistatus, config: &Config) -> Result<bool, Box<
debug!("[traverse] Node..."); debug!("[traverse] Node...");
if !(&mut result.response[current_index].propstat[0].prop.share_types).contains(&ShareType{ share_type: 3 }) { if !(&mut result.response[current_index].propstat[0].prop.share_types).contains(&ShareType{ share_type: 3 }) {
debug!("[traverse] it's not public"); debug!("[traverse] it's not public");
let username = config.credentials.username.as_str(); let username = "adam";
let username_seg_string = format!("/{}/", username); let username_seg_string = format!("/{}/", username);
let username_seg = username_seg_string.as_str(); let username_seg = username_seg_string.as_str();
let index = &result.response[current_index].href.find(username_seg).unwrap_or(0); let index = &result.response[current_index].href.find(username_seg).unwrap_or(0);
let new_index = index + username.len() + 2; let new_index = index + username.len() + 2;
let new_href = &result.response[current_index].href[new_index..]; let new_href = &result.response[current_index].href[new_index..];
publicise_it(new_href, config).await.unwrap(); publicise_it(new_href, config.credentials.password.as_ref().unwrap()).await.unwrap();
} else { } else {
debug!("[traverse] it's already public"); debug!("[traverse] it's already public");
} }
@ -226,26 +223,27 @@ async fn traverse(mut result: Multistatus, config: &Config) -> Result<bool, Box<
#[tokio::main] #[tokio::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
env_logger::Builder::from_env(Env::default()).init();
env_logger::Builder::from_env(Env::default().default_filter_or("debug"))
.target(Target::Stdout)
.init();
println!("Publicise it!\n\n"); println!("Publicise it!\n\n");
let mut config = init().unwrap(); let mut config = init().unwrap();
if config.credentials.password == None { if config.credentials.password == None {
let output = Command::new(&config.credentials.password_script.as_ref().unwrap()).output().unwrap(); let output = Command::new(&config.credentials.password_script.as_ref().unwrap()).output().unwrap();
if output.stdout.len() == 0 {
panic!("[main] Failed to acquire password from provided script.");
}
config.credentials.password = Some(String::from_utf8(output.stdout).unwrap()); config.credentials.password = Some(String::from_utf8(output.stdout).unwrap());
} }
debug!("[main] {:?}", &config); debug!("{:?}", &config);
let full_path = &(String::from("/remote.php/dav/files/") + &config.credentials.username + "/" + &config.paths.target); let full_path = &(String::from("/remote.php/dav/files/") + &config.credentials.username + "/" + &config.paths.target);
let folder_contents: String = let folder_contents: String =
get_folder_contents(full_path, &config) get_folder_contents(full_path, &config)
.await .await
.unwrap(); .unwrap();
let result: Multistatus = from_str(&folder_contents).unwrap(); let result: Multistatus = from_str(&folder_contents).unwrap();
debug!("[main] {:?}", result); debug!("{:?}", result);
let _ = traverse(result, &config).await.unwrap(); let _ = traverse(result, &config).await.unwrap();
Ok(()) Ok(())
} }