Compare commits
5 Commits
b006333035
...
83c8f63fe3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83c8f63fe3 | ||
|
|
aaeb3f1930 | ||
|
|
6604c26204 | ||
|
|
ba6d6483e0 | ||
|
|
58cafcfaa3 |
@@ -6,6 +6,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"maps"
|
||||
"net/http"
|
||||
@@ -29,9 +30,13 @@ import (
|
||||
var _staticFileDir embed.FS
|
||||
var publicHandler = func() http.Handler {
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
return http.FileServer(http.Dir("./http"))
|
||||
return http.FileServer(http.Dir("./http/public"))
|
||||
}
|
||||
return http.FileServer(http.FS(_staticFileDir))
|
||||
sub, err := fs.Sub(_staticFileDir, "public")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return http.FileServer(http.FS(sub))
|
||||
}()
|
||||
|
||||
func Main() {
|
||||
|
||||
3090
cmd/http/moolah.dat
3090
cmd/http/moolah.dat
File diff suppressed because it is too large
Load Diff
1
cmd/http/moolah.dat
Symbolic link
1
cmd/http/moolah.dat
Symbolic link
@@ -0,0 +1 @@
|
||||
moolah.dat.real
|
||||
3091
cmd/http/moolah.dat.real
Normal file
3091
cmd/http/moolah.dat.real
Normal file
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,8 @@
|
||||
<body style="height: 100%;" onload="init();">
|
||||
<h1>Moolah2 Hub</h1>
|
||||
<ul style="line-height: 3em;">
|
||||
<li><a href="/public/transactions.html">Transactions on Shared Chase</a></li>
|
||||
<li><a href="/public/explore.html">Explore Bel's Money</a></li>
|
||||
<li><a href="/transactions.html">Transactions on Shared Chase</a></li>
|
||||
<li><a href="/explore.html">Explore Bel's Money</a></li>
|
||||
<li><a href="/api/bal?x=y&mode=bal&likeName=AssetAccount&chart=stack&predictionMonths=120&bpi=true&zoomStart=YYYY-MM&prediction=interest=AssetAccount:Cash%20\$%200.02&prediction=contributions=AssetAccount:Bonds%20$%201875&prediction=interest=AssetAccount:Monthly%20\$%200.03&prediction=contributions=AssetAccount:Monthly%20$%202500&predictFixedGrowth=VBTLX=0.02&predictFixedGrowth=GLD=0.02&predictFixedGrowth=FXAIX=0.03&predictFixedGrowth=FSPSX=0.03&whatIf=AssetAccount:Cash%20$%20-.10000&=">Project Bel's Net Worth</a></li>
|
||||
<li><a href="/api/reg?x=y&mode=reg&likeName=Withdrawal:&chart=stack&predictionMonths=3&bpi=false&zoomStart=YYYY-MM&prediction=autoContributions=&predictFixedGrowth=VBTLX=0&whatIf=AssetAccount:Cash%20$%20-.10000&=">Expect Bel's Expenses</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
function callback(responseBody, responseStatus) {
|
||||
}
|
||||
var f = String(window.location).split("/public/transactions.html")[1]
|
||||
var f = String(window.location).split("/transactions.html")[1]
|
||||
if (!f) {
|
||||
f = "/moolah.dat"
|
||||
}
|
||||
|
||||
@@ -36,26 +36,51 @@ func (files Files) TempGetLastNLines(n int) ([]string, error) {
|
||||
|
||||
func (files Files) TempSetLastNLines(n int, lines []string) error {
|
||||
p := files.paths()[0]
|
||||
|
||||
newFile, err := func() (string, error) {
|
||||
w, err := ioutil.TempFile(os.TempDir(), path.Base(p))
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
r, err := os.Open(p)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
if _, err := peekLastNLines(w, bufio.NewReader(r), n); err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
for i := range lines {
|
||||
fmt.Fprintln(w, lines[i])
|
||||
if _, err := fmt.Fprintln(w, lines[i]); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.Name(), nil
|
||||
}()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Rename(w.Name(), p)
|
||||
r, err := os.Open(newFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
w, err := os.Create(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer w.Close()
|
||||
|
||||
_, err = io.Copy(w, r)
|
||||
return err
|
||||
}
|
||||
|
||||
func peekLastNLines(w io.Writer, r *bufio.Reader, n int) ([]string, error) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ledger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -401,22 +402,39 @@ func TestFilesTempSetLastNLines(t *testing.T) {
|
||||
c := d
|
||||
t.Run(name, func(t *testing.T) {
|
||||
p := path.Join(t.TempDir(), base64.URLEncoding.EncodeToString([]byte(t.Name())))
|
||||
os.WriteFile(p, []byte(c.given), os.ModePerm)
|
||||
files := Files([]string{p})
|
||||
if err := files.TempSetLastNLines(c.n, c.input); err != nil {
|
||||
s := err.Error()
|
||||
if _, err := os.Stat(s); err == nil {
|
||||
got, _ := os.ReadFile(s)
|
||||
if string(got) != c.want {
|
||||
t.Errorf("want\n%s, got\n%s", c.want, got)
|
||||
}
|
||||
}
|
||||
realp := p + ".real"
|
||||
|
||||
os.WriteFile(realp, []byte(c.given), os.ModePerm)
|
||||
if err := os.Symlink(realp, p); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if stat, err := os.Lstat(p); err != nil {
|
||||
t.Error(err)
|
||||
} else if stat.Mode().IsRegular() {
|
||||
t.Error("p is already a regular file")
|
||||
}
|
||||
|
||||
files := Files([]string{p})
|
||||
if err := files.TempSetLastNLines(c.n, c.input); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
got, _ := os.ReadFile(p)
|
||||
if string(got) != c.want {
|
||||
t.Errorf("want\n%s, got\n%s", c.want, got)
|
||||
}
|
||||
|
||||
realb, _ := os.ReadFile(realp)
|
||||
b, _ := os.ReadFile(realp)
|
||||
if !bytes.Equal(b, realb) {
|
||||
t.Errorf("%s no longer links to %s", p, realp)
|
||||
}
|
||||
|
||||
if stat, err := os.Lstat(p); err != nil {
|
||||
t.Error(err)
|
||||
} else if stat.Mode().IsRegular() {
|
||||
t.Error("p is now a regular file")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user