diff options
| author | James Mills <prologic@shortcircuit.net.au> | 2020-03-21 09:55:06 +1000 |
|---|---|---|
| committer | James Mills <prologic@shortcircuit.net.au> | 2020-03-21 09:55:06 +1000 |
| commit | 4dae45a68ff1ff32a251a5835b2a2723ae125d1c (patch) | |
| tree | b3abe641f39f50ac444aee2bb617d7b4ab44187d /pkg/app/app.go | |
| parent | 76fa613b7eaf1c8626d2a51901c623af7bf1a665 (diff) | |
Restructured source code layout, Added rice support for templates and static assets
Diffstat (limited to 'pkg/app/app.go')
| -rw-r--r-- | pkg/app/app.go | 222 |
1 files changed, 0 insertions, 222 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go deleted file mode 100644 index 0efd22a..0000000 --- a/pkg/app/app.go +++ /dev/null @@ -1,222 +0,0 @@ -// Package app manages main application server. -package app - -import ( - "errors" - "fmt" - "html/template" - "log" - "net" - "net/http" - "path" - - "github.com/fsnotify/fsnotify" - "github.com/gorilla/mux" - "github.com/wybiral/tube/pkg/media" - "github.com/wybiral/tube/pkg/onionkey" -) - -// App represents main application. -type App struct { - Config *Config - Library *media.Library - Watcher *fsnotify.Watcher - Templates *template.Template - Feed []byte - Tor *tor - Listener net.Listener - Router *mux.Router -} - -// NewApp returns a new instance of App from Config. -func NewApp(cfg *Config) (*App, error) { - if cfg == nil { - cfg = DefaultConfig() - } - a := &App{ - Config: cfg, - } - // Setup Library - a.Library = media.NewLibrary() - // Setup Watcher - w, err := fsnotify.NewWatcher() - if err != nil { - return nil, err - } - a.Watcher = w - // Setup Listener - ln, err := newListener(cfg.Server) - if err != nil { - return nil, err - } - a.Listener = ln - // Setup Templates - a.Templates = template.Must(template.ParseGlob("templates/*")) - // Setup Tor - if cfg.Tor.Enable { - t, err := newTor(cfg.Tor) - if err != nil { - return nil, err - } - a.Tor = t - } - // Setup Router - r := mux.NewRouter().StrictSlash(true) - r.HandleFunc("/", a.indexHandler).Methods("GET") - r.HandleFunc("/v/{id}.mp4", a.videoHandler).Methods("GET") - r.HandleFunc("/v/{prefix}/{id}.mp4", a.videoHandler).Methods("GET") - r.HandleFunc("/t/{id}", a.thumbHandler).Methods("GET") - r.HandleFunc("/t/{prefix}/{id}", a.thumbHandler).Methods("GET") - r.HandleFunc("/v/{id}", a.pageHandler).Methods("GET") - r.HandleFunc("/v/{prefix}/{id}", a.pageHandler).Methods("GET") - r.HandleFunc("/feed.xml", a.rssHandler).Methods("GET") - // Static file handler - fsHandler := http.StripPrefix( - "/static/", - http.FileServer(http.Dir("./static/")), - ) - r.PathPrefix("/static/").Handler(fsHandler).Methods("GET") - a.Router = r - return a, nil -} - -// Run imports the library and starts server. -func (a *App) Run() error { - if a.Tor != nil { - var err error - cs := a.Config.Server - key := a.Tor.OnionKey - if key == nil { - key, err = onionkey.GenerateKey() - if err != nil { - return err - } - a.Tor.OnionKey = key - } - onion, err := key.Onion() - if err != nil { - return err - } - onion.Ports[80] = fmt.Sprintf("%s:%d", cs.Host, cs.Port) - err = a.Tor.Controller.AddOnion(onion) - if err != nil { - return errors.New("unable to start Tor onion service") - } - log.Printf("Onion service: http://%s.onion", onion.ServiceID) - } - for _, pc := range a.Config.Library { - p := &media.Path{ - Path: pc.Path, - Prefix: pc.Prefix, - } - err := a.Library.AddPath(p) - if err != nil { - return err - } - err = a.Library.Import(p) - if err != nil { - return err - } - a.Watcher.Add(p.Path) - } - buildFeed(a) - go startWatcher(a) - return http.Serve(a.Listener, a.Router) -} - -// HTTP handler for / -func (a *App) indexHandler(w http.ResponseWriter, r *http.Request) { - log.Printf("/") - pl := a.Library.Playlist() - if len(pl) > 0 { - http.Redirect(w, r, "/v/"+pl[0].ID, 302) - } else { - a.Templates.ExecuteTemplate(w, "index.html", &struct { - Playing *media.Video - Playlist media.Playlist - }{ - Playing: &media.Video{ID: ""}, - Playlist: a.Library.Playlist(), - }) - } -} - -// HTTP handler for /v/id -func (a *App) pageHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - id := vars["id"] - prefix, ok := vars["prefix"] - if ok { - id = path.Join(prefix, id) - } - log.Printf("/v/%s", id) - playing, ok := a.Library.Videos[id] - if !ok { - a.Templates.ExecuteTemplate(w, "index.html", &struct { - Playing *media.Video - Playlist media.Playlist - }{ - Playing: &media.Video{ID: ""}, - Playlist: a.Library.Playlist(), - }) - return - } - w.Header().Set("Content-Type", "text/html; charset=utf-8") - a.Templates.ExecuteTemplate(w, "index.html", &struct { - Playing *media.Video - Playlist media.Playlist - }{ - Playing: playing, - Playlist: a.Library.Playlist(), - }) -} - -// HTTP handler for /v/id.mp4 -func (a *App) videoHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - id := vars["id"] - prefix, ok := vars["prefix"] - if ok { - id = path.Join(prefix, id) - } - log.Printf("/v/%s", id) - m, ok := a.Library.Videos[id] - if !ok { - return - } - title := m.Title - disposition := "attachment; filename=\"" + title + ".mp4\"" - w.Header().Set("Content-Disposition", disposition) - w.Header().Set("Content-Type", "video/mp4") - http.ServeFile(w, r, m.Path) -} - -// HTTP handler for /t/id -func (a *App) thumbHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - id := vars["id"] - prefix, ok := vars["prefix"] - if ok { - id = path.Join(prefix, id) - } - log.Printf("/t/%s", id) - m, ok := a.Library.Videos[id] - if !ok { - return - } - w.Header().Set("Cache-Control", "public, max-age=7776000") - if m.ThumbType == "" { - w.Header().Set("Content-Type", "image/jpeg") - http.ServeFile(w, r, "static/defaulticon.jpg") - } else { - w.Header().Set("Content-Type", m.ThumbType) - w.Write(m.Thumb) - } -} - -// HTTP handler for /feed.xml -func (a *App) rssHandler(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Cache-Control", "public, max-age=7776000") - w.Header().Set("Content-Type", "text/xml") - w.Write(a.Feed) -} |
