|
@ -42,6 +42,8 @@ var port = ":3000" |
|
|
// exiftooInstalled tells us if the exiftool binary is installed or not.
|
|
|
// exiftooInstalled tells us if the exiftool binary is installed or not.
|
|
|
var exiftoolInstalled = true |
|
|
var exiftoolInstalled = true |
|
|
|
|
|
|
|
|
|
|
|
var logStripMsg = "...stripped from logs for brevity..." |
|
|
|
|
|
|
|
|
// generatedInDistribusi is an internal marker to help recognise when
|
|
|
// generatedInDistribusi is an internal marker to help recognise when
|
|
|
// distribusi-go has generated files.
|
|
|
// distribusi-go has generated files.
|
|
|
var generatedInDistribusi = "<meta name='generator' content='distribusi-go' />" |
|
|
var generatedInDistribusi = "<meta name='generator' content='distribusi-go' />" |
|
@ -114,24 +116,41 @@ type htmlTag = string |
|
|
// htmlTags is a fileType/subType to htmlTag mapping for HTML generation purposes.
|
|
|
// htmlTags is a fileType/subType to htmlTag mapping for HTML generation purposes.
|
|
|
var htmlTags = map[fileType]map[subType]htmlTag{ |
|
|
var htmlTags = map[fileType]map[subType]htmlTag{ |
|
|
"text": { |
|
|
"text": { |
|
|
"html": "<section id=\"%s\">%s</section>", |
|
|
"html": `<section id="%s">%s</section>`, |
|
|
"generic": "<pre>%s</pre>", |
|
|
"generic": `<pre>%s</pre>`, |
|
|
}, |
|
|
}, |
|
|
"image": { |
|
|
"image": { |
|
|
"thumbnail": "<figure><a href=\"%s\"><img class='thumbnail' src='data:image/jpg;base64,%s'></a><figcaption>%s</figcaption></figure>", |
|
|
"thumbnail": trimAllNewlines(`<figure> |
|
|
"generic": "<figure><a href=\"%s\"><img class='%s' loading='lazy' src=\"%s\"/></a><figcaption>%s</figcaption></figure>", |
|
|
<a href="%s"> |
|
|
|
|
|
<img class="thumbnail" src="data:image/jpg;base64,%s"> |
|
|
|
|
|
</a> |
|
|
|
|
|
<figcaption>%s</figcaption> |
|
|
|
|
|
</figure>`), |
|
|
|
|
|
"generic": trimAllNewlines(`<figure> |
|
|
|
|
|
<a href="%s"> |
|
|
|
|
|
<img class=%s loading="lazy" src="%s"/> |
|
|
|
|
|
</a> |
|
|
|
|
|
<figcaption>%s</figcaption> |
|
|
|
|
|
</figure>`), |
|
|
}, |
|
|
}, |
|
|
"application": { |
|
|
"application": { |
|
|
"pdf": "<object data=\"%s\" class='pdf' type='application/pdf'><embed src=\"%s\" type='application/pdf'/></object>", |
|
|
"pdf": trimAllNewlines(`<object data="%s" class="pdf" type="application/pdf"> |
|
|
|
|
|
<embed src="%s" type="application/pdf"/> |
|
|
|
|
|
</object>`), |
|
|
}, |
|
|
}, |
|
|
"audio": { |
|
|
"audio": { |
|
|
"generic": "<audio controls> <source src=\"%s\" type='audio/%s'> Your browser does not support the audio element. </audio>", |
|
|
"generic": trimAllNewlines(`<audio controls> |
|
|
|
|
|
<source src="%s" type="audio/%s"> |
|
|
|
|
|
Your browser does not support the audio element. |
|
|
|
|
|
</audio>`), |
|
|
}, |
|
|
}, |
|
|
"video": { |
|
|
"video": { |
|
|
"generic": "<video controls> <source src=\"%s\" type='video/%s'> </video>", |
|
|
"generic": trimAllNewlines(`<video controls> |
|
|
|
|
|
<source src="%s" type="video/%s"> |
|
|
|
|
|
</video>`), |
|
|
}, |
|
|
}, |
|
|
"unknown": { |
|
|
"unknown": { |
|
|
"generic": "<a class='%s' href=\"%s\">%s</a>", |
|
|
"generic": `<a class="%s" href="%s">%s</a>`, |
|
|
}, |
|
|
}, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -283,7 +302,7 @@ Example: |
|
|
|
|
|
|
|
|
if c.Bool("serve") { |
|
|
if c.Bool("serve") { |
|
|
go func() { |
|
|
go func() { |
|
|
logrus.Debug("starting up web server") |
|
|
logrus.Debug("attempting to start up the web server") |
|
|
|
|
|
|
|
|
if err := serveHTTP(root); err != nil { |
|
|
if err := serveHTTP(root); err != nil { |
|
|
ch <- err |
|
|
ch <- err |
|
@ -423,7 +442,7 @@ func distribusify(c *cli.Context, root string, ignore []string) error { |
|
|
continue |
|
|
continue |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
unknown, href, err := getHref(c, file, mtype) |
|
|
unknown, href, err := mkHref(c, file, mtype) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
logrus.Debugf("failed to generate href for %s", file) |
|
|
logrus.Debugf("failed to generate href for %s", file) |
|
|
continue |
|
|
continue |
|
@ -570,11 +589,18 @@ func trimFinalNewline(contents []byte) string { |
|
|
return strings.TrimSuffix(string(contents), "\n") |
|
|
return strings.TrimSuffix(string(contents), "\n") |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// getHref figures out which href tag corresponds to which file by navigating
|
|
|
// trimAllNewlines removes all new lines.
|
|
|
|
|
|
func trimAllNewlines(contents string) string { |
|
|
|
|
|
return strings.ReplaceAll(string(contents), "\n", "") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// mkHref figures out which href tag corresponds to which file by navigating
|
|
|
// the mimetype. If a type of file is unknown, this is signalled via the bool
|
|
|
// the mimetype. If a type of file is unknown, this is signalled via the bool
|
|
|
// return value.
|
|
|
// return value.
|
|
|
func getHref(c *cli.Context, fpath string, mtype string) (bool, string, error) { |
|
|
func mkHref(c *cli.Context, fpath string, mtype string) (bool, string, error) { |
|
|
var href string |
|
|
var href string |
|
|
|
|
|
var hrefTemplate string |
|
|
|
|
|
var strippedDebugOutput string |
|
|
var unknown bool |
|
|
var unknown bool |
|
|
|
|
|
|
|
|
fname := filepath.Base(fpath) |
|
|
fname := filepath.Base(fpath) |
|
@ -587,9 +613,13 @@ func getHref(c *cli.Context, fpath string, mtype string) (bool, string, error) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if stype == "html" { |
|
|
if stype == "html" { |
|
|
href = fmt.Sprintf(htmlTags[ftype][stype], fname, trimFinalNewline(fcontents)) |
|
|
hrefTemplate = htmlTags[ftype][stype] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, trimFinalNewline(fcontents)) |
|
|
|
|
|
strippedDebugOutput = fmt.Sprintf(hrefTemplate, fname, logStripMsg) |
|
|
} else { |
|
|
} else { |
|
|
href = fmt.Sprintf(htmlTags[ftype]["generic"], trimFinalNewline(fcontents)) |
|
|
hrefTemplate = htmlTags[ftype]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, trimFinalNewline(fcontents)) |
|
|
|
|
|
strippedDebugOutput = fmt.Sprintf(hrefTemplate, logStripMsg) |
|
|
} |
|
|
} |
|
|
} else if ftype == "image" { |
|
|
} else if ftype == "image" { |
|
|
caption, err := getCaption(c, fpath) |
|
|
caption, err := getCaption(c, fpath) |
|
@ -598,33 +628,46 @@ func getHref(c *cli.Context, fpath string, mtype string) (bool, string, error) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if stype == "gif" { |
|
|
if stype == "gif" { |
|
|
href = fmt.Sprintf(htmlTags[ftype]["generic"], fname, stype, fname, caption) |
|
|
hrefTemplate = htmlTags[ftype]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, stype, fname, caption) |
|
|
} else { |
|
|
} else { |
|
|
thumb, err := genThumb(c, fpath, caption) |
|
|
thumb, err := genThumb(c, fpath, caption) |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
|
|
|
hrefTemplate = htmlTags[ftype]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, stype, fname, caption) |
|
|
logrus.Debugf("failed to generate thumbnail for %s, showing original image", fpath) |
|
|
logrus.Debugf("failed to generate thumbnail for %s, showing original image", fpath) |
|
|
href = fmt.Sprintf(htmlTags[ftype]["generic"], fname, stype, fname, caption) |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
href = fmt.Sprintf(htmlTags[ftype]["thumbnail"], fname, thumb, caption) |
|
|
hrefTemplate = htmlTags[ftype]["thumbnail"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, thumb, caption) |
|
|
|
|
|
strippedDebugOutput = fmt.Sprintf(hrefTemplate, fname, logStripMsg, caption) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} else if ftype == "application" { |
|
|
} else if ftype == "application" { |
|
|
if stype == "pdf" { |
|
|
if stype == "pdf" { |
|
|
href = fmt.Sprintf(htmlTags[ftype][stype], fname, fname) |
|
|
hrefTemplate = htmlTags[ftype][stype] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, fname) |
|
|
} else { |
|
|
} else { |
|
|
unknown = true |
|
|
unknown = true |
|
|
href = fmt.Sprintf(htmlTags["unknown"]["generic"], stype, fname, fname) |
|
|
hrefTemplate = htmlTags["unknown"]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, stype, fname, fname) |
|
|
} |
|
|
} |
|
|
} else if ftype == "audio" { |
|
|
} else if ftype == "audio" { |
|
|
href = fmt.Sprintf(htmlTags[ftype]["generic"], fname, stype) |
|
|
hrefTemplate = htmlTags[ftype]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, stype) |
|
|
} else if ftype == "video" { |
|
|
} else if ftype == "video" { |
|
|
href = fmt.Sprintf(htmlTags[ftype]["generic"], fname, stype) |
|
|
hrefTemplate = htmlTags[ftype]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, fname, stype) |
|
|
} else { |
|
|
} else { |
|
|
unknown = true |
|
|
unknown = true |
|
|
href = fmt.Sprintf(htmlTags["unknown"]["generic"], stype, fname, fname) |
|
|
hrefTemplate = htmlTags["unknown"]["generic"] |
|
|
|
|
|
href = fmt.Sprintf(hrefTemplate, stype, fname, fname) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
logrus.Debugf("generated href for %s: %s", fname, href) |
|
|
if strippedDebugOutput != "" { |
|
|
|
|
|
logrus.Debugf("%s was wrapped in: %s", fname, strippedDebugOutput) |
|
|
|
|
|
} else { |
|
|
|
|
|
logrus.Debugf("%s was wrapped in: %s", fname, href) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return unknown, href, nil |
|
|
return unknown, href, nil |
|
|
} |
|
|
} |
|
@ -632,31 +675,43 @@ func getHref(c *cli.Context, fpath string, mtype string) (bool, string, error) { |
|
|
// mkDiv cosntructs a HTML div for inclusion in the generated index.html.
|
|
|
// mkDiv cosntructs a HTML div for inclusion in the generated index.html.
|
|
|
func mkDiv(c *cli.Context, mtype string, href, fname string, unknown bool) (string, error) { |
|
|
func mkDiv(c *cli.Context, mtype string, href, fname string, unknown bool) (string, error) { |
|
|
var div string |
|
|
var div string |
|
|
|
|
|
var divTemplate string |
|
|
|
|
|
var strippedDebugOutput string |
|
|
|
|
|
|
|
|
filename := fmt.Sprintf("<span class='filename'>%s</span>", fname) |
|
|
filename := fmt.Sprintf("<span class='filename'>%s</span>", fname) |
|
|
|
|
|
|
|
|
ftype, stype := parseMtype(mtype) |
|
|
ftype, stype := parseMtype(mtype) |
|
|
|
|
|
|
|
|
if ftype == "text" { |
|
|
if ftype == "text" { |
|
|
divTag := "<div id=\"%s\" class='%s'>%s%s</div>" |
|
|
divTemplate = "<div id=\"%s\" class='%s'>%s%s</div>" |
|
|
div = fmt.Sprintf(divTag, fname, ftype, href, filename) |
|
|
div = fmt.Sprintf(divTemplate, fname, ftype, href, filename) |
|
|
|
|
|
strippedDebugOutput = fmt.Sprintf(divTemplate, fname, ftype, logStripMsg, filename) |
|
|
} else if ftype == "os" { |
|
|
} else if ftype == "os" { |
|
|
divTag := "<div id=\"%s\" class='x-%s'>%s</div>" |
|
|
if stype == "directory" { |
|
|
div = fmt.Sprintf(divTag, fname, stype, href) |
|
|
divTemplate = "<div id=\"%s\" class='x-%s'>%s</div>" |
|
|
|
|
|
div = fmt.Sprintf(divTemplate, fname, stype, href) |
|
|
|
|
|
} else { |
|
|
|
|
|
// don't include filename since link already has it
|
|
|
|
|
|
divTemplate = "<div id=\"%s\" class='%s'>%s</div>" |
|
|
|
|
|
div = fmt.Sprintf(divTemplate, fname, ftype, href) |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
if unknown { |
|
|
if unknown { |
|
|
// we really don't know what this is, so the filename is the href and we
|
|
|
// don't include filename since link already has it
|
|
|
// avoid adding it again
|
|
|
divTemplate = "<div id=\"%s\" class='%s'>%s</div>" |
|
|
divTag := "<div id=\"%s\" class='%s'>%s</div>" |
|
|
div = fmt.Sprintf(divTemplate, fname, ftype, href) |
|
|
div = fmt.Sprintf(divTag, fname, ftype, href) |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
// images, videos, etc. still get a filename
|
|
|
divTemplate = "<div id=\"%s\" class='%s'>%s%s</div>" |
|
|
divTag := "<div id=\"%s\" class='%s'>%s%s</div>" |
|
|
div = fmt.Sprintf(divTemplate, fname, ftype, href, filename) |
|
|
div = fmt.Sprintf(divTag, fname, ftype, href, filename) |
|
|
strippedDebugOutput = fmt.Sprintf(divTemplate, fname, ftype, logStripMsg, filename) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
logrus.Debugf("generated div wrapper for %s: %s", fname, div) |
|
|
if strippedDebugOutput != "" { |
|
|
|
|
|
logrus.Debugf("%s was wrapped in: %s", fname, strippedDebugOutput) |
|
|
|
|
|
} else { |
|
|
|
|
|
logrus.Debugf("%s was wrapped in: %s", fname, div) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return div, nil |
|
|
return div, nil |
|
|
} |
|
|
} |
|
|