restructuring
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
package routes
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crowsnest/internal/data"
|
"crowsnest/internal/data"
|
||||||
"crowsnest/internal/model"
|
"crowsnest/internal/model"
|
||||||
"crowsnest/internal/viewmodel"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@@ -15,7 +14,7 @@ func (ord articleDateOrder) Weight(a *model.Article) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List the latest articles using the base template.
|
// List the latest articles using the base template.
|
||||||
func Index(w http.ResponseWriter, req *http.Request) {
|
func (app *App) Index(w http.ResponseWriter, req *http.Request) {
|
||||||
// retrieve from repo
|
// retrieve from repo
|
||||||
fds, err := data.NewFileDatastore("persistence/spiegel100.json")
|
fds, err := data.NewFileDatastore("persistence/spiegel100.json")
|
||||||
if err != nil { http.Error(w, "Failed to load datastore", http.StatusInternalServerError); return; }
|
if err != nil { http.Error(w, "Failed to load datastore", http.StatusInternalServerError); return; }
|
||||||
@@ -30,9 +29,9 @@ func Index(w http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// convert to viewmodel
|
// convert to viewmodel
|
||||||
articleVMs := make([]*viewmodel.ArticleViewModel, 0, len(articles))
|
articleVMs := make([]*model.ArticleViewModel, 0, len(articles))
|
||||||
for _, a := range articles {
|
for _, a := range articles {
|
||||||
articleVMs = append(articleVMs, viewmodel.NewArticleViewModel(a))
|
articleVMs = append(articleVMs, a.ViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
// render template
|
// render template
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
package routes
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crowsnest/internal/data"
|
"crowsnest/internal/data"
|
||||||
"crowsnest/internal/model"
|
"crowsnest/internal/model"
|
||||||
"crowsnest/internal/viewmodel"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -25,7 +24,7 @@ func (ord articleTermFrequency) Weight(a *model.Article) int {
|
|||||||
|
|
||||||
// Enpoint that returns a list of articles given search terms in the post
|
// Enpoint that returns a list of articles given search terms in the post
|
||||||
// request of a search form. Uses the content template.
|
// request of a search form. Uses the content template.
|
||||||
func UpSearch(w http.ResponseWriter, req *http.Request) {
|
func (app *App) UpSearch(w http.ResponseWriter, req *http.Request) {
|
||||||
// parse the form data
|
// parse the form data
|
||||||
err := req.ParseForm()
|
err := req.ParseForm()
|
||||||
if err != nil { http.Error(w, "Unable to parse form", http.StatusBadRequest); return; }
|
if err != nil { http.Error(w, "Unable to parse form", http.StatusBadRequest); return; }
|
||||||
@@ -50,15 +49,15 @@ func UpSearch(w http.ResponseWriter, req *http.Request) {
|
|||||||
if len(searchTerms) != 0 {
|
if len(searchTerms) != 0 {
|
||||||
articles, err = repo.GetByCriteria(articleTermFrequency{ terms: searchTerms })
|
articles, err = repo.GetByCriteria(articleTermFrequency{ terms: searchTerms })
|
||||||
} else {
|
} else {
|
||||||
Index(w, req)
|
app.Index(w, req)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err != nil { http.Error(w, "Failed to get articles from repo", http.StatusInternalServerError); return; }
|
if err != nil { http.Error(w, "Failed to get articles from repo", http.StatusInternalServerError); return; }
|
||||||
|
|
||||||
// convert to viewmodel
|
// convert to viewmodel
|
||||||
articleVMs := make([]*viewmodel.ArticleViewModel, 0, len(articles))
|
articleVMs := make([]*model.ArticleViewModel, 0, len(articles))
|
||||||
for _, a := range articles {
|
for _, a := range articles {
|
||||||
articleVMs = append(articleVMs, viewmodel.NewArticleViewModel(a))
|
articleVMs = append(articleVMs, a.ViewModel())
|
||||||
}
|
}
|
||||||
|
|
||||||
// render template
|
// render template
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crowsnest/internal/routes"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type App struct {}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// routes
|
app := &App{}
|
||||||
http.HandleFunc("GET /", routes.Index)
|
|
||||||
http.HandleFunc("POST /up/search", routes.UpSearch)
|
|
||||||
|
|
||||||
// serve files from the "static" directory
|
server := http.Server{
|
||||||
fs := http.FileServer(http.Dir("assets/static"))
|
Addr: ":8080",
|
||||||
http.Handle("GET /static/", http.StripPrefix("/", fs))
|
Handler: app.routes(),
|
||||||
|
}
|
||||||
// start server
|
|
||||||
http.ListenAndServe(":8080", nil)
|
server.ListenAndServe()
|
||||||
|
log.Println("server started, listening on :8080")
|
||||||
}
|
}
|
||||||
|
|||||||
19
cmd/frontend/routes.go
Normal file
19
cmd/frontend/routes.go
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (app *App) routes() http.Handler {
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
|
||||||
|
// dynamic routes
|
||||||
|
mux.HandleFunc("GET /", app.Index)
|
||||||
|
mux.HandleFunc("POST /up/search", app.UpSearch)
|
||||||
|
|
||||||
|
// serve files from the "static" directory
|
||||||
|
fs := http.FileServer(http.Dir("assets/static"))
|
||||||
|
mux.Handle("GET /static/", http.StripPrefix("/", fs))
|
||||||
|
|
||||||
|
return mux
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// TODO docstring
|
// TODO docstring
|
||||||
type Article struct {
|
type Article struct {
|
||||||
SourceUrl string
|
SourceUrl string
|
||||||
@@ -16,18 +17,38 @@ type Article struct {
|
|||||||
Author string
|
Author string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO docstring
|
||||||
|
type ArticleViewModel struct {
|
||||||
|
Title string
|
||||||
|
Author string
|
||||||
|
PublishDate string
|
||||||
|
SourceUrl string
|
||||||
|
Summary string
|
||||||
|
}
|
||||||
|
|
||||||
// Generates a hash based on the source url of the article. Can be used to
|
|
||||||
// identify the article.
|
// TODO docstring
|
||||||
func (article *Article) Hash() string {
|
func (a *Article) ViewModel() *ArticleViewModel {
|
||||||
hash := sha256.Sum256([]byte(article.SourceUrl))
|
summary := a.Content
|
||||||
return hex.EncodeToString(hash[:])
|
if len(a.Content) > 300 {
|
||||||
|
summary = summary[:300]
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ArticleViewModel{
|
||||||
|
Title: a.Title,
|
||||||
|
Author: a.Author,
|
||||||
|
PublishDate: a.PublishDate.Local().Format("02.01.2006 03:04"),
|
||||||
|
SourceUrl: a.SourceUrl,
|
||||||
|
Summary: summary,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- implement IIdentifiable interface ---
|
// --- implement IIdentifiable interface ---
|
||||||
|
|
||||||
// Using the Identifier attribute as the Id.
|
// Generates a hash based on the source url of the article. Can be used to
|
||||||
|
// identify the article.
|
||||||
func (article *Article) Id() string {
|
func (article *Article) Id() string {
|
||||||
return article.Hash()
|
hash := sha256.Sum256([]byte(article.SourceUrl))
|
||||||
|
return hex.EncodeToString(hash[:])
|
||||||
}
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package viewmodel
|
|
||||||
|
|
||||||
import "crowsnest/internal/model"
|
|
||||||
|
|
||||||
|
|
||||||
type ArticleViewModel struct {
|
|
||||||
Title string
|
|
||||||
Author string
|
|
||||||
PublishDate string
|
|
||||||
SourceUrl string
|
|
||||||
Summary string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewArticleViewModel(a *model.Article) *ArticleViewModel {
|
|
||||||
summary := a.Content
|
|
||||||
if len(a.Content) > 300 {
|
|
||||||
summary = summary[:300]
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ArticleViewModel{
|
|
||||||
Title: a.Title,
|
|
||||||
Author: a.Author,
|
|
||||||
PublishDate: a.PublishDate.Local().Format("02.01.2006 03:04"),
|
|
||||||
SourceUrl: a.SourceUrl,
|
|
||||||
Summary: summary,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user