2015-01-26 03:39:16 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
2015-01-26 05:29:07 +00:00
|
|
|
"flag"
|
2015-01-26 03:39:16 +00:00
|
|
|
"bufio"
|
|
|
|
"strings"
|
|
|
|
"path/filepath"
|
|
|
|
"text/template"
|
|
|
|
)
|
|
|
|
|
2015-01-26 05:29:07 +00:00
|
|
|
var searchDir string
|
2015-01-26 05:03:27 +00:00
|
|
|
|
2015-01-26 03:39:16 +00:00
|
|
|
func main() {
|
|
|
|
fmt.Println("Starting...")
|
2015-01-26 05:29:07 +00:00
|
|
|
|
|
|
|
// Get any arguments
|
|
|
|
dirPtr := flag.String("d", "Code", "Directory to scan for each user.")
|
|
|
|
flag.Parse()
|
|
|
|
searchDir = *dirPtr
|
|
|
|
|
2015-01-26 03:39:16 +00:00
|
|
|
generate(findProjects())
|
|
|
|
}
|
|
|
|
|
|
|
|
type User struct {
|
|
|
|
Name string
|
|
|
|
Projects []Project
|
|
|
|
}
|
|
|
|
|
|
|
|
type Project struct {
|
|
|
|
Name string
|
|
|
|
Path string
|
|
|
|
}
|
|
|
|
|
|
|
|
func findProjects() map[string]User {
|
2015-01-26 05:03:27 +00:00
|
|
|
files, _ := filepath.Glob("/home/*/" + searchDir + "/*")
|
2015-01-26 03:39:16 +00:00
|
|
|
users := make(map[string]User)
|
|
|
|
|
|
|
|
for _, path := range files {
|
|
|
|
pparts := strings.Split(path, "/")
|
|
|
|
uname := pparts[2]
|
2015-01-26 04:08:10 +00:00
|
|
|
fname := filepath.Base(path)
|
|
|
|
|
2015-01-26 05:04:02 +00:00
|
|
|
// Exclude certain file names
|
|
|
|
if strings.HasPrefix(fname, ".") || strings.HasSuffix(fname, ".log") || strings.HasSuffix(fname, "~") {
|
2015-01-26 04:08:10 +00:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2015-01-26 05:05:53 +00:00
|
|
|
// Ensure file is other-readable
|
|
|
|
// TODO: just detect if we can actually read this, instead
|
|
|
|
info, _ := os.Stat(path)
|
|
|
|
if info.Mode() & 0004 == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2015-01-26 04:08:10 +00:00
|
|
|
proj := &Project{Name: fname, Path: strings.Replace(path, "/home/", "~", -1)}
|
2015-01-26 03:39:16 +00:00
|
|
|
u, exists := users[uname]
|
|
|
|
if !exists {
|
2015-01-26 05:03:27 +00:00
|
|
|
fmt.Printf("Found %s for ~%s.\n", searchDir, uname)
|
2015-01-26 03:39:16 +00:00
|
|
|
projs := []Project{*proj}
|
|
|
|
u = User{Name: uname, Projects: projs}
|
|
|
|
} else {
|
|
|
|
u.Projects = append(u.Projects, *proj)
|
|
|
|
}
|
|
|
|
users[uname] = u
|
|
|
|
}
|
|
|
|
return users
|
|
|
|
}
|
|
|
|
|
|
|
|
type Page struct {
|
2015-01-26 05:03:27 +00:00
|
|
|
FolderName string
|
2015-01-26 03:39:16 +00:00
|
|
|
Host string
|
|
|
|
Users map[string]User
|
|
|
|
Updated string
|
|
|
|
UpdatedForHumans string
|
|
|
|
}
|
|
|
|
|
2015-01-26 04:28:05 +00:00
|
|
|
func graphicalName(n string) string {
|
|
|
|
r := strings.NewReplacer("tilde", "~", "ctrl-c", "^C", "nuclear", "☢")
|
|
|
|
return r.Replace(n)
|
|
|
|
}
|
|
|
|
|
2015-01-26 03:39:16 +00:00
|
|
|
func generate(users map[string]User) {
|
|
|
|
fmt.Println("Generating page.")
|
|
|
|
|
2015-01-26 05:03:27 +00:00
|
|
|
f, err := os.Create(os.Getenv("HOME") + "/public_html/" + strings.ToLower(searchDir) + ".html")
|
2015-01-26 03:39:16 +00:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
w := bufio.NewWriter(f)
|
|
|
|
template, err := template.ParseFiles("templates/code.html")
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Extra page data
|
|
|
|
host, _ := os.Hostname()
|
2015-01-26 04:27:34 +00:00
|
|
|
curTime := time.Now().UTC()
|
|
|
|
updatedReadable := curTime.Format(time.RFC1123)
|
|
|
|
updated := curTime.Format(time.RFC3339)
|
2015-01-26 03:39:16 +00:00
|
|
|
|
|
|
|
// Generate the page
|
2015-01-26 05:03:27 +00:00
|
|
|
page := &Page{FolderName: searchDir, Host: graphicalName(host), UpdatedForHumans: updatedReadable, Updated: updated, Users: users}
|
2015-01-26 03:39:16 +00:00
|
|
|
template.ExecuteTemplate(w, "code", page)
|
|
|
|
w.Flush()
|
|
|
|
|
|
|
|
fmt.Println("DONE!")
|
|
|
|
}
|