Path realization (dirty)
This commit is contained in:
parent
582f870578
commit
ab662f414c
|
@ -0,0 +1 @@
|
|||
**/cache
|
|
@ -34,5 +34,4 @@ $HTTP["host"] == "sa.example.com" {
|
|||
))
|
||||
)
|
||||
}
|
||||
```
|
||||
Учтите тот факт, что в настоящее время SkunkyArt корректно работать может только на поддомене.
|
||||
```
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"listen": "0.0.0.0:3003",
|
||||
"base_uri": null,
|
||||
"cache": {
|
||||
"enabled": true,
|
||||
"path": "cache",
|
||||
|
|
8
main.go
8
main.go
|
@ -39,6 +39,10 @@ func main() {
|
|||
page, _ := strconv.ParseInt(r.URL.Query().Get("p"), 10, 32)
|
||||
q := url.QueryEscape(r.URL.Query().Get("q"))
|
||||
|
||||
if util.Conf.Base_uri != "" {
|
||||
w.Header().Set("Content-Location", util.Conf.Base_uri)
|
||||
}
|
||||
|
||||
switch e {
|
||||
case "image":
|
||||
fmt.Fprintln(w, misc.Getimage(p, url.QueryEscape(r.URL.Query().Get("t"))))
|
||||
|
@ -97,6 +101,10 @@ func main() {
|
|||
}
|
||||
|
||||
func endpoint(url string) (string, string) {
|
||||
if util.Conf.Base_uri != "" {
|
||||
url = strings.Replace(url, util.Conf.Base_uri, "/", 1)
|
||||
}
|
||||
|
||||
end := strings.Index(url[1:], "/")
|
||||
if end == -1 {
|
||||
return url[1:], ""
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
package misc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
t "html/template"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func DD(page int, out chan string) {
|
||||
var buf bytes.Buffer
|
||||
{
|
||||
var (
|
||||
j struct {
|
||||
Deviations []util.Deviation
|
||||
}
|
||||
d, p string
|
||||
tmp struct {
|
||||
D, P string
|
||||
}
|
||||
)
|
||||
|
||||
if page == 0 {
|
||||
|
@ -26,17 +25,14 @@ func DD(page int, out chan string) {
|
|||
json.Unmarshal([]byte(rawjson), &j)
|
||||
|
||||
for _, a := range j.Deviations {
|
||||
d += util.Images(a, a.Media, false)
|
||||
tmp.D += util.Images(a, a.Media, false)
|
||||
}
|
||||
|
||||
if page > 1 {
|
||||
p += "<a href=\"/dd?p=" + strconv.Itoa(int(page)-1) + "\"><-- Back</a> "
|
||||
tmp.P += "<a href=\"" + util.Conf.Base_uri + "dd?p=" + strconv.Itoa(int(page)-1) + "\"><-- Back</a> "
|
||||
}
|
||||
p += "<a href=\"/dd?p=" + strconv.Itoa(int(page)+1) + "\">Next --></a>"
|
||||
tmp.P += "<a href=\"" + util.Conf.Base_uri + "dd?p=" + strconv.Itoa(int(page)+1) + "\">Next --></a>"
|
||||
|
||||
tmp, _ := t.ParseFiles("templates/dd.htm")
|
||||
tmp.Execute(&buf, t.HTML(d))
|
||||
tmp.ExecuteTemplate(&buf, "P", t.HTML(p))
|
||||
out <- util.TmpExec("templates/dd.htm", &tmp)
|
||||
}
|
||||
out <- buf.String()
|
||||
}
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
package misc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
"math"
|
||||
"os"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func Search(q, p, scope string, output chan string) {
|
||||
var buf bytes.Buffer
|
||||
var tmp struct {
|
||||
Results, Pages string
|
||||
Total int
|
||||
}
|
||||
|
||||
if q != "" {
|
||||
var j struct {
|
||||
EstTotal int
|
||||
|
@ -30,10 +31,6 @@ func Search(q, p, scope string, output chan string) {
|
|||
|
||||
json.Unmarshal([]byte(rawjson), &j)
|
||||
|
||||
var tmp struct {
|
||||
Results, Pages string
|
||||
Total int
|
||||
}
|
||||
for _, a := range j.Deviations {
|
||||
tmp.Results += util.Images(a, a.Media, false)
|
||||
}
|
||||
|
@ -45,7 +42,7 @@ func Search(q, p, scope string, output chan string) {
|
|||
if x == 417 {
|
||||
break
|
||||
}
|
||||
tmp.Pages += "<a href=\"/search?p=" + strconv.Itoa(x+1) + "&scope=all&q=" + q + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
tmp.Pages += "<a href=\"" + util.Conf.Base_uri + "search?p=" + strconv.Itoa(x+1) + "&scope=all&q=" + q + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
}
|
||||
case "tag":
|
||||
if p == "" {
|
||||
|
@ -53,20 +50,14 @@ func Search(q, p, scope string, output chan string) {
|
|||
}
|
||||
next, _ := strconv.ParseInt(p, 10, 32)
|
||||
if int(next) > 1 {
|
||||
tmp.Pages += "<a href=\"/search?p=" + strconv.Itoa(int(next)-1) + "&scope=tag&q=" + q + "\"><-- Back</a> "
|
||||
tmp.Pages += "<a href=\"" + util.Conf.Base_uri + "search?p=" + strconv.Itoa(int(next)-1) + "&scope=tag&q=" + q + "\"><-- Back</a> "
|
||||
}
|
||||
tmp.Pages += "<a href=\"/search?p=" + strconv.Itoa(int(next)+1) + "&scope=tag&q=" + q + "\">Next --></a>"
|
||||
tmp.Pages += "<a href=\"" + util.Conf.Base_uri + "search?p=" + strconv.Itoa(int(next)+1) + "&scope=tag&q=" + q + "\">Next --></a>"
|
||||
default:
|
||||
output <- "Missing or invalid scope."
|
||||
}
|
||||
|
||||
tmpl, _ := template.ParseFiles("templates/search/search.htm")
|
||||
tmpl.Execute(&buf, tmp.Total)
|
||||
tmpl.ExecuteTemplate(&buf, "R", template.HTML(tmp.Results))
|
||||
tmpl.ExecuteTemplate(&buf, "P", template.HTML(tmp.Pages))
|
||||
} else {
|
||||
doc, _ := os.ReadFile("templates/search/search-base.htm")
|
||||
output <- string(doc)
|
||||
output <- "Missing query."
|
||||
}
|
||||
output <- buf.String()
|
||||
output <- util.TmpExec("templates/search/search.htm", &tmp)
|
||||
}
|
||||
|
|
|
@ -62,9 +62,7 @@ func GetComments(uri, cursor string, page, typ int, id []string) *string {
|
|||
rawjson, next, prev := js(cursor, page, id, typ)
|
||||
|
||||
err := json.Unmarshal([]byte(*rawjson), &comments)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
util.Err(err)
|
||||
|
||||
// обработка жирсона
|
||||
var htm string
|
||||
|
@ -85,9 +83,7 @@ func GetComments(uri, cursor string, page, typ int, id []string) *string {
|
|||
}
|
||||
|
||||
err := json.Unmarshal([]byte(b.TextContent.Html.Markup), &comments)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
util.Err(err)
|
||||
|
||||
for _, a := range comments.Blocks {
|
||||
msgbody = a.Text
|
||||
|
@ -120,7 +116,7 @@ func GetComments(uri, cursor string, page, typ int, id []string) *string {
|
|||
|
||||
msgbody = util.Parse(msgbody)
|
||||
|
||||
htm += fmt.Sprintf("<div class=\"msg\" style=\"%[10]s\"><p id=\"%[2]d\"><img src=\"/avatar/%[1]s\" width=\"30px\" height=\"30px\"/> <a href=\"/user/%[1]s\"><b class=\"%[6]s %[5]t\">%[1]s</b></a> %[4]s %[9]s<p>%[3]s<p>👍: %[7]d ⏩: %[8]d</p></div>\n", b.User.Username, b.CommentId, msgbody, b.Posted.UTC().String(), b.User.IsBanned, isauthor, b.Likes, b.Replies, reply, space)
|
||||
htm += fmt.Sprintf("<div class=\"msg\" style=\"%[10]s\"><p id=\"%[2]d\"><img src=\""+util.Conf.Base_uri+"avatar/%[1]s\" width=\"30px\" height=\"30px\"/> <a href=\""+util.Conf.Base_uri+"user/%[1]s\"><b class=\"%[6]s %[5]t\">%[1]s</b></a> %[4]s %[9]s<p>%[3]s<p>👍: %[7]d ⏩: %[8]d</p></div>\n", b.User.Username, b.CommentId, msgbody, b.Posted.UTC().String(), b.User.IsBanned, isauthor, b.Likes, b.Replies, reply, space)
|
||||
}
|
||||
|
||||
// если комментариев больше, чем 0, то отображаем их, иначе пишем, что комментов нет.
|
||||
|
|
14
post/main.go
14
post/main.go
|
@ -1,9 +1,7 @@
|
|||
package post
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
"regexp"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
|
@ -94,7 +92,7 @@ func _post(id []string, author string, url string, page int) string {
|
|||
|
||||
tmp.Tags = ""
|
||||
for _, a := range j.Deviation.Extended.Tags {
|
||||
tmp.Tags += "<a href=\"/search?q=" + a.Name + "&scope=tag\">#" + a.Name + "</a> "
|
||||
tmp.Tags += "<a href=\"" + util.Conf.Base_uri + "search?q=" + a.Name + "&scope=tag\">#" + a.Name + "</a> "
|
||||
}
|
||||
|
||||
tmp.Comments = ""
|
||||
|
@ -116,7 +114,6 @@ func Get(uri string, page int, output chan string) {
|
|||
|
||||
id := regexp.MustCompile("[0-9]+").FindAllString(uri, -1)
|
||||
|
||||
var buffer bytes.Buffer
|
||||
body, status, _, _ := util.Request(url, "")
|
||||
if status == 200 {
|
||||
body = body[strings.Index(body, " by ")+4:]
|
||||
|
@ -127,14 +124,7 @@ func Get(uri string, page int, output chan string) {
|
|||
}
|
||||
|
||||
// темплейт
|
||||
templ, _ := template.ParseFiles("templates/post.htm")
|
||||
templ.Execute(&buffer, tmp)
|
||||
templ.ExecuteTemplate(&buffer, "T", template.HTML(tmp.Tags))
|
||||
templ.ExecuteTemplate(&buffer, "D", template.HTML(tmp.Description))
|
||||
templ.ExecuteTemplate(&buffer, "R", template.HTML(tmp.Recomendations))
|
||||
templ.ExecuteTemplate(&buffer, "C", template.HTML(string(tmp.Comments)))
|
||||
|
||||
output <- buffer.String()
|
||||
output <- util.TmpExec("templates/post.htm", &tmp)
|
||||
} else {
|
||||
output <- "Something went wrong. Status: " + strconv.Itoa(int(status))
|
||||
}
|
||||
|
|
|
@ -38,6 +38,8 @@ form input, button, select {
|
|||
color: rgb(160, 0, 147);
|
||||
}
|
||||
.content {
|
||||
background-color: #001624;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Daily Deviations | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<form method="get" action="/search">
|
||||
<form method="get" action="search">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<select name="scope">
|
||||
<option value="all">All</option>
|
||||
|
@ -16,11 +16,9 @@
|
|||
</form>
|
||||
<h1>Daily Deviations</h1>
|
||||
<div class="content">
|
||||
{{.}}
|
||||
{{.D}}
|
||||
</div>
|
||||
{{define "P"}}
|
||||
<hr>
|
||||
{{.}}
|
||||
<hr>
|
||||
{{.P}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
</html>
|
|
@ -3,17 +3,19 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<form method="get" action="/search">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<select name="scope">
|
||||
<option value="all">All</option>
|
||||
<option value="tag">Tag</option>
|
||||
</select>
|
||||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
<h1><a href="/dd">Daily Deviations</a> <a href="/about">About</a> <a href="https://git.macaw.me/skunky/SkunkyArt" target="_blank">Source Code</a></h1>
|
||||
<center>
|
||||
<form method="get" action="search">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<select name="scope">
|
||||
<option value="all">All</option>
|
||||
<option value="tag">Tag</option>
|
||||
</select>
|
||||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
<h1><a href="dd">Daily Deviations</a> | <a href="about">About</a> | <a href="https://git.macaw.me/skunky/SkunkyArt" target="_blank">Source Code</a></h1>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +1,13 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
!BAZE!
|
||||
<meta charset="UTF-8">
|
||||
<title>{{.Author}} — {{.Postname}} | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<form method="get" action="/search">
|
||||
<form method="get" action="search">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<select name="scope">
|
||||
<option value="all">All</option>
|
||||
|
@ -15,39 +16,35 @@
|
|||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
<figure>
|
||||
<img src="/avatar/{{.Author}}" width="30px">
|
||||
<span><strong><a href="/user/{{.Author}}">{{.Author}}</a></strong> — {{if (.DD)}}
|
||||
<img src="avatar/{{.Author}}" width="30px">
|
||||
<span><strong><a href="user/{{.Author}}">{{.Author}}</a></strong> — {{if (.DD)}}
|
||||
<span class="dd" title="Daily Deviation!"><b>{{.Postname}}</b></span>
|
||||
{{else}}{{.Postname}}{{end}}
|
||||
{{if (ne .License "none")}}({{.License}}){{end}} {{if (.Ai)}}[🤖]{{end}}
|
||||
{{if (.Nsfw)}}[<span class="nsfw">NSFW</span>]{{end}}
|
||||
</span>
|
||||
<br>
|
||||
{{if (ne .Img "/image/")}}
|
||||
{{if (ne .Img "no")}}
|
||||
<img src="{{.Img}}" width="50%">
|
||||
<br>
|
||||
{{end}}
|
||||
<span>Published: <strong>{{.Time}}</strong>; Views: <strong>{{.Views}}</strong>; Favourites: <strong>{{.FavsCount}}</strong>; Downloads: <strong>{{.Downloads}}</strong></span>
|
||||
{{define "T"}}
|
||||
{{if (ne . "")}}
|
||||
{{if (ne .Tags "")}}
|
||||
<br>
|
||||
<span>Tags: <strong>{{.}}</strong></span>
|
||||
<span>Tags: <strong>{{.Tags}}</strong></span>
|
||||
{{end}}
|
||||
{{if (ne .Description "")}}
|
||||
<br>
|
||||
<br>
|
||||
<figcaption>{{.Description}}</figcaption>
|
||||
{{end}}
|
||||
{{define "R"}}
|
||||
{{if (ne .Recomendations "")}}
|
||||
<h2>See also:</h2>
|
||||
<div class="content">
|
||||
{{.}}
|
||||
{{.Recomendations}}
|
||||
</div>
|
||||
{{end}}
|
||||
<br>
|
||||
<br>
|
||||
{{define "D"}}
|
||||
<figcaption>{{.}}</figcaption>
|
||||
{{end}}
|
||||
{{define "C"}}
|
||||
{{.}}
|
||||
{{.Comments}}
|
||||
</figure>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
</html>
|
|
@ -1,18 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Search | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<form method="get" action="/search">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<select name="scope">
|
||||
<option value="all">All</option>
|
||||
<option value="tag">Tag</option>
|
||||
</select>
|
||||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +1,13 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
!BAZE!
|
||||
<meta charset="UTF-8">
|
||||
<title>Search | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<form method="get" action="/search">
|
||||
<form method="get" action="search">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<select name="scope">
|
||||
<option value="all">All</option>
|
||||
|
@ -14,18 +15,16 @@
|
|||
</select>
|
||||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
<hr>
|
||||
{{if (ne . 0)}}
|
||||
<h1>Total resuls: {{.}}</h1>
|
||||
{{if (ne .Results "")}}
|
||||
{{if (ne .Total 0)}}
|
||||
<h1>Total resuls: {{.Total}}</h1>
|
||||
{{end}}
|
||||
{{define "R"}}
|
||||
<div class="content">
|
||||
{{.}}
|
||||
{{.Results}}
|
||||
</div>
|
||||
{{.Pages}}
|
||||
{{else}}
|
||||
<p>No results :(</p>
|
||||
{{end}}
|
||||
{{define "P"}}
|
||||
<hr>
|
||||
{{.}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
</html>
|
|
@ -1,20 +1,23 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
!BAZE!
|
||||
<title>{{.Name}}'s Gallery | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<img src="/avatar/{{.Name}}" width="60px"><h1>Gallery of {{.Name}}</h1></img>
|
||||
<h2><a href="/user/{{.Name}}">Home</a> | <a href="/user/{{.Name}}?a=search">Search</a></h2>
|
||||
{{define "G"}}
|
||||
<img src="avatar/{{.Name}}" width="60px"><h1>Gallery of {{.Name}}</h1></img>
|
||||
<h2><form method="get" action="">
|
||||
<input type="text" name="q" placeholder="Search {{.Name}}'s Gallery!" autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<input type="hidden" name="a" value="search">
|
||||
<button type="submit">Search!</button>
|
||||
</form> <a href="user/{{.Name}}">Home</a>
|
||||
</h2>
|
||||
|
||||
<div class="content">
|
||||
{{.}}
|
||||
{{.Posts}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "P"}}
|
||||
<hr>
|
||||
<p><b>Pages: {{.}}</b></p>
|
||||
<p><b>Pages: {{.Nav}}</b></p>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
</html>
|
|
@ -1,15 +1,16 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
!BAZE!
|
||||
<title>{{.Name}} | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
{{if (ne .Bg "/image/")}}
|
||||
{{if (ne .Bg "no")}}
|
||||
<img src="{{.Bg}}" width="30%" title="{{.Bgname}}">
|
||||
{{end}}
|
||||
<h1><img src="/avatar/{{.Name}}" width="60px">{{.Name}} {{.Gender}}</h1>
|
||||
<h2><a href="/user/{{.Name}}?a=gallery">Gallery</a></h2>
|
||||
<h1><img src="avatar/{{.Name}}" width="60px">{{.Name}} {{.Gender}}</h1>
|
||||
<h2><a href="user/{{.Name}}?a=gallery">Gallery</a></h2>
|
||||
<p>Watchers: {{.Watchers}}; Watching: {{.Watching}}; Comments on Profile: {{.CMMRCPF}}; Posts: {{.Posts}}; Pageviews: {{.Pageviews}}; Comments: {{.CM}};
|
||||
Favourites: {{.Fav}}; Friends: {{.Friends}}
|
||||
</p>
|
||||
|
@ -18,22 +19,12 @@
|
|||
<a href="https://{{.Site}}" target="_blank">{{.SiteTitle}}</a>
|
||||
</p>
|
||||
<p><i title="User status">{{.Status}}</i></p>
|
||||
{{define "S"}}
|
||||
<h2>Social Links</h2>
|
||||
<p>
|
||||
{{.}}
|
||||
</p>
|
||||
{{end}}
|
||||
{{define "I"}}
|
||||
<p>{{.Social}}</p>
|
||||
<h2>Interests</h2>
|
||||
<p>{{.}}</p>
|
||||
{{end}}
|
||||
{{define "D"}}
|
||||
<p>{{.Interests}}</p>
|
||||
<h2>About me</h2>
|
||||
<p>{{.}}</p>
|
||||
{{end}}
|
||||
{{define "C"}}
|
||||
{{.}}
|
||||
<p>{{.Description}}</p>
|
||||
{{.Comments}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
</html>
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Search {{.}}'s Gallery | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<img src="/avatar/{{.}}" width="60px"><h1>Search gallery of {{.}}.</h1></img>
|
||||
<h2><a href="/user/{{.}}">Home</a> | <a href="/user/{{.}}?a=gallery">Gallery</a></h2>
|
||||
<form method="get" action="/user/{{.}}">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<input type="hidden" name="a" value="search">
|
||||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,25 +1,26 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
!BAZE!
|
||||
<title>Search {{.Name}}'s Gallery | SkunkyArt</title>
|
||||
<link rel="stylesheet" href="/static/base.css">
|
||||
<link rel="stylesheet" href="static/base.css">
|
||||
</head>
|
||||
<body>
|
||||
<img src="/avatar/{{.Name}}" width="60px"><h1>Search gallery of {{.Name}}. Total Deviations: {{.Total}}</h1></img>
|
||||
<h2><a href="/user/{{.Name}}">Home</a> | <a href="/user/{{.Name}}?a=gallery">Gallery</a></h2>
|
||||
<form method="get" action="/user/{{.Name}}">
|
||||
<input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<input type="hidden" name="a" value="search">
|
||||
<button type="submit">Search!</button>
|
||||
</form>
|
||||
{{define "R"}}
|
||||
<img src="avatar/{{.Name}}" width="60px"><h1>Search gallery of {{.Name}}. Total Deviations: {{.Total}}</h1></img>
|
||||
<h2><form method="get" action="">
|
||||
<input type="text" name="q" placeholder="Search {{.Name}}'s Gallery!" autocomplete="off" autocapitalize="none" spellcheck="false">
|
||||
<input type="hidden" name="a" value="search">
|
||||
<button type="submit">Search!</button>
|
||||
</form> <a href="user/{{.Name}}">Home</a>
|
||||
</h2>
|
||||
{{if (ne .Total 0)}}
|
||||
<div class="content">
|
||||
{{.}}
|
||||
{{.Results}}
|
||||
</div>
|
||||
{{end}}
|
||||
{{define "P"}}
|
||||
<hr>
|
||||
<p><b>Pages: {{.}}</b></p>
|
||||
<p><b>Pages: {{.Pages}}</b></p>
|
||||
{{else}}
|
||||
<p>Gallery is empty :(</p>
|
||||
{{end}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
</html>
|
2
todo.md
2
todo.md
|
@ -1,7 +1,7 @@
|
|||
Нужно сделать:
|
||||
- провести оптимизацию кода
|
||||
- кеширование жсона
|
||||
- реализовать работу на определённом пути (https://example.com/skunkyart)
|
||||
- ~~реализовать работу на определённом пути (https://example.com/skunkyart)~~
|
||||
- ~~добавить устаревание кеша и его максимальный вес~~
|
||||
- ~~проксирование и кеширование гифок~~
|
||||
- картинки в комментариях
|
||||
|
|
191
user/about.go
191
user/about.go
|
@ -1,10 +1,7 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"skunkyart/post"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
|
@ -12,122 +9,102 @@ import (
|
|||
)
|
||||
|
||||
type Tmp struct {
|
||||
Watchers, Posts, Watching, Pageviews, CMMRCPF, CM, Fav, Friends int
|
||||
Name, Description, Bg, Bgname, Country, RegDate, Gender, Site, SiteTitle, Social, Interests, Status string
|
||||
Watchers, Posts, Watching, Pageviews, CMMRCPF, CM, Fav, Friends int
|
||||
Name, Description, Bg, Bgname, Country, RegDate, Gender, Site, SiteTitle, Social, Interests, Status, Comments string
|
||||
}
|
||||
|
||||
func about(name *string, page int, output chan string) {
|
||||
ums := time.Now().Unix()
|
||||
uid := make([]string, 1)
|
||||
|
||||
var buf bytes.Buffer
|
||||
{
|
||||
var tmp Tmp
|
||||
var j ab
|
||||
|
||||
// парсинг
|
||||
rawjson := util.Puppy("dauserprofile/init/about?username=" + *name)
|
||||
err := json.Unmarshal([]byte(rawjson), &j)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
if rawjson == "Something went wrong. Status: 403" {
|
||||
output <- "Rate limit from Cloudfront."
|
||||
} else {
|
||||
output <- "Something went wrong."
|
||||
}
|
||||
} else {
|
||||
// ошибки
|
||||
switch j.ErrorDescription {
|
||||
case "User deactivated.":
|
||||
output <- "User deactivated their account or has been banned."
|
||||
case "user_not_found.":
|
||||
output <- "Not exists user."
|
||||
}
|
||||
j.ErrorDescription = ""
|
||||
|
||||
uid[0] = strconv.Itoa(j.Gruser.GruserId)
|
||||
for _, a := range j.Gruser.Page.Modules {
|
||||
if a.ModuleData.About.Country != "" {
|
||||
tmp.Country = a.ModuleData.About.Country
|
||||
}
|
||||
|
||||
switch a.Name {
|
||||
case "about":
|
||||
var j struct {
|
||||
Blocks []struct {
|
||||
Text string
|
||||
// InlineStyleRanges []struct {
|
||||
// Offset, Length int
|
||||
// Style string
|
||||
// EntityMap struct {
|
||||
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(a.ModuleData.About.TextContent.Html.Markup), &j)
|
||||
|
||||
for _, a := range j.Blocks {
|
||||
tmp.Description += a.Text + "<p>"
|
||||
}
|
||||
case "cover_deviation":
|
||||
tmp.Bg = util.Images(a.ModuleData.CoverDeviation.CoverDeviation, a.ModuleData.CoverDeviation.CoverDeviation.Media, true)
|
||||
tmp.Bgname = a.ModuleData.CoverDeviation.CoverDeviation.Title
|
||||
}
|
||||
|
||||
if a.ModuleData.About.DeviantFor > 0 {
|
||||
tmp.RegDate = time.Unix(ums-a.ModuleData.About.DeviantFor, 0).UTC().String()
|
||||
}
|
||||
|
||||
switch a.ModuleData.About.Gender {
|
||||
case "female":
|
||||
tmp.Gender = "♀️"
|
||||
case "male":
|
||||
tmp.Gender = "♂️"
|
||||
}
|
||||
|
||||
if a.ModuleData.About.Website != "" {
|
||||
tmp.Site = a.ModuleData.About.Website
|
||||
if a.ModuleData.About.WebsiteLabel != "" {
|
||||
tmp.SiteTitle = a.ModuleData.About.WebsiteLabel
|
||||
} else {
|
||||
tmp.SiteTitle = a.ModuleData.About.Website
|
||||
}
|
||||
}
|
||||
|
||||
for _, a := range a.ModuleData.About.SocialLinks {
|
||||
tmp.Social += "<a href=\"" + a.Value + "\" target=\"_blank\">" + a.Value + "</a><p>"
|
||||
}
|
||||
|
||||
for _, a := range a.ModuleData.About.Interests {
|
||||
tmp.Interests += "<b>" + a.Label + "</b>: " + a.Value + "<p>"
|
||||
}
|
||||
|
||||
if a.ModuleData.About.Tagline != "" {
|
||||
tmp.Status = a.ModuleData.About.Tagline
|
||||
}
|
||||
|
||||
// говно
|
||||
tmp.Watchers = j.PageExtraData.Stats.Watchers
|
||||
tmp.Posts = j.PageExtraData.Stats.Deviations
|
||||
tmp.Watching = j.PageExtraData.Stats.Watching
|
||||
tmp.CMMRCPF = j.PageExtraData.Stats.CommentsReceivedProfile
|
||||
tmp.CM = j.PageExtraData.Stats.CommentsMade
|
||||
tmp.Fav = j.PageExtraData.Stats.Favourites
|
||||
tmp.Friends = j.PageExtraData.Stats.Friends
|
||||
tmp.Name = j.Owner.Username
|
||||
}
|
||||
|
||||
// темплейты
|
||||
tmpl, _ := template.ParseFiles("templates/user/info.htm")
|
||||
tmpl.Execute(&buf, tmp)
|
||||
tmpl.ExecuteTemplate(&buf, "S", template.HTML(tmp.Social))
|
||||
tmpl.ExecuteTemplate(&buf, "I", template.HTML(tmp.Interests))
|
||||
tmpl.ExecuteTemplate(&buf, "D", template.HTML(tmp.Description))
|
||||
tmpl.ExecuteTemplate(&buf, "C", template.HTML(*post.GetComments("user/"+tmp.Name, "", page+1, 4, uid)))
|
||||
e := rerror(&rawjson)
|
||||
if e != "" {
|
||||
output <- e
|
||||
}
|
||||
}
|
||||
json.Unmarshal([]byte(rawjson), &j)
|
||||
|
||||
output <- buf.String()
|
||||
// ошибки
|
||||
uid[0] = strconv.Itoa(j.Gruser.GruserId)
|
||||
for _, a := range j.Gruser.Page.Modules {
|
||||
if a.ModuleData.About.Country != "" {
|
||||
tmp.Country = a.ModuleData.About.Country
|
||||
}
|
||||
|
||||
switch a.Name {
|
||||
case "about":
|
||||
var j struct {
|
||||
Blocks []struct {
|
||||
Text string
|
||||
// InlineStyleRanges []struct {
|
||||
// Offset, Length int
|
||||
// Style string
|
||||
// EntityMap struct {
|
||||
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(a.ModuleData.About.TextContent.Html.Markup), &j)
|
||||
|
||||
for _, a := range j.Blocks {
|
||||
tmp.Description += a.Text + "<p>"
|
||||
}
|
||||
case "cover_deviation":
|
||||
tmp.Bg = util.Images(a.ModuleData.CoverDeviation.CoverDeviation, a.ModuleData.CoverDeviation.CoverDeviation.Media, true)
|
||||
tmp.Bgname = a.ModuleData.CoverDeviation.CoverDeviation.Title
|
||||
}
|
||||
|
||||
if a.ModuleData.About.DeviantFor > 0 {
|
||||
tmp.RegDate = time.Unix(ums-a.ModuleData.About.DeviantFor, 0).UTC().String()
|
||||
}
|
||||
|
||||
switch a.ModuleData.About.Gender {
|
||||
case "female":
|
||||
tmp.Gender = "♀️"
|
||||
case "male":
|
||||
tmp.Gender = "♂️"
|
||||
}
|
||||
|
||||
if a.ModuleData.About.Website != "" {
|
||||
tmp.Site = a.ModuleData.About.Website
|
||||
if a.ModuleData.About.WebsiteLabel != "" {
|
||||
tmp.SiteTitle = a.ModuleData.About.WebsiteLabel
|
||||
} else {
|
||||
tmp.SiteTitle = a.ModuleData.About.Website
|
||||
}
|
||||
}
|
||||
|
||||
for _, a := range a.ModuleData.About.SocialLinks {
|
||||
tmp.Social += "<a href=\"" + a.Value + "\" target=\"_blank\">" + a.Value + "</a><p>"
|
||||
}
|
||||
|
||||
for _, a := range a.ModuleData.About.Interests {
|
||||
tmp.Interests += "<b>" + a.Label + "</b>: " + a.Value + "<p>"
|
||||
}
|
||||
|
||||
if a.ModuleData.About.Tagline != "" {
|
||||
tmp.Status = a.ModuleData.About.Tagline
|
||||
}
|
||||
|
||||
// говно
|
||||
tmp.Watchers = j.PageExtraData.Stats.Watchers
|
||||
tmp.Posts = j.PageExtraData.Stats.Deviations
|
||||
tmp.Watching = j.PageExtraData.Stats.Watching
|
||||
tmp.CMMRCPF = j.PageExtraData.Stats.CommentsReceivedProfile
|
||||
tmp.CM = j.PageExtraData.Stats.CommentsMade
|
||||
tmp.Fav = j.PageExtraData.Stats.Favourites
|
||||
tmp.Friends = j.PageExtraData.Stats.Friends
|
||||
tmp.Name = j.Owner.Username
|
||||
tmp.Comments = *post.GetComments("user/"+tmp.Name, "", page+1, 4, uid)
|
||||
}
|
||||
|
||||
output <- util.TmpExec("templates/user/info.htm", tmp)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func gallery(name *string, output chan string, page string) {
|
||||
var buf bytes.Buffer
|
||||
{
|
||||
var tmp struct {
|
||||
Posts, Name, Nav string
|
||||
|
@ -35,38 +31,30 @@ func gallery(name *string, output chan string, page string) {
|
|||
|
||||
rawjson := util.Puppy("dauserprofile/init/gallery?username=" + *name + "&page=" + page + "&deviations_limit=50&with_subfolders=false")
|
||||
err := json.Unmarshal([]byte(rawjson), &j)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
if rawjson == "Something went wrong. Status: 403" {
|
||||
output <- "Rate limit from CloudFront."
|
||||
} else {
|
||||
output <- "Something went wrong."
|
||||
}
|
||||
} else {
|
||||
for _, a := range j.Gruser.Page.Modules {
|
||||
if a.ModuleData.FolderDeviations.Username != "" {
|
||||
tmp.Name = a.ModuleData.FolderDeviations.Username
|
||||
}
|
||||
if a.ModuleData.FolderDeviations.TotalPageCount != 0 {
|
||||
tmp.TP = a.ModuleData.FolderDeviations.TotalPageCount
|
||||
}
|
||||
|
||||
for _, a := range a.ModuleData.FolderDeviations.Deviations {
|
||||
tmp.Posts += util.Images(a, a.Media, false)
|
||||
}
|
||||
|
||||
tmp.Nav = ""
|
||||
for x := 0; x < tmp.TP; x++ {
|
||||
tmp.Nav += "<a href=\"/user/" + tmp.Name + "?a=gallery&p=" + strconv.Itoa(x+1) + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
}
|
||||
}
|
||||
util.Err(err)
|
||||
e := rerror(&rawjson)
|
||||
if e != "" {
|
||||
output <- e
|
||||
}
|
||||
|
||||
tmpl, _ := template.ParseFiles("templates/user/gallery.htm")
|
||||
tmpl.Execute(&buf, tmp)
|
||||
tmpl.ExecuteTemplate(&buf, "G", template.HTML(tmp.Posts))
|
||||
tmpl.ExecuteTemplate(&buf, "P", template.HTML(tmp.Nav))
|
||||
}
|
||||
for _, a := range j.Gruser.Page.Modules {
|
||||
if a.ModuleData.FolderDeviations.Username != "" {
|
||||
tmp.Name = a.ModuleData.FolderDeviations.Username
|
||||
}
|
||||
if a.ModuleData.FolderDeviations.TotalPageCount != 0 {
|
||||
tmp.TP = a.ModuleData.FolderDeviations.TotalPageCount
|
||||
}
|
||||
|
||||
output <- buf.String()
|
||||
for _, a := range a.ModuleData.FolderDeviations.Deviations {
|
||||
tmp.Posts += util.Images(a, a.Media, false)
|
||||
}
|
||||
|
||||
tmp.Nav = ""
|
||||
for x := 0; x < tmp.TP; x++ {
|
||||
tmp.Nav += "<a href=\"" + util.Conf.Base_uri + "user/" + tmp.Name + "?a=gallery&p=" + strconv.Itoa(x+1) + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
}
|
||||
}
|
||||
output <- util.TmpExec("templates/user/gallery.htm", &tmp)
|
||||
}
|
||||
}
|
||||
|
|
25
user/misc.go
25
user/misc.go
|
@ -1,6 +1,7 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"skunkyart/util"
|
||||
)
|
||||
|
||||
|
@ -45,3 +46,27 @@ type ab struct {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rerror(err *string) string {
|
||||
if len(*err) < 100 {
|
||||
var j struct {
|
||||
ErrorDescription string
|
||||
}
|
||||
|
||||
json.Unmarshal([]byte(*err), &j)
|
||||
|
||||
switch j.ErrorDescription {
|
||||
case "User deactivated.":
|
||||
return "User deactivated their account or has been banned."
|
||||
case "user_not_found.":
|
||||
return "Not exists user."
|
||||
default:
|
||||
if *err == "Something went wrong. Status: 403" {
|
||||
return "Rate limit from CloudFront."
|
||||
} else {
|
||||
return "Something went wrong."
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"math"
|
||||
"skunkyart/util"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func search(user, query *string, page int, output chan string) {
|
||||
var buf bytes.Buffer
|
||||
{
|
||||
var tmp struct {
|
||||
Total int
|
||||
|
@ -26,31 +22,25 @@ func search(user, query *string, page int, output chan string) {
|
|||
if *query != "" {
|
||||
rawjson := util.Puppy("dashared/gallection/search?username=" + *user + "&q=" + *query + "&offset=" + strconv.Itoa(50*page) + "&type=gallery&order=most-recent&init=true&limit=50")
|
||||
err := json.Unmarshal([]byte(rawjson), &q)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
if q.EstTotal != 0 {
|
||||
tmp.Total = q.EstTotal
|
||||
}
|
||||
util.Err(err)
|
||||
|
||||
for _, a := range q.Results {
|
||||
tmp.Results += util.Images(a, a.Media, false)
|
||||
}
|
||||
|
||||
tmp.Pages = ""
|
||||
tmp.Name = *user
|
||||
for x := 0; x < int(math.Round(float64(q.EstTotal/50))); x++ {
|
||||
tmp.Pages += "<a href=\"/user/" + tmp.Name + "?a=search&p=" + strconv.Itoa(x+1) + "&q=" + *query + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
}
|
||||
if q.EstTotal != 0 {
|
||||
tmp.Total = q.EstTotal
|
||||
}
|
||||
tmpl, _ := template.ParseFiles("templates/user/search.htm")
|
||||
tmpl.Execute(&buf, tmp)
|
||||
tmpl.ExecuteTemplate(&buf, "R", template.HTML(tmp.Results))
|
||||
tmpl.ExecuteTemplate(&buf, "P", template.HTML(tmp.Pages))
|
||||
|
||||
for _, a := range q.Results {
|
||||
tmp.Results += util.Images(a, a.Media, false)
|
||||
}
|
||||
|
||||
tmp.Pages = ""
|
||||
tmp.Name = *user
|
||||
for x := 0; x < int(math.Round(float64(q.EstTotal/50))); x++ {
|
||||
tmp.Pages += "<a href=\"/user/" + tmp.Name + "?a=search&p=" + strconv.Itoa(x+1) + "&q=" + *query + "\">" + strconv.Itoa(x+1) + "</a> "
|
||||
}
|
||||
|
||||
output <- util.TmpExec("templates/user/search.htm", &tmp)
|
||||
} else {
|
||||
tmpl, _ := template.ParseFiles("templates/user/search-base.htm")
|
||||
tmpl.Execute(&buf, *user)
|
||||
output <- "Missing query."
|
||||
}
|
||||
}
|
||||
output <- buf.String()
|
||||
}
|
||||
|
|
|
@ -16,9 +16,7 @@ func check(what ...string) {
|
|||
dir, err := os.Open(Conf.Cache.Path)
|
||||
if err != nil {
|
||||
err = os.Mkdir(Conf.Cache.Path, 0700)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintln(err))
|
||||
}
|
||||
Err(err)
|
||||
}
|
||||
stat, _ := dir.Stat()
|
||||
|
||||
|
@ -71,9 +69,7 @@ func Cache(img string) string {
|
|||
a = a[0:strings.Index(a, "/")]
|
||||
if a == "image" || a == "video" {
|
||||
err := os.WriteFile(Conf.Cache.Path+"/"+encsum, []byte(body), 0700)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
Err(err)
|
||||
|
||||
return string(body)
|
||||
}
|
||||
|
@ -85,9 +81,7 @@ func Cache(img string) string {
|
|||
}
|
||||
} else {
|
||||
file, err := io.ReadAll(file)
|
||||
if err != nil {
|
||||
println(err)
|
||||
}
|
||||
Err(err)
|
||||
return string(file)
|
||||
}
|
||||
file.Close()
|
||||
|
|
|
@ -2,7 +2,6 @@ package util
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
@ -14,18 +13,17 @@ type cconf struct {
|
|||
}
|
||||
|
||||
type c struct {
|
||||
Listen string
|
||||
Cache cconf
|
||||
Proxy, Nsfw bool
|
||||
Listen, Base_uri string
|
||||
Cache cconf
|
||||
Proxy, Nsfw bool
|
||||
}
|
||||
|
||||
var Conf = c{
|
||||
Listen: "127.0.0.1:3003",
|
||||
Listen: "127.0.0.1:3003",
|
||||
Base_uri: "/",
|
||||
Cache: cconf{
|
||||
Enabled: true,
|
||||
Path: "cache",
|
||||
// Max_size: 4000000,
|
||||
// Lifetime: 10000,
|
||||
},
|
||||
Proxy: true,
|
||||
Nsfw: true,
|
||||
|
@ -39,7 +37,7 @@ func ParseConfig() {
|
|||
a = a[2:]
|
||||
switch a {
|
||||
case "help":
|
||||
println(`SkunkyArt v1.0 Beta
|
||||
println(`SkunkyArt v1.2
|
||||
Usage:
|
||||
- config: specify config file path;
|
||||
- help: prints this message.
|
||||
|
@ -51,7 +49,7 @@ lost+skunk, 2024. Source Code: https://git.macaw.me/skunky/skunkyart`)
|
|||
case "config":
|
||||
file, err := os.ReadFile(os.Args[b+1])
|
||||
if err != nil {
|
||||
log.Fatalln(fmt.Sprint(err))
|
||||
log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
if len(file) > 0 {
|
||||
|
@ -67,7 +65,7 @@ lost+skunk, 2024. Source Code: https://git.macaw.me/skunky/skunkyart`)
|
|||
|
||||
file, err := os.ReadFile(cfile)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintln(err))
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
json.Unmarshal(file, &Conf)
|
||||
|
|
|
@ -80,7 +80,10 @@ func Images(deviation Deviation, media Media, nfmt bool) string {
|
|||
}
|
||||
|
||||
if nfmt {
|
||||
return "/image/" + image
|
||||
if image == "" {
|
||||
return "no"
|
||||
}
|
||||
return Conf.Base_uri + "image/" + image
|
||||
}
|
||||
|
||||
var link string
|
||||
|
@ -94,7 +97,7 @@ func Images(deviation Deviation, media Media, nfmt bool) string {
|
|||
}
|
||||
|
||||
if image != "" {
|
||||
image = "<img src=\"/image/" + image + "\" width=\"15%\">"
|
||||
image = "<img src=\"" + Conf.Base_uri + "image/" + image + "\" width=\"15%\">"
|
||||
} else {
|
||||
image = "<h1>[ TEXT ]</h1>"
|
||||
}
|
||||
|
@ -111,5 +114,5 @@ func Images(deviation Deviation, media Media, nfmt bool) string {
|
|||
deviation.Title += " [<span class=\"nsfw\">NSFW</span>]"
|
||||
}
|
||||
|
||||
return "<div class=\"block\">" + image + "<br><a href=\"/post" + link + "\">" + deviation.Author.Username + deviation.Title + "</a></div>"
|
||||
return "<div class=\"block\">" + image + "<br><a href=\"" + Conf.Base_uri + "post" + link + "\">" + deviation.Author.Username + deviation.Title + "</a></div>"
|
||||
}
|
||||
|
|
30
util/misc.go
30
util/misc.go
|
@ -2,9 +2,10 @@ package util
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
@ -15,23 +16,32 @@ func Request(url string, cookie string) (string, int, []*http.Cookie, http.Heade
|
|||
request, err := http.NewRequest("GET", url, nil)
|
||||
request.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:123.0) Gecko/20100101 Firefox/123.0.0")
|
||||
request.Header.Set("Cookie", cookie)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
Err(err)
|
||||
response, err := cli.Do(request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
Err(err)
|
||||
body, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
Err(err)
|
||||
response.Body.Close()
|
||||
return string(body), response.StatusCode, response.Cookies(), response.Header
|
||||
}
|
||||
|
||||
func TmpExec(file string, templatee any) string {
|
||||
var buf bytes.Buffer
|
||||
tmpl, err := template.ParseFiles(file)
|
||||
Err(err)
|
||||
|
||||
tmpl.Execute(&buf, &templatee)
|
||||
return strings.ReplaceAll(buf.String(), "!BAZE!", "<base href=\""+Conf.Base_uri+"\">")
|
||||
}
|
||||
|
||||
func Render(n *html.Node) string {
|
||||
var buffer bytes.Buffer
|
||||
html.Render(io.Writer(&buffer), n)
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func Err(err error) {
|
||||
if err != nil {
|
||||
println(err.Error())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ func Parse(n string) string {
|
|||
switch a.Key {
|
||||
case "src":
|
||||
if a.Val[8:9] == "e" {
|
||||
uri = "/emoji/" + a.Val[37:len(a.Val)-4]
|
||||
uri = Conf.Base_uri + "emoji/" + a.Val[37:len(a.Val)-4]
|
||||
}
|
||||
case "title":
|
||||
title = a.Val
|
||||
|
|
Loading…
Reference in New Issue