use arboard::Clipboard;
use image::{ImageBuffer, ImageOutputFormat, RgbaImage};
use std::{
env::temp_dir,
fs::File,
io::{BufWriter, Write},
process::{exit, Command},
time::{Instant, SystemTime},
};
const FOLDER_NAME: &str = "clipboard-gdrive";
fn main() {
let mut clipboard = Clipboard::new().unwrap();
let text = clipboard.get_text();
let image = clipboard.get_image();
if text.is_ok() {
eprintln!("Not implemented yet");
exit(1);
} else if image.is_ok() {
let s = Instant::now();
let cur_timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis();
let temp_path = temp_dir()
.join("clipboard_google_drive")
.with_file_name(&cur_timestamp.to_string())
.with_extension("png");
let temp_file = File::create(&temp_path).unwrap();
let image_data = image.unwrap();
let image: RgbaImage = ImageBuffer::from_raw(
image_data.width.try_into().unwrap(),
image_data.height.try_into().unwrap(),
image_data.bytes.into_owned(),
)
.unwrap();
let mut writer = BufWriter::new(temp_file);
image.write_to(&mut writer, ImageOutputFormat::Png).unwrap();
writer.flush().unwrap();
println!("Image file saved;elapsed={:?}", s.elapsed());
let s = Instant::now();
let upload = Command::new("gdrive")
.args([
"upload",
"--delete",
"--share",
"--parent",
&get_parent_id(),
"--name",
&format!(
"{}.{}",
&cur_timestamp.to_string(),
&temp_path.extension().unwrap().to_str().unwrap()
),
temp_path.to_str().unwrap(),
])
.output()
.expect("Failed to upload to Google Drive");
let mut shared_link: String = String::from("");
for line in String::from_utf8(upload.stdout.to_vec()).unwrap().lines() {
if !line.starts_with("File is readable by anyone at") {
continue;
}
let chunks: Vec<&str> = line.split(" ").collect();
shared_link = chunks.last().unwrap().to_string();
}
shared_link = shared_link.replace("export=download", "export=view");
println!(
"Image file uploaded;shared_link={:?},elapsed={:?}",
shared_link,
s.elapsed()
);
clipboard.set_text(&shared_link).expect(&format!(
"Failed to set file URI to clipboard;{}",
&shared_link
));
} else {
eprintln!("Clipboard failure");
exit(1);
}
}
fn get_parent_id() -> String {
let output = Command::new("gdrive")
.args([
"list",
"--no-header",
"--query",
&format!("name = '{}'", FOLDER_NAME,),
])
.output()
.expect("Failed to find folder id");
let entry = String::from_utf8(output.stdout.to_vec()).unwrap();
let chunks: Vec<&str> = entry.split(" ").collect();
return chunks
.first()
.expect(&format!("Failed to find folder;expected={FOLDER_NAME}"))
.to_string();
}