initial working version
This commit is contained in:
commit
c0d428297e
3 changed files with 102 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "pixelfed_batch_uploader"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
reqwest = { version = "0.11", features = ["blocking", "json", "multipart"] }
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
91
src/main.rs
Normal file
91
src/main.rs
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use reqwest::blocking::Client;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Config {
|
||||||
|
pixelfed_url: String,
|
||||||
|
access_token: String,
|
||||||
|
visibility: String, // Should be "unlisted"
|
||||||
|
default_text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_config() -> Result<Config, Box<dyn Error>> {
|
||||||
|
let config_str = fs::read_to_string("config.json")?;
|
||||||
|
let config: Config = serde_json::from_str(&config_str)?;
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_jpeg_files(directory: &str) -> Vec<String> {
|
||||||
|
let mut images = Vec::new();
|
||||||
|
if let Ok(entries) = fs::read_dir(directory) {
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let path = entry.path();
|
||||||
|
if let Some(ext) = path.extension() {
|
||||||
|
if ext.eq_ignore_ascii_case("jpg") || ext.eq_ignore_ascii_case("jpeg") {
|
||||||
|
images.push(path.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
images
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upload_images_batch(client: &Client, config: &Config, images: &[String], batch_num: usize, total_batches: usize) -> Result<(), Box<dyn Error>> {
|
||||||
|
let url = format!("{}/api/v1/media", config.pixelfed_url);
|
||||||
|
let mut media_ids = Vec::new();
|
||||||
|
|
||||||
|
for image_path in images {
|
||||||
|
let form = reqwest::blocking::multipart::Form::new()
|
||||||
|
.file("file", image_path)?;
|
||||||
|
|
||||||
|
let res = client.post(&url)
|
||||||
|
.bearer_auth(&config.access_token)
|
||||||
|
.multipart(form)
|
||||||
|
.send()?;
|
||||||
|
|
||||||
|
let json: serde_json::Value = res.json()?;
|
||||||
|
if let Some(id) = json["id"].as_str() {
|
||||||
|
media_ids.push(id.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !media_ids.is_empty() {
|
||||||
|
let post_url = format!("{}/api/v1/statuses", config.pixelfed_url);
|
||||||
|
let post_text = format!("{} (Batch {} out of {})", config.default_text, batch_num, total_batches);
|
||||||
|
let body = serde_json::json!({
|
||||||
|
"status": post_text,
|
||||||
|
"media_ids": media_ids,
|
||||||
|
"visibility": config.visibility,
|
||||||
|
});
|
||||||
|
|
||||||
|
client.post(&post_url)
|
||||||
|
.bearer_auth(&config.access_token)
|
||||||
|
.json(&body)
|
||||||
|
.send()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let args: Vec<String> = std::env::args().collect();
|
||||||
|
if args.len() < 2 {
|
||||||
|
eprintln!("Usage: {} <directory>", args[0]);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = load_config()?;
|
||||||
|
let images = get_jpeg_files(&args[1]);
|
||||||
|
let client = Client::new();
|
||||||
|
let total_batches = (images.len() + 19) / 20;
|
||||||
|
|
||||||
|
for (i, chunk) in images.chunks(20).enumerate() {
|
||||||
|
upload_images_batch(&client, &config, chunk, i + 1, total_batches)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("All images uploaded successfully.");
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in a new issue