WIP restructure to a single entry point
This commit is contained in:
parent
17973144c5
commit
fc03a3ca39
19
cmd/cutup.go
Normal file
19
cmd/cutup.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/vilmibm/trunkless/cutup"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(cutupCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var cutupCmd = &cobra.Command{
|
||||||
|
Use: "cutup",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
cutup.Cutup(os.Stdin)
|
||||||
|
},
|
||||||
|
}
|
20
cmd/ingest.go
Normal file
20
cmd/ingest.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/vilmibm/trunkless/ingest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(ingestCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var ingestCmd = &cobra.Command{
|
||||||
|
Use: "ingest",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return ingest.Ingest(strings.Join(args[1:], " "), os.Stdin)
|
||||||
|
},
|
||||||
|
}
|
19
cmd/root.go
Normal file
19
cmd/root.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
var rootCmd = &cobra.Command{
|
||||||
|
Use: "trunkless",
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execute() {
|
||||||
|
if err := rootCmd.Execute(); err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, err.Error())
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
17
cmd/serve.go
Normal file
17
cmd/serve.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/vilmibm/trunkless/web"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(serveCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
var serveCmd = &cobra.Command{
|
||||||
|
Use: "serve",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return web.Serve()
|
||||||
|
},
|
||||||
|
}
|
175
cutup/cutup.go
Normal file
175
cutup/cutup.go
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
package cutup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func conjPrep(phraseBuff []byte, r rune) int {
|
||||||
|
if r != ' ' {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
suffices := []string{"from", "at", "but", "however", "yet", "though", "and", "to", "on", "or"}
|
||||||
|
maxLen := 8 // TODO magic number based on longest suffix
|
||||||
|
offset := len(phraseBuff) - maxLen
|
||||||
|
if offset < 0 {
|
||||||
|
offset = 0
|
||||||
|
}
|
||||||
|
end := string(phraseBuff[offset:])
|
||||||
|
for _, s := range suffices {
|
||||||
|
if strings.HasSuffix(end, " "+s) {
|
||||||
|
return len(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func Cutup(ins io.Reader) {
|
||||||
|
phraseMarkers := map[rune]bool{
|
||||||
|
';': true,
|
||||||
|
',': true,
|
||||||
|
':': true,
|
||||||
|
'.': true,
|
||||||
|
'?': true,
|
||||||
|
'!': true,
|
||||||
|
//'(': true,
|
||||||
|
')': true,
|
||||||
|
//'{': true,
|
||||||
|
'}': true,
|
||||||
|
//'[': true,
|
||||||
|
']': true,
|
||||||
|
//'\'': true,
|
||||||
|
//'"': true,
|
||||||
|
//'“': true,
|
||||||
|
'”': true,
|
||||||
|
'=': true,
|
||||||
|
'`': true,
|
||||||
|
'-': true,
|
||||||
|
'|': true,
|
||||||
|
'>': true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// I want to experiment with treating prepositions and conjunctions as phrase
|
||||||
|
// markers.
|
||||||
|
|
||||||
|
// to do this i would need to check the phraseBuff when I check phraseMarkers and then split accordingly
|
||||||
|
|
||||||
|
s := bufio.NewScanner(ins)
|
||||||
|
phraseBuff := []byte{}
|
||||||
|
printed := false
|
||||||
|
for s.Scan() {
|
||||||
|
text := strings.TrimSpace(s.Text())
|
||||||
|
for i, r := range text {
|
||||||
|
if ok := phraseMarkers[r]; ok {
|
||||||
|
if len(phraseBuff) >= 10 {
|
||||||
|
cleaned := clean(phraseBuff)
|
||||||
|
if len(cleaned) > 0 {
|
||||||
|
fmt.Println(cleaned)
|
||||||
|
printed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !printed {
|
||||||
|
//fmt.Fprintf(os.Stderr, "SKIP: %s\n", string(phraseBuff))
|
||||||
|
}
|
||||||
|
printed = false
|
||||||
|
phraseBuff = []byte{}
|
||||||
|
} else if v := conjPrep(phraseBuff, r); v > 0 {
|
||||||
|
// TODO erase or keep? starting with erase.
|
||||||
|
phraseBuff = phraseBuff[0 : len(phraseBuff)-v]
|
||||||
|
// TODO this pasta is copied
|
||||||
|
if len(phraseBuff) >= 10 {
|
||||||
|
cleaned := clean(phraseBuff)
|
||||||
|
if len(cleaned) > 0 {
|
||||||
|
fmt.Println(cleaned)
|
||||||
|
printed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !printed {
|
||||||
|
//fmt.Fprintf(os.Stderr, "SKIP: %s\n", string(phraseBuff))
|
||||||
|
}
|
||||||
|
printed = false
|
||||||
|
phraseBuff = []byte{}
|
||||||
|
} else {
|
||||||
|
asStr := string(phraseBuff)
|
||||||
|
if r == ' ' && strings.HasSuffix(asStr, " ") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if i == 0 && len(phraseBuff) > 0 && phraseBuff[len(phraseBuff)-1] != ' ' && r != ' ' {
|
||||||
|
phraseBuff = append(phraseBuff, byte(' '))
|
||||||
|
}
|
||||||
|
phraseBuff = append(phraseBuff, byte(r))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isAlpha(r rune) bool {
|
||||||
|
alphaChars := map[rune]bool{
|
||||||
|
'a': true,
|
||||||
|
'b': true,
|
||||||
|
'c': true,
|
||||||
|
'd': true,
|
||||||
|
'e': true,
|
||||||
|
'f': true,
|
||||||
|
'g': true,
|
||||||
|
'h': true,
|
||||||
|
'i': true,
|
||||||
|
'j': true,
|
||||||
|
'k': true,
|
||||||
|
'l': true,
|
||||||
|
'm': true,
|
||||||
|
'n': true,
|
||||||
|
'o': true,
|
||||||
|
'p': true,
|
||||||
|
'q': true,
|
||||||
|
'r': true,
|
||||||
|
's': true,
|
||||||
|
't': true,
|
||||||
|
'u': true,
|
||||||
|
'v': true,
|
||||||
|
'w': true,
|
||||||
|
'x': true,
|
||||||
|
'y': true,
|
||||||
|
'z': true,
|
||||||
|
}
|
||||||
|
lookup := strings.ToLower(string(r))
|
||||||
|
return alphaChars[rune(lookup[0])]
|
||||||
|
}
|
||||||
|
|
||||||
|
func alphaPercent(s string) float64 {
|
||||||
|
total := 0.0
|
||||||
|
alpha := 0.0
|
||||||
|
|
||||||
|
for _, r := range s {
|
||||||
|
total++
|
||||||
|
if isAlpha(r) {
|
||||||
|
alpha++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 100 * (alpha / total)
|
||||||
|
}
|
||||||
|
|
||||||
|
func clean(bs []byte) string {
|
||||||
|
s := string(bs)
|
||||||
|
s = strings.ReplaceAll(s, "’", "'")
|
||||||
|
s = strings.ReplaceAll(s, "\"", "")
|
||||||
|
s = strings.ReplaceAll(s, "(", "")
|
||||||
|
s = strings.ReplaceAll(s, "[", "")
|
||||||
|
s = strings.ReplaceAll(s, "{", "")
|
||||||
|
s = strings.ReplaceAll(s, "<", "")
|
||||||
|
s = strings.ReplaceAll(s, "_", "")
|
||||||
|
s = strings.ReplaceAll(s, "*", "")
|
||||||
|
s = strings.TrimLeft(s, "'\"")
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
s = strings.ToLower(s)
|
||||||
|
|
||||||
|
if alphaPercent(s) < 50.0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
21
db/db.go
Normal file
21
db/db.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dsn = "phrase.db?cache=shared&mode=r"
|
||||||
|
MaxID = 467014991
|
||||||
|
)
|
||||||
|
|
||||||
|
func Connect() (*sql.DB, error) {
|
||||||
|
db, err := sql.Open("sqlite3", dsn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return db, nil
|
||||||
|
}
|
3
go.mod
3
go.mod
@ -12,6 +12,7 @@ require (
|
|||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
github.com/go-playground/validator/v10 v10.14.0 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||||
github.com/leodido/go-urn v1.2.4 // indirect
|
github.com/leodido/go-urn v1.2.4 // indirect
|
||||||
@ -20,6 +21,8 @@ require (
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||||
|
github.com/spf13/cobra v1.8.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
|
8
go.sum
8
go.sum
@ -4,6 +4,7 @@ github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZX
|
|||||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||||
@ -23,6 +24,8 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
|
|||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||||
@ -42,6 +45,11 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
|
|||||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||||
|
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||||
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
package main
|
package ingest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"io"
|
||||||
"strings"
|
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
)
|
)
|
||||||
@ -29,10 +27,7 @@ func createSource(db *sql.DB, sourceName string) (int64, error) {
|
|||||||
return result.LastInsertId()
|
return result.LastInsertId()
|
||||||
}
|
}
|
||||||
|
|
||||||
func _main(args []string) error {
|
func Ingest(sourceName string, ins io.Reader) error {
|
||||||
if len(os.Args) == 0 {
|
|
||||||
return errors.New("need a source name argument")
|
|
||||||
}
|
|
||||||
db, err := sql.Open("sqlite3", dsn)
|
db, err := sql.Open("sqlite3", dsn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -40,9 +35,8 @@ func _main(args []string) error {
|
|||||||
|
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
s := bufio.NewScanner(os.Stdin)
|
s := bufio.NewScanner(ins)
|
||||||
|
|
||||||
sourceName := strings.Join(os.Args[1:], " ")
|
|
||||||
sourceID, err := createSource(db, sourceName)
|
sourceID, err := createSource(db, sourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not make source: %w", err)
|
return fmt.Errorf("could not make source: %w", err)
|
||||||
@ -68,10 +62,3 @@ func _main(args []string) error {
|
|||||||
|
|
||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
|
||||||
if err := _main(os.Args[1:]); err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "error: %s", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
101
main.go
101
main.go
@ -1,106 +1,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"github.com/vilmibm/trunkless/cmd"
|
||||||
"log"
|
|
||||||
"math/big"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"crypto/rand"
|
|
||||||
"database/sql"
|
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
dsn = "phrase.db?cache=shared&mode=r"
|
|
||||||
maxID = 467014991
|
|
||||||
)
|
|
||||||
|
|
||||||
func connectDB() (*sql.DB, error) {
|
|
||||||
db, err := sql.Open("sqlite3", dsn)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return db, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type source struct {
|
|
||||||
ID int64
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type phrase struct {
|
|
||||||
ID int64
|
|
||||||
Text string
|
|
||||||
Source source
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
r := gin.Default()
|
cmd.Execute()
|
||||||
r.SetFuncMap(template.FuncMap{
|
|
||||||
"upper": strings.ToUpper,
|
|
||||||
})
|
|
||||||
r.LoadHTMLFiles("templates/index.tmpl")
|
|
||||||
r.StaticFile("/cutive.ttf", "./assets/cutive.ttf")
|
|
||||||
r.StaticFile("/favicon.ico", "./assets/favicon.ico")
|
|
||||||
r.StaticFile("/bg_light.gif", "./assets/bg_light.gif")
|
|
||||||
r.StaticFile("/bg_dark.gif", "./assets/bg_dark.gif")
|
|
||||||
r.StaticFile("/main.js", "./assets/main.js")
|
|
||||||
r.StaticFile("/html2canvas.min.js", "./assets/html2canvas.min.js")
|
|
||||||
|
|
||||||
randMax := big.NewInt(maxID)
|
|
||||||
|
|
||||||
r.HEAD("/", func(c *gin.Context) {
|
|
||||||
c.String(http.StatusOK, "")
|
|
||||||
})
|
|
||||||
|
|
||||||
r.GET("/", func(c *gin.Context) {
|
|
||||||
c.HTML(http.StatusOK, "index.tmpl", struct {
|
|
||||||
MaxID int
|
|
||||||
// TODO anything else?
|
|
||||||
}{maxID})
|
|
||||||
})
|
|
||||||
|
|
||||||
r.GET("/line", func(c *gin.Context) {
|
|
||||||
db, err := connectDB()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err.Error())
|
|
||||||
c.String(http.StatusInternalServerError, "oh no.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
id, err := rand.Int(rand.Reader, randMax)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err.Error())
|
|
||||||
c.String(http.StatusInternalServerError, "oh no.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt, err := db.Prepare("select p.phrase, p.id, s.name from phrases p join sources s on p.sourceid = s.id where p.id = ?")
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err.Error())
|
|
||||||
c.String(http.StatusInternalServerError, "oh no.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
row := stmt.QueryRow(id.Int64())
|
|
||||||
var p phrase
|
|
||||||
var s source
|
|
||||||
err = row.Scan(&p.Text, &s.ID, &s.Name)
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err.Error())
|
|
||||||
c.String(http.StatusInternalServerError, "oh no.")
|
|
||||||
}
|
|
||||||
p.Source = s
|
|
||||||
p.ID = id.Int64()
|
|
||||||
c.JSON(http.StatusOK, p)
|
|
||||||
})
|
|
||||||
|
|
||||||
r.Run() // 8080
|
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
89
web/web.go
Normal file
89
web/web.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"math/big"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/vilmibm/trunkless/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
type source struct {
|
||||||
|
ID int64
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type phrase struct {
|
||||||
|
ID int64
|
||||||
|
Text string
|
||||||
|
Source source
|
||||||
|
}
|
||||||
|
|
||||||
|
func Serve() error {
|
||||||
|
r := gin.Default()
|
||||||
|
r.SetFuncMap(template.FuncMap{
|
||||||
|
"upper": strings.ToUpper,
|
||||||
|
})
|
||||||
|
r.LoadHTMLFiles("templates/index.tmpl")
|
||||||
|
r.StaticFile("/cutive.ttf", "./web/assets/cutive.ttf")
|
||||||
|
r.StaticFile("/favicon.ico", "./web/assets/favicon.ico")
|
||||||
|
r.StaticFile("/bg_light.gif", "./web/assets/bg_light.gif")
|
||||||
|
r.StaticFile("/bg_dark.gif", "./web/assets/bg_dark.gif")
|
||||||
|
r.StaticFile("/main.js", "./web/assets/main.js")
|
||||||
|
r.StaticFile("/html2canvas.min.js", "./web/assets/html2canvas.min.js")
|
||||||
|
|
||||||
|
randMax := big.NewInt(db.MaxID)
|
||||||
|
|
||||||
|
r.HEAD("/", func(c *gin.Context) {
|
||||||
|
c.String(http.StatusOK, "")
|
||||||
|
})
|
||||||
|
|
||||||
|
r.GET("/", func(c *gin.Context) {
|
||||||
|
c.HTML(http.StatusOK, "index.tmpl", struct {
|
||||||
|
MaxID int
|
||||||
|
// TODO anything else?
|
||||||
|
}{db.MaxID})
|
||||||
|
})
|
||||||
|
|
||||||
|
r.GET("/line", func(c *gin.Context) {
|
||||||
|
db, err := db.Connect()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
c.String(http.StatusInternalServerError, "oh no.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
id, err := rand.Int(rand.Reader, randMax)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
c.String(http.StatusInternalServerError, "oh no.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt, err := db.Prepare("select p.phrase, p.id, s.name from phrases p join sources s on p.sourceid = s.id where p.id = ?")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
c.String(http.StatusInternalServerError, "oh no.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
row := stmt.QueryRow(id.Int64())
|
||||||
|
var p phrase
|
||||||
|
var s source
|
||||||
|
err = row.Scan(&p.Text, &s.ID, &s.Name)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err.Error())
|
||||||
|
c.String(http.StatusInternalServerError, "oh no.")
|
||||||
|
}
|
||||||
|
p.Source = s
|
||||||
|
p.ID = id.Int64()
|
||||||
|
c.JSON(http.StatusOK, p)
|
||||||
|
})
|
||||||
|
|
||||||
|
return r.Run() // 8080
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user