Skip to content

Commit 09b72ce

Browse files
committed
initial commit
0 parents  commit 09b72ce

File tree

97 files changed

+16682
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+16682
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea/
2+
.vscode/
3+
dist/
4+
*.boltdb

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
build:
2+
go mod tidy
3+
go build -ldflags "-s -w" -o dist/ .
4+
5+
run:
6+
go mod tidy
7+
go run main.go
8+
9+
compile:
10+
go mod tidy
11+
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w" -o dist/patchouli-linux-amd64 .
12+
GOOS=darwin GOARCH=amd64 go build -ldflags "-s -w" -o dist/patchouli-macos-amd64 .
13+
GOOS=windows GOARCH=amd64 go build -ldflags "-s -w" -o dist/patchouli-windows-amd64.exe .
14+
15+
loc:
16+
go install github.com/boyter/scc/v3@latest
17+
scc --exclude-dir vendor --exclude-dir public .
18+
19+
check:
20+
go install github.com/client9/misspell/cmd/misspell@latest
21+
misspell -error app
22+
go install github.com/fzipp/gocyclo/cmd/gocyclo@latest
23+
gocyclo -over 16 app
24+
go install honnef.co/go/tools/cmd/staticcheck@latest
25+
staticcheck ./...
26+
go install github.com/securego/gosec/v2/cmd/gosec@latest
27+
gosec -quiet --severity high ./...
28+
go install github.com/sonatype-nexus-community/nancy@latest
29+
go list -json -deps ./... | nancy sleuth
30+
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
31+
golangci-lint run

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Patchouli - Be up to date
2+
3+
[![Go Report Card](https://goreportcard.com/badge/github.com/typomedia/patchouli)](https://goreportcard.com/report/github.com/typomedia/patchouli)
4+
[![Go Reference](https://pkg.go.dev/badge/github.com/typomedia/patchouli.svg)](https://pkg.go.dev/github.com/typomedia/patchouli)
5+
[![GitHub release](https://img.shields.io/github/release/typomedia/patchouli.svg)](https://github.com/typomedia/patchouli/releases/latest)
6+
[![GitHub license](https://img.shields.io/github/license/typomedia/patchouli.svg)](https://github.com/typomedia/patchouli/blob/master/LICENSE)
7+
8+
Patchouli is a lightweight patch management planner for operating systems. It comes with an intuitive web interface.
9+
10+
All data will be stored in a single `patchouli.boltdb` file in the current working directory.
11+
12+
## Run
13+
14+
make run
15+
16+
## Build
17+
18+
make build
19+
20+
## Cross compile
21+
22+
make compile
23+
24+
## Technology
25+
26+
- [Go](https://golang.org/)
27+
- [Fiber](https://gofiber.io/)
28+
- [htmx](https://htmx.org/)
29+
- [Pico](https://picocss.com/)
30+
- [bbolt](https://github.com/etcd-io/bbolt)
31+
32+
## Todo
33+
34+
- [ ] add a login page
35+
- [ ] email notifications
36+
- [ ] protect api used by the frontend
37+
- [ ] optimize json/csv export
38+
- [ ] add json/csv import api
39+
- [ ] refactor some quirky code
40+
- [ ] write some tests...
41+
42+
## License
43+
44+
Patchouli is licensed under the [GNU General Public License v3.0](LICENSE).
45+
46+
---
47+
Copyright © 2024 Typomedia Foundation. All rights reserved.

app/app.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package app
2+
3+
import "fmt"
4+
5+
type Application struct {
6+
Name string
7+
Version string
8+
Author string
9+
Description string
10+
Explanation string
11+
}
12+
13+
var App = Application{
14+
Name: "Patchouli",
15+
Version: "0.1.0",
16+
Author: "Philipp Speck <[email protected]>",
17+
Description: "Patch Management Tool",
18+
Explanation: "Git HTTP Daemon for managing multiple repositories via web hooks.",
19+
}
20+
21+
func Logo() string {
22+
banner := fmt.Sprintf("%s %s\n", App.Name, App.Version)
23+
banner += App.Author
24+
25+
return banner
26+
}

app/handler/api/csv/export.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package csv
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/gofiber/fiber/v2"
7+
"github.com/gofiber/fiber/v2/log"
8+
"github.com/typomedia/patchouli/app/helper/csv"
9+
"github.com/typomedia/patchouli/app/store/boltdb"
10+
"github.com/typomedia/patchouli/app/structs"
11+
)
12+
13+
func Export(c *fiber.Ctx) error {
14+
db := boltdb.New()
15+
16+
err := db.SetBucket("machine")
17+
if err != nil {
18+
return err
19+
}
20+
21+
machines, _ := db.GetAll("machine")
22+
23+
Machines := structs.Machines{}
24+
25+
for _, v := range machines {
26+
machine := structs.Machine{}
27+
err = json.Unmarshal(v, &machine)
28+
if err != nil {
29+
return err
30+
}
31+
Machines = append(Machines, machine)
32+
33+
}
34+
35+
defer db.Close()
36+
37+
csvString, err := csv.Marshal(Machines)
38+
if err != nil {
39+
log.Error(err)
40+
}
41+
42+
csvBytes := []byte(csvString)
43+
44+
c.Response().Header.Set("Content-Type", "text/csv")
45+
c.Response().Header.Set("Content-Disposition", "attachment; filename=machines.csv")
46+
c.Response().Header.Set("Content-Length", fmt.Sprintf("%d", len(csvBytes)))
47+
c.Response().SetBodyRaw(csvBytes)
48+
49+
return nil
50+
}

app/handler/api/htmx/operator.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package htmx
2+
3+
import (
4+
"encoding/json"
5+
"github.com/gofiber/fiber/v2"
6+
"github.com/gofiber/fiber/v2/log"
7+
"github.com/typomedia/patchouli/app/store/boltdb"
8+
"github.com/typomedia/patchouli/app/structs"
9+
)
10+
11+
func Operator(c *fiber.Ctx) error {
12+
id := c.Params("machine")
13+
selected := c.Query("selected")
14+
15+
db := boltdb.New()
16+
17+
err := db.SetBucket("machine")
18+
if err != nil {
19+
return err
20+
}
21+
22+
machine := structs.Machine{}
23+
err = db.Get(id, &machine, "machine")
24+
if err != nil {
25+
log.Error(err)
26+
}
27+
28+
err = db.SetBucket("operator")
29+
if err != nil {
30+
return err
31+
}
32+
33+
operators, _ := db.GetAll("operator")
34+
35+
Operators := structs.Operators{}
36+
for _, v := range operators {
37+
operator := structs.Operator{}
38+
err = json.Unmarshal(v, &operator)
39+
if err != nil {
40+
return err
41+
}
42+
Operators = append(Operators, operator)
43+
}
44+
45+
defer db.Close()
46+
47+
if selected == "" {
48+
selected = machine.Operator.Id
49+
}
50+
51+
return c.Render("app/views/api/htmx/operators", fiber.Map{
52+
"Operators": Operators,
53+
"Selected": selected,
54+
})
55+
}

app/handler/api/htmx/operators.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package htmx
2+
3+
import (
4+
"encoding/json"
5+
"github.com/gofiber/fiber/v2"
6+
"github.com/typomedia/patchouli/app/store/boltdb"
7+
"github.com/typomedia/patchouli/app/structs"
8+
)
9+
10+
func Operators(c *fiber.Ctx) error {
11+
selected := c.Query("selected")
12+
13+
db := boltdb.New()
14+
15+
err := db.SetBucket("operator")
16+
if err != nil {
17+
return err
18+
}
19+
20+
operators, _ := db.GetAll("operator")
21+
22+
Operators := structs.Operators{}
23+
for _, v := range operators {
24+
operator := structs.Operator{}
25+
err = json.Unmarshal(v, &operator)
26+
if err != nil {
27+
return err
28+
}
29+
Operators = append(Operators, operator)
30+
}
31+
32+
defer db.Close()
33+
34+
return c.Render("app/views/api/htmx/operators", fiber.Map{
35+
"Operators": Operators,
36+
"Selected": selected,
37+
})
38+
}

app/handler/api/htmx/systems.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package htmx
2+
3+
import (
4+
"encoding/json"
5+
"github.com/gofiber/fiber/v2"
6+
"github.com/typomedia/patchouli/app/store/boltdb"
7+
"github.com/typomedia/patchouli/app/structs"
8+
)
9+
10+
func Systems(c *fiber.Ctx) error {
11+
selected := c.Query("selected")
12+
13+
db := boltdb.New()
14+
15+
err := db.SetBucket("systems")
16+
if err != nil {
17+
return err
18+
}
19+
20+
systems, _ := db.GetAll("systems")
21+
22+
Systems := structs.Systems{}
23+
for _, v := range systems {
24+
system := structs.System{}
25+
err = json.Unmarshal(v, &system)
26+
if err != nil {
27+
return err
28+
}
29+
Systems = append(Systems, system)
30+
}
31+
32+
defer db.Close()
33+
34+
return c.Render("app/views/api/htmx/systems", fiber.Map{
35+
"Systems": Systems,
36+
"Selected": selected,
37+
})
38+
}

app/handler/api/json/export.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package json
2+
3+
import (
4+
"encoding/json"
5+
"github.com/gofiber/fiber/v2"
6+
"github.com/typomedia/patchouli/app/store/boltdb"
7+
"github.com/typomedia/patchouli/app/structs"
8+
)
9+
10+
func Export(c *fiber.Ctx) error {
11+
db := boltdb.New()
12+
13+
err := db.SetBucket("machine")
14+
if err != nil {
15+
return err
16+
}
17+
18+
machines, _ := db.GetAll("machine")
19+
20+
Machines := structs.Machines{}
21+
22+
for _, v := range machines {
23+
machine := structs.Machine{}
24+
err = json.Unmarshal(v, &machine)
25+
if err != nil {
26+
return err
27+
}
28+
Machines = append(Machines, machine)
29+
30+
}
31+
32+
defer db.Close()
33+
34+
return c.JSON(Machines)
35+
}

0 commit comments

Comments
 (0)