Commit b1ad145532

b1ad14553277d9d72a5e4b4462a52a2e2d0fdbb1

parent: 155a7b9ea6

Verified · cmc

cmc <hello@cleberg.net> · 2026-07-15 06:54 UTC

fix: remove russian language throughout

Layout: unified · split

README.md −40
@@ -8,7 +8,6 @@
8 8
9Instances: [`INSTANCES.md`](INSTANCES.md) 9Instances: [`INSTANCES.md`](INSTANCES.md)
10 10
11# EN 🇺🇸
12## Description 11## Description
13SkunkyArt 🦨 — an alternative frontend for DeviantArt that works entirely 12SkunkyArt 🦨 — an alternative frontend for DeviantArt that works entirely
14without JavaScript. 13without JavaScript.
@@ -32,42 +31,3 @@ To do this, you must either make a PR by adding your instance to the
32`instances.json` and `INSTANCES.md` files (you can use `--add-instance` 31`instances.json` and `INSTANCES.md` files (you can use `--add-instance`
33cli-argument to automatically add the instance to these files) or create an 32cli-argument to automatically add the instance to these files) or create an
34Issue. 33Issue.
35
36## Acknowledgements
37* [vlnst](https://git.bloat.cat/vlnst) — wrote a Docker file.
38* [Лис⚛](https://go.kde.org/matrix/#/@fox:matrix.org) — helped me understand Go
39 and gave me a lot of useful advice on this language.
40* [meoww](https://codeberg.org/meoww) — translated some sentences into English
41 and wrote a service for openrc
42
43# RU 🇷🇺
44## Описание
45SkunkyArt 🦨 — альтернативный фронтенд к DeviantArt, который полностью работает
46без JS (JavaScript).
47
48## Сборка
49Рекомендуется производить сборку с тегом 'embed', поскольку он встраивает
50заготовки в бинарный файл. Если вы планируете изменять заготовки, то не
51используйте этот тег. Также вы можете добавить аргумент `-ldflags "-w -s"` (у
52GCCGO он называется по-другому — `gccgoflags`) для уменьшения размера выходного
53файла. Вот пример:
54
55`go build -tags embed -ldflags "-w -s"`
56
57## Настройка
58Пример конфига находится в файле `config.example.json`. Чтобы указать свой
59конфиг, используйте cli-аргумент `--config`.
60
61См. [`SETUP-RU.md`](SETUP-RU.md) для информации о настройки фронтенда.
62
63## Добавление инстанса в список
64Чтобы это сделать, вы должны либо сделать PR, добавив в файлы `instances.json` и
65`INSTANCES.md` свой инстанс (можете воспользоваться cli-аргументом
66`--add-instance`, который автоматически это сделает), либо создать Issue.
67
68## Благодарности
69* [vlnst](https://git.bloat.cat/vlnst) — написал Docker-файл.
70* [Лис⚛](https://go.kde.org/matrix/#/@fox:matrix.org) — помог разобраться в Go и
71 много чего полезного посоветовал по этому языку.
72* [meoww](https://codeberg.org/meoww) — перевела некоторые предложения на
73 английский язык и написала сервис для openrc
SETUP-RU.md deleted −42
@@ -1,42 +0,0 @@
1[English version 🇬🇧](SETUP.md)
2
3# Единицы измерения
4Размер файла в кеше измеряется в мегабайтах.<br>
5Единицы времени:
6* `i` — минуты
7* `h` — часы
8* `w` — недели
9* `m` — месяца
10* `y` — года
11
12# Конфигурация
13* `listen` — IP и порт для слушанья; заполняется по такой форме: ip:port
14* `uri` — URI инстанса. Пример: `"uri":"/art/"` -> https://skunky.ebloid.ru/art/
15* `cache` — Система кеширования; по умолчанию выключена
16 * `enabled` — Состояние системы кеширования; требуется булёвое значение
17 * `path` — Полный путь до каталога, куда будет сохраняться кеш
18 * `lifetime` — Время жизни файла в кеше, требует целочисленное значение, дополненное суффиксом времени (см. 'Единицы времени')
19 * `max-size` — Максимальный размер файла
20 * `update-interval` — Интервал для автоматической ротации кеша
21* `static-path` — Строка, являющаяся путём до статики. SkunkyArt при запуске скопирует содержимое этого каталога в ОЗУ. Однако, если вы собрали фронтенд с тегом 'embed', то этого не произайдёт
22* `download-proxy` — Адрес прокси для загрузки файлов
23* `user-agent` — Строка, которая используется в качестве User-Agent'а
24
25# Настройка обратного прокси
26Если вы собираетесь хостить инстанс в Интернете, то вам следует настроить заголовок прокси [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto). В противном случае, все ссылки на вашем инстансе будут вида "http". Ниже есть информация о том, как настроить обратное проксирование:
27
28Nginx:
29```apache
30server {
31 listen 443 ssl;
32 server_name skunky.example.com;
33
34 # Если используется поддомен, то вместо ((BASE_URL)), укажите '/'.
35 location ((BASE_URL)) {
36 proxy_set_header X-Forwarded-Proto $scheme;
37 proxy_set_header Host $host;
38 proxy_http_version 1.1;
39 proxy_pass http://((IP)):((PORT));
40 }
41}
42```\ No newline at end of file
SETUP.md −2
@@ -1,5 +1,3 @@
1[Версия на русском языке 🇷🇺](SETUP-RU.md)
2
3# Units 1# Units
4Maximum file size in megabytes, requires numeric value.<br> 2Maximum file size in megabytes, requires numeric value.<br>
5Time units: 3Time units:
app/api.go +1 −1
@@ -57,7 +57,7 @@ func (a API) sendMedia(d *devianter.Deviation) {
57 } 57 }
58} 58}
59 59
60// TODO: сделать фильтры 60// TODO: add filters
61func (a API) Random() { 61func (a API) Random() {
62 // Bounded retries: the loop used to be unbounded, and the DeviantArt-error 62 // Bounded retries: the loop used to be unbounded, and the DeviantArt-error
63 // path never incremented attempt, so a single request could spin forever 63 // path never incremented attempt, so a single request could spin forever
app/cache.go +1 −1
@@ -1,4 +1,4 @@
1// TODO: реализовать кеширование JSON и почистить код 1// TODO: implement JSON caching and clean up the code
2package app 2package app
3 3
4import ( 4import (
app/parsers.go +1 −1
@@ -188,7 +188,7 @@ type text struct {
188 To int 188 To int
189} 189}
190 190
191// переписать весь этот пиздец нахуй 191// TODO: rewrite this whole mess
192func ParseDescription(dscr devianter.Text) string { 192func ParseDescription(dscr devianter.Text) string {
193 var parsedDescription strings.Builder 193 var parsedDescription strings.Builder
194 TagBuilder := func(content string, tags ...string) string { 194 TagBuilder := func(content string, tags ...string) string {
app/router.go +1 −1
@@ -52,7 +52,7 @@ func Router() {
52 return fileReaded 52 return fileReaded
53 } 53 }
54 54
55 // функция, что управляет всем 55 // the function that drives everything
56 handle := func(w http.ResponseWriter, r *http.Request) { 56 handle := func(w http.ResponseWriter, r *http.Request) {
57 path := parsepath(r.URL.Path) 57 path := parsepath(r.URL.Path)
58 Host = "http://" + r.Host 58 Host = "http://" + r.Host
app/util.go +2 −2
@@ -261,13 +261,13 @@ func GetValueOfTag(t *html.Tokenizer) string {
261 } 261 }
262} 262}
263 263
264// навигация по страницам 264// page navigation
265type DeviationList struct { 265type DeviationList struct {
266 Pages int 266 Pages int
267 More bool 267 More bool
268} 268}
269 269
270// FIXME: на некоротрых артах первая страница может вызывать полное отсутствие панели навигации. 270// FIXME: on some artworks the first page can make the navigation panel disappear entirely.
271func (s skunkyart) NavBase(c DeviationList) string { 271func (s skunkyart) NavBase(c DeviationList) string {
272 var list strings.Builder 272 var list strings.Builder
273 273
app/wrapper.go +3 −3
@@ -167,7 +167,7 @@ func (s skunkyart) GRUser() {
167 } 167 }
168} 168}
169 169
170// посты 170// posts
171func (s skunkyart) Deviation(author, postname string) { 171func (s skunkyart) Deviation(author, postname string) {
172 id_search := regexp.MustCompile("[0-9]+").FindAllString(postname, -1) 172 id_search := regexp.MustCompile("[0-9]+").FindAllString(postname, -1)
173 if len(id_search) < 1 { 173 if len(id_search) < 1 {
@@ -209,7 +209,7 @@ func (s skunkyart) Deviation(author, postname string) {
209 } 209 }
210 } 210 }
211 211
212 // хештэги 212 // hashtags
213 for _, x := range post.Post.Deviation.Extended.Tags { 213 for _, x := range post.Post.Deviation.Extended.Tags {
214 var tag strings.Builder 214 var tag strings.Builder
215 tag.WriteString(` <a href="`) 215 tag.WriteString(` <a href="`)
@@ -270,7 +270,7 @@ func (s skunkyart) Search() {
270 ss.Content, daError, err = devianter.PerformSearch(s.Query, s.Page, s.Type) 270 ss.Content, daError, err = devianter.PerformSearch(s.Query, s.Page, s.Type)
271 case 'g', 'f': 271 case 'g', 'f':
272 ss.Content, daError, err = devianter.PerformSearch(s.Query, s.Page, s.Type, s.Args.Get("usr")) 272 ss.Content, daError, err = devianter.PerformSearch(s.Query, s.Page, s.Type, s.Args.Get("usr"))
273 case 'r': // скраппер, поскольку девиантартовцы зажопили гостевое API для поиска групп 273 case 'r': // scraper, since DeviantArt withholds the guest API for group search
274 var ( 274 var (
275 usernames = make(map[int]string) 275 usernames = make(map[int]string)
276 url strings.Builder 276 url strings.Builder
static/templates-noembed.go +1 −1
@@ -91,7 +91,7 @@ func try(err error) {
91 } 91 }
92} 92}
93 93
94/* сделано на основе https://github.com/psanford/memfs; требуется для корректной работы templates.ParseFS */ 94/* based on https://github.com/psanford/memfs; required for templates.ParseFS to work correctly */
95type fileInfo struct { 95type fileInfo struct {
96 name string 96 name string
97} 97}