Adapt to more recent Go version
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
このコミットが含まれているのは:
コミット
e9e364611a
|
@ -0,0 +1,31 @@
|
|||
GO ?= go
|
||||
RM ?= rm
|
||||
SCDOC ?= scdoc
|
||||
GOFLAGS ?= -v -ldflags "-w -X `go list`.Version=$(VERSION) -X `go list`.Commit=$(COMMIT) -X `go list`.Build=$(BUILD)" -tags "static_build"
|
||||
PREFIX ?= /usr/local
|
||||
BINDIR ?= bin
|
||||
MANDIR ?= share/man
|
||||
MKDIR ?= mkdir
|
||||
CP ?= cp
|
||||
|
||||
VERSION = `git describe --abbrev=0 --tags 2>/dev/null || echo "$VERSION"`
|
||||
COMMIT = `git rev-parse --short HEAD || echo "$COMMIT"`
|
||||
BRANCH = `git rev-parse --abbrev-ref HEAD`
|
||||
BUILD = `git show -s --pretty=format:%cI`
|
||||
|
||||
GOARCH ?= amd64
|
||||
GOOS ?= linux
|
||||
|
||||
all: akyuu
|
||||
|
||||
akyuu:
|
||||
$(GO) build $(GOFLAGS)
|
||||
clean:
|
||||
$(RM) -f akyuu akyuuctl akyuu-znc-import doc/akyuu.1
|
||||
install:
|
||||
$(MKDIR) -p $(DESTDIR)$(PREFIX)/$(BINDIR)
|
||||
$(MKDIR) -p $(DESTDIR)/var/lib/akyuu
|
||||
$(CP) -f akyuu $(DESTDIR)$(PREFIX)/$(BINDIR)
|
||||
$(CP) -R templates $(DESTDIR)/var/lib/akyuu
|
||||
$(MKDIR) -p $(DESTDIR)/var/lib/akyuu/data
|
||||
.PHONY: akyuu clean install
|
27
README.md
27
README.md
|
@ -1,4 +1,4 @@
|
|||
# htwtxt – hosted twtxt server
|
||||
# akyuu – a twtxt server that never forgets
|
||||
|
||||
## Rationale
|
||||
|
||||
|
@ -24,11 +24,6 @@ space.
|
|||
- all HTML+CSS is read from a templates directory, which can be freely chosen at
|
||||
server start so as to ease customization of the interface
|
||||
|
||||
## Docker image
|
||||
|
||||
A docker image maintained by the htwtxt user buckket can be found here:
|
||||
<https://hub.docker.com/r/buckket/htwtxt/>
|
||||
|
||||
## Setup and run
|
||||
|
||||
### Setup Go build environment
|
||||
|
@ -53,17 +48,15 @@ available.)
|
|||
|
||||
Once your Go build environment is ready, do this:
|
||||
|
||||
git clone https://github.com/plomlompom/htwtxt $GOPATH/src/htwtxt
|
||||
go get htwtxt
|
||||
mkdir ~/htwtxt
|
||||
$GOPATH/bin/htwtxt
|
||||
go install marisa.chaotic.ninja/akyuu@latest
|
||||
$GOPATH/bin/akyuu [options]
|
||||
|
||||
This will build and start the server, which will store login and feed data below
|
||||
`~/htwtxt`. An alternate directory may be specified with the `--dir` flag.
|
||||
`~/akyuu`. An alternate directory may be specified with the `--dir` flag.
|
||||
|
||||
### Writing twtxt messages via API
|
||||
|
||||
Using htwtxt from a web browser for purposes such as writing a twtxt message
|
||||
Using akyuu from a web browser for purposes such as writing a twtxt message
|
||||
should be self-explanatory (just use the HTML form on the start page). But it's
|
||||
also possible to write new messages directly to a twtxt feed via a `POST`
|
||||
request to `/feeds`. Just provide appropriate values for the data fields `name`
|
||||
|
@ -77,10 +70,10 @@ line example utilizing the curl tool:
|
|||
|
||||
### Configure port number and TLS
|
||||
|
||||
By default, htwtxt serves unencrypted HTTP over port 8000. But the executable
|
||||
By default, akyuu serves unencrypted HTTP over port 8000. But the executable
|
||||
accepts the flag `--port` to provide an alternate port number, and the flags
|
||||
`--cert` and `--key` to provide paths to an SSL certificate and key file to run
|
||||
htwtxt as an HTTPS server.
|
||||
akyuu as an HTTPS server.
|
||||
|
||||
You might encounter the following issue when trying to set a low port number
|
||||
(such as the HTTP standard 80, or the HTTPS standard 443):
|
||||
|
@ -90,7 +83,7 @@ You might encounter the following issue when trying to set a low port number
|
|||
This is [a common privilege problem](http://stackoverflow.com/q/413807) and
|
||||
[might be solved](http://stackoverflow.com/a/414258) bis this:
|
||||
|
||||
sudo setcap 'cap_net_bind_service=+ep' $GOPATH/bin/htwtxt
|
||||
sudo setcap 'cap_net_bind_service=+ep' $GOPATH/bin/akyuu
|
||||
|
||||
### Public or closed sign-up
|
||||
|
||||
|
@ -118,7 +111,7 @@ posed on the password reset links they enable by setting their mail address.
|
|||
|
||||
### Change HTML templates
|
||||
|
||||
By default, HTML templates are read out of `$GOPATH/src/htwtxt/templates/`. An
|
||||
By default, HTML templates are read out of `$GOPATH/src/akyuu/templates/`. An
|
||||
alternate directory can be given with the flag `--templates` (it should contain
|
||||
template files of the same names as the default ones, however).
|
||||
|
||||
|
@ -127,6 +120,8 @@ template files of the same names as the default ones, however).
|
|||
htwtxt (c) 2016 Christian Heller a.k.a. [plomlompom](http://www.plomlompom.de),
|
||||
with template design input by [Kai Kubasta](http://kaikubasta.de).
|
||||
|
||||
akyuu (c) 2023-present Izuru Yakumo.
|
||||
|
||||
License: Affero GPL version 3, see `./LICENSE`
|
||||
|
||||
Current version number: 1.0.7
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
module marisa.chaotic.ninja/akyuu
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/gorilla/mux v1.8.0
|
||||
golang.org/x/crypto v0.8.0
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
)
|
||||
|
||||
require (
|
||||
golang.org/x/sys v0.7.0 // indirect
|
||||
golang.org/x/term v0.7.0 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ=
|
||||
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
|
||||
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
28
handlers.go
28
handlers.go
|
@ -1,17 +1,21 @@
|
|||
// $TheSupernovaDuo: akyuu,v master 2023/4/14 21:2:6 yakumo_izuru Exp $
|
||||
// See LICENSE for copyright details
|
||||
package main
|
||||
|
||||
import "bufio"
|
||||
import "crypto/rand"
|
||||
import "encoding/base64"
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
import "gopkg.in/gomail.v2"
|
||||
import "log"
|
||||
import "github.com/gorilla/mux"
|
||||
import "net/http"
|
||||
import "os"
|
||||
import "strconv"
|
||||
import "strings"
|
||||
import "time"
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gopkg.in/gomail.v2"
|
||||
"log"
|
||||
"github.com/gorilla/mux"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func passwordResetRequestGetHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if "" == mailuser {
|
||||
|
|
58
io.go
58
io.go
|
@ -1,29 +1,32 @@
|
|||
// htwtxt – hosted twtxt server; see README for copyright and license info
|
||||
|
||||
// $TheSupernovaDuo: akyuu,v master 2023/4/14 21:2:6 yakumo_izuru Exp $
|
||||
// See LICENSE for copyright details
|
||||
package main
|
||||
|
||||
import "bufio"
|
||||
import "errors"
|
||||
import "log"
|
||||
import "os"
|
||||
import "strings"
|
||||
import "io/ioutil"
|
||||
|
||||
const loginsFile = "logins.txt"
|
||||
const feedsDir = "feeds"
|
||||
const ipDelaysFile = "ip_delays.txt"
|
||||
const pwResetFile = "password_reset.txt"
|
||||
const pwResetWaitFile = "password_reset_wait.txt"
|
||||
|
||||
var certPath string
|
||||
var dataDir string
|
||||
var feedsPath string
|
||||
var ipDelaysPath string
|
||||
var keyPath string
|
||||
var loginsPath string
|
||||
var pwResetPath string
|
||||
var pwResetWaitPath string
|
||||
var templPath string
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
const (
|
||||
loginsFile = "logins.txt"
|
||||
feedsDir = "feeds"
|
||||
ipDelaysFile = "ip_delays.txt"
|
||||
pwResetFile = "password_reset.txt"
|
||||
pwResetWaitFile = "password_reset_wait.txt"
|
||||
)
|
||||
var (
|
||||
certPath string
|
||||
dataDir string
|
||||
feedsPath string
|
||||
ipDelaysPath string
|
||||
keyPath string
|
||||
loginsPath string
|
||||
pwResetPath string
|
||||
pwResetWaitPath string
|
||||
templPath string
|
||||
)
|
||||
|
||||
func createFileIfNotExists(path string) {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
|
@ -45,7 +48,7 @@ func openFile(path string) *os.File {
|
|||
}
|
||||
|
||||
func linesFromFile(path string) []string {
|
||||
text, err := ioutil.ReadFile(path)
|
||||
text, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Fatal("Can't read file", err)
|
||||
}
|
||||
|
@ -57,7 +60,7 @@ func linesFromFile(path string) []string {
|
|||
|
||||
func writeAtomic(path, text string) {
|
||||
tmpFile := path + "_tmp"
|
||||
if err := ioutil.WriteFile(tmpFile, []byte(text), 0600); err != nil {
|
||||
if err := os.WriteFile(tmpFile, []byte(text), 0600); err != nil {
|
||||
log.Fatal("Trouble writing file", err)
|
||||
}
|
||||
if err := os.Rename(path, path+"_"); err != nil {
|
||||
|
@ -76,7 +79,7 @@ func writeLinesAtomic(path string, lines []string) {
|
|||
}
|
||||
|
||||
func appendToFile(path string, msg string) {
|
||||
text, err := ioutil.ReadFile(path)
|
||||
text, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Fatal("Can't read file", err)
|
||||
}
|
||||
|
@ -164,6 +167,5 @@ func initFilesAndDirs() {
|
|||
createFileIfNotExists(pwResetPath)
|
||||
createFileIfNotExists(pwResetWaitPath)
|
||||
createFileIfNotExists(ipDelaysPath)
|
||||
// TODO: Handle err here.
|
||||
_ = os.Mkdir(feedsPath, 0700)
|
||||
}
|
||||
|
|
68
main.go
68
main.go
|
@ -1,34 +1,38 @@
|
|||
// htwtxt – hosted twtxt server; see README for copyright and license info
|
||||
|
||||
// $TheSupernovaDuo: akyuu,v master 2023/4/14 21:2:6 yakumo_izuru Exp $
|
||||
// See LICENSE for copyright details
|
||||
package main
|
||||
|
||||
import "errors"
|
||||
import "flag"
|
||||
import "fmt"
|
||||
import "golang.org/x/crypto/bcrypt"
|
||||
import "golang.org/x/crypto/ssh/terminal"
|
||||
import "gopkg.in/gomail.v2"
|
||||
import "html/template"
|
||||
import "io/ioutil"
|
||||
import "log"
|
||||
import "net"
|
||||
import "net/http"
|
||||
import "os"
|
||||
import "strconv"
|
||||
import "strings"
|
||||
import "syscall"
|
||||
import "time"
|
||||
|
||||
const resetLinkExp = 1800
|
||||
const resetWaitTime = 3600 * 24
|
||||
const version = "1.0"
|
||||
|
||||
var contact string
|
||||
var dialer *gomail.Dialer
|
||||
var mailuser string
|
||||
var myself string
|
||||
var signupOpen bool
|
||||
var templ *template.Template
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
"gopkg.in/gomail.v2"
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
const (
|
||||
resetLinkExp = 1800
|
||||
resetWaitTime = 3600 * 24
|
||||
version = "1.0"
|
||||
)
|
||||
var (
|
||||
contact string
|
||||
dialer *gomail.Dialer
|
||||
mailuser string
|
||||
myself string
|
||||
signupOpen bool
|
||||
templ *template.Template
|
||||
)
|
||||
|
||||
func execTemplate(w http.ResponseWriter, file string, input string) {
|
||||
type data struct{ Msg string }
|
||||
|
@ -243,9 +247,9 @@ func readOptions() (string, int, string, int, string, bool) {
|
|||
flag.StringVar(&keyPath, "key", "", "SSL key file")
|
||||
flag.StringVar(&certPath, "cert", "", "SSL certificate file")
|
||||
flag.StringVar(&templPath, "templates",
|
||||
os.Getenv("GOPATH")+"/src/htwtxt/templates",
|
||||
os.Getenv("GOPATH")+"/src/akyuu/templates",
|
||||
"directory where to expect HTML templates")
|
||||
flag.StringVar(&dataDir, "dir", os.Getenv("HOME")+"/htwtxt",
|
||||
flag.StringVar(&dataDir, "dir", os.Getenv("HOME")+"/akyuu",
|
||||
"directory to store feeds and login data")
|
||||
flag.StringVar(&contact, "contact",
|
||||
"[operator passed no contact info to server]",
|
||||
|
@ -284,7 +288,7 @@ func main() {
|
|||
mailserver, mailport, mailpw, port, newLogin, showVersion :=
|
||||
readOptions()
|
||||
if showVersion {
|
||||
fmt.Println("htwtxt", version)
|
||||
fmt.Println("akyuu", FullVersion())
|
||||
return
|
||||
}
|
||||
initFilesAndDirs()
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// $TheSupernovaDuo: akyuu,v master 2023/4/14 21:2:6 yakumo_izuru Exp $
|
||||
// See LICENSE for copyright details
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultVersion = "0.0.0"
|
||||
defaultCommit = "HEAD"
|
||||
defaultBuild = "0000-01-01:00:00+00:00"
|
||||
)
|
||||
|
||||
var (
|
||||
// Version is the tagged release version in the form <major>.<minor>.<patch>
|
||||
// following semantic versioning and is overwritten by the build system.
|
||||
Version = defaultVersion
|
||||
|
||||
// Commit is the commit sha of the build (normally from Git) and is overwritten
|
||||
// by the build system.
|
||||
Commit = defaultCommit
|
||||
|
||||
// Build is the date and time of the build as an RFC3339 formatted string
|
||||
// and is overwritten by the build system.
|
||||
Build = defaultBuild
|
||||
)
|
||||
|
||||
// FullVersion display the full version and build
|
||||
func FullVersion() string {
|
||||
var sb strings.Builder
|
||||
|
||||
isDefault := Version == defaultVersion && Commit == defaultCommit && Build == defaultBuild
|
||||
|
||||
if !isDefault {
|
||||
sb.WriteString(fmt.Sprintf("%s@%s %s", Version, Commit, Build))
|
||||
}
|
||||
|
||||
if info, ok := debug.ReadBuildInfo(); ok {
|
||||
if isDefault {
|
||||
sb.WriteString(fmt.Sprintf(" %s", info.Main.Version))
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf(" %s", info.GoVersion))
|
||||
if info.Main.Sum != "" {
|
||||
sb.WriteString(fmt.Sprintf(" %s", info.Main.Sum))
|
||||
}
|
||||
}
|
||||
|
||||
return sb.String()
|
||||
}
|
読み込み中…
新しいイシューから参照