minewebgen - config_generators.go
1 package main
2
3 import (
4 "net/http"
5 "os"
6 "path"
7 "sort"
8 "strconv"
9 "sync"
10
11 "vimagination.zapto.org/minewebgen/internal/data"
12 )
13
14 type Generators struct {
15 mu sync.RWMutex
16 List []*data.Generator
17 }
18
19 func (gs *Generators) New(path string) *data.Generator {
20 gPath := freePath(path)
21 if gPath == "" {
22 return nil
23 }
24 gs.mu.Lock()
25 defer gs.mu.Unlock()
26 id := len(gs.List)
27 for n, g := range gs.List {
28 if n != g.ID {
29 id = n
30 break
31 }
32 }
33 g := &data.Generator{
34 ID: id,
35 Path: gPath,
36 Name: "New Generator",
37 }
38 gs.List = append(gs.List, g)
39 sort.Sort(gs)
40 return g
41 }
42
43 func (gs *Generators) Get(id int) *data.Generator {
44 gs.mu.RLock()
45 defer gs.mu.RUnlock()
46 for _, g := range gs.List {
47 if g.ID == id {
48 return g
49 }
50 }
51 return nil
52 }
53
54 func (gs *Generators) Download(w http.ResponseWriter, r *http.Request) {
55 b := path.Base(r.URL.Path)
56 if len(b) < 5 || b[len(b)-4:] != ".zip" {
57 http.Error(w, "not found", http.StatusNotFound)
58 return
59 }
60 id, err := strconv.Atoi(b[:len(b)-4])
61 if err != nil {
62 http.Error(w, "not found", http.StatusNotFound)
63 }
64 g := gs.Get(id)
65 if g == nil {
66 http.Error(w, "unknown generator", http.StatusNotFound)
67 return
68 }
69 w.Header().Set("Content-Type", "application/zip")
70 archive(w, g.Path)
71 }
72
73 func (gs *Generators) Remove(id int) error {
74 gs.mu.Lock()
75 gs.mu.Unlock()
76 for n, g := range gs.List {
77 if g.ID == id {
78 copy(gs.List[n:], gs.List[n+1:])
79 gs.List = gs.List[:len(gs.List)-1]
80 os.RemoveAll(g.Path)
81 break
82 }
83 }
84 return nil
85 }
86
87 func (gs *Generators) Len() int {
88 return len(gs.List)
89 }
90
91 func (gs *Generators) Less(i, j int) bool {
92 return gs.List[i].ID < gs.List[j].ID
93 }
94
95 func (gs *Generators) Swap(i, j int) {
96 gs.List[i], gs.List[j] = gs.List[j], gs.List[i]
97 }