@@ 1,6 1,8 @@
package main
import (
+ "encoding/gob"
+ "errors"
"fmt"
"html/template"
"image/png"
@@ 9,26 11,32 @@ import (
"net"
"net/http"
"net/url"
+ "os"
"path/filepath"
"strings"
+ "git.sr.ht/~mendelmaleh/download"
"git.sr.ht/~mendelmaleh/dummy"
"git.sr.ht/~mendelmaleh/freetype"
"git.sr.ht/~mendelmaleh/freetype/truetype"
+ "git.sr.ht/~mendelmaleh/gfonts"
+ "git.sr.ht/~mendelmaleh/match"
"github.com/pelletier/go-toml"
"golang.org/x/net/netutil"
)
type Config struct {
Dummy struct {
- Conns int
- Addr, Pattern, Fonts, Font string
+ Conns int
+ Addr, Pattern string
+ }
+ Fonts struct {
+ Path, Default, Matcher, Key string
}
}
-var fonts = make(map[string]*truetype.Font)
-
func main() {
+ // config
doc, err := ioutil.ReadFile("config.toml")
if err != nil {
log.Fatal(err)
@@ 40,42 48,109 @@ func main() {
log.Fatal(err)
}
- fontfiles, err := ioutil.ReadDir(config.Dummy.Fonts)
- if err != nil {
- log.Fatal(err)
- }
+ // get fonts
+ fonts := make(map[string]string) // font name to font file
+ matcher := new(match.Model)
- for _, file := range fontfiles {
- if filepath.Ext(file.Name()) != ".ttf" {
- continue
+ // if fonts weren't downloaded already
+ if _, err := os.Stat(config.Fonts.Path); errors.Is(err, os.ErrNotExist) {
+ // get available fonts
+ resp, err := gfonts.Get(config.Fonts.Key, gfonts.SortPopularity)
+ if err != nil {
+ log.Fatal(err)
}
- filebytes, err := ioutil.ReadFile(config.Dummy.Fonts + file.Name())
+ // downloader options
+ download.DefaultOptions.Concurrent = true
+
+ // download fonts
+ files := make(chan download.FileBuffer)
+ go func() {
+ if err := download.New().Chan(resp.Styles("regular"), files, nil); err != nil {
+ log.Fatal(err)
+ }
+ }()
+
+ // register and save fonts
+ var fontNames []string
+ for f := range files {
+ font, err := freetype.ParseFont(f.Buffer.Bytes())
+ if err != nil {
+ // TODO: except ttf version errors
+ log.Printf("Error loading %s: %v", f.Path, err)
+ continue
+ }
+
+ path := filepath.Join(config.Fonts.Path, f.Path)
+ if err := os.MkdirAll(path, 0744); err != nil {
+ log.Fatal(err)
+ }
+
+ path = filepath.Join(path, f.Name)
+ if err := ioutil.WriteFile(path, f.Buffer.Bytes(), 0644); err != nil {
+ log.Fatal(err)
+ }
+
+ name := font.Name(truetype.NameIDFontFamily)
+ fonts[name] = path
+ fontNames = append(fontNames, name)
+ }
+
+ // generate model
+ matcher = match.New(fontNames, 2, 3, 4, 5)
+
+ // save map and matcher
+ file, err := os.Create(config.Fonts.Matcher)
if err != nil {
- log.Println(err) // don't exit if one font doesn't work
- continue
+ log.Fatal(err)
+ }
+
+ gb := gob.NewEncoder(file)
+
+ if err := gb.Encode(fonts); err != nil {
+ log.Fatal(err)
+ }
+ if err := gb.Encode(matcher); err != nil {
+ log.Fatal(err)
}
- font, err := freetype.ParseFont(filebytes)
+ file.Close()
+ log.Println("Done downloading fonts")
+ } else {
+ file, err := os.Open(config.Fonts.Matcher)
if err != nil {
- log.Println(err)
- continue
+ log.Fatal(err)
}
- // fmt.Println(font.Name(truetype.NameIDFontFamily))
- fonts[font.Name(truetype.NameIDFontFamily)] = font
- }
+ gb := gob.NewDecoder(file)
- if len(fonts) < 1 {
- log.Fatal("No fonts loaded")
+ if err := gb.Decode(&fonts); err != nil {
+ log.Fatal(err)
+ }
+ if err := gb.Decode(matcher); err != nil {
+ log.Fatal(err)
+ }
+
+ file.Close()
+ log.Println("Done loading from gob file")
}
- // set default font after it's loaded
- font, ok := fonts[config.Dummy.Font]
+ // set default font and ensure it can be loaded
+ file, ok := fonts[config.Fonts.Default]
if !ok {
log.Fatal("Default font not found")
}
+ bits, err := ioutil.ReadFile(file)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ font, err := freetype.ParseFont(bits)
+ if err != nil {
+ log.Fatal(err)
+ }
+
dopt := dummy.DefaultOptions
dopt.Font = font
@@ 93,25 168,25 @@ func main() {
http.HandleFunc(config.Dummy.Pattern,
func(w http.ResponseWriter, r *http.Request) {
- Dummy(w, r, Options{dopt.Copy()})
+ Dummy(w, r, Options{dopt.Copy(), fonts, matcher})
},
)
http.HandleFunc(config.Dummy.Pattern+"tar/",
func(w http.ResponseWriter, r *http.Request) {
- Tar(w, r, Options{dopt.Copy()})
+ Tar(w, r, Options{dopt.Copy(), fonts, matcher})
},
)
http.HandleFunc(config.Dummy.Pattern+"zip/",
func(w http.ResponseWriter, r *http.Request) {
- Zip(w, r, Options{dopt.Copy()})
+ Zip(w, r, Options{dopt.Copy(), fonts, matcher})
},
)
http.HandleFunc(config.Dummy.Pattern+"web/",
func(w http.ResponseWriter, r *http.Request) {
- Web(w, r, Options{dopt.Copy()}, config, tmpl)
+ Web(w, r, Options{dopt.Copy(), fonts, matcher}, config, tmpl)
},
)