mirror of
https://github.com/nkanaev/yarr.git
synced 2025-09-13 09:55:36 +00:00
reorganise bin files
This commit is contained in:
45
cmd/feed2json/main.go
Normal file
45
cmd/feed2json/main.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/nkanaev/yarr/src/parser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Println("usage: <script> [url|filepath]")
|
||||
return
|
||||
}
|
||||
url := os.Args[1]
|
||||
var r io.Reader
|
||||
|
||||
if strings.HasPrefix(url, "http") {
|
||||
res, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to get url %s: %s", url, err)
|
||||
}
|
||||
r = res.Body
|
||||
} else {
|
||||
var err error
|
||||
r, err = os.Open(url)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open file: %s", err)
|
||||
}
|
||||
}
|
||||
feed, err := parser.Parse(r)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse feed: %s", err)
|
||||
}
|
||||
body, err := json.MarshalIndent(feed, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to marshall feed: %s", err)
|
||||
}
|
||||
fmt.Println(string(body))
|
||||
}
|
48
cmd/generate_versioninfo/main.go
Normal file
48
cmd/generate_versioninfo/main.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var rsrc = `1 VERSIONINFO
|
||||
FILEVERSION {VERSION_COMMA},0,0
|
||||
PRODUCTVERSION {VERSION_COMMA},0,0
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "080904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Old MacDonald's Farm"
|
||||
VALUE "FileDescription", "Yet another RSS reader"
|
||||
VALUE "FileVersion", "{VERSION}"
|
||||
VALUE "InternalName", "yarr"
|
||||
VALUE "LegalCopyright", "nkanaev"
|
||||
VALUE "OriginalFilename", "yarr.exe"
|
||||
VALUE "ProductName", "yarr"
|
||||
VALUE "ProductVersion", "{VERSION}"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x809, 1252
|
||||
END
|
||||
END
|
||||
|
||||
1 ICON "icon.ico"
|
||||
`
|
||||
|
||||
func main() {
|
||||
var version, outfile string
|
||||
flag.StringVar(&version, "version", "0.0", "")
|
||||
flag.StringVar(&outfile, "outfile", "versioninfo.rc", "")
|
||||
flag.Parse()
|
||||
|
||||
version_comma := strings.ReplaceAll(version, ".", ",")
|
||||
|
||||
out := strings.ReplaceAll(rsrc, "{VERSION}", version)
|
||||
out = strings.ReplaceAll(out, "{VERSION_COMMA}", version_comma)
|
||||
|
||||
ioutil.WriteFile(outfile, []byte(out), 0644)
|
||||
}
|
99
cmd/package_macos/main.go
Normal file
99
cmd/package_macos/main.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var plist = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleName</key>
|
||||
<string>yarr</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>yarr</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>nkanaev.yarr</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>VERSION</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>yarr</string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>icon</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.news</string>
|
||||
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<string>True</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.13</string>
|
||||
<key>LSUIElement</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2020 nkanaev. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
`
|
||||
|
||||
func run(cmd ...string) {
|
||||
fmt.Println(cmd)
|
||||
err := exec.Command(cmd[0], cmd[1:]...).Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var version, outdir string
|
||||
flag.StringVar(&version, "version", "0.0", "")
|
||||
flag.StringVar(&outdir, "outdir", "", "")
|
||||
flag.Parse()
|
||||
|
||||
outfile := "yarr"
|
||||
|
||||
binDir := path.Join(outdir, "yarr.app", "Contents/MacOS")
|
||||
resDir := path.Join(outdir, "yarr.app", "Contents/Resources")
|
||||
|
||||
plistFile := path.Join(outdir, "yarr.app", "Contents/Info.plist")
|
||||
pkginfoFile := path.Join(outdir, "yarr.app", "Contents/PkgInfo")
|
||||
|
||||
os.MkdirAll(binDir, 0700)
|
||||
os.MkdirAll(resDir, 0700)
|
||||
|
||||
f, _ := ioutil.ReadFile(path.Join(outdir, outfile))
|
||||
ioutil.WriteFile(path.Join(binDir, outfile), f, 0755)
|
||||
|
||||
ioutil.WriteFile(plistFile, []byte(strings.Replace(plist, "VERSION", version, 1)), 0644)
|
||||
ioutil.WriteFile(pkginfoFile, []byte("APPL????"), 0644)
|
||||
|
||||
iconFile := path.Join(outdir, "icon.png")
|
||||
iconsetDir := path.Join(outdir, "icon.iconset")
|
||||
os.Mkdir(iconsetDir, 0700)
|
||||
|
||||
for _, res := range []int{1024, 512, 256, 128, 64, 32, 16} {
|
||||
outfile := fmt.Sprintf("icon_%dx%d.png", res, res)
|
||||
if res == 1024 || res == 64 {
|
||||
outfile = fmt.Sprintf("icon_%dx%d@2x.png", res/2, res/2)
|
||||
}
|
||||
cmd := []string{
|
||||
"sips", "-s", "format", "png", "--resampleWidth", strconv.Itoa(res),
|
||||
iconFile, "--out", path.Join(iconsetDir, outfile),
|
||||
}
|
||||
run(cmd...)
|
||||
}
|
||||
|
||||
icnsFile := path.Join(resDir, "icon.icns")
|
||||
run("iconutil", "-c", "icns", iconsetDir, "-o", icnsFile)
|
||||
}
|
41
cmd/readability/main.go
Normal file
41
cmd/readability/main.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/nkanaev/yarr/src/content/readability"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
fmt.Println("usage: <script> [url]")
|
||||
return
|
||||
}
|
||||
url := os.Args[1]
|
||||
var r io.Reader
|
||||
|
||||
if strings.HasPrefix(url, "http") {
|
||||
res, err := http.Get(url)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to get url %s: %s", url, err)
|
||||
}
|
||||
r = res.Body
|
||||
} else {
|
||||
var err error
|
||||
r, err = os.Open(url)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open file: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
content, err := readability.ExtractContent(r)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to extract content: %s", err)
|
||||
}
|
||||
fmt.Println(content)
|
||||
}
|
155
cmd/yarr/main.go
Normal file
155
cmd/yarr/main.go
Normal file
@@ -0,0 +1,155 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/nkanaev/yarr/src/platform"
|
||||
"github.com/nkanaev/yarr/src/server"
|
||||
"github.com/nkanaev/yarr/src/storage"
|
||||
)
|
||||
|
||||
var Version string = "0.0"
|
||||
var GitHash string = "unknown"
|
||||
|
||||
var OptList = make([]string, 0)
|
||||
|
||||
func opt(envVar, defaultValue string) string {
|
||||
OptList = append(OptList, envVar)
|
||||
value := os.Getenv(envVar)
|
||||
if value != "" {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func parseAuthfile(authfile io.Reader) (username, password string, err error) {
|
||||
scanner := bufio.NewScanner(authfile)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
parts := strings.SplitN(line, ":", 2)
|
||||
if len(parts) != 2 {
|
||||
return "", "", fmt.Errorf("wrong syntax (expected `username:password`)")
|
||||
}
|
||||
username = parts[0]
|
||||
password = parts[1]
|
||||
break
|
||||
}
|
||||
return username, password, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
platform.FixConsoleIfNeeded()
|
||||
|
||||
var addr, db, authfile, auth, certfile, keyfile, basepath, logfile string
|
||||
var ver, open bool
|
||||
|
||||
flag.CommandLine.SetOutput(os.Stdout)
|
||||
|
||||
flag.Usage = func() {
|
||||
out := flag.CommandLine.Output()
|
||||
fmt.Fprintf(out, "Usage of %s:\n", os.Args[0])
|
||||
flag.PrintDefaults()
|
||||
fmt.Fprintln(out, "\nThe environmental variables, if present, will be used to provide\nthe default values for the params above:")
|
||||
fmt.Fprintln(out, " ", strings.Join(OptList, ", "))
|
||||
}
|
||||
|
||||
flag.StringVar(&addr, "addr", opt("YARR_ADDR", "127.0.0.1:7070"), "address to run server on")
|
||||
flag.StringVar(&basepath, "base", opt("YARR_BASE", ""), "base path of the service url")
|
||||
flag.StringVar(&authfile, "auth-file", opt("YARR_AUTHFILE", ""), "`path` to a file containing username:password. Takes precedence over --auth (or YARR_AUTH)")
|
||||
flag.StringVar(&auth, "auth", opt("YARR_AUTH", ""), "string with username and password in the format `username:password`")
|
||||
flag.StringVar(&certfile, "cert-file", opt("YARR_CERTFILE", ""), "`path` to cert file for https")
|
||||
flag.StringVar(&keyfile, "key-file", opt("YARR_KEYFILE", ""), "`path` to key file for https")
|
||||
flag.StringVar(&db, "db", opt("YARR_DB", ""), "storage file `path`")
|
||||
flag.StringVar(&logfile, "log-file", opt("YARR_LOGFILE", ""), "`path` to log file to use instead of stdout")
|
||||
flag.BoolVar(&ver, "version", false, "print application version")
|
||||
flag.BoolVar(&open, "open", false, "open the server in browser")
|
||||
flag.Parse()
|
||||
|
||||
if ver {
|
||||
fmt.Printf("v%s (%s)\n", Version, GitHash)
|
||||
return
|
||||
}
|
||||
|
||||
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||
if logfile != "" {
|
||||
file, err := os.OpenFile(logfile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to setup log file: ", err)
|
||||
}
|
||||
defer file.Close()
|
||||
log.SetOutput(file)
|
||||
} else {
|
||||
log.SetOutput(os.Stdout)
|
||||
}
|
||||
|
||||
configPath, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
log.Fatal("Failed to get config dir: ", err)
|
||||
}
|
||||
|
||||
if db == "" {
|
||||
storagePath := filepath.Join(configPath, "yarr")
|
||||
if err := os.MkdirAll(storagePath, 0755); err != nil {
|
||||
log.Fatal("Failed to create app config dir: ", err)
|
||||
}
|
||||
db = filepath.Join(storagePath, "storage.db")
|
||||
}
|
||||
|
||||
log.Printf("using db file %s", db)
|
||||
|
||||
var username, password string
|
||||
if authfile != "" {
|
||||
f, err := os.Open(authfile)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to open auth file: ", err)
|
||||
}
|
||||
defer f.Close()
|
||||
username, password, err = parseAuthfile(f)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to parse auth file: ", err)
|
||||
}
|
||||
} else if auth != "" {
|
||||
username, password, err = parseAuthfile(strings.NewReader(auth))
|
||||
if err != nil {
|
||||
log.Fatal("Failed to parse auth literal: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
if (certfile != "" || keyfile != "") && (certfile == "" || keyfile == "") {
|
||||
log.Fatalf("Both cert & key files are required")
|
||||
}
|
||||
|
||||
store, err := storage.New(db)
|
||||
if err != nil {
|
||||
log.Fatal("Failed to initialise database: ", err)
|
||||
}
|
||||
|
||||
srv := server.NewServer(store, addr)
|
||||
|
||||
if basepath != "" {
|
||||
srv.BasePath = "/" + strings.Trim(basepath, "/")
|
||||
}
|
||||
|
||||
if certfile != "" && keyfile != "" {
|
||||
srv.CertFile = certfile
|
||||
srv.KeyFile = keyfile
|
||||
}
|
||||
|
||||
if username != "" && password != "" {
|
||||
srv.Username = username
|
||||
srv.Password = password
|
||||
}
|
||||
|
||||
log.Printf("starting server at %s", srv.GetAddr())
|
||||
if open {
|
||||
platform.Open(srv.GetAddr())
|
||||
}
|
||||
platform.Start(srv)
|
||||
}
|
47
cmd/yarr/main_test.go
Normal file
47
cmd/yarr/main_test.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPasswordFromAuthfile(t *testing.T) {
|
||||
for _, tc := range [...]struct {
|
||||
authfile string
|
||||
expectedUsername string
|
||||
expectedPassword string
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
authfile: "username:password",
|
||||
expectedUsername: "username",
|
||||
expectedPassword: "password",
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
authfile: "username-and-no-password",
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
authfile: "username:password:with:columns",
|
||||
expectedUsername: "username",
|
||||
expectedPassword: "password:with:columns",
|
||||
expectedError: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.authfile, func(t *testing.T) {
|
||||
username, password, err := parseAuthfile(strings.NewReader(tc.authfile))
|
||||
if tc.expectedUsername != username {
|
||||
t.Errorf("expected username %q, got %q", tc.expectedUsername, username)
|
||||
}
|
||||
if tc.expectedPassword != password {
|
||||
t.Errorf("expected password %q, got %q", tc.expectedPassword, password)
|
||||
}
|
||||
if tc.expectedError && err == nil {
|
||||
t.Errorf("expected error, got nil")
|
||||
} else if !tc.expectedError && err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user