package importer import ( "encoding/csv" "io" "strings" "git.yetaga.in/alazyreader/library/media" ) func CSVToBooks(r io.Reader) ([]media.Book, error) { reader := csv.NewReader(r) header, err := reader.Read() if err != nil { return nil, err } hmap := parseHeader(header) books := []media.Book{} for { row, err := reader.Read() if err == io.EOF { break } if err != nil { return books, err } b := media.Book{ Title: row[hmap["title"]], Authors: parseAuthors(row[hmap["author"]]), SortAuthor: row[hmap["authorlast"]], ISBN10: row[hmap["isbn-10"]], ISBN13: row[hmap["isbn-13"]], Format: row[hmap["format"]], Genre: row[hmap["genre"]], Publisher: row[hmap["publisher"]], Series: row[hmap["series"]], Volume: row[hmap["volume"]], Year: row[hmap["year"]], Signed: row[hmap["signed"]] == "yes", // convert from known string to bool Description: row[hmap["description"]], Notes: row[hmap["notes"]], CoverURL: row[hmap["coverurl"]], } books = append(books, b) } return books, nil } func parseHeader(header []string) map[string]int { m := make(map[string]int, len(header)-1) for i := range header { m[strings.TrimSpace(strings.ToLower(header[i]))] = i } return m } func parseAuthors(a string) []string { as := strings.Split(a, ";") for i := range as { as[i] = strings.TrimSpace(as[i]) } return as }