package main import ( "io" "log" "os" "path/filepath" "time" "launchpad.net/go-xdg" "github.com/gorilla/mux" "github.com/jessevdk/go-flags" "github.com/tylerb/graceful" "github.com/blevesearch/bleve" bleveHttp "github.com/blevesearch/bleve/http" ) type Options struct { CsvFile string `long:"csv" description:"CSV file to build the index from" required:"true"` Listen string `short:"l" long:"listen" description:"Address to listen to" default:":33276"` } func readAlbums(csvPath string, albums chan *Album, errors chan error) { defer close(albums) csvFile, err := os.Open(csvPath) if err != nil { errors <- err return } defer closeOrPanic(csvFile, csvPath) r, err := NewAlbumCsvReader(csvFile) if err != nil { errors <- err return } for { a, err := r.Read() if err != nil { if err == io.EOF { return } errors <- err continue } albums <- a } } func indexAlbums(i bleve.Index, albums chan *Album, errors chan error) { iAlbum := 0 start := time.Now() for a := range albums { err := i.Index(AlbumIDString(a.ID), a) if err != nil { errors <- err } iAlbum++ if iAlbum%100 == 0 { dur := time.Since(start) log.Printf("Indexed %d beer in %s (%f ms / Album)", iAlbum, dur, dur.Seconds()/float64(iAlbum)*1000) } } } func buildOrOpen(basepath string) (bleve.Index, error) { i, err := bleve.Open(basepath) if err == bleve.ErrorIndexPathDoesNotExist { return bleve.New(basepath, buildAlbumMapping()) } return i, err } // Execute executes the job func Execute() error { var opts Options _, err := flags.Parse(&opts) if err != nil { return err } basepath := filepath.Join(xdg.Cache.Home(), "satbd.bar.satellite") log.Printf("basepath is %s", basepath) err = os.MkdirAll(basepath, 0755) if err != nil { return err } i, err := buildOrOpen("satbd.bar.satellite") if err != nil { return err } albums := make(chan *Album) errors := make(chan error) go readAlbums(opts.CsvFile, albums, errors) go indexAlbums(i, albums, errors) go func() { for err := range errors { log.Printf("ERROR: %s", err) } }() router := mux.NewRouter() bleveHttp.RegisterIndexName("album", i) searchHandler := bleveHttp.NewSearchHandler("album") router.Handle("/api/search", searchHandler).Methods("POST") log.Printf("Listening on %s", opts.Listen) graceful.Run(opts.Listen, 10*time.Second, router) return nil } func main() { if err := Execute(); err != nil { log.Printf("got unhandled error: %s", err) os.Exit(1) } }