initial commit, laying some groundwork

This commit is contained in:
Nico 2020-11-15 21:41:19 +00:00
commit af7a4dceb9
3 changed files with 177 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
go.sum
sitegenerator

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module tildegit.org/nihilazo/sitegenerator
go 1.15
require tildegit.org/nihilazo/go-gemtext v0.0.0-20201114202124-890be6eb3742

170
main.go Normal file
View File

@ -0,0 +1,170 @@
// A website generator tool
package main
import (
"tildegit.org/nihilazo/go-gemtext"
"encoding/json"
"fmt"
"io/ioutil"
"io"
"os"
"path/filepath"
)
// TODO replace these hardcoded paths with config
var root string = "/mnt/term/home/nico/website/wiki"
var geminiPrefix string = "gemini://breadpunk.club/~bagel"
var htmlPrefix string = "https://itwont.work"
var geminiOutputDir string = filepath.Join(root, "public_gemini")
var htmlOutputDir string = filepath.Join(root, "public_html")
var inputDir string = filepath.Join(root, "content")
var tagFile string = filepath.Join(root, "tags.json")
type filePathInfo struct {
Path string
New bool // True if the file is new
}
type pageInfo struct {
Path string
Title string
}
// RemoveIndex is a reslicing function.
func RemoveIndex(s []pageInfo, index int) []pageInfo {
return append(s[:index], s[index+1:]...)
}
var tagData map[string][]pageInfo = make(map[string][]pageInfo)
var files []filePathInfo // Files to process (those that are new or have been edited)
func copy(src, dst string) (int64, error) {
sourceFileStat, err := os.Stat(src)
if err != nil {
return 0, err
}
if !sourceFileStat.Mode().IsRegular() {
return 0, fmt.Errorf("%s is not a regular file", src)
}
source, err := os.Open(src)
if err != nil {
return 0, err
}
defer source.Close()
destination, err := os.Create(dst)
if err != nil {
return 0, err
}
defer destination.Close()
nBytes, err := io.Copy(destination, source)
return nBytes, err
}
func processPage(f filePathInfo) error {
// Delete any existing tag references to this file
if filepath.Ext(f.Path) == ".gmi" {
for i,d := range tagData { // For each tag in tagdata
if len(d) != 0 {
for j, _ := range d { // for each file in the tag
if files[j].Path == f.Path {
tagData[i] = RemoveIndex(d,j)
}
}
}
}
// Open the file and parse the gemtext
data, err := ioutil.ReadFile(f.Path)
if err != nil {
return err
}
parse, err := gemtext.ParsePage(string(data))
if err != nil {
return err
}
// TODO get tag data from files
// TODO render and write HTML and gemini
} else if filepath.Ext(f.Path) == ".tpl" {
// TODO handle template files
} else { // Non-gemtext files
rel, err := filepath.Rel(inputDir, f.Path)
if err != nil {
return err
}
copy(f.Path, filepath.Join(htmlOutputDir, rel))
copy(f.Path, filepath.Join(geminiOutputDir, rel))
}
return nil
}
// walkInputDir is called when walking the input directory, finds what files are new or have been edited, adds them to files
func walkInputDir(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() {
rel, err := filepath.Rel(inputDir, path)
if err != nil {
return err
}
outPath := filepath.Join(geminiOutputDir, rel)
outFileInfo, err := os.Stat(outPath)
if err != nil {
if os.IsNotExist(err) {
files = append(files, filePathInfo{Path: path, New: true})
} else {
return err
}
} else {
if info.ModTime().After(outFileInfo.ModTime()) {
files = append(files, filePathInfo{Path: path})
}
}
}
return nil
}
func main() {
loadingJson := true
if _, err := os.Stat(tagFile); err != nil {
if os.IsNotExist(err) {
loadingJson = false
fmt.Println("Not loading tags file, it doesn't exist yet")
} else {
fmt.Println(err)
return
}
}
tagFileData, err := ioutil.ReadFile(tagFile)
if loadingJson {
err = json.Unmarshal([]byte(tagFileData), &tagData)
if err != nil {
fmt.Println(err)
return
}
}
err = filepath.Walk(inputDir, walkInputDir) // walks the tree, creates the files slice and updates tagData
if err != nil {
fmt.Println(err)
return
}
for _, file := range files {
err := processPage(file) // Process all the updated files.
if err != nil {
fmt.Println(err)
return
}
}
// TODO tag pages
json, err := json.Marshal(tagData)
err = ioutil.WriteFile(tagFile, json, 0644)
if err != nil {
fmt.Println(err)
return
}
}