Getting files

This commit is contained in:
Neale Pickett 2020-03-01 15:03:46 -06:00
parent 7a5b2aa3c1
commit fbba5ac004
4 changed files with 59 additions and 14 deletions

View File

@ -17,8 +17,8 @@ type ReadSeekCloser interface {
} }
type PuzzleProvider interface { type PuzzleProvider interface {
Metadata(cat string, points int) (io.ReadCloser, error) Open(cat string, points int, path string) (ReadSeekCloser, error)
Open(cat string, points int, path string) (io.ReadCloser, error) ModTime(cat string, points int, path string) (time.Time, error)
Inventory() []Category Inventory() []Category
} }
@ -35,6 +35,7 @@ type StateExport struct {
type StateProvider interface { type StateProvider interface {
Export(teamId string) *StateExport Export(teamId string) *StateExport
TeamName(teamId string) (string, error)
SetTeamName(teamId, teamName string) error SetTeamName(teamId, teamName string) error
} }

View File

@ -4,6 +4,7 @@ import (
"log" "log"
"net/http" "net/http"
"strings" "strings"
"strconv"
) )
type HTTPServer struct { type HTTPServer struct {
@ -11,16 +12,18 @@ type HTTPServer struct {
Puzzles PuzzleProvider Puzzles PuzzleProvider
Theme ThemeProvider Theme ThemeProvider
State StateProvider State StateProvider
Base string
} }
func NewHTTPServer(base string, theme ThemeProvider, state StateProvider, puzzles PuzzleProvider) *HTTPServer { func NewHTTPServer(base string, theme ThemeProvider, state StateProvider, puzzles PuzzleProvider) *HTTPServer {
base = strings.TrimRight(base, "/")
h := &HTTPServer{ h := &HTTPServer{
ServeMux: http.NewServeMux(), ServeMux: http.NewServeMux(),
Puzzles: puzzles, Puzzles: puzzles,
Theme: theme, Theme: theme,
State: state, State: state,
Base: base,
} }
base = strings.TrimRight(base, "/")
h.HandleFunc(base+"/", h.ThemeHandler) h.HandleFunc(base+"/", h.ThemeHandler)
h.HandleFunc(base+"/state", h.StateHandler) h.HandleFunc(base+"/state", h.StateHandler)
h.HandleFunc(base+"/register", h.RegisterHandler) h.HandleFunc(base+"/register", h.RegisterHandler)
@ -137,9 +140,36 @@ func (h *HTTPServer) AnswerHandler(w http.ResponseWriter, req *http.Request) {
} }
func (h *HTTPServer) ContentHandler(w http.ResponseWriter, req *http.Request) { func (h *HTTPServer) ContentHandler(w http.ResponseWriter, req *http.Request) {
path := req.URL.Path teamId := req.FormValue("id")
if path == "/" { if _, err := h.State.TeamName(teamId); err != nil {
path = "/puzzle.json" http.Error(w, "Team Not Found", http.StatusNotFound)
return
} }
JSendf(w, JSendFail, "unimplemented", "I haven't written this yet")
trimLen := len(h.Base) + len("/content/")
parts := strings.SplitN(req.URL.Path[trimLen:], "/", 3)
if len(parts) < 3 {
http.Error(w, "Not Found", http.StatusNotFound)
return
}
cat := parts[0]
pointsStr := parts[1]
filename := parts[2]
if (filename == "") {
filename = "puzzles.json"
}
points, _ := strconv.Atoi(pointsStr)
mf, err := h.Puzzles.Open(cat, points, filename)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
defer mf.Close()
mt, _ := h.Puzzles.ModTime(cat, points, filename)
http.ServeContent(w, req, filename, mt, mf)
} }

View File

@ -2,11 +2,12 @@ package main
import ( import (
"github.com/spf13/afero" "github.com/spf13/afero"
"io"
"log" "log"
"strings" "strings"
"bufio" "bufio"
"strconv" "strconv"
"time"
"fmt"
) )
type Mothballs struct { type Mothballs struct {
@ -21,14 +22,23 @@ func NewMothballs(fs afero.Fs) *Mothballs {
} }
} }
func (m *Mothballs) Metadata(cat string, points int) (io.ReadCloser, error) { func (m *Mothballs) Open(cat string, points int, filename string) (ReadSeekCloser, error) {
f, err := m.Fs.Open("/dev/null") mb, ok := m.categories[cat]
return f, err if ! ok {
return nil, fmt.Errorf("No such category: %s", cat)
}
path := fmt.Sprintf("content/%d/%s", points, filename)
return mb.Open(path)
} }
func (m *Mothballs) Open(cat string, points int, filename string) (io.ReadCloser, error) { func (m *Mothballs) ModTime(cat string, points int, filename string) (mt time.Time, err error) {
f, err := m.Fs.Open("/dev/null") mb, ok := m.categories[cat]
return f, err if ! ok {
return mt, fmt.Errorf("No such category: %s", cat)
}
mt = mb.ModTime()
return
} }
func (m *Mothballs) Inventory() []Category { func (m *Mothballs) Inventory() []Category {

View File

@ -164,6 +164,10 @@ func (zfs *Zipfs) Refresh() error {
return nil return nil
} }
func (zfs *Zipfs) ModTime() (time.Time) {
return zfs.mtime
}
func (zfs *Zipfs) get(filename string) (*zip.File, error) { func (zfs *Zipfs) get(filename string) (*zip.File, error) {
for _, f := range zfs.zf.File { for _, f := range zfs.zf.File {
if filename == f.Name { if filename == f.Name {