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
|
||||
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 std::env;
|
||||
use std::error::Error;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tokio;
|
||||
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]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Get image path from command line arguments
|
||||
|
@ -40,24 +72,29 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
|||
eprintln!("Usage: {} <image_path>", args[0]);
|
||||
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
|
||||
let config = Config::from_env()?;
|
||||
|
||||
// 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);
|
||||
|
||||
// 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(())
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
// 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("Content-Type", "application/json")
|
||||
.json(&json!({
|
||||
"model": config.openai_model, // Now using the model from config
|
||||
"model": config.openai_model,
|
||||
"max_tokens": 300,
|
||||
"messages": [
|
||||
{
|
||||
|
@ -112,12 +149,15 @@ async fn get_image_description(config: &Config, image_path: &str) -> Result<Stri
|
|||
|
||||
async fn upload_to_wordpress(
|
||||
config: &Config,
|
||||
image_path: &str,
|
||||
image_path: &Path,
|
||||
description: &str,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let client = reqwest::Client::new();
|
||||
let file_data = tokio::fs::read(image_path).await?;
|
||||
let filename = Path::new(image_path)
|
||||
let file_data = tokio::fs::read(image_path)
|
||||
.await
|
||||
.map_err(|e| format!("Failed to read image for upload: {}", e))?;
|
||||
|
||||
let filename = image_path
|
||||
.file_name()
|
||||
.ok_or("Invalid filename")?
|
||||
.to_str()
|
||||
|
|
Loading…
Reference in a new issue