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) } } }