Skip to content
Snippets Groups Projects
api.go 4.33 KiB
Newer Older
//
//  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)
	// 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}