Commit 048bb470ab

048bb470ab8dc3adce83d2e615f3ab369efa2199

parent: 32c61ec8ea

Unsigned

lost+skunk <skunky@macaw.me> · 2025-02-22 12:30 UTC

Переключатель кеша в озу, небольшие улучшения ксс, фикс нсфв, фикс максимального размера кеша

Layout: unified · split

app/api.go +7 −1
@@ -41,12 +41,18 @@ func (a API) Error(description string, status int) {
41func (a API) sendMedia(d *devianter.Deviation) { 41func (a API) sendMedia(d *devianter.Deviation) {
42 mediaUrl, name := devianter.UrlFromMedia(d.Media) 42 mediaUrl, name := devianter.UrlFromMedia(d.Media)
43 a.main.SetFilename(name) 43 a.main.SetFilename(name)
44
45 if len(mediaUrl) != 0 { 44 if len(mediaUrl) != 0 {
45 return
46 }
47
48 if CFG.Proxy {
46 mediaUrl = mediaUrl[21:] 49 mediaUrl = mediaUrl[21:]
47 dot := strings.Index(mediaUrl, ".") 50 dot := strings.Index(mediaUrl, ".")
48 a.main.Writer.Header().Del("Content-Type") 51 a.main.Writer.Header().Del("Content-Type")
49 a.main.DownloadAndSendMedia(mediaUrl[:dot], mediaUrl[dot+11:]) 52 a.main.DownloadAndSendMedia(mediaUrl[:dot], mediaUrl[dot+11:])
53 } else {
54 a.main.Writer.Header().Add("Location", mediaUrl)
55 a.main.Writer.WriteHeader(302)
50 } 56 }
51} 57}
52 58
app/cache.go +45 −31
@@ -38,17 +38,7 @@ func (s skunkyart) DownloadAndSendMedia(subdomain, path string) {
38 fileName := sha1.Sum([]byte(subdomain + path)) 38 fileName := sha1.Sum([]byte(subdomain + path))
39 filePath := CFG.Cache.Path + "/" + hex.EncodeToString(fileName[:]) 39 filePath := CFG.Cache.Path + "/" + hex.EncodeToString(fileName[:])
40 40
41 mx.Lock() 41 c := func() {
42 if tempFS[fileName] == nil {
43 tempFS[fileName] = &file{}
44 }
45 mx.Unlock()
46
47 if tempFS[fileName].Content != nil {
48 response = tempFS[fileName].Content
49 tempFS[fileName].Score += 2
50 break
51 } else {
52 file, err := os.Open(filePath) 42 file, err := os.Open(filePath)
53 if err != nil { 43 if err != nil {
54 if dwnld := Download(url.String()); dwnld.Status == 200 && dwnld.Headers["Content-Type"][0][:5] == "image" { 44 if dwnld := Download(url.String()); dwnld.Status == 200 && dwnld.Headers["Content-Type"][0][:5] == "image" {
@@ -63,27 +53,44 @@ func (s skunkyart) DownloadAndSendMedia(subdomain, path string) {
63 try(e) 53 try(e)
64 response = file 54 response = file
65 } 55 }
56 }
66 57
67 go func() { 58 if CFG.Cache.MemCache {
68 defer restore() 59 mx.Lock()
69 60 if tempFS[fileName] == nil {
70 mx.RLock() 61 tempFS[fileName] = &file{}
71 tempFS[fileName].Content = response 62 }
72 mx.RUnlock() 63 mx.Unlock()
73
74 for {
75 time.Sleep(1 * time.Minute)
76 64
77 mx.Lock() 65 if tempFS[fileName].Content != nil {
78 if tempFS[fileName].Score <= 0 { 66 response = tempFS[fileName].Content
79 delete(tempFS, fileName) 67 tempFS[fileName].Score += 2
68 break
69 } else {
70 c()
71 go func() {
72 defer restore()
73
74 mx.RLock()
75 tempFS[fileName].Content = response
76 mx.RUnlock()
77
78 for {
79 time.Sleep(1 * time.Minute)
80
81 mx.Lock()
82 if tempFS[fileName].Score <= 0 {
83 delete(tempFS, fileName)
84 mx.Unlock()
85 return
86 }
87 tempFS[fileName].Score--
80 mx.Unlock() 88 mx.Unlock()
81 return
82 } 89 }
83 tempFS[fileName].Score-- 90 }()
84 mx.Unlock() 91 }
85 } 92 } else {
86 }() 93 c()
87 } 94 }
88 case CFG.Proxy: 95 case CFG.Proxy:
89 dwnld := Download(url.String()) 96 dwnld := Download(url.String())
@@ -112,6 +119,7 @@ func InitCacheSystem() {
112 println(err.Error()) 119 println(err.Error())
113 } 120 }
114 121
122 var total int64
115 for _, file := range dir { 123 for _, file := range dir {
116 fileName := c.Path + "/" + file.Name() 124 fileName := c.Path + "/" + file.Name()
117 fileInfo, err := file.Info() 125 fileInfo, err := file.Info()
@@ -128,9 +136,15 @@ func InitCacheSystem() {
128 } 136 }
129 } 137 }
130 138
131 if c.MaxSize != 0 && fileInfo.Size() > c.MaxSize { 139 total += fileInfo.Size()
132 try(os.RemoveAll(fileName)) 140 // if c.MaxSize != 0 && fileInfo.Size() > c.MaxSize {
133 } 141 // try(os.RemoveAll(fileName))
142 // }
143 }
144
145 if c.MaxSize != 0 && total > c.MaxSize {
146 try(os.RemoveAll(c.Path))
147 os.Mkdir(c.Path, 0700)
134 } 148 }
135 149
136 time.Sleep(time.Second * time.Duration(c.UpdateInterval)) 150 time.Sleep(time.Second * time.Duration(c.UpdateInterval))
app/config.go +4 −3
@@ -12,12 +12,13 @@ import (
12) 12)
13 13
14var Release struct { 14var Release struct {
15 Version string 15 Version string
16 Description string 16 Description string
17} 17}
18 18
19type cache_config struct { 19type cache_config struct {
20 Enabled bool 20 Enabled bool
21 MemCache bool `json:"memcache"`
21 Path string 22 Path string
22 MaxSize int64 `json:"max-size"` 23 MaxSize int64 `json:"max-size"`
23 Lifetime string 24 Lifetime string
@@ -93,9 +94,9 @@ func ExecuteConfig() {
93 94
94 About = instanceAbout{ 95 About = instanceAbout{
95 Proxy: CFG.Proxy, 96 Proxy: CFG.Proxy,
96 Nsfw: CFG.Nsfw, 97 Nsfw: CFG.Nsfw,
97 } 98 }
98 99
99 static.StaticPath = CFG.StaticPath 100 static.StaticPath = CFG.StaticPath
100 devianter.UserAgent = CFG.UserAgent 101 devianter.UserAgent = CFG.UserAgent
101 } 102 }
app/wrapper.go +10 −3
@@ -36,13 +36,12 @@ func (s skunkyart) GRUser() {
36 for _, x := range g.Gruser.Page.Modules { 36 for _, x := range g.Gruser.Page.Modules {
37 switch x.Name { 37 switch x.Name {
38 case "about", "group_about": 38 case "about", "group_about":
39 switch g.Owner.Group { 39 if g.Owner.Group {
40 case true:
41 var about = &x.ModuleData.GroupAbout 40 var about = &x.ModuleData.GroupAbout
42 group.Group = true 41 group.Group = true
43 group.CreationDate = x.ModuleData.GroupAbout.FoundatedAt.UTC().String() 42 group.CreationDate = x.ModuleData.GroupAbout.FoundatedAt.UTC().String()
44 group.About.DescriptionFormatted = ParseDescription(about.Description) 43 group.About.DescriptionFormatted = ParseDescription(about.Description)
45 case false: 44 } else if false {
46 group.About.A = x.ModuleData.About 45 group.About.A = x.ModuleData.About
47 var about = &group.About.A 46 var about = &group.About.A
48 group.CreationDate = time.Unix(time.Now().Unix()-x.ModuleData.About.RegDate, 0).UTC().String() 47 group.CreationDate = time.Unix(time.Now().Unix()-x.ModuleData.About.RegDate, 0).UTC().String()
@@ -186,6 +185,14 @@ func (s skunkyart) Deviation(author, postname string) {
186 return 185 return
187 } 186 }
188 187
188 if post.Post.Deviation.NSFW {
189 s.Writer.WriteHeader(403)
190 wr(s.Writer, `<html><link rel="stylesheet" href="`+
191 UrlBuilder("stylesheet")+
192 `" /><h1>NSFW content are disabled on this instance.</h1></html>`)
193 return
194 }
195
189 if post.Post.Comments.Total <= 50 { 196 if post.Post.Comments.Total <= 50 {
190 post.Post.Comments.Cursor = "" 197 post.Post.Comments.Cursor = ""
191 } 198 }
config.example.json +2 −1
@@ -6,11 +6,12 @@
6 "path": "cache", 6 "path": "cache",
7 "lifetime": null, 7 "lifetime": null,
8 "max-size": 200, 8 "max-size": 200,
9 "memcache": false,
9 "update-interval": 5 10 "update-interval": 5
10 }, 11 },
11 "static-path": "static", 12 "static-path": "static",
12 "download-proxy": "http://127.0.0.1:8080", 13 "download-proxy": "http://127.0.0.1:8080",
13 "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36", 14 "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
14 "proxy": true, 15 "proxy": true,
15 "nsfw": true 16 "nsfw": false
16} 17}
static/css/skunky.css +21 −9
@@ -1,6 +1,6 @@
1/* TAGS */ 1/* TAGS */
2html { 2html {
3 font-family: Ubuntu; 3 font-family: ubuntu, system-ui;
4 background-color:black; 4 background-color:black;
5 color: rgb(234, 216, 216); 5 color: rgb(234, 216, 216);
6} 6}
@@ -45,24 +45,22 @@ input:focus {
45 justify-content: center; 45 justify-content: center;
46} 46}
47.block { 47.block {
48 max-width: 20%; 48 padding: 0px 0px 6px 0px;
49 height: 0%; 49 border: 3px solid #000;
50 padding: 4px;
51 border-radius: 2px;
52 border: 3px solid #091f19;
53 word-break: break-all; 50 word-break: break-all;
54 background-color: #091f19; 51 background-color: #091f19;
55 margin-left: 5px; 52 margin-left: 5px;
56 margin-top: 5px; 53 margin-top: 5px;
57 text-align: center; 54 text-align: center;
58} 55}
56.block h1 {
57 padding: 8.5vh;
58}
59.block:hover { 59.block:hover {
60 border: 3px solid #4d27d6; 60 border: 3px solid #4d27d6;
61 transition: 400ms; 61 transition: 400ms;
62} 62}
63.block img, .plates .user-plate img { 63
64 width: 100%;
65}
66.block p { 64.block p {
67 word-break: break-all; 65 word-break: break-all;
68} 66}
@@ -185,6 +183,20 @@ input:focus {
185 font-size: 60%; 183 font-size: 60%;
186 max-width: 80% 184 max-width: 80%
187 } 185 }
186 .block img, .plates .user-plate img {
187 width: 100%;
188 }
189}
190
191@media (orientation: landscape) {
192 .block {
193 width: 20%;
194 }
195 .block img, .plates .user-plate img {
196 width: 100%;
197 height: 30vh;
198 object-fit: cover;
199 }
188} 200}
189 201
190@media (max-width: 1462px) and (orientation: landscape) { 202@media (max-width: 1462px) and (orientation: landscape) {
static/html/gruser.htm +1 −1
@@ -30,7 +30,7 @@
30 </form> <h1>| {{.Templates.GroupUser.GR.Owner.Username}}</h1> 30 </form> <h1>| {{.Templates.GroupUser.GR.Owner.Username}}</h1>
31 </header> 31 </header>
32 {{if eq .Type 'a'}} 32 {{if eq .Type 'a'}}
33 {{if ne .Templates.GroupUser.About.BG ""}} 33 {{if and (and (ne .Templates.About.Nsfw true) (ne .Templates.GroupUser.About.BGMeta.NSFW true)) (ne .Templates.GroupUser.About.BG "")}}
34 <a href="{{.Templates.GroupUser.About.BGMeta.Url}}" class="ubg"><img title="{{if ne .Templates.GroupUser.GR.Owner.Username .Templates.GroupUser.About.BGMeta.Author.Username}} 34 <a href="{{.Templates.GroupUser.About.BGMeta.Url}}" class="ubg"><img title="{{if ne .Templates.GroupUser.GR.Owner.Username .Templates.GroupUser.About.BGMeta.Author.Username}}
35 {{.Templates.GroupUser.About.BGMeta.Author.Username}} - {{end}}{{.Templates.GroupUser.About.BGMeta.Title}}" src="{{.Templates.GroupUser.About.BG}}"></a> 35 {{.Templates.GroupUser.About.BGMeta.Author.Username}} - {{end}}{{.Templates.GroupUser.About.BGMeta.Title}}" src="{{.Templates.GroupUser.About.BG}}"></a>
36 {{end}} 36 {{end}}