commit - f018f5a676cd8a415a426d8302bc1950a9dd20b4
commit + e396d327ce7472ac9a79ab7df26755d6e50ef0c7
blob - 99641078e9a491a9611743912649a41225603666
blob + 4fdd36ec7bd8c1eff3fe3f07c55628360acf7a7f
--- internal/service/handlers.go
+++ internal/service/handlers.go
import (
"html/template"
"net/http"
-
- "github.com/streatCodes/rss/rss"
+ "net/url"
)
-type TemplateData struct {
- Results []rss.Channel
-}
-
var templateFuncs = template.FuncMap{
- "timeAgo": timeAgo,
+ "timeAgo": timeAgo,
+ "pathEscape": url.PathEscape,
}
func render(w http.ResponseWriter, name string, data any) {
isHtmx := r.Header.Get("HX-Request") == "true"
searchQuery := r.URL.Query().Get("search")
- channels, err := service.findChannel(searchQuery)
+ results, err := service.findChannel(searchQuery)
if err != nil {
panic("TODO")
}
if isHtmx {
- render(w, "results", channels)
+ render(w, "results", results)
return
}
- render(w, "home", TemplateData{Results: channels})
+ render(w, "home", results)
}
blob - fc7a36095e3546d9ad62f9fc8ff9dc680428be92
blob + 7ed9210fb5ae6c58e79f7f2e061779b2107ecb8d
--- internal/service/search.go
+++ internal/service/search.go
package service
import (
+ "log"
"net/http"
"net/url"
"github.com/streatCodes/rss/rss"
)
-func (service *Service) findChannel(query string) ([]rss.Channel, error) {
+type ChannelResult struct {
+ ChannelUrl string
+ Channel rss.Channel
+}
+
+func (service *Service) findChannel(query string) ([]ChannelResult, error) {
//If the search query is a URL then ingest the feed
if parsedURL, err := url.ParseRequestURI(query); err == nil {
+ channelUrl := parsedURL.String()
+
//Check to see if we have the feed in the database
- if channel, err := service.db.GetChannel(parsedURL.String()); channel != nil && err == nil {
- return []rss.Channel{*channel}, nil
+ if channel, err := service.db.GetChannel(channelUrl); channel != nil && err == nil {
+ return []ChannelResult{{ChannelUrl: channelUrl, Channel: *channel}}, nil
}
//Fetch from the internet
- res, err := http.Get(query)
+ log.Printf("Indexing channel %s\n", channelUrl)
+ res, err := http.Get(channelUrl)
if err != nil {
return nil, err
}
return nil, err
}
- err = service.db.SaveChannel(parsedURL.String(), &feed.Channel)
+ err = service.db.SaveChannel(channelUrl, &feed.Channel)
if err != nil {
return nil, err
}
- return []rss.Channel{feed.Channel}, nil
+ return []ChannelResult{{ChannelUrl: channelUrl, Channel: feed.Channel}}, nil
}
- return []rss.Channel{}, nil
+ return []ChannelResult{}, nil
}
blob - 0cf6eed00b7dcfbdeca42e826f92a48ce7895b6c
blob + 23302b9aa8be8f918eb35fbd152ef550a6366a1c
--- internal/templates/home.tmpl
+++ internal/templates/home.tmpl
</form>
<div id="search-results">
- {{ template "results" .Results }}
+ {{ template "results" . }}
</div>
</main>
{{ template "footer" }}
blob - 9d3a73da08d07995b9a751c618d6103d58855e78
blob + 659b7e94cc258811911c19033cd2fa7efe7b88b6
--- internal/templates/results.tmpl
+++ internal/templates/results.tmpl
<div class="results">
{{ range . }}
<div class="result">
- <img src="{{ .Image.Href }}" width="170" height="170" />
+ <img src="{{ .Channel.Image.Href }}" width="170" height="170" />
<div>
<hgroup>
<div class="flex">
- <h2>{{ .Title }}</h2>
- <a class="button">Episodes</a>
+ <h2>{{ .Channel.Title }}</h2>
+ <a class="button" href="/channel/{{ .ChannelUrl | pathEscape}}">Episodes</a>
</div>
- <time datetime="{{ .PubDate.Format "2006-01-02T15:04:05Z07:00" }}">
- Last updated {{ .PubDate | timeAgo }}
+ <time datetime="{{ .Channel.PubDate.Format "2006-01-02T15:04:05Z07:00" }}">
+ Last updated {{ .Channel.PubDate | timeAgo }}
</time>
</hgroup>
- <p>{{ .Description }}</p>
+ <p>{{ .Channel.Description }}</p>
<div class="tag-line">
- {{ if gt (len .Link) 0 }}
- <a href="{{index .Link 0}}" class="button">
+ {{ if gt (len .Channel.Link) 0 }}
+ <a href="{{index .Channel.Link 0}}" class="button">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-globe2" viewBox="0 0 16 16">
<path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m7.5-6.923c-.67.204-1.335.82-1.887 1.855q-.215.403-.395.872c.705.157 1.472.257 2.282.287zM4.249 3.539q.214-.577.481-1.078a7 7 0 0 1 .597-.933A7 7 0 0 0 3.051 3.05q.544.277 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9 9 0 0 1-1.565-.667A6.96 6.96 0 0 0 1.018 7.5zm1.4-2.741a12.3 12.3 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332M8.5 5.09V7.5h2.99a12.3 12.3 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.6 13.6 0 0 1 7.5 10.91V8.5zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741zm-3.282 3.696q.18.469.395.872c.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a7 7 0 0 1-.598-.933 9 9 0 0 1-.481-1.079 8.4 8.4 0 0 0-1.198.49 7 7 0 0 0 2.276 1.522zm-1.383-2.964A13.4 13.4 0 0 1 3.508 8.5h-2.49a6.96 6.96 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667m6.728 2.964a7 7 0 0 0 2.275-1.521 8.4 8.4 0 0 0-1.197-.49 9 9 0 0 1-.481 1.078 7 7 0 0 1-.597.933M8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855q.216-.403.395-.872A12.6 12.6 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.96 6.96 0 0 0 14.982 8.5h-2.49a13.4 13.4 0 0 1-.437 3.008M14.982 7.5a6.96 6.96 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008zM11.27 2.461q.266.502.482 1.078a8.4 8.4 0 0 0 1.196-.49 7 7 0 0 0-2.275-1.52c.218.283.418.597.597.932m-.488 1.343a8 8 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/>
</svg>
</a>
{{ end }}
- <a href="mailto:{{.Owner.Email}}" class="button" style="margin-right: 1rem">
+ <a href="mailto:{{.Channel.Owner.Email}}" class="button" style="margin-right: 1rem">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-envelope" viewBox="0 0 16 16">
<path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/>
</svg>
</a>
- {{ range .Categories }}
+ {{ range .Channel.Categories }}
<a class="category">#{{ .Text }}</a>
{{ end }}
</div>