github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/web/post/post.go (about)

     1  package webpost
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strconv"
     7  	"strings"
     8  	"sync"
     9  
    10  	"github.com/ngocphuongnb/tetua/app/entities"
    11  	"github.com/ngocphuongnb/tetua/app/repositories"
    12  	"github.com/ngocphuongnb/tetua/app/server"
    13  	"github.com/ngocphuongnb/tetua/app/utils"
    14  	"github.com/ngocphuongnb/tetua/views"
    15  )
    16  
    17  func List(c server.Context) error {
    18  	paginate, err := repositories.Post.Paginate(c.Context(), &entities.PostFilter{
    19  		Filter: &entities.Filter{
    20  			BaseUrl:         utils.Url("/posts"),
    21  			Page:            c.QueryInt("page"),
    22  			IgnoreUrlParams: []string{"user"},
    23  		},
    24  		UserIDs: []int{c.User().ID},
    25  		Approve: "all",
    26  		Publish: "all",
    27  	})
    28  
    29  	if err != nil {
    30  		c.WithError("Something went wrong", err)
    31  	}
    32  
    33  	return c.Render(views.PostList(paginate))
    34  }
    35  
    36  func Delete(c server.Context) error {
    37  	if err := repositories.Post.DeleteByID(c.Context(), c.ParamInt("id")); err != nil {
    38  		c.Logger().Error("Error deleting post", err)
    39  		return c.Status(http.StatusBadRequest).Json(&entities.Message{
    40  			Type:    "error",
    41  			Message: "Error deleting post",
    42  		})
    43  	}
    44  
    45  	return c.Status(http.StatusOK).Json(&entities.Message{
    46  		Type:    "success",
    47  		Message: "Post deleted",
    48  	})
    49  }
    50  
    51  func View(c server.Context) error {
    52  	var post = &entities.Post{}
    53  	var slug = c.Param("slug")
    54  	var slugParts = strings.Split(slug, "-")
    55  
    56  	if len(slugParts) < 2 {
    57  		return ViewPage(c)
    58  	}
    59  
    60  	var slugId = slugParts[len(slugParts)-1]
    61  	var relatedPosts []*entities.Post
    62  	var comments = []*entities.Comment{}
    63  	var wg sync.WaitGroup
    64  	var postId, err = strconv.Atoi(slugId)
    65  
    66  	if err != nil {
    67  		return ViewPage(c)
    68  	}
    69  
    70  	if post, err = repositories.Post.PublishedPostByID(c.Context(), postId); err != nil || post == nil {
    71  		return ViewPage(c)
    72  	}
    73  
    74  	postSlug := fmt.Sprintf("%s-%d", post.Slug, post.ID)
    75  
    76  	if postSlug != slug {
    77  		return c.RedirectToRoute("post.view", entities.Map{"slug": postSlug})
    78  	}
    79  
    80  	wg.Add(2)
    81  	go func() {
    82  		if err := repositories.Post.IncreaseViewCount(c.Context(), postId, 1); err != nil {
    83  			c.Logger().Error("Error incrementing post view", err)
    84  		}
    85  	}()
    86  
    87  	go func(wg *sync.WaitGroup) {
    88  		defer wg.Done()
    89  		relatedPosts = getRelatedPosts(c, post)
    90  	}(&wg)
    91  
    92  	go func(wg *sync.WaitGroup) {
    93  		defer wg.Done()
    94  		comments, err = repositories.Comment.Find(c.Context(), &entities.CommentFilter{
    95  			PostIDs: []int{postId},
    96  			Filter: &entities.Filter{
    97  				Limit: 10000,
    98  			},
    99  		})
   100  	}(&wg)
   101  
   102  	wg.Wait()
   103  	c.Meta().Title = post.Name
   104  	c.Meta().Description = post.Description
   105  
   106  	if post.FeaturedImage != nil {
   107  		c.Meta().Image = post.FeaturedImage.Url()
   108  	}
   109  
   110  	return c.Render(views.PostView(post, relatedPosts, comments))
   111  }
   112  
   113  func getRelatedPosts(c server.Context, post *entities.Post) []*entities.Post {
   114  	var relatedPosts []*entities.Post
   115  	var err error
   116  
   117  	if relatedPosts, err = repositories.Post.Find(c.Context(), &entities.PostFilter{
   118  		Filter: &entities.Filter{
   119  			Limit:      8,
   120  			ExcludeIDs: []int{post.ID},
   121  			Sorts: []*entities.Sort{{
   122  				Field: "view_count",
   123  				Order: "desc",
   124  			}},
   125  		},
   126  		TopicIDs: utils.SliceMap(post.Topics, func(topic *entities.Topic) int {
   127  			return topic.ID
   128  		}),
   129  	}); err != nil {
   130  		c.Logger().Error("Error finding related posts", err)
   131  	}
   132  
   133  	return relatedPosts
   134  }