package main
import (
"encoding/csv"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/perlw/pict/internal/app/pictadd"
"github.com/perlw/pict/internal/pkg/store"
)
func collectDataFromCsv(csvFilename string) []pictadd.FileWithMetadata {
filesWithMetadata := make([]pictadd.FileWithMetadata, 0, 10)
csvFile, err := os.Open(csvFilename)
if err != nil {
flag.PrintDefaults()
fmt.Println("could not find/read csv file")
os.Exit(1)
}
defer csvFile.Close()
csvReader := csv.NewReader(csvFile)
for {
record, err := csvReader.Read()
if err == io.EOF {
break
}
var fileData pictadd.FileWithMetadata
if len(record) > 0 {
fileData.Filename = record[0]
}
if len(record) > 1 {
fileData.Tags = strings.Split(record[1], ",")
}
if len(record) > 2 {
fileData.Title = record[2]
}
if len(record) > 3 {
fileData.Timestamp = parseTimestampFromFilename(fileData.Filename, record[3])
}
filesWithMetadata = append(filesWithMetadata, fileData)
}
return filesWithMetadata
}
func parseTimestampFromFilename(filename, format string) int64 {
var result int64
var start, end int
start = strings.Index(format, "[[")
end = strings.Index(format, "]]")
timeFormat := format[start+2 : end]
if start > -1 && end > -1 && end > start {
timeFormat = strings.Replace(timeFormat, "YYYY", "2006", -1)
timeFormat = strings.Replace(timeFormat, "MM", "01", -1)
timeFormat = strings.Replace(timeFormat, "DD", "02", -1)
timeFormat = strings.Replace(timeFormat, "hh", "15", -1)
timeFormat = strings.Replace(timeFormat, "mm", "04", -1)
timeFormat = strings.Replace(timeFormat, "ss", "05", -1)
}
if format != "" {
if dt, err := time.Parse(
timeFormat, filepath.Base(filename)[start:end-2],
); err != nil {
fmt.Printf("invalid timestamp: %s\n", err.Error())
result = time.Now().Unix()
} else {
result = dt.Unix()
}
} else {
result = time.Now().Unix()
}
return result
}
func main() {
var tagsArg, storageDir string
var goAhead, fixThumbnails, fixPreviews bool
var timestampArg int64
var filenameFormat, title string
var csvFilename string
var imageFilename string
flag.StringVar(
&storageDir, "storage-dir", "./", "where to find database files etc",
)
flag.BoolVar(&fixThumbnails, "fix-thumbnails", false, "fixes thumbnails")
flag.BoolVar(&fixPreviews, "fix-previews", false, "fixes previews")
flag.StringVar(&tagsArg, "tags", "", "tags to add/create")
flag.StringVar(&title, "title", "", "the title to attach to the image")
flag.Int64Var(×tampArg, "timestamp", 0, "timestamp, defaults to now")
flag.StringVar(&filenameFormat, "format", "", "the format of the filename")
flag.StringVar(&csvFilename, "csv", "", "read files from csv (format: filename,\"tag_a,tag_b\",title,filenameformat)")
flag.StringVar(&imageFilename, "file", "", "name of a single file")
flag.BoolVar(&goAhead, "yes", false, "tells it to go ahead, used for scripts")
flag.Parse()
var filesWithMetadata []pictadd.FileWithMetadata
if csvFilename != "" && imageFilename != "" {
flag.PrintDefaults()
fmt.Println("can't specify both -csv and -file")
os.Exit(1)
} else if csvFilename != "" {
filesWithMetadata = collectDataFromCsv(csvFilename)
} else if imageFilename != "" {
tags := strings.Split(tagsArg, ",")
var timestamp int64
if filenameFormat != "" {
timestamp = parseTimestampFromFilename(imageFilename, filenameFormat)
} else {
if timestampArg <= 0 {
timestamp = time.Now().Unix()
} else {
timestamp = time.Unix(timestampArg, 0).Unix()
}
}
filesWithMetadata = []pictadd.FileWithMetadata{
{
Filename: imageFilename,
Tags: tags,
Title: title,
Timestamp: timestamp,
},
}
} else {
flag.PrintDefaults()
fmt.Println("must specify either -csv or -file")
os.Exit(1)
}
store, err := store.NewSQLiteProvider(
filepath.Join(storageDir, "metadata.db"),
)
if err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(2)
}
defer store.Close()
opts := []pictadd.Option{
pictadd.WithStoreProvider(store),
pictadd.WithImageStorageDir(storageDir),
}
if goAhead {
opts = append(opts, pictadd.WithGoAhead())
}
app, err := pictadd.New(
opts...,
)
if err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(3)
}
if fixThumbnails {
if err := app.FixThumbnails(filesWithMetadata); err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(4)
}
}
if fixPreviews {
if err := app.FixPreviews(filesWithMetadata); err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(4)
}
}
if !fixThumbnails && !fixPreviews {
if err := app.Import(filesWithMetadata); err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(4)
}
}
}