archive/ArchiveState.go

184 lines
5.0 KiB
Go

package archive
import (
"fmt"
"html/template"
"net/http"
)
type ArchiveState struct {
svr *ArchiveServer
log *LogSource
logBestSlug string
query string
queryIsRegex bool
ym YearMonth
page int
highestPage int
}
func NewArchiveState(svr *ArchiveServer) *ArchiveState {
return &ArchiveState{svr: svr}
}
func (this *ArchiveState) selectSource(log *LogSource) error {
logBestSlug, err := this.svr.bestSlugFor(log)
if err != nil {
return err
}
this.log = log
this.logBestSlug = logBestSlug
return nil
}
func (this *ArchiveState) renderError(w http.ResponseWriter, msg string) {
this.renderTemplate(w, []byte(template.HTMLEscapeString(msg)))
}
func (this *ArchiveState) renderTemplate(w http.ResponseWriter, body []byte) {
this.renderTemplateHead(w)
w.Write(body)
this.renderTemplateFoot(w)
}
func (this *ArchiveState) renderTemplateHead(w http.ResponseWriter) {
w.Header().Set(`Content-Type`, `text/html; charset=UTF-8`)
w.Header().Set(`X-UA-Compatible`, `IE=Edge`)
w.WriteHeader(200)
title := `Archives`
if this.log != nil {
title = this.log.Description + ` Archives`
}
showPageURLs := (this.log != nil && len(this.query) == 0)
w.Write([]byte(`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>` + template.HTMLEscapeString(title) + `</title>
<link rel="stylesheet" type="text/css" href="/style.css">
</head>
<body>
<div class="layout-top nav">
<div id="tr1" style="display:none;"></div>
<div id="tr2" style="display:none;"></div>
<div class="ddmenu" id="spm" style="display:none;">
<a href="/">Latest</a>
<a onclick="fontSize(1);">Font increase</a>
<a onclick="fontSize(-1);">Font decrease</a>
<a href="/download" onclick="return confirm('Are you sure you want to download a backup?');">Download backup</a>
</div>
<a onclick="toggleMenu();"><div id="logo" class="layout-pushdown"></div></a>
<span class="area-nav">
<form method="GET" id="frmHub">
<select name="h" id="selHub">
`))
for i, h := range this.svr.cfg.Logs {
slug, _ := this.svr.bestSlugFor(&this.svr.cfg.Logs[i])
current := (this.log == &this.svr.cfg.Logs[i])
w.Write([]byte(`<option value="` + template.HTMLEscapeString(slug) + `" ` + attr(current, "selected") + `>` + template.HTMLEscapeString(h.Description) + `</option>`))
}
w.Write([]byte(`
</select>
</form>
`))
if showPageURLs {
w.Write([]byte(`
<form method="GET">
<input type="hidden" name="h" value="` + template.HTMLEscapeString(this.logBestSlug) + `">
<select id="seldate" onchange="setYM(this);">
`))
// Generate month dropdown options
lastY := -1
for ympair := this.log.EarliestDate(); !ympair.Equals(this.log.LatestDate()); ympair = ympair.Next() {
if ympair.Year != lastY {
if lastY != -1 {
w.Write([]byte(`</optgroup>`))
}
w.Write([]byte(`<optgroup label="` + fmt.Sprintf("%s", ympair.Year) + `">`))
lastY = ympair.Year
}
w.Write([]byte(fmt.Sprintf(`<option value="%d-%d" %s>%s</option>`, ympair.Year, ympair.Month, attr(ympair.Equals(this.ym), "selected"), template.HTMLEscapeString(ympair.Month.String()))))
}
//
pageBase := fmt.Sprintf(`/%s/%d/%d`, this.logBestSlug, this.ym.Year, this.ym.Month)
previousPage := this.page - 1
if previousPage < 0 {
previousPage = 0
}
nextPage := this.page + 1
if nextPage > this.highestPage {
nextPage = this.highestPage
}
w.Write([]byte(`
</optgroup>
</select>
<input type="hidden" name="y" id="f_y" value="">
<input type="hidden" name="m" id="f_m" value="">
<input type="hidden" name="p" value="0" >
</form>
<div class="mini-separator layout-pushdown"></div>
<a class="btn" href="` + pageBase + `/page-0">&laquo;</a><a
class="btn" id="pgprev" href="` + pageBase + `/page-` + fmt.Sprintf("%d", previousPage) + `">&lsaquo;</a>
` + fmt.Sprintf("%d", this.page) + `
<a class="btn" id="pgnext" href="` + pageBase + `/page-` + fmt.Sprintf("%d", nextPage) + `">&rsaquo;</a><a
class="btn" href="` + pageBase + `">&raquo;</a>
`))
}
w.Write([]byte(`
<div class="pad"></div>
</span>
<span class="area-search">
<form method="GET">
<input type="hidden" name="h" value="` + template.HTMLEscapeString(this.logBestSlug) + `">
<input type="text" id="searchbox" name="q" value="` + template.HTMLEscapeString(this.query) + `" placeholder="Search...">
<input type="submit" value="&raquo;">
<input type="checkbox" class="layout-pushdown" name="rx" value="1" title="PCRE Regular Expression" ` + attr(this.queryIsRegex, "checked") + `>
</form>
</span>
</div>
<div class="layout-body" id="chatarea">
`))
// Header ends
}
func (this *ArchiveState) renderTemplateFoot(w http.ResponseWriter) {
w.Write([]byte(`
</div>
<script type="text/javascript" src="/archive.js?nonce=` + fmt.Sprintf("%d", this.svr.startup.Unix()) + `"></script>
</body>
</html>
`))
}