126 lines
3.5 KiB
Go
126 lines
3.5 KiB
Go
package models
|
||
|
||
import (
|
||
"html/template"
|
||
"main/config"
|
||
"strings"
|
||
)
|
||
|
||
// Структура поста
|
||
type Post struct {
|
||
ID int
|
||
Author string
|
||
Title string
|
||
Body template.HTML
|
||
PostingTime string
|
||
UpdateTime string
|
||
Tags string
|
||
}
|
||
|
||
type Posts []Post
|
||
|
||
const (
|
||
LOCK_POST_DESCR = "🤖 Пост доступен только для зарегистрированных пользователей. Аккаунты создаются администратором. Превью для приватных постов не предусмотрено..."
|
||
SMALL_POST_DESCR = "🛸 Прилетело НЛО и украло описание поста..."
|
||
)
|
||
|
||
func (posts Posts) GetPostById(id int) Post {
|
||
if id < 1 || id > len(posts) {
|
||
return posts[0]
|
||
}
|
||
return posts[len(posts)-id]
|
||
}
|
||
|
||
func (posts Posts) GetPrevPageNumber(pageNumber int) int {
|
||
if 1 > pageNumber-1 {
|
||
return pageNumber
|
||
} else {
|
||
return pageNumber - 1
|
||
}
|
||
}
|
||
|
||
func (posts Posts) GetNextPageNumber(pageNumber int) int {
|
||
if posts.GetMaxPageNumber() < pageNumber+1 {
|
||
return pageNumber
|
||
} else {
|
||
return pageNumber + 1
|
||
}
|
||
}
|
||
|
||
func (posts Posts) GetMaxPageNumber() int {
|
||
if len(posts) == 0 {
|
||
return 1
|
||
}
|
||
pages := len(posts) / config.Cfg.MaxPostsOnPage
|
||
if len(posts)%config.Cfg.MaxPostsOnPage != 0 {
|
||
pages++
|
||
}
|
||
return pages
|
||
}
|
||
|
||
func (p Posts) TagsMap() map[string]int {
|
||
tagsCount := make(map[string]int)
|
||
|
||
for _, post := range p {
|
||
for _, tag := range strings.Fields(post.Tags) {
|
||
if tag != "" {
|
||
tagsCount[tag]++
|
||
}
|
||
}
|
||
}
|
||
|
||
return tagsCount
|
||
}
|
||
|
||
// Подсписок постов по номеру страницы
|
||
func (posts Posts) GetSublistByPageNumber(pageNumber int) Posts {
|
||
// Рассчитываем индекс начала и конца среза
|
||
if pageNumber < 1 {
|
||
return posts[0:config.Cfg.MaxPostsOnPage]
|
||
}
|
||
startIndex := (pageNumber - 1) * config.Cfg.MaxPostsOnPage
|
||
endIndex := startIndex + config.Cfg.MaxPostsOnPage
|
||
// Проверяем, не превышает ли конец доступный размер
|
||
if startIndex >= len(posts) {
|
||
// Возвращаем пустой срез, если номер страницы вне допустимого диапазона
|
||
return Posts{}
|
||
}
|
||
if endIndex > len(posts) {
|
||
// Если конец превышает длину списка, устанавливаем его на длину списка
|
||
endIndex = len(posts)
|
||
}
|
||
// Возвращаем подсписок постов
|
||
return posts[startIndex:endIndex]
|
||
}
|
||
|
||
// Поиск постов по тэгам
|
||
func (posts Posts) GetPostListBySubstring(substring string) Posts {
|
||
res := make(Posts, 0, len(posts))
|
||
// Если первый символ - #, то поиск происходит по тегам
|
||
if substring = substring + " "; substring[0] == '#' {
|
||
for i := range posts {
|
||
// добавляю пробел, чтобы не было ситуации включения одного тега в начало другого
|
||
if strings.Contains(posts[i].Tags+" ", substring) {
|
||
res = append(res, posts[i])
|
||
}
|
||
}
|
||
}
|
||
return res
|
||
}
|
||
|
||
// Получение превью поста
|
||
func (post Post) PostDescription() template.HTML {
|
||
const maxLength = 500
|
||
|
||
if len(post.Body) > maxLength {
|
||
spanIndex := strings.Index(string(post.Body), "<span>")
|
||
min := min(spanIndex, maxLength)
|
||
if min != -1 {
|
||
return template.HTML(post.Body[:min] + "...")
|
||
} else {
|
||
return template.HTML(post.Body[:maxLength] + "...")
|
||
}
|
||
}
|
||
return template.HTML(SMALL_POST_DESCR)
|
||
}
|