сделал ajax с использованием htmx
parent
0540bdf1d2
commit
2d4a6c77a5
|
@ -1,2 +1,3 @@
|
||||||
config.json
|
config.json
|
||||||
hikan.ru
|
hikan.ru
|
||||||
|
*.server*
|
|
@ -69,6 +69,7 @@ h1::before { top: 0; }
|
||||||
h1::after { bottom: 0; }
|
h1::after { bottom: 0; }
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
cursor: pointer;
|
||||||
background-color: #77abbb;
|
background-color: #77abbb;
|
||||||
color: black;
|
color: black;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
File diff suppressed because one or more lines are too long
2
eye.sh
2
eye.sh
|
@ -4,7 +4,7 @@ stty -echoctl # Отключает вывод управляющих симво
|
||||||
# НАСТРОЙКА СКРИПТА ТУТ ###########################################################
|
# НАСТРОЙКА СКРИПТА ТУТ ###########################################################
|
||||||
DURATION=1 # Задержка между проверками в секундах
|
DURATION=1 # Задержка между проверками в секундах
|
||||||
WATCH_TARGETS=("assets" "mvc" "posts" "tools" "main.go" "config.json") # Массив целей для наблюдения (директории и файлы)
|
WATCH_TARGETS=("assets" "mvc" "posts" "tools" "main.go" "config.json") # Массив целей для наблюдения (директории и файлы)
|
||||||
BINARY_PATH="./main" # Путь до бинарного файла
|
BINARY_PATH="./main.server" # Путь до бинарного файла
|
||||||
BUILD_CMD="go build -o $BINARY_PATH main.go" # Команда для сборки
|
BUILD_CMD="go build -o $BINARY_PATH main.go" # Команда для сборки
|
||||||
###################################################################################
|
###################################################################################
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,10 @@ import (
|
||||||
func MainPageHandler(app *models.App) http.HandlerFunc {
|
func MainPageHandler(app *models.App) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var err error
|
var (
|
||||||
|
pageData []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
// Количество запросов, обработанных сервером за 24ч
|
// Количество запросов, обработанных сервером за 24ч
|
||||||
if r.Method == "COUNT" {
|
if r.Method == "COUNT" {
|
||||||
|
@ -38,17 +41,24 @@ func MainPageHandler(app *models.App) http.HandlerFunc {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Страничка рендерится только если ее нет в кэше
|
cacheKey := models_pages.MainPageTmplName
|
||||||
pageData, ok := app.PagesCache.Get(models_pages.MainPageTmplName)
|
ajax := r.URL.Query().Get("ajax") == "true"
|
||||||
if !ok {
|
if ajax {
|
||||||
pageData, err = models_pages.RenderMainPage(app.Templates, app.Version)
|
cacheKey += "?ajax=true"
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
app.PagesCache.Set(models_pages.MainPageTmplName, pageData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pageData, ok := app.PagesCache.Get(cacheKey); ok {
|
||||||
|
sendMainPage(w, pageData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pageData, err = models_pages.RenderMainPage(app.Templates, app.Version, ajax)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
app.PagesCache.Set(cacheKey, pageData)
|
||||||
|
|
||||||
sendMainPage(w, pageData)
|
sendMainPage(w, pageData)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,28 +6,35 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Обработчик главной страницы
|
// Обработчик страницы поста
|
||||||
func PostPageHandler(app *models.App) http.HandlerFunc {
|
func PostPageHandler(app *models.App) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
var err error
|
|
||||||
|
|
||||||
// Ссылка вида /postname
|
|
||||||
link := r.URL.Path
|
link := r.URL.Path
|
||||||
|
cacheKey := link
|
||||||
// Страничка рендерится только если ее нет в кэше
|
ajax := r.URL.Query().Get("ajax") == "true"
|
||||||
pageData, ok := app.PagesCache.Get(link)
|
if ajax {
|
||||||
if !ok {
|
cacheKey += "?ajax=true"
|
||||||
|
|
||||||
post := app.PostsMap[models_pages.PostLink(link)]
|
|
||||||
|
|
||||||
pageData, err = post.RenderPostPage(app.Templates, app.Version)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
app.PagesCache.Set(link, pageData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pageData, ok := app.PagesCache.Get(cacheKey); ok {
|
||||||
|
sendPostPage(w, pageData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
post := app.PostsMap[models_pages.PostLink(link)]
|
||||||
|
|
||||||
|
var (
|
||||||
|
pageData []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
pageData, err = post.RenderPostPage(app.Templates, app.Version, ajax)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
app.PagesCache.Set(cacheKey, pageData)
|
||||||
|
|
||||||
sendPostPage(w, pageData)
|
sendPostPage(w, pageData)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,37 +10,39 @@ import (
|
||||||
|
|
||||||
// Обработчик странички со списком постов
|
// Обработчик странички со списком постов
|
||||||
func PostsPageHandler(app *models.App) http.HandlerFunc {
|
func PostsPageHandler(app *models.App) http.HandlerFunc {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var err error
|
|
||||||
|
|
||||||
// Ссылка вида /posts/0
|
|
||||||
link := r.URL.Path
|
link := r.URL.Path
|
||||||
|
cacheKey := link
|
||||||
|
|
||||||
// Страничка рендерится только если ее нет в кэше
|
ajax := r.URL.Query().Get("ajax") == "true"
|
||||||
pageData, ok := app.PagesCache.Get(link)
|
if ajax {
|
||||||
if !ok {
|
cacheKey += "?ajax=true"
|
||||||
|
|
||||||
// Из мапы формирую отсортированный список всех постов (сначала новые)
|
|
||||||
postsList := app.PostsMap.PostsList()
|
|
||||||
|
|
||||||
// Ошибки тут быть не может, так как этот обработчик настроен
|
|
||||||
// на только существующие реально pageNumber и в случае
|
|
||||||
// какого то не существующего номера страницы он просто
|
|
||||||
// не сработает (в главном main настроены маршруты)
|
|
||||||
pageNumber, _ := strconv.Atoi(path.Base(link))
|
|
||||||
|
|
||||||
page := models_pages.CreatePostsPage(postsList, pageNumber, app.Cfg.PostsMaxCountOnPage)
|
|
||||||
|
|
||||||
pageData, err = page.RenderPostsPage(app.Templates, app.Version)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
app.PagesCache.Set(link, pageData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pageData, ok := app.PagesCache.Get(cacheKey); ok {
|
||||||
|
sendPostsPage(w, pageData)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
postsList := app.PostsMap.PostsList()
|
||||||
|
pageNumber, _ := strconv.Atoi(path.Base(link))
|
||||||
|
page := models_pages.CreatePostsPage(postsList, pageNumber, app.Cfg.PostsMaxCountOnPage)
|
||||||
|
|
||||||
|
var (
|
||||||
|
pageData []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
pageData, err = page.RenderPostsPage(app.Templates, app.Version, ajax)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.PagesCache.Set(cacheKey, pageData)
|
||||||
sendPostsPage(w, pageData)
|
sendPostsPage(w, pageData)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отправляет страницу
|
// Отправляет страницу
|
||||||
|
|
|
@ -8,10 +8,11 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Имя соответствующего шаблона
|
// Имя соответствующего шаблона
|
||||||
MainPageTmplName = "main.gohtml"
|
MainPageTmplName = "main.gohtml"
|
||||||
|
MainPageTmplNameAjax = "main_ajax.gohtml"
|
||||||
)
|
)
|
||||||
|
|
||||||
func RenderMainPage(templates *template.Template, version int64) ([]byte, error) {
|
func RenderMainPage(templates *template.Template, version int64, ajax bool) ([]byte, error) {
|
||||||
var pageData bytes.Buffer
|
var pageData bytes.Buffer
|
||||||
|
|
||||||
context := map[string]any{
|
context := map[string]any{
|
||||||
|
@ -19,7 +20,12 @@ func RenderMainPage(templates *template.Template, version int64) ([]byte, error)
|
||||||
"renderingTimestamp": time.Now().Unix(),
|
"renderingTimestamp": time.Now().Unix(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := templates.ExecuteTemplate(&pageData, MainPageTmplName, context); err != nil {
|
templateName := MainPageTmplName
|
||||||
|
if ajax {
|
||||||
|
templateName = MainPageTmplNameAjax
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := templates.ExecuteTemplate(&pageData, templateName, context); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Имя соответствующего шаблона
|
// Имя соответствующего шаблона
|
||||||
PostPageTmplName = "post.gohtml"
|
PostPageTmplName = "post.gohtml"
|
||||||
|
PostPageTmplNameAjax = "post_ajax.gohtml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PostLink string
|
type PostLink string
|
||||||
|
@ -19,7 +20,7 @@ type Post struct {
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Post) RenderPostPage(templates *template.Template, version int64) ([]byte, error) {
|
func (p *Post) RenderPostPage(templates *template.Template, version int64, ajax bool) ([]byte, error) {
|
||||||
var pageData bytes.Buffer
|
var pageData bytes.Buffer
|
||||||
|
|
||||||
context := map[string]any{
|
context := map[string]any{
|
||||||
|
@ -29,7 +30,12 @@ func (p *Post) RenderPostPage(templates *template.Template, version int64) ([]by
|
||||||
"modTimestamp": p.Timestamp,
|
"modTimestamp": p.Timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := templates.ExecuteTemplate(&pageData, PostPageTmplName, context); err != nil {
|
templateName := PostPageTmplName
|
||||||
|
if ajax {
|
||||||
|
templateName = PostPageTmplNameAjax
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := templates.ExecuteTemplate(&pageData, templateName, context); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,8 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Имя соответствующего шаблона
|
// Имя соответствующего шаблона
|
||||||
PostsPageTmplName = "posts.gohtml"
|
PostsPageTmplName = "posts.gohtml"
|
||||||
|
PostsPageTmplNameAjax = "posts_ajax.gohtml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PostsMap map[PostLink]*Post
|
type PostsMap map[PostLink]*Post
|
||||||
|
@ -101,7 +102,7 @@ func CreatePostsPage(postsList PostsList, pageNumber, postsMaxCountOnPage int) *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PostsPage) RenderPostsPage(templates *template.Template, version int64) ([]byte, error) {
|
func (p *PostsPage) RenderPostsPage(templates *template.Template, version int64, ajax bool) ([]byte, error) {
|
||||||
var pageData bytes.Buffer
|
var pageData bytes.Buffer
|
||||||
|
|
||||||
var prevPageNumber, nextPageNumber int
|
var prevPageNumber, nextPageNumber int
|
||||||
|
@ -114,22 +115,22 @@ func (p *PostsPage) RenderPostsPage(templates *template.Template, version int64)
|
||||||
|
|
||||||
nextPageNumber = (p.PageNumber + 1) % p.PagesCount
|
nextPageNumber = (p.PageNumber + 1) % p.PagesCount
|
||||||
|
|
||||||
pagi := fmt.Sprintf(
|
|
||||||
`<a href="/posts/%d"><-</a> %d/%d <a href="/posts/%d">-></a>`,
|
|
||||||
prevPageNumber,
|
|
||||||
p.PageNumber+1,
|
|
||||||
p.PagesCount,
|
|
||||||
nextPageNumber,
|
|
||||||
)
|
|
||||||
|
|
||||||
context := map[string]any{
|
context := map[string]any{
|
||||||
"pagi": template.HTML(pagi),
|
"prevPageNumber": prevPageNumber,
|
||||||
|
"pageNumberInc": p.PageNumber + 1,
|
||||||
|
"pagesCount": p.PagesCount,
|
||||||
|
"nextPageNumber": nextPageNumber,
|
||||||
"version": version,
|
"version": version,
|
||||||
"renderingTimestamp": time.Now().Unix(),
|
"renderingTimestamp": time.Now().Unix(),
|
||||||
"posts": p.PostsListOnPage,
|
"posts": p.PostsListOnPage,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := templates.ExecuteTemplate(&pageData, PostsPageTmplName, context); err != nil {
|
templateName := PostsPageTmplName
|
||||||
|
if ajax {
|
||||||
|
templateName = PostsPageTmplNameAjax
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := templates.ExecuteTemplate(&pageData, templateName, context); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="shortcut icon" href="/assets/pic/favicon.ico?v={{ .version }}" type="image/x-icon">
|
<link rel="shortcut icon" href="/assets/pic/favicon.ico?v={{ .version }}" type="image/x-icon">
|
||||||
<link rel="stylesheet" href="/assets/css/styles.css?v={{ .version }}" type="text/css">
|
<link rel="stylesheet" href="/assets/css/styles.css?v={{ .version }}" type="text/css">
|
||||||
|
<script src="/assets/scripts/htmx.js?v={{ .version }}"></script>
|
||||||
|
<script>document.addEventListener('htmx:afterSwap', function() {window.scrollTo(0, 0);});</script>
|
||||||
</head>
|
</head>
|
||||||
{{ end }}
|
{{ end }}
|
|
@ -19,7 +19,19 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
see <a href="/">main page</a> or go to <a href="/posts/0">posts section</a>
|
see <a href="/"
|
||||||
|
hx-get="/?ajax=true"
|
||||||
|
hx-target="main"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-push-url="/">
|
||||||
|
main page</a> or go to
|
||||||
|
<a href="/posts/0"
|
||||||
|
hx-get="/posts/0?ajax=true"
|
||||||
|
hx-target="main"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-push-url="/posts/0">
|
||||||
|
posts section
|
||||||
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
{{ template "head" . }}
|
|
||||||
<body>
|
|
||||||
{{ template "header" . }}
|
|
||||||
<main>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<code>welcome to my little site</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
$whoami
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
my name is serr (you can easily guess my real name if you speak Russian :d), and i didn't come up with that nickname, i just started being called it
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
i was born in 2003, i'm currently a cybersecurity major at university
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<code>pronouns: he/him</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
what do i do?
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
programming is my lifestyle
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
i love growing in all areas of programming - i am literally interested in everything: web development, low-level programming, formal grammars and a lot more!
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
i like the idea of <a href="https://en.wikipedia.org/wiki/Symbolic_execution" target="_blank">symbolic</a>/concolic execution and virtual code execution in general
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
things i love
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
<strong>> coffee</strong>. i REALLY love coffee. almost any. and a lot of<br/>
|
|
||||||
<strong>> movies and TV series</strong> (especially TV series). i watch something almost every day<br/>
|
|
||||||
<strong>> true crime</strong>. i'm obsessed with serial killer cases, mysterious disappearances, unsolved murders - all that dark stuff<br/>
|
|
||||||
<strong>> russian underground rap</strong> like Slava KPSS, Zamay, MB Packet, Ovsyankin etc.<br/>
|
|
||||||
<strong>> simple and extensible code</strong>. i think if your code is overly complex, it means you are doing something wrong. most things are simpler than they seem
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
projects
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
> <a href="https://git.hikan.ru/serr/candycache" target="_blank">git.hikan.ru/serr/candycache</a> - simple and efficient Go cache<br/>
|
|
||||||
> <a href="https://git.hikan.ru/serr/eye-hot-reloader" target="_blank">git.hikan.ru/serr/eye-hot-reloader</a> - lightweight directories monitor with automatic rebuild and restart functionality for any project type<br/>
|
|
||||||
> <del>telegram bot with schedule for SPBPU - <a href="https://t.me/polysched_bot" target="_blank">polysched_bot</a></del> (transferred to a more proactive owner)<br/>
|
|
||||||
> <del>telegram bot with schedule for SPMI - <a href="https://t.me/gornischedule_bot" target="_blank">gornischedule_bot</a></del> (closed)<br/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h1>
|
|
||||||
nice links
|
|
||||||
</h1>
|
|
||||||
<p>
|
|
||||||
> huge collection of Xakep issues - <a href="https://図書館.きく.コム/" target="_blank">図書館.きく.コム</a><br/>
|
|
||||||
> i like to surf here - <a href="https://neocities.org/browse" target="_blank">neocities.org/browse</a><br/>
|
|
||||||
> very atmospheric forum about black metal - <a href="https://www.lycanthropia.net/" target="_blank">lycanthropia</a><br/>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{{ template "footer" . }}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "head" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "header" . }}
|
||||||
|
{{ template "main_ajax" . }}
|
||||||
|
{{ template "footer" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,72 @@
|
||||||
|
{{ template "main_ajax" . }}
|
||||||
|
|
||||||
|
{{ define "main_ajax" }}
|
||||||
|
<main>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<code>welcome to my little site</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
$whoami
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
my name is serr (you can easily guess my real name if you speak Russian :d), and i didn't come up with that nickname, i just started being called it
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
i was born in 2003, i'm currently a cybersecurity major at university
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>pronouns: he/him</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
what do i do?
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
programming is my lifestyle
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
i love growing in all areas of programming - i am literally interested in everything: web development, low-level programming, formal grammars and a lot more!
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
i like the idea of <a href="https://en.wikipedia.org/wiki/Symbolic_execution" target="_blank">symbolic</a>/concolic execution and virtual code execution in general
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
things i love
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
<strong>> coffee</strong>. i REALLY love coffee. almost any. and a lot of<br/>
|
||||||
|
<strong>> movies and TV series</strong> (especially TV series). i watch something almost every day<br/>
|
||||||
|
<strong>> true crime</strong>. i'm obsessed with serial killer cases, mysterious disappearances, unsolved murders - all that dark stuff<br/>
|
||||||
|
<strong>> russian underground rap</strong> like Slava KPSS, Zamay, MB Packet, Ovsyankin etc.<br/>
|
||||||
|
<strong>> simple and extensible code</strong>. i think if your code is overly complex, it means you are doing something wrong. most things are simpler than they seem
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
projects
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
> <a href="https://git.hikan.ru/serr/candycache" target="_blank">git.hikan.ru/serr/candycache</a> - simple and efficient Go cache<br/>
|
||||||
|
> <a href="https://git.hikan.ru/serr/eye-hot-reloader" target="_blank">git.hikan.ru/serr/eye-hot-reloader</a> - lightweight directories monitor with automatic rebuild and restart functionality for any project type<br/>
|
||||||
|
> <del>telegram bot with schedule for SPBPU - <a href="https://t.me/polysched_bot" target="_blank">polysched_bot</a></del> (transferred to a more proactive owner)<br/>
|
||||||
|
> <del>telegram bot with schedule for SPMI - <a href="https://t.me/gornischedule_bot" target="_blank">gornischedule_bot</a></del> (closed)<br/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h1>
|
||||||
|
nice links
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
> huge collection of Xakep issues - <a href="https://図書館.きく.コム/" target="_blank">図書館.きく.コム</a><br/>
|
||||||
|
> i like to surf here - <a href="https://neocities.org/browse" target="_blank">neocities.org/browse</a><br/>
|
||||||
|
> very atmospheric forum about black metal - <a href="https://www.lycanthropia.net/" target="_blank">lycanthropia</a><br/>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{{ end }}
|
|
@ -1,16 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
{{ template "head" . }}
|
|
||||||
<body>
|
|
||||||
{{ template "header" . }}
|
|
||||||
<main>
|
|
||||||
<div>
|
|
||||||
{{ .data }}
|
|
||||||
<p>
|
|
||||||
<code>create time: {{ .modTimestamp }}</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
{{ template "footer" . }}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "head" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "header" . }}
|
||||||
|
{{ template "post_ajax" . }}
|
||||||
|
{{ template "footer" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,12 @@
|
||||||
|
{{ template "post_ajax" . }}
|
||||||
|
|
||||||
|
{{ define "post_ajax" }}
|
||||||
|
<main>
|
||||||
|
<div>
|
||||||
|
{{ .data }}
|
||||||
|
<p>
|
||||||
|
<code>create time: {{ .modTimestamp }}</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{{ end }}
|
|
@ -1,29 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
{{ template "head" . }}
|
|
||||||
<body>
|
|
||||||
{{ template "header" . }}
|
|
||||||
<main>
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
<code>posts sorted by create time</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{ range $ind, $post := .posts }}
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
{{ $post.Preview }}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a href="{{ $post.Link }}">read more</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<code>create time: {{ $post.Timestamp }}</code>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
<div class="pagi">{{ .pagi }}</div>
|
|
||||||
</main>
|
|
||||||
{{ template "footer" . }}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
{{ template "head" . }}
|
||||||
|
<body>
|
||||||
|
{{ template "header" . }}
|
||||||
|
{{ template "posts_ajax" . }}
|
||||||
|
{{ template "footer" . }}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,41 @@
|
||||||
|
{{ template "posts_ajax" . }}
|
||||||
|
|
||||||
|
{{ define "posts_ajax" }}
|
||||||
|
<main>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<code>posts sorted by create time</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{ range $ind, $post := .posts }}
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
{{ $post.Preview }}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="{{ $post.Link }}"
|
||||||
|
hx-get="{{ $post.Link }}?ajax=true"
|
||||||
|
hx-target="main"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-push-url="{{ $post.Link }}">read more</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>create time: {{ $post.Timestamp }}</code>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<div class="pagi">
|
||||||
|
<a href="/posts/{{ .prevPageNumber }}"
|
||||||
|
hx-get="/posts/{{ .prevPageNumber }}?ajax=true"
|
||||||
|
hx-target="main"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-push-url="/posts/{{ .prevPageNumber }}"><-</a>
|
||||||
|
{{ .pageNumberInc }}/{{ .pagesCount }}
|
||||||
|
<a href="/posts/{{ .nextPageNumber }}"
|
||||||
|
hx-get="/posts/{{ .nextPageNumber }}?ajax=true"
|
||||||
|
hx-target="main"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
hx-push-url="/posts/{{ .nextPageNumber }}">-></a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{{ end }}
|
Loading…
Reference in New Issue