Skip to content

Commit

Permalink
Support for multiple authors
Browse files Browse the repository at this point in the history
  • Loading branch information
svera authored May 12, 2023
1 parent 1879220 commit 441b95b
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 35 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ coreander
bin
tmp
*.zip
*.exe
21 changes: 17 additions & 4 deletions internal/index/bleve_read.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

// Search look for documents which match with the passed keywords. Returns a maximum <resultsPerPage> books, offset by <page>
func (b *BleveIndexer) Search(keywords string, page, resultsPerPage int, wordsPerMinute float64) (*controller.Result, error) {
for _, prefix := range []string{"Author:", "Series:", "Title:", "\""} {
for _, prefix := range []string{"Authors:", "Series:", "Title:", "\""} {
if strings.HasPrefix(strings.Trim(keywords, " "), prefix) {
query := bleve.NewQueryStringQuery(keywords)

Expand All @@ -37,7 +37,7 @@ func (b *BleveIndexer) Search(keywords string, page, resultsPerPage int, wordsPe
continue
}
qa := bleve.NewMatchQuery(keyword)
qa.SetField("Author")
qa.SetField("Authors")
authorQueries = append(authorQueries, qa)

qt := bleve.NewMatchQuery(keyword)
Expand Down Expand Up @@ -70,7 +70,7 @@ func (b *BleveIndexer) runQuery(query query.Query, page, resultsPerPage int, wor

searchOptions := bleve.NewSearchRequestOptions(query, resultsPerPage, (page-1)*resultsPerPage, false)
searchOptions.SortBy([]string{"-_score", "Series", "SeriesIndex"})
searchOptions.Fields = []string{"Title", "Author", "Description", "Year", "Words", "Series", "SeriesIndex", "Pages", "Type"}
searchOptions.Fields = []string{"Title", "Authors", "Description", "Year", "Words", "Series", "SeriesIndex", "Pages", "Type"}
searchResult, err := b.idx.Search(searchOptions)
if err != nil {
return nil, err
Expand All @@ -97,10 +97,23 @@ func (b *BleveIndexer) runQuery(query query.Query, page, resultsPerPage int, wor
}

for i, val := range searchResult.Hits {
var (
authors []interface{}
ok bool
)

// Bleve indexes string slices of one element as just string
if authors, ok = val.Fields["Authors"].([]interface{}); !ok {
authors = append(authors, val.Fields["Authors"])
}
authorsStrings := make([]string, len(authors))
for j, author := range authors {
authorsStrings[j] = author.(string)
}
doc := metadata.Metadata{
ID: val.ID,
Title: val.Fields["Title"].(string),
Author: val.Fields["Author"].(string),
Authors: authorsStrings,
Description: template.HTML(val.Fields["Description"].(string)),
Year: val.Fields["Year"].(string),
Words: val.Fields["Words"].(float64),
Expand Down
20 changes: 10 additions & 10 deletions internal/index/bleve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func testCases() []testCase {
"lib/book1.epub",
metadata.Metadata{
Title: "Test A",
Author: "Pérez",
Authors: []string{"Pérez"},
Description: "Just test metadata",
Language: "es",
},
Expand All @@ -77,7 +77,7 @@ func testCases() []testCase {
{
ID: "book1.epub",
Title: "Test A",
Author: "Pérez",
Authors: []string{"Pérez"},
Description: "Just test metadata",
},
},
Expand All @@ -88,7 +88,7 @@ func testCases() []testCase {
"lib/book2.epub",
metadata.Metadata{
Title: "Test B",
Author: "Benoît",
Authors: []string{"Benoît"},
Description: "Just test metadata",
Language: "fr",
},
Expand All @@ -101,7 +101,7 @@ func testCases() []testCase {
{
ID: "book2.epub",
Title: "Test B",
Author: "Benoît",
Authors: []string{"Benoît"},
Description: "Just test metadata",
},
},
Expand All @@ -112,7 +112,7 @@ func testCases() []testCase {
"lib/book3.epub",
metadata.Metadata{
Title: "Test C",
Author: "Clifford D. Simak",
Authors: []string{"Clifford D. Simak"},
Description: "Just test metadata",
Language: "en",
},
Expand All @@ -125,7 +125,7 @@ func testCases() []testCase {
{
ID: "book3.epub",
Title: "Test C",
Author: "Clifford D. Simak",
Authors: []string{"Clifford D. Simak"},
Description: "Just test metadata",
},
},
Expand All @@ -136,7 +136,7 @@ func testCases() []testCase {
"lib/book4.epub",
metadata.Metadata{
Title: "Test D",
Author: "James Ellroy",
Authors: []string{"James Ellroy"},
Description: "Just test metadata",
Language: "en",
},
Expand All @@ -149,7 +149,7 @@ func testCases() []testCase {
{
ID: "book4.epub",
Title: "Test D",
Author: "James Ellroy",
Authors: []string{"James Ellroy"},
Description: "Just test metadata",
},
},
Expand All @@ -160,7 +160,7 @@ func testCases() []testCase {
"lib/book5.epub",
metadata.Metadata{
Title: "Test E",
Author: "James Ellroy",
Authors: []string{"James Ellroy"},
Description: "Just test metadata",
Language: "en",
},
Expand All @@ -173,7 +173,7 @@ func testCases() []testCase {
{
ID: "book5.epub",
Title: "Test E",
Author: "James Ellroy",
Authors: []string{"James Ellroy"},
Description: "Just test metadata",
},
},
Expand Down
6 changes: 6 additions & 0 deletions internal/infrastructure/template_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,11 @@ func TemplateEngine(viewsFS fs.FS, printers map[string]*message.Printer) (*html.
return strings.ToUpper(text)
})

engine.AddFunc("notLast", notLast[string])

return engine, nil
}

func notLast[V any](slice []V, index int) bool {
return index < len(slice)-1
}
18 changes: 14 additions & 4 deletions internal/metadata/epub.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,25 @@ func (e EpubReader) Metadata(file string) (Metadata, error) {
if len(opf.Metadata.Title) > 0 && len(opf.Metadata.Title[0]) > 0 {
title = opf.Metadata.Title[0]
}
author := ""
var authors []string
if len(opf.Metadata.Creator) > 0 {
for _, creator := range opf.Metadata.Creator {
if creator.Role == "aut" || creator.Role == "" {
author = creator.FullName
break
// Some epub files mistakenly put all authors in a single field instead of using a field for each one.
// We want to identify those cases looking for specific separators and then indexing each author properly.
names := strings.Split(creator.FullName, "&")
for i := range names {
names[i] = strings.TrimSpace(names[i])
}
authors = append(authors, names...)
}
}
}

if len(authors) == 0 {
authors = []string{""}
}

description := ""
if len(opf.Metadata.Description) > 0 {
p := bluemonday.UGCPolicy()
Expand Down Expand Up @@ -88,7 +98,7 @@ func (e EpubReader) Metadata(file string) (Metadata, error) {
}
bk = Metadata{
Title: title,
Author: author,
Authors: authors,
Description: template.HTML(description),
Language: language,
Year: year,
Expand Down
2 changes: 1 addition & 1 deletion internal/metadata/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
type Metadata struct {
ID string
Title string
Author string
Authors []string
Description template.HTML
Language string
Year string
Expand Down
2 changes: 1 addition & 1 deletion internal/metadata/pdf.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (p PdfReader) Metadata(file string) (Metadata, error) {

bk = Metadata{
Title: title,
Author: pdf.GetAuthor(),
Authors: []string{pdf.GetAuthor()},
Description: template.HTML(description),
Language: pdf.GetLanguage(),
Year: year,
Expand Down
19 changes: 13 additions & 6 deletions internal/webserver/embedded/views/epub-reader.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
<a id="prev" href="#prev" class="navlink btn btn-dark text-truncate">«</a>
</div>
<div class="col-8">
<select class="form-select" id="toc">
<option value="">{{t .Lang "Loading document, please wait"}}</option>
</select>
<select class="form-select" id="toc"></select>
</div>
<div class="col-2">
<a id="next" href="#next" class="navlink btn btn-dark text-truncate">»</a>
Expand All @@ -37,8 +35,11 @@
</div>
</nav>
</header>

<div id="viewer" class="scrolled mt-5"></div>
<div id="loading" class="mt-5">
<span class="spinner-border" role="status" aria-hidden="true"></span>
</div>

<script>
var params = URLSearchParams && new URLSearchParams(document.location.search.substring(1));
var url = params && params.get("url") && decodeURIComponent(params.get("url"));
Expand Down Expand Up @@ -94,9 +95,15 @@
book.loaded.navigation.then(function (toc) {
let $select = document.getElementById("toc"),
docfrag = document.createDocumentFragment(),
viewer = document.getElementById("viewer");
loading = document.getElementById("loading");

$select.options.length = 0;
if (loading) {
loading.remove();
}

if ($select.options.length > 0) {
return;
}

toc.forEach(function (chapter) {
var option = document.createElement("option");
Expand Down
2 changes: 1 addition & 1 deletion internal/webserver/embedded/views/partials/actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>
&nbsp;&nbsp;{{t .Lang "Read"}}</a></li>
<li><a href="files/{{.BookID}}" class="dropdown-item" download>
<li><a href="files/{{.Book.ID}}" class="dropdown-item" download>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cloud-download" viewBox="0 0 16 16">
<path d="M4.406 1.342A5.53 5.53 0 0 1 8 0c2.69 0 4.923 2 5.166 4.579C14.758 4.804 16 6.137 16 7.773 16 9.569 14.502 11 12.687 11H10a.5.5 0 0 1 0-1h2.688C13.979 10 15 8.988 15 7.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 2.825 10.328 1 8 1a4.53 4.53 0 0 0-2.941 1.1c-.757.652-1.153 1.438-1.153 2.055v.448l-.445.049C2.064 4.805 1 5.952 1 7.318 1 8.785 2.23 10 3.781 10H6a.5.5 0 0 1 0 1H3.781C1.708 11 0 9.366 0 7.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383z"/>
<path d="M7.646 15.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 14.293V5.5a.5.5 0 0 0-1 0v8.793l-2.146-2.147a.5.5 0 0 0-.708.708l3 3z"/>
Expand Down
13 changes: 8 additions & 5 deletions internal/webserver/embedded/views/results.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<p>{{t .Lang "No matches found" }}</p>
{{end}}

<div class="list-group">
<div class="list-group list-group-flush">
{{if .Results}} {{range $i, $book := .Results}}
<div class="list-group-item">
<div class="row">
Expand All @@ -35,10 +35,13 @@ <h4 class="text-start">{{$book.Title}} <small class="small text-muted">{{$book.Y
</div>
<div class="row">
<div class="col-12 text-start">
{{if $book.Author}}
{{$authorTitle := t $lang "Search for more titles by %s" $book.Author}}
<h5><a href="?search=Author&colon;&quot;{{$book.Author}}&quot;"
title={{$authorTitle}}>{{$book.Author}}</a></h5>
{{if $book.Authors}}
<h5>
{{range $i, $author := $book.Authors}}
{{$authorTitle := t $lang "Search for more titles by %s" $author}}
<a href="?search=Authors&colon;&quot;{{$author}}&quot;" title={{$authorTitle}}>{{$author}}</a>{{if notLast $book.Authors $i}}, {{end}}
{{end}}
</h5>
{{else}}
<h5>{{t $lang "Unknown author"}}</h5>
{{end}}
Expand Down
26 changes: 23 additions & 3 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func Build(platform string) error {

// Build binary files of the current version for all supported platforms and zip them
func Release() error {
platforms := []string{"rpi32", "rpi64", "osxintel", "osxapple"}
platforms := []string{"linux32", "linux64", "linuxarm32", "linuxarm64", "osxintel", "osxapple", "win64"}
version, err := version()
if err != nil {
return err
Expand Down Expand Up @@ -67,13 +67,23 @@ func env(platform string) (map[string]string, error) {
env := map[string]string{}

switch platform {
case "rpi32":
case "linux32":
return map[string]string{
"GOOS": "linux",
"GOARCH": "386",
}, nil
case "linux64":
return map[string]string{
"GOOS": "linux",
"GOARCH": "amd64",
}, nil
case "linuxarm32":
return map[string]string{
"GOOS": "linux",
"GOARCH": "arm",
"GOARM": "7",
}, nil
case "rpi64":
case "linuxarm64":
return map[string]string{
"GOOS": "linux",
"GOARCH": "arm64",
Expand All @@ -88,6 +98,16 @@ func env(platform string) (map[string]string, error) {
"GOOS": "darwin",
"GOARCH": "arm64",
}, nil
case "win32":
return map[string]string{
"GOOS": "windows",
"GOARCH": "386",
}, nil
case "win64":
return map[string]string{
"GOOS": "windows",
"GOARCH": "amd64",
}, nil
}

return env, fmt.Errorf("Platform '%s' not supported", platform)
Expand Down

0 comments on commit 441b95b

Please sign in to comment.