implement redirection handlers, implement data retrieval functions
This commit is contained in:
parent
5877e2556c
commit
4c3811bc87
|
@ -1,8 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"errors"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"text/template"
|
"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) {
|
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"))
|
id := models.SiteId(r.URL.Query().Get("id"))
|
||||||
|
|
||||||
siteEntry, err := app.siteEntries.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) {
|
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) {
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (app *application) serverError(w http.ResponseWriter, err error) {
|
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) {
|
func (app *application) notFound(w http.ResponseWriter) {
|
||||||
app.clientError(w, http.StatusNotFound)
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ func (app *application) routes() *http.ServeMux {
|
||||||
mux.HandleFunc("/", app.home)
|
mux.HandleFunc("/", app.home)
|
||||||
mux.HandleFunc("/webmasters/view", app.webmasterView)
|
mux.HandleFunc("/webmasters/view", app.webmasterView)
|
||||||
mux.HandleFunc("/sites/view", app.siteEntryView)
|
mux.HandleFunc("/sites/view", app.siteEntryView)
|
||||||
|
mux.HandleFunc("/next", app.nextSiteEntry)
|
||||||
|
mux.HandleFunc("/prev", app.prevSiteEntry)
|
||||||
|
|
||||||
return mux
|
return mux
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (m *SiteEntryModel) Insert(name string, url string, webmaster *Webmaster) (
|
||||||
|
|
||||||
// Retrieve a SiteEntry from the database by id
|
// Retrieve a SiteEntry from the database by id
|
||||||
func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
|
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 = ?`
|
WHERE id = ?`
|
||||||
|
|
||||||
row := m.DB.QueryRow(stmt, id)
|
row := m.DB.QueryRow(stmt, id)
|
||||||
|
@ -48,7 +48,7 @@ func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
|
||||||
|
|
||||||
|
|
||||||
var timeStr string
|
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 err != nil {
|
||||||
if errors.Is(err, sql.ErrNoRows) {
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
return nil, ErrNoRecord
|
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
|
// 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)
|
dateAdded, err := time.Parse(time.DateTime, timeStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -69,7 +69,31 @@ func (m *SiteEntryModel) Get(id SiteId) (*SiteEntry, error) {
|
||||||
|
|
||||||
// Retrieve a SiteEntry from the database by url
|
// Retrieve a SiteEntry from the database by url
|
||||||
func (m *SiteEntryModel) GetByUrl(url string) (*SiteEntry, error) {
|
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
|
// 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 {
|
func (m *SiteEntryModel) Delete(entry *SiteEntry) error {
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue