new sw show template
This commit is contained in:
+1
-1
@@ -22,7 +22,7 @@ func NewDomain() Domain {
|
||||
releaseRepository := &ReleaseRepository{db: DB}
|
||||
fileRepository := NewFileRepository()
|
||||
|
||||
softwareService := NewSoftwareService(softwareRepository)
|
||||
softwareService := NewSoftwareService(softwareRepository, releaseRepository)
|
||||
|
||||
tic80Updater := NewSoftwareUpdaterTIC80Service(
|
||||
softwareRepository,
|
||||
|
||||
@@ -72,6 +72,7 @@ func (fr *FileRepository) UnzipFile(path, destPath string) error {
|
||||
|
||||
for _, f := range r.File {
|
||||
path := filepath.Join(fullDestPath, f.Name)
|
||||
fmt.Printf("ZIP: Extracting %s\n", path)
|
||||
|
||||
if f.FileInfo().IsDir() {
|
||||
os.MkdirAll(path, 0755)
|
||||
|
||||
@@ -7,6 +7,7 @@ type ReleaseRepositoryInterface interface {
|
||||
CreateIfNotExist(release *Release) error
|
||||
FindLatestBySoftwareID(softwareID uint) (*Release, error)
|
||||
FindBySoftwareIDAndVersion(softwareID uint, version string) (*Release, error)
|
||||
ListBySoftwareID(softwareID uint) []Release
|
||||
}
|
||||
|
||||
type ReleaseRepository struct {
|
||||
@@ -40,3 +41,9 @@ func (r *ReleaseRepository) FindBySoftwareIDAndVersion(softwareID uint, version
|
||||
err := r.db.Where("software_id = ? AND version = ?", softwareID, version).First(&release).Error
|
||||
return &release, err
|
||||
}
|
||||
|
||||
func (r *ReleaseRepository) ListBySoftwareID(softwareID uint) []Release {
|
||||
var releases []Release
|
||||
r.db.Where("software_id = ?", softwareID).Find(&releases)
|
||||
return releases
|
||||
}
|
||||
|
||||
@@ -1,24 +1,42 @@
|
||||
package domain
|
||||
|
||||
import "sort"
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
type SoftwareListDTO struct {
|
||||
Software
|
||||
LatestRelease *Release
|
||||
}
|
||||
|
||||
type SoftwareShowData struct {
|
||||
Software *Software
|
||||
Releases []Release
|
||||
LatestRelease *Release
|
||||
WebPlayableRelease *Release
|
||||
}
|
||||
|
||||
type SoftwareServiceInterface interface {
|
||||
List() ([]SoftwareListDTO, error)
|
||||
GetByName(name string) (*Software, error)
|
||||
GetLatestRelease(softwareID string) (*Release, error)
|
||||
GetForShowByName(name string) (*SoftwareShowData, error)
|
||||
}
|
||||
|
||||
type SoftwareService struct {
|
||||
softeare_repository SoftwareRepositoryInterface
|
||||
release_repository ReleaseRepositoryInterface
|
||||
}
|
||||
|
||||
func NewSoftwareService(softeare_repository SoftwareRepositoryInterface) *SoftwareService {
|
||||
return &SoftwareService{softeare_repository: softeare_repository}
|
||||
func NewSoftwareService(
|
||||
softeare_repository SoftwareRepositoryInterface,
|
||||
release_repository ReleaseRepositoryInterface,
|
||||
) *SoftwareService {
|
||||
return &SoftwareService{
|
||||
softeare_repository: softeare_repository,
|
||||
release_repository: release_repository,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SoftwareService) List() ([]SoftwareListDTO, error) {
|
||||
@@ -44,6 +62,42 @@ func (s *SoftwareService) List() ([]SoftwareListDTO, error) {
|
||||
|
||||
func (s *SoftwareService) GetByName(name string) (*Software, error) {
|
||||
return s.softeare_repository.GetByName(name)
|
||||
|
||||
}
|
||||
|
||||
func (s *SoftwareService) GetForShowByName(name string) (*SoftwareShowData, error) {
|
||||
software, err := s.softeare_repository.GetByName(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if software == nil {
|
||||
return nil, fmt.Errorf("software not found")
|
||||
}
|
||||
|
||||
releases := s.release_repository.ListBySoftwareID(software.ID)
|
||||
|
||||
var latest_release *Release
|
||||
if len(releases) > 0 {
|
||||
sort.Slice(releases, func(i, j int) bool {
|
||||
return releases[i].CreatedAt.After(releases[j].CreatedAt)
|
||||
})
|
||||
latest_release = &releases[0]
|
||||
}
|
||||
|
||||
var web_payable_release *Release
|
||||
for _, release := range releases {
|
||||
if release.HTMLFolderPath != "" {
|
||||
web_payable_release = &release
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return &SoftwareShowData{
|
||||
Software: software,
|
||||
Releases: releases,
|
||||
LatestRelease: latest_release,
|
||||
WebPlayableRelease: web_payable_release,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *SoftwareService) GetLatestRelease(softwareID string) (*Release, error) {
|
||||
|
||||
@@ -15,7 +15,7 @@ func NewRootController() *RootController {
|
||||
return &RootController{}
|
||||
}
|
||||
|
||||
func (c *RootController) index(w http.ResponseWriter, r *http.Request) {
|
||||
func (c *RootController) Index(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
tmpl, err := template_utils.GetTemplate("root_index", "http/views/shared/layout.html", "http/views/root/index.html")
|
||||
if err != nil {
|
||||
|
||||
@@ -17,7 +17,7 @@ func NewSoftwareController(software_service domain.SoftwareServiceInterface) *So
|
||||
return &SoftwareController{softwareService: software_service}
|
||||
}
|
||||
|
||||
func (c *SoftwareController) index(w http.ResponseWriter, r *http.Request) {
|
||||
func (c *SoftwareController) Index(w http.ResponseWriter, r *http.Request) {
|
||||
softwares, err := c.softwareService.List()
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
@@ -33,41 +33,20 @@ func (c *SoftwareController) index(w http.ResponseWriter, r *http.Request) {
|
||||
tmpl.Execute(w, softwares)
|
||||
}
|
||||
|
||||
type SoftwareShowData struct {
|
||||
Software *domain.Software
|
||||
LatestRelease *domain.Release
|
||||
}
|
||||
|
||||
func (c *SoftwareController) show(w http.ResponseWriter, r *http.Request) {
|
||||
func (c *SoftwareController) Show(w http.ResponseWriter, r *http.Request) {
|
||||
name := chi.URLParam(r, "name")
|
||||
|
||||
software, err := c.softwareService.GetByName(name)
|
||||
data, err := c.softwareService.GetForShowByName(name)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if software == nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
latest_release, err := c.softwareService.GetLatestRelease(software.Name)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if latest_release == nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
tmpl, err := template_utils.GetTemplate("software_show", "http/views/shared/layout.html", "http/views/software/show.html")
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
tmpl.Execute(w, SoftwareShowData{
|
||||
Software: software,
|
||||
LatestRelease: latest_release,
|
||||
})
|
||||
tmpl.Execute(w, data)
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func NewSoftwareUpdaterController(service domain.SoftwareUpdaterServiceInterface
|
||||
return &SoftwareUpdaterController{service: service}
|
||||
}
|
||||
|
||||
func (c *SoftwareUpdaterController) update(w http.ResponseWriter, r *http.Request) {
|
||||
func (c *SoftwareUpdaterController) Update(w http.ResponseWriter, r *http.Request) {
|
||||
secret := r.URL.Query().Get("secret")
|
||||
if secret != os.Getenv("UPDATE_SECRET") {
|
||||
http.Error(w, "Unauthorized", http.StatusUnauthorized)
|
||||
|
||||
+4
-4
@@ -33,11 +33,11 @@ func NewRouter(
|
||||
func (r *Router) Init() *chi.Mux {
|
||||
router := chi.NewRouter()
|
||||
|
||||
router.Get("/", r.rootController.index)
|
||||
router.Get("/software", r.softwareController.index)
|
||||
router.Get("/software/{name}", r.softwareController.show)
|
||||
router.Get("/", r.rootController.Index)
|
||||
router.Get("/software", r.softwareController.Index)
|
||||
router.Get("/software/{name}", r.softwareController.Show)
|
||||
|
||||
router.Get("/update", r.softwareUpdaterController.update)
|
||||
router.Get("/update", r.softwareUpdaterController.Update)
|
||||
router.Get("/download/{name}/source", r.downloadController.GetLatestSource)
|
||||
router.Get("/download/{name}/cartridge", r.downloadController.GetLatestCartridge)
|
||||
router.Get("/download/{name}/{version}/source", r.downloadController.GetSource)
|
||||
|
||||
@@ -2,27 +2,14 @@
|
||||
<h1 class="my-4">Softwares</h1>
|
||||
|
||||
<div class="row">
|
||||
{{range .}}
|
||||
<div class="col-12 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{.Title}}</h5>
|
||||
<h6 class="card-subtitle mb-2 text-muted">{{.Author}}</h6>
|
||||
<p class="card-text">{{.Desc}}</p>
|
||||
<p class="card-text"><strong>Version:</strong> {{.LatestRelease.Version}}</p>
|
||||
<p class="card-text"><strong>License:</strong> {{.License}}</p>
|
||||
<p class="card-text"><a href="{{.Site}}" target="_blank">Website</a></p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="btn-group d-flex justify-content-end" role="group" aria-label="Operations">
|
||||
<a href="/download/{{.Name}}/source" class="btn btn-primary btn-sm">Source</a>
|
||||
<a href="/download/{{.Name}}/cartridge" class="btn btn-primary btn-sm">Cartridge</a>
|
||||
<a href="/software/{{.Name}}" class="btn btn-primary btn-sm">Releases</a>
|
||||
<a href="/play/{{.Name}}/{{.LatestRelease.Version}}" class="btn btn-primary btn-sm">Play</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul>
|
||||
{{range .}}
|
||||
<li>
|
||||
<a href="/software/{{.Name}}">{{.Title}}</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
@@ -1,8 +1,39 @@
|
||||
{{define "content"}}
|
||||
<h1 class="my-4">Releases for {{.Software.Title}}</h1>
|
||||
|
||||
<div class="row">
|
||||
{{range .Software.Releases}}
|
||||
<div class="col-12 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{.Software.Title}}</h5>
|
||||
<h6 class="card-subtitle mb-2 text-muted">{{.Software.Author}}</h6>
|
||||
<p class="card-text">{{.Software.Desc}}</p>
|
||||
<p class="card-text"><strong>Version:</strong> {{.LatestRelease.Version}}</p>
|
||||
<p class="card-text"><strong>License:</strong> {{.Software.License}}</p>
|
||||
<p class="card-text"><a href="{{.Software.Site}}" target="_blank">Website</a></p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="btn-group d-flex justify-content-end" role="group" aria-label="Operations">
|
||||
<a href="/download/{{.Software.Name}}/source" class="btn btn-primary btn-sm">Source</a>
|
||||
<a href="/download/{{.Software.Name}}/cartridge" class="btn btn-primary btn-sm">Cartridge</a>
|
||||
<a href="/software/{{.Software.Name}}" class="btn btn-primary btn-sm">Releases</a>
|
||||
<a href="/play/{{.Software.Name}}/{{.LatestRelease.Version}}" class="btn btn-primary btn-sm">Play</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
EEEE
|
||||
{{if .WebPlayableRelease}}
|
||||
<h3>Play</h3>
|
||||
<div class="mb-4">
|
||||
<div class="ratio ratio-4x3" style="max-width: 960px; margin: 0 auto;">
|
||||
<iframe id="gameFrame" src="/play/{{.Software.Name}}/{{.WebPlayableRelease.Version}}/content/index.html"
|
||||
frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<h3>Releases</h3>
|
||||
<div class="row">
|
||||
{{range .Releases}}
|
||||
<div class="col-12 mb-4">
|
||||
<div class="card h-100">
|
||||
<div class="card-body">
|
||||
@@ -12,10 +43,12 @@
|
||||
<div class="card-footer">
|
||||
<div class="btn-group d-flex justify-content-center" role="group" aria-label="Operations">
|
||||
{{if .HTMLFolderPath}}
|
||||
<a href="/play/{{$.Software.Name}}/{{.Version}}" class="btn btn-success btn-sm">Play</a>
|
||||
<a href="/play/{{$.Software.Name}}/{{.Version}}" class="btn btn-success btn-sm">Play</a>
|
||||
{{end}}
|
||||
<a href="/download/{{$.Software.Name}}/{{.Version}}/source" class="btn btn-primary btn-sm">Source</a>
|
||||
<a href="/download/{{$.Software.Name}}/{{.Version}}/cartridge" class="btn btn-primary btn-sm">Cartridge</a>
|
||||
<a href="/download/{{$.Software.Name}}/{{.Version}}/source"
|
||||
class="btn btn-primary btn-sm">Source</a>
|
||||
<a href="/download/{{$.Software.Name}}/{{.Version}}/cartridge"
|
||||
class="btn btn-primary btn-sm">Cartridge</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -24,4 +57,4 @@
|
||||
</div>
|
||||
|
||||
<p><a href="/" class="btn btn-primary">Back to Softwares</a></p>
|
||||
{{end}}
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user