Refactor HTML creation
This commit is contained in:
parent
2e5140f669
commit
5da1cf0bd5
3 changed files with 70 additions and 104 deletions
102
pkg/html/html.go
102
pkg/html/html.go
|
|
@ -2,6 +2,7 @@ package html
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
|
|
@ -79,69 +80,31 @@ textarea {
|
|||
}
|
||||
`
|
||||
|
||||
func FullHTML(h HTMLData) string {
|
||||
var sb strings.Builder
|
||||
var errorBuilder strings.Builder
|
||||
const (
|
||||
// errorListItem is shown after adding a feed. It shows if error or success.
|
||||
errorListItem = `<li class="%s"><a href="%s">%s</a> - %s</li>`
|
||||
|
||||
FeedCount := 0
|
||||
DatabaseSize := stats.GetDBSize()
|
||||
|
||||
// This is the error message that will be displayed if there are any errors
|
||||
if len(h.ParseResult) > 0 {
|
||||
errorBuilder.WriteString("<ul>")
|
||||
for _, result := range h.ParseResult {
|
||||
var listItemClass, statusMsg string
|
||||
if result.IsError {
|
||||
listItemClass = "error"
|
||||
statusMsg = result.Msg
|
||||
} else {
|
||||
listItemClass = "success"
|
||||
statusMsg = result.Msg
|
||||
}
|
||||
errorBuilder.WriteString(fmt.Sprintf(`<li class="%s"><a href="%s">%s</a> - %s</li>`, listItemClass, result.FeedURL, result.FeedURL, statusMsg))
|
||||
}
|
||||
errorBuilder.WriteString("</ul>")
|
||||
}
|
||||
StatusMsg := errorBuilder.String()
|
||||
|
||||
sb.WriteString(`
|
||||
<!DOCTYPE html>
|
||||
// htmlTemplate is the HTML template for the entire page.
|
||||
htmlTemplate = `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
`)
|
||||
|
||||
if h.Description != "" {
|
||||
sb.WriteString(`<meta name="description" content="` + h.Description + `">`)
|
||||
}
|
||||
|
||||
if h.Keywords != "" {
|
||||
sb.WriteString(`<meta name="keywords" content="` + h.Keywords + `">`)
|
||||
}
|
||||
|
||||
if h.Author != "" {
|
||||
sb.WriteString(`<meta name="author" content="` + h.Author + `">`)
|
||||
}
|
||||
|
||||
if h.CanonicalURL != "" {
|
||||
sb.WriteString(`<link rel="canonical" href="` + h.CanonicalURL + `">`)
|
||||
}
|
||||
|
||||
sb.WriteString(`
|
||||
<title>` + h.Title + `</title>
|
||||
<style>` + style + `</style>
|
||||
<meta name="description" content="%s">
|
||||
<meta name="keywords" content="%s">
|
||||
<meta name="author" content="%s">
|
||||
<link rel="canonical" href="%s">
|
||||
<title>%s</title>
|
||||
<style>%s</style>
|
||||
</head>
|
||||
<body>
|
||||
` + StatusMsg + `
|
||||
%s
|
||||
<span class="title"><h1><a href="/">FeedVault</a></h1></span>
|
||||
<div class="leftright">
|
||||
<div class="left">
|
||||
<small>Archive of <a href="https://en.wikipedia.org/wiki/Web_feed">web feeds</a>. ` + fmt.Sprintf("%d", FeedCount) + ` feeds. ~` + DatabaseSize + `.</small>
|
||||
<small>Archive of <a href="https://en.wikipedia.org/wiki/Web_feed">web feeds</a>. %d feeds. ~%s.</small>
|
||||
</div>
|
||||
<div class="right">
|
||||
<!-- Search -->
|
||||
<form action="#" method="get">
|
||||
<input type="text" name="q" placeholder="Search">
|
||||
<button type="submit">Search</button>
|
||||
|
|
@ -162,7 +125,7 @@ func FullHTML(h HTMLData) string {
|
|||
</nav>
|
||||
<hr>
|
||||
<main>
|
||||
` + h.Content + `
|
||||
%s
|
||||
</main>
|
||||
<hr>
|
||||
<footer>
|
||||
|
|
@ -178,14 +141,41 @@ func FullHTML(h HTMLData) string {
|
|||
<a href="mailto:hello@feedvault.se">hello@feedvault.se</a>
|
||||
</div>
|
||||
<div class="right">
|
||||
` + quotes.FunMsg[rand.Intn(len(quotes.FunMsg))] + `
|
||||
%s
|
||||
</div>
|
||||
</div>
|
||||
</small>
|
||||
</footer>
|
||||
</body>
|
||||
</html>`)
|
||||
|
||||
return sb.String()
|
||||
</html>`
|
||||
)
|
||||
|
||||
func buildErrorList(parseResults []models.ParseResult) string {
|
||||
var errorBuilder strings.Builder
|
||||
if len(parseResults) > 0 {
|
||||
errorBuilder.WriteString("<ul>")
|
||||
for _, result := range parseResults {
|
||||
// CSS class for the list item. Green for success, red for error.
|
||||
listItemClass := "success"
|
||||
if result.IsError {
|
||||
listItemClass = "error"
|
||||
}
|
||||
errorBuilder.WriteString(fmt.Sprintf(errorListItem, listItemClass, result.FeedURL, result.FeedURL, result.Msg))
|
||||
}
|
||||
errorBuilder.WriteString("</ul>")
|
||||
}
|
||||
return errorBuilder.String()
|
||||
}
|
||||
|
||||
func FullHTML(h HTMLData) string {
|
||||
statusMsg := buildErrorList(h.ParseResult)
|
||||
feedCount := 0
|
||||
databaseSize, err := stats.GetDBSize()
|
||||
if err != nil {
|
||||
databaseSize = "0 KiB"
|
||||
log.Println("Error getting database size:", err)
|
||||
}
|
||||
|
||||
funMsg := quotes.FunMsg[rand.Intn(len(quotes.FunMsg))]
|
||||
return fmt.Sprintf(htmlTemplate, h.Description, h.Keywords, h.Author, h.CanonicalURL, h.Title, style, statusMsg, feedCount, databaseSize, h.Content, funMsg)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,7 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/TheLovinator1/FeedVault/pkg/stats"
|
||||
)
|
||||
|
||||
type TemplateData struct {
|
||||
Title string
|
||||
Description string
|
||||
Keywords string
|
||||
Author string
|
||||
CanonicalURL string
|
||||
FeedCount int
|
||||
DatabaseSize string
|
||||
Request *http.Request
|
||||
ParseErrors []ParseResult
|
||||
}
|
||||
|
||||
type ParseResult struct {
|
||||
FeedURL string
|
||||
Msg string
|
||||
IsError bool
|
||||
}
|
||||
|
||||
func (d *TemplateData) GetDatabaseSizeAndFeedCount() {
|
||||
// TODO: Get the feed count from the database
|
||||
// TODO: Add amount of entries
|
||||
// TODO: Add amount of users
|
||||
d.DatabaseSize = stats.GetDBSize()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package stats
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
|
@ -14,20 +13,16 @@ type Cache struct {
|
|||
|
||||
var cache Cache
|
||||
|
||||
// Get the size of the database and return as nearest human readable size.
|
||||
//
|
||||
// e.g. 1.23 KiB, 4.56 MiB, 7.89 GiB, 0.12 TiB
|
||||
// The size is cached for 10 minutes
|
||||
func GetDBSize() string {
|
||||
func GetDBSize() (string, error) {
|
||||
// If cache is less than 10 minutes old, return cached data
|
||||
if time.Since(cache.timestamp).Minutes() < 10 {
|
||||
return cache.data
|
||||
return cache.data, nil
|
||||
}
|
||||
|
||||
// TODO: This should be read from the environment
|
||||
fileInfo, err := os.Stat("feedvault.db")
|
||||
if err != nil {
|
||||
log.Println("Error getting file info:", err)
|
||||
return "0 B"
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Get the file size in bytes
|
||||
|
|
@ -35,16 +30,23 @@ func GetDBSize() string {
|
|||
|
||||
// Convert to human readable size and append the unit (KiB, MiB, GiB, TiB)
|
||||
var size float64
|
||||
|
||||
if fileSize < 1024*1024 {
|
||||
// If the file size is less than 1 KiB, return the size in bytes
|
||||
size = float64(fileSize) / 1024
|
||||
cache.data = fmt.Sprintf("%.2f KiB", size)
|
||||
|
||||
} else if fileSize < 1024*1024*1024 {
|
||||
// If the file size is less than 1 MiB, return the size in KiB
|
||||
size = float64(fileSize) / (1024 * 1024)
|
||||
cache.data = fmt.Sprintf("%.2f MiB", size)
|
||||
|
||||
} else if fileSize < 1024*1024*1024*1024 {
|
||||
// If the file size is less than 1 GiB, return the size in MiB
|
||||
size = float64(fileSize) / (1024 * 1024 * 1024)
|
||||
cache.data = fmt.Sprintf("%.2f GiB", size)
|
||||
} else {
|
||||
// If the file size is 1 GiB or more, return the size in TiB
|
||||
size = float64(fileSize) / (1024 * 1024 * 1024 * 1024)
|
||||
cache.data = fmt.Sprintf("%.2f TiB", size)
|
||||
}
|
||||
|
|
@ -52,7 +54,6 @@ func GetDBSize() string {
|
|||
// Update cache timestamp
|
||||
cache.timestamp = time.Now()
|
||||
|
||||
log.Println("Returning database size, it is", cache.data)
|
||||
|
||||
return cache.data
|
||||
// Return the human readable size
|
||||
return cache.data, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue