Compare commits
2 Commits
9db7c4b44d
...
64ce7e3777
Author | SHA1 | Date |
---|---|---|
nbsp | 64ce7e3777 | |
nbsp | 8588cbd16d |
|
@ -19,7 +19,7 @@ make
|
||||||
- [ ] feels manager
|
- [ ] feels manager
|
||||||
- [ ] feels publishing
|
- [ ] feels publishing
|
||||||
- [x] plaintext
|
- [x] plaintext
|
||||||
- [ ] html
|
- [x] html
|
||||||
- [ ] gopher
|
- [ ] gopher
|
||||||
- [ ] graffiti
|
- [ ] graffiti
|
||||||
- [x] documentation with manpages
|
- [x] documentation with manpages
|
||||||
|
|
|
@ -133,7 +133,7 @@ func newFeels(state *ui.State) {
|
||||||
vt.Attach(state.PostEvent())
|
vt.Attach(state.PostEvent())
|
||||||
vt.Focus()
|
vt.Focus()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
err := vt.Start(exec.Command(os.ExpandEnv(os.Getenv("EDITOR")), path.Join(os.Getenv("HOME"), ".ttbp/entries", now.Format("20060102")+".txt")))
|
err := vt.Start(exec.Command(os.ExpandEnv(os.Getenv("EDITOR")), path.Join(ttbp.PathUserEntries, now.Format("20060102")+".txt")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@ package app
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.sr.ht/~rockorager/vaxis"
|
"git.sr.ht/~rockorager/vaxis"
|
||||||
|
"git.tilde.town/nbsp/neofeels/ttbp"
|
||||||
"git.tilde.town/nbsp/neofeels/ui"
|
"git.tilde.town/nbsp/neofeels/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,8 +19,8 @@ type Posted struct {
|
||||||
|
|
||||||
func NewPosted() *Posted {
|
func NewPosted() *Posted {
|
||||||
var content string
|
var content string
|
||||||
info, err := os.Stat(path.Join(os.Getenv("HOME"), ".ttbp/entries", time.Now().Format("20060102")+".txt"))
|
info, err := os.ReadFile(path.Join(ttbp.PathUserEntries, time.Now().Format("20060102")+".txt"))
|
||||||
if os.IsNotExist(err) || info.IsDir() || info.Size() == 0 {
|
if os.IsNotExist(err) || strings.Trim(string(info), " \r\n\t") == "" {
|
||||||
content = `your post is empty and was not published.
|
content = `your post is empty and was not published.
|
||||||
see you next time!`
|
see you next time!`
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!--- this header automatically generated by ttbp initialization on %DATETIME% --->
|
||||||
|
<title>~%USER% on TTBP</title>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="meta">
|
||||||
|
<h1>
|
||||||
|
<a href="index.html#">~%USER%</a>@<a href="/~%USER%/neofeels">TTBP</a>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<!---put your custom html here-->
|
||||||
|
|
||||||
|
<!---don't put anything after this line-->
|
||||||
|
<div id="tlogs"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,48 @@
|
||||||
|
body {
|
||||||
|
background-color: #E0B0FF;
|
||||||
|
font-family: courier
|
||||||
|
}
|
||||||
|
|
||||||
|
#meta {
|
||||||
|
top: -.5em;
|
||||||
|
position: fixed;
|
||||||
|
height: 3.5em;
|
||||||
|
float: left;
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e0b0ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tlogs {
|
||||||
|
margin-top: 5em;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry {
|
||||||
|
border: 1px dotted white;
|
||||||
|
padding: .4em;
|
||||||
|
margin-bottom:-4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry p {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry p.permalink {
|
||||||
|
font-size: .6em;
|
||||||
|
font-color: #808080;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.entry h5 {
|
||||||
|
text-align: right;
|
||||||
|
margin-top: .2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
background-color: black;
|
||||||
|
color: #e0b0ff;
|
||||||
|
font-size: 90%;
|
||||||
|
border: 1px dotted white;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
48
main.go
48
main.go
|
@ -1,11 +1,59 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.tilde.town/nbsp/neofeels/app"
|
"git.tilde.town/nbsp/neofeels/app"
|
||||||
|
"git.tilde.town/nbsp/neofeels/config"
|
||||||
|
"git.tilde.town/nbsp/neofeels/ttbp"
|
||||||
"git.tilde.town/nbsp/neofeels/ui"
|
"git.tilde.town/nbsp/neofeels/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//go:embed assets/header.html
|
||||||
|
var header string
|
||||||
|
|
||||||
|
//go:embed assets/footer.html
|
||||||
|
var footer []byte
|
||||||
|
|
||||||
|
//go:embed assets/style.css
|
||||||
|
var style []byte
|
||||||
|
|
||||||
|
func initializePrompt() {
|
||||||
|
fmt.Println(`i don't recognize you, stranger. let's make friends.
|
||||||
|
|
||||||
|
the feels engine is an internal blogging platform on tilde.town. it assists you
|
||||||
|
in recording your feels, giving you the option to publish to html or gopher, and
|
||||||
|
read the feels of other users on tilde.town.
|
||||||
|
|
||||||
|
press ↵ to set up an account, or Ctrl+c to quit. you can always come back later.`)
|
||||||
|
input := bufio.NewScanner(os.Stdin)
|
||||||
|
input.Scan()
|
||||||
|
|
||||||
|
println(ttbp.PathUserConfig, ttbp.PathUserFeels)
|
||||||
|
|
||||||
|
user, _ := user.Current()
|
||||||
|
header := strings.ReplaceAll(header, "%USER%", user.Username)
|
||||||
|
header = strings.ReplaceAll(header, "%DATETIME%", time.Now().Format(time.DateTime))
|
||||||
|
os.MkdirAll(ttbp.PathUserConfig, 0700)
|
||||||
|
os.MkdirAll(ttbp.PathUserEntries, 0700)
|
||||||
|
os.WriteFile(path.Join(ttbp.PathUserConfig, "header.txt"), []byte(header), 0644)
|
||||||
|
os.WriteFile(path.Join(ttbp.PathUserConfig, "footer.txt"), footer, 0644)
|
||||||
|
os.WriteFile(path.Join(ttbp.PathUserConfig, "style.css"), style, 0644)
|
||||||
|
config.Default.Write()
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
if _, err := os.Stat(ttbp.PathUserRc); err != nil {
|
||||||
|
initializePrompt()
|
||||||
|
}
|
||||||
|
|
||||||
state, err := ui.New(app.NewMainMenu())
|
state, err := ui.New(app.NewMainMenu())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
35
ttbp/ttbp.go
35
ttbp/ttbp.go
|
@ -24,6 +24,15 @@ var (
|
||||||
PathGraff = path.Join(PathVar, "graffiti")
|
PathGraff = path.Join(PathVar, "graffiti")
|
||||||
PathWall = path.Join(PathGraff, "wall.txt")
|
PathWall = path.Join(PathGraff, "wall.txt")
|
||||||
PathWallLock = path.Join(PathGraff, ".lock")
|
PathWallLock = path.Join(PathGraff, ".lock")
|
||||||
|
PathUser = os.Getenv("HOME")
|
||||||
|
PathUserFeels = path.Join(PathUser, ".ttbp")
|
||||||
|
PathUserHTML = path.Join(PathUser, "public_html")
|
||||||
|
PathUserConfig = path.Join(PathUserFeels, "config")
|
||||||
|
PathUserEntries = path.Join(PathUserFeels, "entries")
|
||||||
|
PathUserWWW = path.Join(PathUserFeels, "www")
|
||||||
|
PathUserRc = path.Join(PathUserConfig, "ttbprc")
|
||||||
|
PathUserNopub = path.Join(PathUserConfig, "nopub")
|
||||||
|
PathUserSubs = path.Join(PathUserConfig, "subs")
|
||||||
)
|
)
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
|
@ -99,7 +108,7 @@ func GetPostsForUser(user string) (posts []Post) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
nopubFile, err := os.OpenFile(path.Join(os.Getenv("HOME"), ".ttbp/config/nopub"), os.O_RDONLY|os.O_CREATE, 0644)
|
nopubFile, err := os.OpenFile(PathUserNopub, os.O_RDONLY|os.O_CREATE, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -169,7 +178,7 @@ type Subscriptions struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetSubscriptions() *Subscriptions {
|
func GetSubscriptions() *Subscriptions {
|
||||||
file, err := os.OpenFile(path.Join(os.Getenv("HOME"), ".ttbp/config/subs"), os.O_RDONLY|os.O_CREATE, 0600)
|
file, err := os.OpenFile(PathUserSubs, os.O_RDONLY|os.O_CREATE, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Subscriptions{}
|
return &Subscriptions{}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +218,7 @@ func (subscriptions *Subscriptions) Unsubscribe(user User) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (subscriptions *Subscriptions) Write() {
|
func (subscriptions *Subscriptions) Write() {
|
||||||
file, err := os.Create(path.Join(os.Getenv("HOME"), ".ttbp/config/subs"))
|
file, err := os.Create(PathUserSubs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -232,7 +241,7 @@ func NewNopub(t time.Time) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dateString := t.Format("20060102.txt")
|
dateString := t.Format("20060102.txt")
|
||||||
file, err := os.OpenFile(path.Join(os.Getenv("HOME"), ".ttbp/config/nopub"), os.O_RDWR|os.O_CREATE, 0600)
|
file, err := os.OpenFile(PathUserNopub, os.O_RDWR|os.O_CREATE, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -256,12 +265,16 @@ func Publish(t time.Time) {
|
||||||
return // TODO: expose this error to the user
|
return // TODO: expose this error to the user
|
||||||
}
|
}
|
||||||
if cfg.Publishing {
|
if cfg.Publishing {
|
||||||
file, err := os.Create(path.Join(os.Getenv("HOME"), ".ttbp/www/index.html"))
|
if _, err := os.Stat(PathUserWWW); os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(PathUserWWW, 0700)
|
||||||
|
os.Symlink(path.Join(PathUserConfig, "style.css"), path.Join(PathUserWWW, "style.css"))
|
||||||
|
}
|
||||||
|
file, err := os.Create(path.Join(PathUserWWW, "index.html"))
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
// load header and footer
|
// load header and footer
|
||||||
header, err := os.ReadFile(path.Join(os.Getenv("HOME"), ".ttbp/config/header.txt"))
|
header, err := os.ReadFile(path.Join(PathUserConfig, "header.txt"))
|
||||||
footer, err := os.ReadFile(path.Join(os.Getenv("HOME"), ".ttbp/config/footer.txt"))
|
footer, err := os.ReadFile(path.Join(PathUserConfig, "footer.txt"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -272,7 +285,7 @@ func Publish(t time.Time) {
|
||||||
writer.WriteString(string(header) + "\n")
|
writer.WriteString(string(header) + "\n")
|
||||||
user, _ := user.Current()
|
user, _ := user.Current()
|
||||||
for _, post := range GetPostsForUser(user.Username) {
|
for _, post := range GetPostsForUser(user.Username) {
|
||||||
if !post.Nopub {
|
if !post.Nopub && post.Words > 0 {
|
||||||
writePage(post, header, footer)
|
writePage(post, header, footer)
|
||||||
writer.WriteString(writeEntry(post) + "\n")
|
writer.WriteString(writeEntry(post) + "\n")
|
||||||
}
|
}
|
||||||
|
@ -284,8 +297,8 @@ func Publish(t time.Time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func writePage(post Post, header, footer []byte) {
|
func writePage(post Post, header, footer []byte) {
|
||||||
dateString := post.Date.Format("20060102")
|
dateString := post.Date.Format("20060102.html")
|
||||||
file, err := os.Create(path.Join(os.Getenv("HOME"), ".ttbp/www/"+dateString+".html"))
|
file, err := os.Create(path.Join(PathUserWWW, dateString))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -299,7 +312,7 @@ func writePage(post Post, header, footer []byte) {
|
||||||
|
|
||||||
func writeEntry(post Post) string {
|
func writeEntry(post Post) string {
|
||||||
dateString := post.Date.Format("20060102")
|
dateString := post.Date.Format("20060102")
|
||||||
file, err := os.ReadFile(path.Join(os.Getenv("HOME"), ".ttbp/entries/"+dateString+".txt"))
|
file, err := os.ReadFile(path.Join(PathUserEntries, dateString+".txt"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue