added hint to .env file when calling the program
This commit is contained in:
parent
fdf0095463
commit
9b54328892
2 changed files with 52 additions and 10 deletions
|
@ -25,3 +25,5 @@ Generated description: Aerial view of a circular lake surrounded by dense forest
|
||||||
Successfully uploaded image to WordPress with description
|
Successfully uploaded image to WordPress with description
|
||||||
Image URL: https://example.wordpress.com/wp-content/uploads/2024/11/DJI_0247-scaled.jpg
|
Image URL: https://example.wordpress.com/wp-content/uploads/2024/11/DJI_0247-scaled.jpg
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Hint: make sure that the `.env` file is located in $PWD when calling the script
|
||||||
|
|
60
src/main.rs
60
src/main.rs
|
@ -3,7 +3,7 @@ use reqwest::{self, multipart};
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use tokio;
|
use tokio;
|
||||||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||||
|
|
||||||
|
@ -32,6 +32,38 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_image_path(path_str: &str) -> Result<PathBuf, Box<dyn Error>> {
|
||||||
|
let path = PathBuf::from(path_str);
|
||||||
|
|
||||||
|
// Check if path exists
|
||||||
|
if !path.exists() {
|
||||||
|
return Err(format!("Image path does not exist: {}", path_str).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's a file
|
||||||
|
if !path.is_file() {
|
||||||
|
return Err(format!("Path is not a file: {}", path_str).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check file extension
|
||||||
|
match path.extension().and_then(|ext| ext.to_str()) {
|
||||||
|
Some(ext) => {
|
||||||
|
let lower_ext = ext.to_lowercase();
|
||||||
|
if !["jpg", "jpeg", "png", "gif"].contains(&lower_ext.as_str()) {
|
||||||
|
return Err(format!("Unsupported file type: {}", ext).into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => return Err("File has no extension".into()),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to canonicalize the path (resolve symlinks and normalize)
|
||||||
|
let canonical_path = path.canonicalize()
|
||||||
|
.map_err(|e| format!("Failed to resolve path: {}", e))?;
|
||||||
|
|
||||||
|
println!("Using image file: {}", canonical_path.display());
|
||||||
|
Ok(canonical_path)
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
// Get image path from command line arguments
|
// Get image path from command line arguments
|
||||||
|
@ -40,24 +72,29 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
eprintln!("Usage: {} <image_path>", args[0]);
|
eprintln!("Usage: {} <image_path>", args[0]);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
let image_path = &args[1];
|
|
||||||
|
// Validate and normalize the image path
|
||||||
|
let image_path = validate_image_path(&args[1])?;
|
||||||
|
|
||||||
// Load configuration
|
// Load configuration
|
||||||
let config = Config::from_env()?;
|
let config = Config::from_env()?;
|
||||||
|
|
||||||
// Get image description from ChatGPT
|
// Get image description from ChatGPT
|
||||||
let description = get_image_description(&config, image_path).await?;
|
let description = get_image_description(&config, &image_path).await?;
|
||||||
println!("Generated description: {}", description);
|
println!("Generated description: {}", description);
|
||||||
|
|
||||||
// Upload image to WordPress and set ALT text
|
// Upload image to WordPress and set ALT text
|
||||||
upload_to_wordpress(&config, image_path, &description).await?;
|
upload_to_wordpress(&config, &image_path, &description).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_image_description(config: &Config, image_path: &str) -> Result<String, Box<dyn Error>> {
|
async fn get_image_description(config: &Config, image_path: &Path) -> Result<String, Box<dyn Error>> {
|
||||||
// Read and encode image
|
// Read and encode image
|
||||||
let image_data = std::fs::read(image_path)?;
|
let image_data = tokio::fs::read(image_path)
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("Failed to read image file: {}", e))?;
|
||||||
|
|
||||||
let base64_image = STANDARD.encode(&image_data);
|
let base64_image = STANDARD.encode(&image_data);
|
||||||
|
|
||||||
// Create ChatGPT API request
|
// Create ChatGPT API request
|
||||||
|
@ -67,7 +104,7 @@ async fn get_image_description(config: &Config, image_path: &str) -> Result<Stri
|
||||||
.header("Authorization", format!("Bearer {}", config.openai_api_key))
|
.header("Authorization", format!("Bearer {}", config.openai_api_key))
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.json(&json!({
|
.json(&json!({
|
||||||
"model": config.openai_model, // Now using the model from config
|
"model": config.openai_model,
|
||||||
"max_tokens": 300,
|
"max_tokens": 300,
|
||||||
"messages": [
|
"messages": [
|
||||||
{
|
{
|
||||||
|
@ -112,12 +149,15 @@ async fn get_image_description(config: &Config, image_path: &str) -> Result<Stri
|
||||||
|
|
||||||
async fn upload_to_wordpress(
|
async fn upload_to_wordpress(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
image_path: &str,
|
image_path: &Path,
|
||||||
description: &str,
|
description: &str,
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let file_data = tokio::fs::read(image_path).await?;
|
let file_data = tokio::fs::read(image_path)
|
||||||
let filename = Path::new(image_path)
|
.await
|
||||||
|
.map_err(|e| format!("Failed to read image for upload: {}", e))?;
|
||||||
|
|
||||||
|
let filename = image_path
|
||||||
.file_name()
|
.file_name()
|
||||||
.ok_or("Invalid filename")?
|
.ok_or("Invalid filename")?
|
||||||
.to_str()
|
.to_str()
|
||||||
|
|
Loading…
Reference in a new issue