This commit is contained in:
lost+skunk 2024-08-01 22:48:05 +03:00
parent 2dfeaae772
commit c5514c3875
23 changed files with 445 additions and 249 deletions

166
app/cli.go Normal file
View file

@ -0,0 +1,166 @@
package app
import (
"bufio"
"bytes"
"encoding/json"
"os"
"time"
)
func ExecuteCommandLineArguments() {
const helpmsg = `SkunkyArt v1.3.1 [CSS improvements for mobile and the strips on Daily Deviations]
Usage:
- [-c|--config] | path to config
- [-a|--add-instance] | generates 'instances.json' and 'INSTANCES.md' files with ur instance
- [-h|--help] | returns this message
Example:
./skunkyart -c config.json
Copyright lost+skunk, X11. https://git.macaw.me/skunky/skunkyart/src/tag/v1.3.1`
a := os.Args[1:]
for n, x := range a {
switch x {
case "-c", "--config":
if len(a) >= 2 {
CFG.cfg = a[n+1]
} else {
exit("Not enought arguments", 1)
}
case "-h", "--help":
exit(helpmsg, 0)
case "-a", "--add-instance":
addInstance()
}
}
}
type settingsUrls struct {
I2P string `json:"i2p,omitempty"`
Ygg string `json:"ygg,omitempty"`
Tor string `json:"tor,omitempty"`
Clearnet string `json:"clearnet,omitempty"`
}
type settingsParams struct {
Nsfw bool `json:"nsfw"`
Proxy bool `json:"proxy"`
}
type settings struct {
Title string `json:"title"`
Country string `json:"country"`
ModifiedSrc string `json:"modified-src,omitempty"`
Urls settingsUrls `json:"urls"`
Settings settingsParams `json:"settings"`
}
func addInstance() {
prompt := func(txt string, necessary bool) string {
input := bufio.NewScanner(os.Stdin)
for {
print(txt)
print(": ")
input.Scan()
if i := input.Text(); necessary && i == "" {
println("Please specify the", txt)
} else {
return i
}
}
}
var settingsVar struct {
Instances []settings `json:"instances"`
}
instancesJson, err := os.OpenFile("instances.test.json", os.O_CREATE|os.O_WRONLY, 0644)
try(err)
defer instancesJson.Close()
instances, err := os.OpenFile("INSTANCES.md", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
try(err)
defer instances.Close()
for {
if Templates["instances.json"] == "" {
print("\rDownloading instance list...")
} else {
println("\r\033[2KDownloaded!")
try(json.Unmarshal([]byte(Templates["instances.json"]), &settingsVar))
settingsVar.Instances = append(settingsVar.Instances, settings{
Title: prompt("Title", true),
Country: prompt("Country", true),
ModifiedSrc: prompt("Link to modified sources", false),
Settings: settingsParams{
Nsfw: CFG.Nsfw,
Proxy: CFG.Proxy,
},
Urls: settingsUrls{
Clearnet: prompt("Clearnet link", false),
Ygg: prompt("Yggdrasil link", false),
Tor: prompt("Onion link", false),
I2P: prompt("I2P link", false),
},
})
j, err := json.MarshalIndent(&settingsVar, "", " ")
try(err)
instancesJson.Write(j)
settingsVar := &settingsVar.Instances[len(settingsVar.Instances)-1]
var mdstr bytes.Buffer
mdstr.WriteString("\n|")
if settingsVar.Urls.Clearnet != "" {
mdstr.WriteString("[")
mdstr.WriteString(settingsVar.Title)
mdstr.WriteString("](")
mdstr.WriteString(settingsVar.Urls.Clearnet)
mdstr.WriteString(")")
} else {
mdstr.WriteString(settingsVar.Title)
}
mdstr.WriteString("|")
urls := []string{settingsVar.Urls.Ygg, settingsVar.Urls.I2P, settingsVar.Urls.Tor}
for i, l := 0, len(urls); i < l; i++ {
url := urls[i]
if url != "" {
mdstr.WriteString("[Yes](")
mdstr.WriteString(url)
mdstr.WriteString(")|")
} else {
mdstr.WriteString("No|")
}
}
settings := []bool{settingsVar.Settings.Nsfw, settingsVar.Settings.Proxy}
for i, l := 0, len(settings); i < l; i++ {
if settings[i] {
mdstr.WriteString("Yes|")
} else {
mdstr.WriteString("No|")
}
}
if settingsVar.ModifiedSrc != "" {
mdstr.WriteString("[Yes](")
mdstr.WriteString(settingsVar.ModifiedSrc)
mdstr.WriteString(")|")
} else {
mdstr.WriteString("No|")
}
mdstr.WriteString(settingsVar.Country)
mdstr.WriteString("|")
instances.Write(mdstr.Bytes())
break
}
time.Sleep(500 * time.Millisecond)
}
exit("Done! Now add the files 'instances.json' and 'INSTANCES.md' to the 'master' branch in the repository https://git.macaw.me/skunky/SkunkyArt", 0)
}

View file

@ -21,7 +21,7 @@ type cache_config struct {
type config struct {
cfg string
Listen string
BasePath string `json:"base-path"`
URI string `json:"uri"`
Cache cache_config
Proxy, Nsfw bool
UserAgent string `json:"user-agent"`
@ -30,15 +30,15 @@ type config struct {
}
var CFG = config{
cfg: "config.json",
Listen: "127.0.0.1:3003",
BasePath: "/",
cfg: "config.json",
Listen: "127.0.0.1:3003",
URI: "/",
Cache: cache_config{
Enabled: true,
Enabled: false,
Path: "cache",
UpdateInterval: 1,
},
Dirs: []string{"html", "css"},
Dirs: []string{"html", "css", "misc"},
UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
Proxy: true,
Nsfw: true,
@ -47,42 +47,6 @@ var CFG = config{
var lifetimeParsed int64
func ExecuteConfig() {
go func() {
for {
func() {
defer func() {
if r := recover(); r != nil {
recover()
}
}()
Templates["instances.json"] = string(Download("https://git.macaw.me/skunky/SkunkyArt/raw/branch/master/instances.json").Body)
}()
time.Sleep(1 * time.Hour)
}
}()
const helpmsg = `SkunkyArt v1.3.1 [CSS improvements for mobile and strips on Daily Deviations]
Usage:
- [-c|--config] - path to config
- [-h|--help] - returns this message
Example:
./skunkyart -c config.json
Copyright lost+skunk, X11. https://git.macaw.me/skunky/skunkyart/src/tag/v1.3.1`
a := os.Args
for n, x := range a {
switch x {
case "-c", "--config":
if len(a) >= 3 {
CFG.cfg = a[n+1]
} else {
exit("Not enought arguments", 1)
}
case "-h", "--help":
exit(helpmsg, 0)
}
}
if CFG.cfg != "" {
f, err := os.ReadFile(CFG.cfg)
tryWithExitStatus(err, 1)

View file

@ -11,7 +11,7 @@ var Host string
func Router() {
parsepath := func(path string) map[int]string {
if l := len(CFG.BasePath); len(path) > l {
if l := len(CFG.URI); len(path) > l {
path = path[l-1:]
} else {
path = "/"
@ -54,7 +54,7 @@ func Router() {
var skunky skunkyart
skunky.Writer = w
skunky.Args = r.URL.Query()
skunky.BasePath = CFG.BasePath
skunky.BasePath = CFG.URI
arg := skunky.Args.Get
skunky.QueryRaw = arg("q")
@ -75,7 +75,7 @@ func Router() {
default:
skunky.ReturnHTTPError(404)
case "":
skunky.ExecuteTemplate("index.htm", &CFG.BasePath)
skunky.ExecuteTemplate("index.htm", &CFG.URI)
case "post":
skunky.Deviation(path[2], path[3])
case "search":

View file

@ -32,6 +32,20 @@ func tryWithExitStatus(err error, code int) {
}
}
func RefreshInstances() {
for {
func() {
defer func() {
if r := recover(); r != nil {
recover()
}
}()
Templates["instances.json"] = string(Download("https://git.macaw.me/skunky/SkunkyArt/raw/branch/master/instances.json").Body)
}()
time.Sleep(1 * time.Hour)
}
}
// some crap for frontend
func (s skunkyart) ExecuteTemplate(file string, data any) {
var buf strings.Builder
@ -46,7 +60,7 @@ func UrlBuilder(strs ...string) string {
var str strings.Builder
l := len(strs)
str.WriteString(Host)
str.WriteString(CFG.BasePath)
str.WriteString(CFG.URI)
for n, x := range strs {
str.WriteString(x)
if n+1 < l && !(strs[n+1][0] == '?' || strs[n+1][0] == '&') && !(x[0] == '?' || x[0] == '&') {
@ -220,11 +234,10 @@ func BuildUserPlate(name string) string {
func GetValueOfTag(t *html.Tokenizer) string {
for tt := t.Next(); ; {
switch tt {
default:
return ""
case html.TextToken:
if tt == html.TextToken {
return string(t.Text())
} else {
return ""
}
}
}

View file

@ -31,20 +31,7 @@ type skunkyart struct {
About struct {
Proxy bool
Nsfw bool
Instances []struct {
Title string
Country string
Urls []struct {
I2P string `json:"i2p"`
Ygg string
Tor string
Clearnet string
}
Settings struct {
Nsfw bool
Proxy bool
}
}
Instances []settings
}
SomeList string
@ -229,48 +216,49 @@ func (s skunkyart) GRUser() {
// посты
func (s skunkyart) Deviation(author, postname string) {
id_search := regexp.MustCompile("[0-9]+").FindAllString(postname, -1)
if len(id_search) >= 1 {
post := &s.Templates.Deviation
id := id_search[len(id_search)-1]
post.Post = devianter.GetDeviation(id, author)
if post.Post.Deviation.TextContent.Excerpt != "" {
post.Post.Description = ParseDescription(post.Post.Deviation.TextContent)
} else {
post.Post.Description = ParseDescription(post.Post.Deviation.Extended.DescriptionText)
}
// время публикации
post.StringTime = post.Post.Deviation.PublishedTime.UTC().String()
post.Post.IMG = ParseMedia(post.Post.Deviation.Media)
for _, x := range post.Post.Deviation.Extended.RelatedContent {
if len(x.Deviations) != 0 {
post.Related += s.DeviationList(x.Deviations, false)
}
}
// хештэги
for _, x := range post.Post.Deviation.Extended.Tags {
var tag strings.Builder
tag.WriteString(` <a href="`)
tag.WriteString(UrlBuilder("search", "?q=", x.Name, "&type=tag"))
tag.WriteString(`">#`)
tag.WriteString(x.Name)
tag.WriteString("</a>")
post.Tags += tag.String()
}
if post.Post.Comments.Total <= 50 {
post.Post.Comments.Cursor = ""
}
post.Comments = s.ParseComments(devianter.GetComments(id, post.Post.Comments.Cursor, s.Page, 1))
s.ExecuteTemplate("deviantion.htm", &s)
} else {
if len(id_search) < 1 {
s.ReturnHTTPError(400)
return
}
post := &s.Templates.Deviation
id := id_search[len(id_search)-1]
post.Post = devianter.GetDeviation(id, author)
if post.Post.Deviation.TextContent.Excerpt != "" {
post.Post.Description = ParseDescription(post.Post.Deviation.TextContent)
} else {
post.Post.Description = ParseDescription(post.Post.Deviation.Extended.DescriptionText)
}
// время публикации
post.StringTime = post.Post.Deviation.PublishedTime.UTC().String()
post.Post.IMG = ParseMedia(post.Post.Deviation.Media)
for _, x := range post.Post.Deviation.Extended.RelatedContent {
if len(x.Deviations) != 0 {
post.Related += s.DeviationList(x.Deviations, false)
}
}
// хештэги
for _, x := range post.Post.Deviation.Extended.Tags {
var tag strings.Builder
tag.WriteString(` <a href="`)
tag.WriteString(UrlBuilder("search", "?q=", x.Name, "&type=tag"))
tag.WriteString(`">#`)
tag.WriteString(x.Name)
tag.WriteString("</a>")
post.Tags += tag.String()
}
if post.Post.Comments.Total <= 50 {
post.Post.Comments.Cursor = ""
}
post.Comments = s.ParseComments(devianter.GetComments(id, post.Post.Comments.Cursor, s.Page, 1))
s.ExecuteTemplate("deviantion.htm", &s)
}
func (s skunkyart) DD() {
@ -298,7 +286,6 @@ func (s skunkyart) DD() {
}
func (s skunkyart) Search() {
s.Atom = false
var err error
ss := &s.Templates.Search
switch s.Type {
@ -365,15 +352,16 @@ func (s skunkyart) Search() {
}
func (s skunkyart) Emojitar(name string) {
if name != "" && (s.Type == 'a' || s.Type == 'e') {
ae, e := devianter.AEmedia(name, s.Type)
if e != nil {
s.ReturnHTTPError(404)
}
wr(s.Writer, ae)
} else {
if name == "" || !(s.Type == 'a' || s.Type == 'e') {
s.ReturnHTTPError(400)
return
}
ae, e := devianter.AEmedia(name, s.Type)
if e != nil {
s.ReturnHTTPError(404)
}
wr(s.Writer, ae)
}
func (s skunkyart) About() {