diff --git a/README.md b/README.md
index a4ccf75..2f25adc 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,6 @@ indir [--host address] [--port port] [--root http_root] directory
```
## to-do:
-- [ ] use templates instead of hard-coded HTML (i was lazy)
+- [x] use templates instead of hard-coded HTML (i was lazy)
- [ ] directory header from readme file
- [ ] directory stylesheet overrides
diff --git a/main.go b/main.go
index c9673a5..60bb278 100755
--- a/main.go
+++ b/main.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "html/template"
"io/fs"
"mime"
"net/http"
@@ -13,6 +14,22 @@ import (
"time"
)
+type (
+ Directory struct {
+ Name string
+ Root bool
+ Files []*File
+ }
+
+ File struct {
+ Name string
+ URI string
+ IsDir bool
+ Size string
+ ModifiedDate string
+ }
+)
+
func main() {
if len(os.Args) < 2 { printHelp() }
@@ -72,47 +89,12 @@ func main() {
".DS_Store",
}
- stylesheet := `
- html {
- background: #101010;
- color: #f0f0f0;
- font-family: 'Monaspace Argon', monospace;
+ dirTemplate, err := template.ParseGlob("./templates/dir.html")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "fatal: failed to parse directory template: %v\n", err)
+ os.Exit(1)
}
- body {
- width: min(calc(100% - 1em), 1000px);
- margin: 0 auto;
- }
-
- table {
- width: 100%;
- border-collapse: collapse;
- }
-
- tr:hover {
- background-color: #80808040;
- }
-
- th {
- text-align: left;
- }
-
- td {
- padding: .2em 0;
- }
-
- a {
- color: #b7fd49;
- }
- a:hover {
- color: white;
- }
-
- footer {
- padding: 1em 0;
- }
- `
-
fmt.Printf("Now hosting \"%s\" at http://%s:%d", filesDir, host, port)
if root != "/" { fmt.Printf("%s", root) }
fmt.Println(".")
@@ -124,25 +106,6 @@ func main() {
}
isRoot := r.URL.Path == root
- responseText := fmt.Sprintf(`
-
-
- Listing %s
-
-
-
-
-
- `, r.URL.Path, stylesheet)
-
- responseText += fmt.Sprintf("Files in %s
\n
", r.URL.Path)
-
- responseText += "\n"
- responseText += "\nName | \nSize | \nModified | \n
\n"
- if !isRoot {
- responseText += "../ | — | — |
\n"
- }
-
filepath := path.Join(filesDir, strings.TrimPrefix(r.URL.Path, root))
info, err := os.Stat(filepath)
if err != nil {
@@ -150,13 +113,13 @@ func main() {
return
}
- if !info.IsDir() && strings.HasSuffix(r.URL.Path, "/") {
- http.Redirect(w, r, strings.TrimSuffix(r.URL.Path, "/"), http.StatusFound)
- } else if info.IsDir() && !strings.HasSuffix(r.URL.Path, "/") {
- http.Redirect(w, r, r.URL.Path + "/", http.StatusFound)
- }
-
+ // downloading file
if !info.IsDir() {
+ if strings.HasSuffix(r.URL.Path, "/") {
+ http.Redirect(w, r, strings.TrimSuffix(r.URL.Path, "/"), http.StatusFound)
+ return
+ }
+
file, err := os.Open(filepath)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
@@ -186,6 +149,17 @@ func main() {
return
}
+ if !strings.HasSuffix(r.URL.Path, "/") {
+ http.Redirect(w, r, r.URL.Path + "/", http.StatusFound)
+ return
+ }
+
+ data := Directory{
+ Root: isRoot,
+ Name: r.URL.Path,
+ Files: []*File{},
+ }
+
fsDir := os.DirFS(filepath)
directories, err := fs.ReadDir(fsDir, ".")
for _, dir := range directories {
@@ -202,9 +176,7 @@ func main() {
uri = r.URL.Path + name
}
- responseText += fmt.Sprintf(
- "%s | ", uri, name)
-
+ sizeStr := "—"
if !info.IsDir() {
size := info.Size()
sizeDenom := "B"
@@ -220,28 +192,27 @@ func main() {
size /= 1000
sizeDenom = "GB"
}
- responseText += fmt.Sprintf("%d%s | ", info.Size(), size, sizeDenom)
- } else {
- responseText += "— | "
+ sizeStr = fmt.Sprintf("%d%s", size, sizeDenom)
}
dateStr := info.ModTime().Format("02-Jan-2006 15:04")
- responseText += fmt.Sprintf("%s | ", dateStr)
- responseText += "
\n"
+ data.Files = append(data.Files, &File{
+ Name: name,
+ URI: uri,
+ IsDir: info.IsDir(),
+ Size: sizeStr,
+ ModifiedDate: dateStr,
+ })
}
if err != nil {
fmt.Fprintf(os.Stderr, "failed to open directory: %v\n", err)
}
- responseText += "
\n"
-
- responseText += "
\n\n"
- responseText += "\n"
- responseText += "\n\n"
w.Header().Set("Content-Type", "text/html")
- w.WriteHeader(200)
- w.Write([]byte(responseText))
+ w.Header().Set("Server", "indir")
+ w.WriteHeader(http.StatusOK)
+ dirTemplate.Execute(w, data)
})))
}
diff --git a/templates/dir.html b/templates/dir.html
new file mode 100644
index 0000000..7d0ac2b
--- /dev/null
+++ b/templates/dir.html
@@ -0,0 +1,91 @@
+
+
+
+
+
+ Files in {{.Name}}
+
+
+
+
+ Files in {{.Name}}
+
+
+
+ Name |
+ Size |
+ Modified |
+
+ {{if not .Root}}
+
+ ../ |
+ — |
+ — |
+
+ {{end}}
+ {{range .Files}}
+
+ {{.Name}} |
+ {{if .IsDir}}—{{else}}{{.Size}}{{end}} |
+ {{.ModifiedDate}} |
+
+ {{end}}
+
+
+
+
+
+