implement redirection handlers, implement data retrieval functions

This commit is contained in:
yequari 2023-07-13 21:39:19 -07:00
parent 5877e2556c
commit 4c3811bc87
4 changed files with 118 additions and 6 deletions

View File

@ -1,8 +1,8 @@
package main
import (
"fmt"
"errors"
"errors"
"fmt"
"net/http"
"text/template"
@ -52,6 +52,17 @@ func (app *application) webmasterCreate(w http.ResponseWriter, r *http.Request)
}
func (app *application) siteEntryView(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/sites/view" {
entries, err := app.siteEntries.Latest()
if err != nil {
app.serverError(w, err)
return
}
for _, entry := range entries {
fmt.Fprintf(w, "%+v\n", entry)
}
return
}
id := models.SiteId(r.URL.Query().Get("id"))
siteEntry, err := app.siteEntries.Get(id)
@ -71,8 +82,37 @@ func (app *application) siteEntryCreate(w http.ResponseWriter, r *http.Request)
}
func (app *application) nextSiteEntry(w http.ResponseWriter, r *http.Request) {
ref := app.cleanUrl(r.Referer())
refSite, err := app.siteEntries.GetByUrl(ref)
if err != nil {
app.serverError(w, err)
return
}
nextSite, err := app.siteEntries.Get(refSite.Next)
if err != nil {
app.serverError(w, err)
app.infoLog.Printf("%+v", nextSite)
return
}
// TODO ping next site to see if it is up
w.Header().Set("Location", nextSite.Url)
w.WriteHeader(http.StatusFound)
}
func (app *application) prevSiteEntry(w http.ResponseWriter, r *http.Request) {
ref := app.cleanUrl(r.Referer())
refSite, err := app.siteEntries.GetByUrl(ref)
if err != nil {
app.serverError(w, err)
return
}
prevSite, err := app.siteEntries.Get(refSite.Prev)
if err != nil {
app.serverError(w, err)
return
}
// TODO ping next site to see if it is up
w.Header().Set("Location", prevSite.Url)
w.WriteHeader(http.StatusFound)
}

View File

@ -3,7 +3,9 @@ package main
import (
"fmt"
"net/http"
"path"
"runtime/debug"
"strings"
)
func (app *application) serverError(w http.ResponseWriter, err error) {
@ -20,3 +22,11 @@ func (app *application) clientError(w http.ResponseWriter, status int) {
func (app *application) notFound(w http.ResponseWriter) {
app.clientError(w, http.StatusNotFound)
}
func (app *application) cleanUrl(url string) string {
s, _ := strings.CutPrefix(url, "http://")
s, _ = strings.CutPrefix(s, "https://")
s = path.Base(path.Clean(s))
s = "http://" + s
return s
}

View File

@ -12,6 +12,8 @@ func (app *application) routes() *http.ServeMux {
mux.HandleFunc("/", app.home)
mux.HandleFunc("/webmasters/view", app.webmasterView)
mux.HandleFunc("/sites/view", app.siteEntryView)
mux.HandleFunc("/next", app.nextSiteEntry)
mux.HandleFunc("/prev", app.prevSiteEntry)
return mux
}

View File

@ -40,7 +40,7 @@ func (m *SiteEntryModel) Insert(name string, url string, webmaster *Webmaster) (
// Retrieve a SiteEntry from the database by id
func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
stmt := `SELECT id, name, url, webmaster, dateAdded FROM siteentries
stmt := `SELECT id, name, url, webmaster, dateAdded, next, prev FROM siteentries
WHERE id = ?`
row := m.DB.QueryRow(stmt, id)
@ -48,7 +48,7 @@ func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
var timeStr string
err := row.Scan(&s.Id, &s.Name, &s.Url, &s.Webmaster, &timeStr)
err := row.Scan(&s.Id, &s.Name, &s.Url, &s.Webmaster, &timeStr, &s.Next, &s.Prev)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNoRecord
@ -57,7 +57,7 @@ func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
}
}
// time is stored as a string in sqlite, so we need to parse it
// probably should be something taken care of in the driver
// probably is something taken care of in the driver
dateAdded, err := time.Parse(time.DateTime, timeStr)
if err != nil {
return nil, err
@ -69,7 +69,31 @@ func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
// Retrieve a SiteEntry from the database by url
func (m *SiteEntryModel) GetByUrl(url string) (*SiteEntry, error) {
return nil, nil
stmt := `SELECT id, name, url, webmaster, dateAdded, next, prev FROM siteentries
WHERE url = ?`
row := m.DB.QueryRow(stmt, url)
s := &SiteEntry{}
var timeStr string
err := row.Scan(&s.Id, &s.Name, &s.Url, &s.Webmaster, &timeStr, &s.Next, &s.Prev)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, ErrNoRecord
} else {
return nil, err
}
}
// time is stored as a string in sqlite, so we need to parse it
// probably is something taken care of in the driver
s.DateAdded, err = time.Parse(time.DateTime, timeStr)
if err != nil {
return nil, err
}
return s, nil
}
// Update existing SiteEntry with the values of passed entry
@ -81,3 +105,39 @@ func (m *SiteEntryModel) Update(entry *SiteEntry) error {
func (m *SiteEntryModel) Delete(entry *SiteEntry) error {
return nil
}
// Get latest
func (m *SiteEntryModel) Latest() ([]*SiteEntry, error) {
stmt := `SELECT id, name, url, webmaster, dateAdded FROM siteentries
ORDER BY dateAdded DESC LIMIT 10`
rows, err := m.DB.Query(stmt)
if err != nil {
return nil, err
}
defer rows.Close()
entries := []*SiteEntry{}
var timeStr string
for rows.Next() {
s := &SiteEntry{}
err = rows.Scan(&s.Id, &s.Name, &s.Url, &s.Webmaster, &timeStr)
if err != nil {
return nil, err
}
s.DateAdded, err = time.Parse(time.DateTime, timeStr)
if err != nil {
return nil, err
}
entries = append(entries, s)
}
if err = rows.Err(); err != nil {
return nil, err
}
return entries, nil
}