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

     1  package web
     2  
     3  import (
     4  	"net/http"
     5  	"strconv"
     6  	"sync"
     7  
     8  	"github.com/gorilla/feeds"
     9  	"github.com/ngocphuongnb/tetua/app/cache"
    10  	"github.com/ngocphuongnb/tetua/app/config"
    11  	"github.com/ngocphuongnb/tetua/app/entities"
    12  	"github.com/ngocphuongnb/tetua/app/repositories"
    13  	"github.com/ngocphuongnb/tetua/app/server"
    14  	"github.com/ngocphuongnb/tetua/app/utils"
    15  	"github.com/ngocphuongnb/tetua/views"
    16  )
    17  
    18  func TopicView(c server.Context) (err error) {
    19  	topicSlug := c.Param("slug")
    20  	topics := utils.SliceFilter(cache.Topics, func(t *entities.Topic) bool {
    21  		return t.Slug == topicSlug
    22  	})
    23  
    24  	if len(topics) == 0 {
    25  		c.Meta().Title = "Topic not found"
    26  		return c.Status(http.StatusNotFound).Render(views.Error("Topic not found"))
    27  	}
    28  
    29  	topic := topics[0]
    30  	c.Meta().Title = topic.Name
    31  	var wg sync.WaitGroup
    32  	var paginate *entities.Paginate[entities.Post]
    33  	var topPosts []*entities.Post
    34  
    35  	wg.Add(2)
    36  	go func(wg *sync.WaitGroup) {
    37  		defer wg.Done()
    38  		paginate, err = repositories.Post.Paginate(c.Context(), &entities.PostFilter{
    39  			Filter: &entities.Filter{
    40  				Page:            c.QueryInt("page"),
    41  				IgnoreUrlParams: []string{"topic"},
    42  			},
    43  			TopicIDs: []int{topic.ID},
    44  		})
    45  	}(&wg)
    46  	go func(wg *sync.WaitGroup) {
    47  		defer wg.Done()
    48  		var topPostErr error
    49  		topPosts, topPostErr = repositories.Post.Find(c.Context(), &entities.PostFilter{
    50  			Filter: &entities.Filter{
    51  				Limit: 8,
    52  				Sorts: []*entities.Sort{{
    53  					Field: "view_count",
    54  					Order: "desc",
    55  				}},
    56  			},
    57  			TopicIDs: []int{topic.ID},
    58  		})
    59  
    60  		if topPostErr != nil {
    61  			c.Logger().Error(topPostErr)
    62  		}
    63  	}(&wg)
    64  
    65  	wg.Wait()
    66  
    67  	if err != nil {
    68  		c.Logger().Error(err)
    69  		return c.Status(http.StatusBadGateway).Render(views.Error("Something went wrong"))
    70  	}
    71  
    72  	return c.Render(views.TopicView(cache.Topics, topic, paginate, topPosts))
    73  }
    74  
    75  func TopicFeed(c server.Context) error {
    76  	topics := utils.SliceFilter(cache.Topics, func(t *entities.Topic) bool {
    77  		return t.Slug == c.Param("slug")
    78  	})
    79  
    80  	if len(topics) == 0 {
    81  		c.Meta().Title = "Topic not found"
    82  		return c.Status(http.StatusNotFound).SendString("Topic not found")
    83  	}
    84  
    85  	topic := topics[0]
    86  	posts, err := repositories.Post.Find(c.Context(), &entities.PostFilter{
    87  		Filter: &entities.Filter{
    88  			Limit: 50,
    89  		},
    90  		TopicIDs: []int{topic.ID},
    91  	})
    92  
    93  	if err != nil {
    94  		c.Logger().Error(err)
    95  		return c.Status(http.StatusNotFound).SendString("Topic not found")
    96  	}
    97  
    98  	feed := &feeds.Feed{
    99  		Title:       topic.Name,
   100  		Link:        &feeds.Link{Href: topic.Url()},
   101  		Description: topic.Description,
   102  		Author:      &feeds.Author{Name: config.Setting("contact_name"), Email: config.Setting("contact_email")},
   103  	}
   104  
   105  	feed.Items = utils.SliceMap(posts, func(post *entities.Post) *feeds.Item {
   106  		return &feeds.Item{
   107  			Id:          strconv.Itoa(post.ID),
   108  			Title:       post.Name,
   109  			Description: post.Description,
   110  			Content:     post.ContentHTML,
   111  			Author:      &feeds.Author{Name: post.User.Name(), Email: post.User.Email},
   112  			Link:        &feeds.Link{Href: post.Url()},
   113  			Created:     *post.CreatedAt,
   114  			Updated:     *post.UpdatedAt,
   115  		}
   116  	})
   117  
   118  	rss, err := feed.ToRss()
   119  	if err != nil {
   120  		c.Logger().Error(err)
   121  		return c.Status(http.StatusInternalServerError).SendString("Error")
   122  	}
   123  
   124  	c.Response().Header("content-type", "application/xml; charset=utf-8")
   125  	return c.SendString(rss)
   126  }