Skip to content
Snippets Groups Projects
api.go 4.21 KiB
Newer Older
  • Learn to ignore specific revisions
  • //
    //  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"
    
    	"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) {
    
    Christian Pointner's avatar
    Christian Pointner committed
    	api := NewAPI(st, im, infoLog, errLog, dbgLog)
    
    	// Groups
    
    	groupsHandler := make(handlers.MethodHandler)
    	groupsHandler["GET"] = api.ListGroups()
    	r.Handle("/groups", groupsHandler)
    
    	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)
    
    	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)
    
    	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)
    
    	indexHandler := make(handlers.MethodHandler)
    	indexHandler["GET"] = api.ListEndpoints() // TODO: fix this
    	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}