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