182 lines
4.2 KiB
Go
182 lines
4.2 KiB
Go
|
package genhtml
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"html"
|
||
|
"os"
|
||
|
"sort"
|
||
|
|
||
|
"github.com/akamensky/argparse"
|
||
|
"github.com/rs/zerolog/log"
|
||
|
"gitlab.com/ChaotiCryptidz/musicutil/types"
|
||
|
"gitlab.com/ChaotiCryptidz/musicutil/utils"
|
||
|
)
|
||
|
|
||
|
type GenHTMLCommandArgs struct {
|
||
|
Source *string
|
||
|
Dest *string
|
||
|
Title *string
|
||
|
Description *string
|
||
|
}
|
||
|
|
||
|
func RegisterGenHTMLCommand(parser *argparse.Parser) (*argparse.Command, *GenHTMLCommandArgs) {
|
||
|
cmd := parser.NewCommand("genhtml", "generates a html file or multiple html files for showing music library")
|
||
|
|
||
|
arguments := &GenHTMLCommandArgs{}
|
||
|
arguments.Source = cmd.String("s", "src", &argparse.Options{
|
||
|
Required: true,
|
||
|
Validate: func(args []string) error {
|
||
|
fileInfo, err := os.Stat(args[0])
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("Source does not exist")
|
||
|
}
|
||
|
|
||
|
if !fileInfo.IsDir() {
|
||
|
return fmt.Errorf("Source is not a directory")
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
},
|
||
|
})
|
||
|
|
||
|
arguments.Dest = cmd.String("d", "dest", &argparse.Options{Required: true})
|
||
|
|
||
|
arguments.Title = cmd.String("", "title", &argparse.Options{Default: ""})
|
||
|
arguments.Description = cmd.String("", "description", &argparse.Options{Default: ""})
|
||
|
|
||
|
return cmd, arguments
|
||
|
}
|
||
|
|
||
|
type GenHTMLCommand struct {
|
||
|
Args *GenHTMLCommandArgs
|
||
|
Files []*types.File
|
||
|
}
|
||
|
|
||
|
func NewGenHTMLCommand(args *GenHTMLCommandArgs) *GenHTMLCommand {
|
||
|
return &GenHTMLCommand{
|
||
|
Args: args,
|
||
|
Files: make([]*types.File, 0),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (c *GenHTMLCommand) scan_for_music() {
|
||
|
log.Info().Msg("Scanning For Music")
|
||
|
|
||
|
files, err := utils.ScanForMusic(*c.Args.Source)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
c.Files = files
|
||
|
}
|
||
|
|
||
|
func (c *GenHTMLCommand) load_tag_information() {
|
||
|
log.Info().Msg("Loading Tag Information")
|
||
|
|
||
|
for _, file := range c.Files {
|
||
|
log.Info().Str("file", file.JoinFilename()).Msg("Loading Tags")
|
||
|
tags, err := utils.ExtractTags(file)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
file.Tags = tags
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (c *GenHTMLCommand) Run() {
|
||
|
log.Info().Msg("Generating HTML")
|
||
|
|
||
|
c.scan_for_music()
|
||
|
c.load_tag_information()
|
||
|
|
||
|
sort.Slice(c.Files, func(i, j int) bool {
|
||
|
if c.Files[i].PathFromSource != c.Files[j].PathFromSource {
|
||
|
return c.Files[i].PathFromSource < c.Files[j].PathFromSource
|
||
|
}
|
||
|
if c.Files[i].Tags.Title != c.Files[j].Tags.Title {
|
||
|
return c.Files[i].Tags.Title < c.Files[j].Tags.Title
|
||
|
}
|
||
|
|
||
|
return c.Files[i].Tags.Artist < c.Files[j].Tags.Artist
|
||
|
})
|
||
|
|
||
|
html_content := ""
|
||
|
html_content = html_content + fmt.Sprintf(`
|
||
|
<!DOCTYPE HTML>
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
|
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/pure-min.css">
|
||
|
<title>%s</title>
|
||
|
<meta property="og:title" content="%s" />
|
||
|
<meta property="og:description" content="%s" />
|
||
|
</head>
|
||
|
<body>
|
||
|
`, *c.Args.Title, *c.Args.Title, *c.Args.Description)
|
||
|
|
||
|
html_content = html_content + tableForFiles(c.Files, true)
|
||
|
|
||
|
html_content = html_content + "</body></html>"
|
||
|
|
||
|
html_file, err := os.Create(*c.Args.Dest + "/index.html")
|
||
|
if err != nil {
|
||
|
log.Fatal().Err(err).Msg("Could not write HTML file")
|
||
|
}
|
||
|
defer html_file.Close()
|
||
|
html_file.Write([]byte(html_content))
|
||
|
}
|
||
|
|
||
|
func tableForFiles(files []*types.File, includesPath bool) string {
|
||
|
html_content := ""
|
||
|
path_head := ""
|
||
|
if includesPath {
|
||
|
path_head = "<th>Path</th>"
|
||
|
}
|
||
|
|
||
|
html_content += fmt.Sprintf(`
|
||
|
<table class="pure-table pure-table-horizontal">
|
||
|
<thead>
|
||
|
<tr>
|
||
|
%s
|
||
|
<th>Title</th>
|
||
|
<th>Artist</th>
|
||
|
<th>Format</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
`, path_head)
|
||
|
|
||
|
isOdd := true
|
||
|
for _, file := range files {
|
||
|
tdClass := "pure-table-even"
|
||
|
if isOdd {
|
||
|
tdClass = "pure-table-odd"
|
||
|
}
|
||
|
|
||
|
data_title := html.EscapeString(file.Tags.Title)
|
||
|
data_artist := html.EscapeString(file.Tags.Artist)
|
||
|
data_extension := html.EscapeString(file.Extension)
|
||
|
|
||
|
path_data := ""
|
||
|
if includesPath {
|
||
|
data_path := html.EscapeString(file.PathFromSource)
|
||
|
path_data = fmt.Sprintf("<td>%s</td>", data_path)
|
||
|
}
|
||
|
|
||
|
html_content = html_content + fmt.Sprintf(`
|
||
|
<tr class="%s">
|
||
|
%s
|
||
|
<td>%s</td>
|
||
|
<td>%s</td>
|
||
|
<td>%s</td>
|
||
|
</tr>
|
||
|
`, tdClass, path_data, data_title, data_artist, data_extension)
|
||
|
isOdd = !isOdd
|
||
|
}
|
||
|
html_content = html_content + `
|
||
|
</tbody>
|
||
|
</table>
|
||
|
`
|
||
|
return html_content
|
||
|
}
|