// // tank // // Import and Playlist Daemon for autoradio project // // // Copyright (C) 2017 Christian Pointner <equinox@helsinki.at> // // This file is part of tank. // // tank is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // any later version. // // tank is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with tank. If not, see <http://www.gnu.org/licenses/>. // package v1 import ( "encoding/json" "io/ioutil" "log" "net/http" "github.com/gorilla/handlers" "github.com/gorilla/mux" "gitlab.servus.at/autoradio/tank/importer" "gitlab.servus.at/autoradio/tank/store" ) func sendWebResponse(w http.ResponseWriter, status int, respdata interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) json.NewEncoder(w).Encode(respdata) // TODO: Error Handling? } type API struct { store *store.Store importer *importer.Importer infoLog *log.Logger errLog *log.Logger dbgLog *log.Logger listing APIListing } func NewAPI(st *store.Store, im *importer.Importer, infoLog, errLog, dbgLog *log.Logger) (api *API) { if infoLog == nil { infoLog = log.New(ioutil.Discard, "", 0) } if errLog == nil { errLog = log.New(ioutil.Discard, "", 0) } if dbgLog == nil { dbgLog = log.New(ioutil.Discard, "", 0) } api = &API{} api.store = st api.importer = im api.infoLog = infoLog api.errLog = errLog api.dbgLog = dbgLog api.listing.Endpoints = make(map[string]*APIEndpoint) return } func (api *API) ListEndpoints() http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { sendWebResponse(w, http.StatusOK, api.listing) }) } func InstallHandler(r *mux.Router, st *store.Store, im *importer.Importer, infoLog, errLog, dbgLog *log.Logger) { api := NewAPI(st, im, infoLog, errLog, dbgLog) // Groups groupsHandler := make(handlers.MethodHandler) groupsHandler["GET"] = api.ListGroups() r.Handle("/groups", groupsHandler) // Imports importsHandler := make(handlers.MethodHandler) importsHandler["GET"] = api.ListImportsOfGroup() 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() r.Handle("/groups/{group-id}/files", filesHandler) fileHandler := make(handlers.MethodHandler) fileHandler["GET"] = api.ReadFileOfGroup() fileHandler["PUT"] = api.UpdateFileOfGroup() fileHandler["DELETE"] = api.DeleteFileOfGroup() r.Handle("/groups/{group-id}/files/{file-id}", fileHandler) // Playlists playlistsHandler := make(handlers.MethodHandler) playlistsHandler["GET"] = api.ListPlaylistsOfGroup() playlistsHandler["POST"] = api.CreatePlaylistForGroup() r.Handle("/groups/{group-id}/playlists", playlistsHandler) playlistHandler := make(handlers.MethodHandler) playlistHandler["GET"] = api.ReadPlaylistOfGroup() playlistHandler["PUT"] = api.UpdatePlaylistOfGroup() playlistHandler["DELETE"] = api.DeletePlaylistOfGroup() r.Handle("/groups/{group-id}/playlists/{playlist-id}", playlistHandler) // Index indexHandler := make(handlers.MethodHandler) // TODO: do api docs based on: // - https://github.com/adams-sarah/test2doc // - https://github.com/bukalapak/snowboard indexHandler["GET"] = api.ListEndpoints() r.Handle("/", indexHandler) r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { p, err := route.GetPathTemplate() if err != nil { return nil } m, err := route.GetMethods() if err != nil || len(m) == 0 { return err } if e, exists := api.listing.Endpoints[p]; exists { e.Methods = append(e.Methods, m...) } else { api.listing.Endpoints[p] = &APIEndpoint{m} } return nil }) }