all repos — flounder @ 1c780cf98187163d3149ff1a98f04c9657bd69e5

A small site builder for the Gemini protocol

main.go (view raw)

  1package main
  2
  3import (
  4	"database/sql"
  5	"flag"
  6	"fmt"
  7	"io/ioutil"
  8	"log"
  9	"os"
 10	"path"
 11	"path/filepath"
 12	"sort"
 13	"strings"
 14	"sync"
 15	"time"
 16)
 17
 18var c Config // global var to hold static configuration
 19
 20type File struct {
 21	Creator     string
 22	Name        string
 23	UpdatedTime time.Time
 24}
 25
 26func getUsers() ([]string, error) {
 27	rows, err := DB.Query(`SELECT username from user`)
 28	if err != nil {
 29		return nil, err
 30	}
 31	var users []string
 32	for rows.Next() {
 33		var user string
 34		err = rows.Scan(&user)
 35		if err != nil {
 36			return nil, err
 37		}
 38		users = append(users, user)
 39	}
 40	return users, nil
 41}
 42
 43/// Perform some checks to make sure the file is OK
 44func checkIfValidFile(filename string, fileBytes []byte) error {
 45	ext := strings.ToLower(path.Ext(filename))
 46	found := false
 47	for _, mimetype := range c.OkExtensions {
 48		if ext == mimetype {
 49			found = true
 50		}
 51	}
 52	if !found {
 53		return fmt.Errorf("Invalid file extension: %s", ext)
 54	}
 55	if len(fileBytes) > c.MaxFileSize {
 56		return fmt.Errorf("File too large. File was %s bytes, Max file size is %s", len(fileBytes), c.MaxFileSize)
 57	}
 58	return nil
 59}
 60
 61func getIndexFiles() ([]*File, error) { // cache this function
 62	result := []*File{}
 63	err := filepath.Walk(c.FilesDirectory, func(path string, info os.FileInfo, err error) error {
 64		if err != nil {
 65			log.Printf("Failure accessing a path %q: %v\n", path, err)
 66			return err // think about
 67		}
 68		// make this do what it should
 69		result = append(result, &File{
 70			Name:        info.Name(),
 71			Creator:     "alex",
 72			UpdatedTime: info.ModTime(),
 73		})
 74		return nil
 75	})
 76	if err != nil {
 77		return nil, err
 78	}
 79	// sort
 80	// truncate
 81	sort.Slice(result, func(i, j int) bool {
 82		return result[i].UpdatedTime.Before(result[j].UpdatedTime)
 83	})
 84	if len(result) > 50 {
 85		result = result[:50]
 86	}
 87	return result, nil
 88} // todo clean up paths
 89
 90func getUserFiles(user string) ([]*File, error) {
 91	result := []*File{}
 92	files, err := ioutil.ReadDir(path.Join(c.FilesDirectory, user))
 93	if err != nil {
 94		return nil, err
 95	}
 96	for _, file := range files {
 97		result = append(result, &File{
 98			Name:        file.Name(),
 99			Creator:     user,
100			UpdatedTime: file.ModTime(),
101		})
102	}
103	return result, nil
104}
105
106func main() {
107	configPath := flag.String("c", "flounder.toml", "path to config file")
108	var err error
109	c, err = getConfig(*configPath)
110	if err != nil {
111		log.Fatal(err)
112	}
113
114	DB, err = sql.Open("sqlite3", c.DBFile)
115	if err != nil {
116		log.Fatal(err)
117	}
118
119	wg := new(sync.WaitGroup)
120	wg.Add(2)
121	go func() {
122		runHTTPServer()
123		wg.Done()
124	}()
125	go func() {
126		runGeminiServer()
127		wg.Done()
128	}()
129	wg.Wait()
130}