github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/plugins/webdav/server.go (about)

     1  // This file is part of the Smart Home
     2  // Program complex distribution https://github.com/e154/smart-home
     3  // Copyright (C) 2024, Filippov Alex
     4  //
     5  // This library is free software: you can redistribute it and/or
     6  // modify it under the terms of the GNU Lesser General Public
     7  // License as published by the Free Software Foundation; either
     8  // version 3 of the License, or (at your option) any later version.
     9  //
    10  // This library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13  // Library General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public
    16  // License along with this library.  If not, see
    17  // <https://www.gnu.org/licenses/>.
    18  
    19  package webdav
    20  
    21  import (
    22  	"context"
    23  	"net/http"
    24  	"strings"
    25  
    26  	"go.uber.org/atomic"
    27  	"golang.org/x/net/webdav"
    28  
    29  	"github.com/e154/smart-home/adaptors"
    30  	"github.com/e154/smart-home/system/bus"
    31  	"github.com/e154/smart-home/system/scripts"
    32  )
    33  
    34  const rootDir = "/webdav"
    35  
    36  type Server struct {
    37  	adaptors  *adaptors.Adaptors
    38  	eventBus  bus.Bus
    39  	isStarted *atomic.Bool
    40  	scripts   *Scripts
    41  	*FS
    42  	handler *webdav.Handler
    43  }
    44  
    45  func NewServer() *Server {
    46  	server := &Server{
    47  		isStarted: atomic.NewBool(false),
    48  	}
    49  
    50  	return server
    51  }
    52  
    53  func (s *Server) Start(adaptors *adaptors.Adaptors, scriptService scripts.ScriptService, eventBus bus.Bus) {
    54  	if !s.isStarted.CompareAndSwap(false, true) {
    55  		return
    56  	}
    57  
    58  	s.adaptors = adaptors
    59  	s.eventBus = eventBus
    60  
    61  	s.FS = NewFS(s.onRemoveHandler)
    62  	s.handler = &webdav.Handler{
    63  		FileSystem: s,
    64  		LockSystem: webdav.NewMemLS(),
    65  	}
    66  
    67  	_ = s.MkdirAll("/webdav/scripts", 0755)
    68  
    69  	s.scripts = NewScripts(s.FS)
    70  	s.scripts.Start(adaptors, scriptService, eventBus)
    71  
    72  }
    73  
    74  func (s *Server) Shutdown() {
    75  	if !s.isStarted.CompareAndSwap(true, false) {
    76  		return
    77  	}
    78  
    79  	s.scripts.Shutdown()
    80  }
    81  
    82  func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    83  	if !s.isStarted.Load() {
    84  		return
    85  	}
    86  	s.handler.ServeHTTP(w, r)
    87  }
    88  
    89  func (s *Server) onRemoveHandler(ctx context.Context, filePath string) (err error) {
    90  	path := strings.Split(filePath, "/")
    91  	if path[2] == "scripts" {
    92  		err = s.scripts.onRemoveHandler(ctx, filePath)
    93  	}
    94  	return
    95  }