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)
|
|||
|
}
|