diff --git a/api/v1/api.go b/api/v1/api.go index 8d8a7a455fce89bf029532e2476e317509709b2b..35976c4112799aac9800cafdc8cd633dedbda2dc 100644 --- a/api/v1/api.go +++ b/api/v1/api.go @@ -85,12 +85,6 @@ func InstallHandler(r *mux.Router, st *store.Store, im *importer.Importer, infoL importsHandler["POST"] = api.CreateImportForGroup() r.Handle("/groups/{group-id}/imports", importsHandler) - importHandler := make(handlers.MethodHandler) - importHandler["GET"] = api.ReadImportOfGroup() - importHandler["PUT"] = api.UploadFileToImportOfGroup() - importHandler["DELETE"] = api.DeleteImportOfGroup() - r.Handle("/groups/{group-id}/imports/{import-id}", importHandler) - // Files filesHandler := make(handlers.MethodHandler) filesHandler["GET"] = api.ListFilesOfGroup() @@ -102,6 +96,12 @@ func InstallHandler(r *mux.Router, st *store.Store, im *importer.Importer, infoL fileHandler["DELETE"] = api.DeleteFileOfGroup() r.Handle("/groups/{group-id}/files/{file-id}", fileHandler) + importHandler := make(handlers.MethodHandler) + importHandler["GET"] = api.ReadImportOfFile() + importHandler["PUT"] = api.UploadFile() + importHandler["DELETE"] = api.CancelImportOfFile() + r.Handle("/groups/{group-id}/files/{file-id}/import", importHandler) + // Playlists playlistsHandler := make(handlers.MethodHandler) playlistsHandler["GET"] = api.ListPlaylistsOfGroup() diff --git a/api/v1/api_imports.go b/api/v1/api_imports.go index ac7e8a317863bf3c6ac63903c264b34e9b8ec104..528723de01f20c48ac69149ed04c654c4aae7632 100644 --- a/api/v1/api_imports.go +++ b/api/v1/api_imports.go @@ -36,24 +36,24 @@ func (api *API) ListImportsOfGroup() http.Handler { func (api *API) CreateImportForGroup() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"creating imports in group not yet implemented"}) + sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"creating imports for group not yet implemented"}) }) } -func (api *API) ReadImportOfGroup() http.Handler { +func (api *API) ReadImportOfFile() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"reading imports of group not yet implemented"}) + sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"reading imports not yet implemented"}) }) } -func (api *API) UploadFileToImportOfGroup() http.Handler { +func (api *API) UploadFile() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"uploading files to imports of group not yet implemented"}) + sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"uploading files not yet implemented"}) }) } -func (api *API) DeleteImportOfGroup() http.Handler { +func (api *API) CancelImportOfFile() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"deleting imports from group not yet implemented"}) + sendWebResponse(w, http.StatusNotImplemented, ErrorResponse{"canceling imports not yet implemented"}) }) } diff --git a/store/files.go b/store/files.go index 28488ad9d8d923f510eec4b2a88296f90a593f22..fc9a11faf0f32c6007e498975ba55d52650a4ee7 100644 --- a/store/files.go +++ b/store/files.go @@ -31,7 +31,7 @@ import ( "github.com/coreos/bbolt" ) -func getFilesBucket(tx *bolt.Tx, group string) (files *bolt.Bucket, err error) { +func getFilesAndImportsBucket(tx *bolt.Tx, group string) (files *bolt.Bucket, imports *bolt.Bucket, err error) { var gb *bolt.Bucket if gb, err = getGroupBucket(tx, group); err != nil { return @@ -48,12 +48,17 @@ func getFilesBucket(tx *bolt.Tx, group string) (files *bolt.Bucket, err error) { if files == nil { err = errors.New("invalid store: files bucket of group '" + group + "' not found") } + + imports = gb.Bucket([]byte(importsBn)) + if files == nil { + err = errors.New("invalid store: imports bucket of group '" + group + "' not found") + } return } func (st *Store) ListFiles(group string) (files Files, err error) { err = st.db.View(func(tx *bolt.Tx) error { - fb, err := getFilesBucket(tx, group) + fb, _, err := getFilesAndImportsBucket(tx, group) if err != nil { return err } @@ -77,7 +82,7 @@ func (st *Store) ListFiles(group string) (files Files, err error) { func (st *Store) CreateFile(group string, file File) (id uint64, err error) { err = st.db.Update(func(tx *bolt.Tx) error { - fb, err := getFilesBucket(tx, group) + fb, _, err := getFilesAndImportsBucket(tx, group) if err != nil { return err } @@ -96,7 +101,7 @@ func (st *Store) CreateFile(group string, file File) (id uint64, err error) { func (st *Store) GetFile(group string, id uint64) (file File, err error) { err = st.db.View(func(tx *bolt.Tx) error { - fb, err := getFilesBucket(tx, group) + fb, _, err := getFilesAndImportsBucket(tx, group) if err != nil { return err } @@ -114,7 +119,7 @@ func (st *Store) GetFile(group string, id uint64) (file File, err error) { func (st *Store) UpdateFile(group string, id uint64, file File) (err error) { err = st.db.Update(func(tx *bolt.Tx) error { - fb, err := getFilesBucket(tx, group) + fb, _, err := getFilesAndImportsBucket(tx, group) if err != nil { return err } @@ -135,7 +140,7 @@ func (st *Store) UpdateFile(group string, id uint64, file File) (err error) { func (st *Store) DeleteFile(group string, id uint64) (err error) { err = st.db.Update(func(tx *bolt.Tx) error { - fb, err := getFilesBucket(tx, group) + fb, _, err := getFilesAndImportsBucket(tx, group) if err != nil { return err } diff --git a/store/store.go b/store/store.go index 178ed7d839a454504f960482bc541279360a3209..d8df49968f345e6bb347093c0a9d900a4a789e0b 100644 --- a/store/store.go +++ b/store/store.go @@ -76,6 +76,7 @@ func openDB(dbPath string, readOnly bool) (db *bolt.DB, version uint64, err erro } // TODO: check all group buckets?? + // - set all new/pending/running imports to aborted return nil }) if err != nil { diff --git a/store/store_test.go b/store/store_test.go index f6cd6c982f17f24d9aa3e87dc6cd2d6d921bb6c6..856ac067d0c01df321a68aafee7f1bbdf28078e8 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -241,7 +241,7 @@ func TestFilesListAndCreate(t *testing.T) { t.Fatalf("listing files of public group failed: %v", err) } if len(files) != 0 { - t.Fatalf("a newly created store should contain no files in public group but ListFiles returned: %q", files) + t.Fatalf("a newly created store should contain no files in public group but ListFiles returned: %v", files) } files, err = store.ListFiles("notexistend") @@ -249,7 +249,7 @@ func TestFilesListAndCreate(t *testing.T) { t.Fatalf("listing files of not existing group shouldn't throw an error but returned: %v", err) } if len(files) != 0 { - t.Fatalf("listing files of not existing group should return and empty list but ListFiles returned: %q", files) + t.Fatalf("listing files of not existing group should return and empty list but ListFiles returned: %v", files) } _, err = store.CreateFile(publicGroupBn, File{}) diff --git a/store/types.go b/store/types.go index ad77c05c86c443f780bb28c06093cfedb2894389..e1ab66c70461d6a389c4b067e7f9c2e158b1916e 100644 --- a/store/types.go +++ b/store/types.go @@ -91,31 +91,54 @@ const ( ImportNew ImportState = iota ImportPending ImportRunning - ImportAborted ImportDone + ImportAborted ) func (s ImportState) String() string { switch s { case ImportNew: return "new" + case ImportPending: + return "pending" case ImportRunning: return "running" - case ImportAborted: - return "aborted" case ImportDone: return "done" + case ImportAborted: + return "aborted" } return "unknown" } +func (s *ImportState) fromString(str string) error { + switch str { + case "new": + *s = ImportNew + case "pending": + *s = ImportPending + case "running": + *s = ImportRunning + case "done": + *s = ImportDone + case "aborted": + *s = ImportAborted + default: + return errors.New("invalid import state: '" + str + "'") + } + return nil +} + func (s ImportState) MarshalText() (data []byte, err error) { data = []byte(s.String()) return } +func (s *ImportState) UnmarshalText(data []byte) (err error) { + return s.fromString(string(data)) +} + type Import struct { - Created TimeAndUser `json:"created"` State ImportState `json:"state"` Success bool `json:"success"` Log map[int64]string `json:"log"` @@ -125,6 +148,7 @@ type Import struct { type FileSource struct { FileName string `json:"filename"` Hash string `json:"hash"` + Import Import `json:"import"` } type FileMetadata struct {