that'll serve news

This commit is contained in:
idk
2022-12-06 22:10:27 +00:00
parent e2dd7d9ba2
commit 2f479d80d3
4 changed files with 196 additions and 8 deletions

13
go.mod Normal file
View File

@ -0,0 +1,13 @@
module i2pgit.org/idk/newsgo
go 1.19
require gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a
require (
gitlab.com/golang-commonmark/html v0.0.0-20191124015941-a22733972181 // indirect
gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82 // indirect
gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 // indirect
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f // indirect
golang.org/x/text v0.3.2 // indirect
)

17
go.sum Normal file
View File

@ -0,0 +1,17 @@
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
gitlab.com/golang-commonmark/html v0.0.0-20191124015941-a22733972181 h1:K+bMSIx9A7mLES1rtG+qKduLIXq40DAzYHtb0XuCukA=
gitlab.com/golang-commonmark/html v0.0.0-20191124015941-a22733972181/go.mod h1:dzYhVIwWCtzPAa4QP98wfB9+mzt33MSmM8wsKiMi2ow=
gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82 h1:oYrL81N608MLZhma3ruL8qTM4xcpYECGut8KSxRY59g=
gitlab.com/golang-commonmark/linkify v0.0.0-20191026162114-a0c2df6c8f82/go.mod h1:Gn+LZmCrhPECMD3SOKlE+BOHwhOYD9j7WT9NUtkCrC8=
gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a h1:O85GKETcmnCNAfv4Aym9tepU8OE0NmcZNqPlXcsBKBs=
gitlab.com/golang-commonmark/markdown v0.0.0-20211110145824-bf3e522c626a/go.mod h1:LaSIs30YPGs1H5jwGgPhLzc8vkNc/k0rDX/fEZqiU/M=
gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84 h1:qqjvoVXdWIcZCLPMlzgA7P9FZWdPGPvP/l3ef8GzV6o=
gitlab.com/golang-commonmark/mdurl v0.0.0-20191124015652-932350d1cb84/go.mod h1:IJZ+fdMvbW2qW6htJx7sLJ04FEs4Ldl/MDsJtMKywfw=
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f h1:Wku8eEdeJqIOFHtrfkYUByc4bCaTeA6fL0UJgfEiFMI=
gitlab.com/golang-commonmark/puny v0.0.0-20191124015043-9f83538fa04f/go.mod h1:Tiuhl+njh/JIg0uS/sOJVYi0x2HEa5rc1OAaVsb5tAs=
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638 h1:uPZaMiz6Sz0PZs3IZJWpU5qHKGNy///1pacZC9txiUI=
gitlab.com/opennota/wd v0.0.0-20180912061657-c5d65f63c638/go.mod h1:EGRJaqe2eO9XGmFtQCvV3Lm9NLico3UhFwUpCG/+mVU=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

90
main.go
View File

@ -1,5 +1,93 @@
package main
func main() {
import (
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"strconv"
server "i2pgit.org/idk/newsgo/server"
)
var (
serve = flag.String("command", "help", "command to run(may be `serve`,`build`,`sign`")
dir = flag.String("newsdir", "build", "directory to serve news from")
statsfile = flag.String("statsfile", "build/stats.json", "file to store stats in")
host = flag.String("host", "127.0.0.1", "host to serve on")
port = flag.String("port", "9696", "port to serve on")
)
func validatePort(s *string) {
_, err := strconv.Atoi(*s)
if err != nil {
log.Println("Port is invalid")
os.Exit(1)
}
}
func validateCommand(s *string) string {
switch *s {
case "serve":
return "serve"
case "build":
return "build"
case "sign":
return "sign"
default:
return "help"
}
}
func Help() {
fmt.Println("newsgo")
fmt.Println("======")
fmt.Println("")
fmt.Println("I2P News Server Tool/Library")
fmt.Println("")
fmt.Println("Usage")
fmt.Println("-----")
fmt.Println("")
fmt.Println("./newsgo -command $command -newsdir $news_directory -statsfile $news_stats_file")
fmt.Println("")
fmt.Println("### Commands")
fmt.Println("")
fmt.Println(" - serve: Serve newsfeeds from a directory")
fmt.Println(" - build: Build newsfeeds from XML(Not Implemented Yet)")
fmt.Println(" - sign: Sign newsfeeds with local keys(Not Implemented Yet)")
fmt.Println("")
fmt.Println("### Options")
fmt.Println("")
fmt.Println(" - `-newsdir`: directory to serve newsfeed from")
fmt.Println(" - `-statsfile`: file to store the stats in, in json format")
fmt.Println("")
}
func Serve(host, port string) error {
ln, err := net.Listen("tcp", net.JoinHostPort(host, port))
if err != nil {
return err
}
s := server.Serve(*dir, *statsfile)
return http.Serve(ln, s)
}
func main() {
flag.Parse()
command := validateCommand(serve)
validatePort(port)
switch command {
case "serve":
if err := Serve(*host, *port); err != nil {
panic(err)
}
case "build":
case "sign":
case "help":
Help()
default:
Help()
}
}

View File

@ -1,17 +1,22 @@
package newsserver
import (
"crypto/sha256"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"gitlab.com/golang-commonmark/markdown"
stats "i2pgit.org/idk/newsgo/server/stats"
)
type NewsServer struct {
NewsDir string
stats.Stats NewsStats
Stats stats.NewsStats
}
var serveTest http.Handler = &NewsServer{}
@ -20,10 +25,12 @@ func (n *NewsServer) ServeHTTP(rw http.ResponseWriter, rq *http.Request) {
path := rq.URL.Path
file := filepath.Join(n.NewsDir, path)
if err := fileCheck(file); err != nil {
log.Println("ServeHTTP:", err.Error())
rw.WriteHeader(404)
return
}
if err := ServeFile(file, rw); err != nil {
log.Println("ServeHTTP:", err.Error())
rw.WriteHeader(404)
}
}
@ -53,26 +60,89 @@ func fileType(file string) (string, error) {
case ".svg":
return "image/svg+xml", nil
default:
return "", fmt.Errorf("fileType: Attempted to serve invalid file type")
return "text/html", nil
}
}
func ServeFile(file string, rw http.ResponseWriter) error {
if err := fileCheck(file); err != nil {
return fmt.Errorf("ServeFile: %s", err)
func openDirectory(wd string) string {
//wd = strings.Replace(wd, leader, "", 1)
files, err := ioutil.ReadDir(wd)
if err != nil {
log.Fatal(err)
}
var readme string
log.Println("Navigating directory:", wd)
nwd := strings.Join(strings.Split(wd, "/")[1:], "/")
readme += fmt.Sprintf("%s\n", filepath.Base(wd))
readme += fmt.Sprintf("%s\n", head(len(filepath.Base(wd))))
readme += fmt.Sprintf("%s\n", "")
readme += fmt.Sprintf("%s\n", "**Directory Listing:**")
readme += fmt.Sprintf("%s\n", "")
for _, file := range files {
if !file.IsDir() {
fmt.Println(file.Name(), file.IsDir())
xname := filepath.Join(wd, file.Name())
bytes, err := ioutil.ReadFile(xname)
if err != nil {
log.Println("Listing error:", err)
}
sum := fmt.Sprintf("%x", sha256.Sum256(bytes))
readme += fmt.Sprintf(" - [%s](%s/%s) : `%d` : `%s` - `%s`\n", file.Name(), filepath.Base(nwd), filepath.Base(file.Name()), file.Size(), file.Mode(), sum)
} else {
fmt.Println(file.Name(), file.IsDir())
readme += fmt.Sprintf(" - [%s](%s/) : `%d` : `%s`\n", file.Name(), file.Name(), file.Size(), file.Mode())
}
}
return readme
}
func hTML(mdtxt string) []byte {
md := markdown.New(markdown.XHTMLOutput(true))
return []byte(md.RenderToString([]byte(mdtxt)))
}
func head(num int) string {
var r string
for i := 0; i < num; i++ {
r += "="
}
return r
}
func ServeFile(file string, rw http.ResponseWriter) error {
//if err := fileCheck(file); err != nil {
// return fmt.Errorf("ServeFile: %s", err)
//}
ftype, err := fileType(file)
if err != nil {
return fmt.Errorf("ServeFile: %s", err)
}
if ftype == "application/x-i2p-su3-news" {
// Log stats here
}
rw.Header().Add("Content-Type", ftype)
f, _ := os.Stat(file)
if f.IsDir() {
bytes := hTML(openDirectory(file))
rw.Write(bytes)
return nil
}
bytes, err := ioutil.ReadFile(file)
if err != nil {
return fmt.Errorf("ServeFile: %s", err)
}
rw.Header().Add("Content-Type", ftype)
log.Println("ServeFile: ", file, ftype)
rw.Write(bytes)
return nil
}
func Serve(newsDir, newsStats string) *NewsServer {
s := &NewsServer{
NewsDir: newsDir,
Stats: stats.NewsStats{
StateFile: newsStats,
},
}
return s
}