Updated to include a manual config specification if you want to try different models.

This commit is contained in:
Steve White 2025-01-28 14:53:50 -06:00
parent ba855d1622
commit 8f51a88997
4 changed files with 28 additions and 12 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.aider* .aider*
.env .env
*.png *.png
gonamer

View File

@ -4,7 +4,7 @@ Gonamer is a command-line tool written in Go that uses any openai compatible vi
## Features ## Features
- Uses OpenAI's vision model to analyze image content - Uses any OpenAI compatible vision model to analyze image content
- Supports JPG, JPEG, PNG, and GIF formats - Supports JPG, JPEG, PNG, and GIF formats
- Generates unique, descriptive filenames - Generates unique, descriptive filenames
- Handles filename conflicts automatically - Handles filename conflicts automatically
@ -22,7 +22,9 @@ go get gopkg.in/yaml.v3
## Configuration ## Configuration
Create a configuration file at `~/.config/gonamer.yaml` with the following structure: By default, Gonamer looks for a configuration file at `~/.config/gonamer.yaml`. You can also specify a custom configuration file using the `-c` flag.
Create a configuration file with the following structure:
```yaml ```yaml
apikey: "your-api-key" apikey: "your-api-key"
@ -38,12 +40,16 @@ Make sure to replace:
## Usage ## Usage
```bash ```bash
gonamer <image_filename> gonamer [-c config.yaml] <image_filename>
``` ```
For example: For example:
```bash ```bash
# Using default config at ~/.config/gonamer.yaml
gonamer vacation_photo.jpg gonamer vacation_photo.jpg
# Using a custom config file
gonamer -c custom-config.yaml vacation_photo.jpg
``` ```
The tool will: The tool will:

BIN
gonamer Executable file

Binary file not shown.

View File

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"flag"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -31,7 +32,7 @@ type OpenAIRequest struct {
// Message represents a message in the OpenAI API request. // Message represents a message in the OpenAI API request.
type Message struct { type Message struct {
Role string `json:"role"` Role string `json:"role"`
Content []Content `json:"content"` Content []Content `json:"content"`
} }
@ -63,8 +64,12 @@ type Config struct {
} }
func main() { func main() {
var configFile string
flag.StringVar(&configFile, "c", "", "Path to config file")
flag.Parse()
// Get the config file path // Get the config file path
configFilePath, err := getConfigFilePath() configFilePath, err := getConfigFilePath(configFile)
if err != nil { if err != nil {
log.Fatalf("Error getting config file path: %v", err) log.Fatalf("Error getting config file path: %v", err)
} }
@ -76,11 +81,12 @@ func main() {
} }
// Get the image filename from the command-line arguments // Get the image filename from the command-line arguments
if len(os.Args) < 2 { if len(flag.Args()) < 1 {
fmt.Println("Usage: go run main.go <image_filename>") fmt.Println("Usage: gonamer [-c config.yaml] <image_filename>")
flag.PrintDefaults()
return return
} }
imageFilename := os.Args[1] imageFilename := flag.Arg(0)
// Validate the image filename extension // Validate the image filename extension
if !ImageExtensionRegex.MatchString(imageFilename) { if !ImageExtensionRegex.MatchString(imageFilename) {
@ -106,7 +112,10 @@ func main() {
} }
// getConfigFilePath returns the path to the config file. // getConfigFilePath returns the path to the config file.
func getConfigFilePath() (string, error) { func getConfigFilePath(configFile string) (string, error) {
if configFile != "" {
return configFile, nil
}
homeDir, err := os.UserHomeDir() homeDir, err := os.UserHomeDir()
if err != nil { if err != nil {
return "", err return "", err
@ -141,8 +150,8 @@ func getSuggestedFilename(imageFilename string, config *Config) (string, error)
// 2. Create the request payload // 2. Create the request payload
requestData := OpenAIRequest{ requestData := OpenAIRequest{
Model: config.Model, Model: config.Model,
Messages: []Message{ Messages: []Message{
{ {
Role: "user", Role: "user",
Content: []Content{ Content: []Content{
@ -335,7 +344,7 @@ func sanitizeFilename(filename string) string {
// Replace invalid characters with underscores // Replace invalid characters with underscores
sanitizedFilename := invalidChars.ReplaceAllString(filenameWithoutExt, "_") sanitizedFilename := invalidChars.ReplaceAllString(filenameWithoutExt, "_")
// Remove non-letter characters from the beginning of the filename // Remove non-letter characters from the beginning of the filename
for len(sanitizedFilename) > 0 && !unicode.IsLetter(rune(sanitizedFilename[0])) { for len(sanitizedFilename) > 0 && !unicode.IsLetter(rune(sanitizedFilename[0])) {
sanitizedFilename = sanitizedFilename[1:] sanitizedFilename = sanitizedFilename[1:]
} }