diff --git a/README.md b/README.md
index 9e30da0..ba6e4b3 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,14 @@
+
+
[](https://go.kde.org/matrix/#/#skunkyart:ebloid.ru)
# Instances
-|Инстанс|Yggdrasil|I2P|Tor|NSFW|Proxifying|Country|
-|:-----:|:-------:|:-:|:-:|:--:|:--------:|:-----:|
+|Instance|Yggdrasil|I2P|Tor|NSFW|Proxifying|Country|
+|:------:|:-------:|:-:|:-:|:--:|:--------:|:-----:|
|[skunky.ebloid.ru](https://skunky.ebloid.ru/art)|[Yes](http://[201:eba5:d1fc:bf7b:cfcb:a811:4b8b:7ea3]/art)|No|No| No | No | Russia |
|[clovius.club](https://skunky.clovius.club)|No|No|No| Yes | Yes | Sweden |
|[bloat.cat](https://skunky.bloat.cat)|No|No|No| Yes | Yes | Romania |
|[frontendfriendly.xyz](https://skunkyart.frontendfriendly.xyz)|No|No|No| Yes | Yes | Finland |
+|[lumaeris.com](https://skunkyart.lumaeris.com)|No|No|No| Yes | Yes | US |
# EN 🇺🇸
## Description
@@ -13,12 +16,12 @@ SkunkyArt 🦨 -- alternative frontend to DeviantArt, which will work without pr
## Config
The sample config is in the `config.example.json` file. To specify your own path to the config, use the CLI argument `-c` or `--config`.
* `listen` -- the address and port on which SkunkyArt will listen
-* `base-path` -- the path to the instance. Example: "`base-path`:"/art/" -> https://skunky.ebloid.ru/art/
+* `base-path` -- the path to the instance. Example: `"base-path":"/art/"` -> https://skunky.ebloid.ru/art/
* `cache` -- caching system; default is off.
-* * `path` -- the path to the cache
-* * `lifetime` -- cache file lifetime; measured in Unix milliseconds.
-* * `max-size` -- maximum file size in bytes.
-* `dirs-to-memory` -- this setting determines which directories will be copied to RAM when SkunkyArt is started. Required
+ * `path` -- the path to the cache
+ * `lifetime` -- the lifetime of the file in the cache. Units: i, h, d, w, m, y. I -- minute, all other units I think are self-explanatory.
+ * `max-size` -- maximum file size in megabytes.
+* `dirs-to-memory` -- this setting determines which directories will be copied to RAM when SkunkyArt is started. Mandatory
* `download-proxy` -- proxy address for downloading files.
## Examples of reverse proxies
Nginx:
@@ -27,17 +30,18 @@ server {
listen 443 ssl;
server_name skunky.example.com;
- location ((BASE URL)) { # if you have a separate subdomain for the frontend, insert '/' instead of '((BASE URL))'.
- proxy_set_header Scheme $scheme;
+ location ((BASE URL)) { # if you have a separate subdomain for the frontend, insert '/' instead of '((BASE URL)))'.
+ proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://((IP)):((PORT));
}
}
```
+Pretty much business as usual, except for the [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) header setting.
## How do I add my instance to the list?
-To do this, you must either make a PR by adding your instance to the `instances.json` file, or report it to the room in Matrix. I don't think it needs any description. However, be aware, this list has a couple rules:
-1. the instance must not use Cloudflare.
+To do this, you must either make a PR by adding your instance to the `instances.json` and `README.md` files, or create an Issue, or report it to the room in Matrix. I don't think it needs any description. However, be warned, this list has a couple rules:
+1. the Instance must not use Cloudflare.
2. If your instance has modified source code, you need to publish it to any free platform. For example, Github and Gitlab are not.
## Acknowledgements
* [Лис⚛](https://go.kde.org/matrix/#/@fox:matrix.org) -- helped me understand Go and gave me a lot of useful advice on this language.
@@ -48,11 +52,11 @@ SkunkyArt 🦨 -- альтернативный фронтенд к DeviantArt,
## Конфиг
Пример конфига находится в файле `config.example.json`. Чтобы указать свой путь до конфига, используйте CLI-аргумент `-c` или `--config`.
* `listen` -- адрес и порт, на котором будет слушать SkunkyArt
-* `base-path` -- путь к инстансу. Пример: "base-path": "/art/" -> https://skunky.ebloid.ru/art/
+* `base-path` -- путь к инстансу. Пример: `"base-path": "/art/"` -> https://skunky.ebloid.ru/art/
* `cache` -- система кеширования; по умолчанию - выкл.
-* * `path` -- путь до кеша
-* * `lifetime` -- время жизни файла в кеше; измеряется в Unix-миллисекундах
-* * `max-size` -- максимальный размер файла в байтах
+ * `path` -- путь до кеша
+ * `lifetime` -- время жизни файла в кеше. Единицы измерения: i, h, d, w, m, y. I -- минута, всё остальные единицы измерения, я считаю понятными и без объяснения.
+ * `max-size` -- максимальный размер файла в мегабайтах
* `dirs-to-memory` -- данная настройка определяет какие каталоги будут скопированы в ОЗУ при запуске SkunkyArt. Обязательна
* `download-proxy` -- адрес прокси для загрузки файлов
## Примеры reverse-прокси
@@ -63,15 +67,16 @@ server {
server_name skunky.example.com;
location ((BASE URL)) { # если у вас отдельный поддомен для фронтенда, вместо '((BASE URL))' вставляйте '/'
- proxy_set_header Scheme $scheme;
+ proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://((IP)):((PORT));
}
}
```
+В целом, всё как обычно, за исключением настройки заголовка [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto).
## Как добавить свой инстанс в список?
-Чтобы это сделать, вы должны либо сделать PR, добавив в файл `instances.json` свой инстанс, либо сообщить о нём в комнате в Matrix. Думаю, он не нуждается в описании. Однако учтите, у этого списка есть пара правил:
+Чтобы это сделать, вы должны либо сделать PR, добавив в файлы `instances.json` и `README.md` свой инстанс, либо создать Issue, или сообщить о нём в комнате в Matrix. Думаю, он не нуждается в описании. Однако учтите, у этого списка есть пара правил:
1. Инстанс не должен использовать Cloudflare.
2. Если ваш инстанс имеет модифицированный исходный код, то вам нужно опубликовать его на любую свободную площадку. Например, Github и Gitlab таковыми не являются.
## Благодарности
diff --git a/TODO.md b/TODO.md
index 2334695..cdb4c95 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,7 +1,16 @@
# v1.3.x
-* Доделать парсинг описания
-* Реализовать миниатюры и оптимизировать CSS под маленькие экраны
+* Написать Makefile
+* Почистить говнокод
+* **Доделать парсинг описания**
+* Избавиться от хардкода под Linux
+* ~~Реализовать стрипы в ежедневных артах~~
+* ~~Исправить баг с навигацией по страницам~~
+* ~~Сделать единицы в конфиге более понятными~~
+* Добавить возможность включить темплейты в бинарник
+* ~~Реализовать миниатюры и оптимизировать CSS под маленькие экраны~~
+* **Реализовать отображение контента, отличного от картинок (видео, аудио, etc)**
+* Улучшить систему кеширования: добавить рейтинг для удаления и копирование изображений в ОЗУ
# v1.4
+* Реализовать API
* Реализовать темы
-* Реализовать многоязычный интерфейс
-* Реализовать API
\ No newline at end of file
+* Реализовать многоязычный интерфейс
\ No newline at end of file
diff --git a/app/config.go b/app/config.go
index c848b9c..3fb8103 100644
--- a/app/config.go
+++ b/app/config.go
@@ -3,14 +3,18 @@ package app
import (
"encoding/json"
"os"
+ "regexp"
+ "strconv"
"time"
+
+ "git.macaw.me/skunky/devianter"
)
type cache_config struct {
Enabled bool
Path string
MaxSize int64 `json:"max-size"`
- Lifetime int64
+ Lifetime string
UpdateInterval int64 `json:"update-interval"`
}
@@ -20,6 +24,7 @@ type config struct {
BasePath string `json:"base-path"`
Cache cache_config
Proxy, Nsfw bool
+ UserAgent string `json:"user-agent"`
DownloadProxy string `json:"download-proxy"`
Dirs []string `json:"dirs-to-memory"`
}
@@ -33,31 +38,36 @@ var CFG = config{
Path: "cache",
UpdateInterval: 1,
},
- Dirs: []string{"html", "css"},
- Proxy: true,
- Nsfw: true,
+ Dirs: []string{"html", "css"},
+ 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,
}
+var lifetimeParsed int64
+
func ExecuteConfig() {
go func() {
- defer func() {
- if r := recover(); r != nil {
- recover()
- }
- }()
for {
- Templates["instances.json"] = string(Download("https://git.macaw.me/skunky/SkunkyArt/raw/branch/master/instances.json").Body)
- time.Sleep(1 * time.Second)
+ 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 [refactoring]
+ 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`
+Copyright lost+skunk, X11. https://git.macaw.me/skunky/skunkyart/src/tag/v1.3.1`
a := os.Args
for n, x := range a {
@@ -75,15 +85,42 @@ Copyright lost+skunk, X11. https://git.macaw.me/skunky/skunkyart/src/tag/v1.3`
if CFG.cfg != "" {
f, err := os.ReadFile(CFG.cfg)
- try_with_exitstatus(err, 1)
+ tryWithExitStatus(err, 1)
- try_with_exitstatus(json.Unmarshal(f, &CFG), 1)
+ tryWithExitStatus(json.Unmarshal(f, &CFG), 1)
if CFG.Cache.Enabled && !CFG.Proxy {
exit("Incompatible settings detected: cannot use caching media content without proxy", 1)
}
- if CFG.Cache.MaxSize != 0 || CFG.Cache.Lifetime != 0 {
+ if CFG.Cache.Enabled {
+ if CFG.Cache.Lifetime != "" {
+ var duration int64
+ day := 24 * time.Hour.Milliseconds()
+ numstr := regexp.MustCompile("[0-9]+").FindAllString(CFG.Cache.Lifetime, -1)
+ num, _ := strconv.Atoi(numstr[len(numstr)-1])
+
+ switch unit := CFG.Cache.Lifetime[len(CFG.Cache.Lifetime)-1:]; unit {
+ case "i":
+ duration = time.Minute.Milliseconds()
+ case "h":
+ duration = time.Hour.Milliseconds()
+ case "d":
+ duration = day
+ case "w":
+ duration = day * 7
+ case "m":
+ duration = day * 30
+ case "y":
+ duration = day * 360
+ default:
+ exit("Invalid unit specified: "+unit, 1)
+ }
+
+ lifetimeParsed = duration * int64(num)
+ }
+ CFG.Cache.MaxSize /= 1024 ^ 2
go InitCacheSystem()
}
+ devianter.UserAgent = CFG.UserAgent
}
}
diff --git a/app/parsers.go b/app/parsers.go
index 0665476..b39e172 100644
--- a/app/parsers.go
+++ b/app/parsers.go
@@ -70,17 +70,81 @@ func (s skunkyart) ParseComments(c devianter.Comments) string {
return cmmts.String()
}
-func (s skunkyart) DeviationList(devs []devianter.Deviation, content ...DeviationList) string {
- var list strings.Builder
+func (s skunkyart) DeviationList(devs []devianter.Deviation, allowAtom bool, content ...DeviationList) string {
if s.Atom && s.Page > 1 {
s.ReturnHTTPError(400)
return ""
- } else if s.Atom {
+ }
+
+ var list, listContent strings.Builder
+
+ for i, l := 0, len(devs); i < l; i++ {
+ data := &devs[i]
+ if preview, fullview := ParseMedia(data.Media, 320), ParseMedia(data.Media); !(data.NSFW && !CFG.Nsfw) {
+ if allowAtom && s.Atom {
+ id := strconv.Itoa(data.ID)
+ listContent.WriteString(``)
+ listContent.WriteString(data.Author.Username)
+ listContent.WriteString(``)
+ listContent.WriteString(data.Title)
+ listContent.WriteString(``)
+ listContent.WriteString(id)
+ listContent.WriteString(``)
+ listContent.WriteString(data.PublishedTime.UTC().Format("Mon, 02 Jan 2006 15:04:05 -0700"))
+ listContent.WriteString(``)
+ listContent.WriteString(``)
+ listContent.WriteString(data.Title)
+ listContent.WriteString(`