kvs_feed.erl 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. -module(kvs_feed).
  2. -author('Maxim Sokhatsky').
  3. -author('Andrii Zadorozhnii').
  4. -author('Alexander Kalenuk').
  5. -copyright('Synrc Research Center, s.r.o.').
  6. -compile(export_all).
  7. -include_lib("kvs/include/feeds.hrl").
  8. -include_lib("kvs/include/users.hrl").
  9. -include_lib("kvs/include/groups.hrl").
  10. -include_lib("kvs/include/feed_state.hrl").
  11. -define(CACHED_ENTRIES, 20).
  12. create() ->
  13. FId = kvs:next_id("feed", 1),
  14. ok = kvs:put(#feed{id = FId} ),
  15. FId.
  16. comments_count(user, Uid) -> case kvs:get(user_etries_count, Uid) of {error,_} -> 0; {ok, UEC} -> UEC#user_etries_count.comments end;
  17. comments_count(entry, Eid) -> case kvs:get(entry, Eid) of {error,_} -> 0; {ok, E} -> comments_count([E],0) end;
  18. comments_count([], Acc) -> Acc;
  19. comments_count([E|T], Acc) ->
  20. C = case lists:keyfind(comments, 1, element(#iterator.feeds, E)) of false -> 0;
  21. {_, Fid} -> case kvs:get(feed, Fid) of {error,_} -> 0;
  22. {ok, Feed } -> Feed#feed.entries_count + comments_count(kvs:entries(Feed, comment), 0) end end,
  23. comments_count(T, C + Acc).
  24. add_like(Fid, Eid, Uid) ->
  25. Write_one_like = fun(Next) ->
  26. Self_id = kvs:next_id("one_like", 1),
  27. kvs:put(#one_like{ % add one like
  28. id = Self_id,
  29. user_id = Uid,
  30. entry_id = Eid,
  31. feed_id = Fid,
  32. created_time = now(),
  33. next = Next
  34. }),
  35. Self_id
  36. end,
  37. % add entry - like
  38. case kvs:get(entry_likes, Eid) of
  39. {ok, ELikes} ->
  40. kvs:put(ELikes#entry_likes{
  41. one_like_head = Write_one_like(ELikes#entry_likes.one_like_head),
  42. total_count = ELikes#entry_likes.total_count + 1
  43. });
  44. {error, _} ->
  45. kvs:put(#entry_likes{
  46. entry_id = Eid,
  47. one_like_head = Write_one_like(undefined),
  48. total_count = 1
  49. })
  50. end,
  51. % add user - like
  52. case kvs:get(user_likes, Uid) of
  53. {ok, ULikes} ->
  54. kvs:put(ULikes#user_likes{
  55. one_like_head = Write_one_like(ULikes#user_likes.one_like_head),
  56. total_count = ULikes#user_likes.total_count + 1
  57. });
  58. {error, _} ->
  59. kvs:put(#user_likes{
  60. user_id = Uid,
  61. one_like_head = Write_one_like(undefined),
  62. total_count = 1
  63. })
  64. end.
  65. entries_count(Uid) ->
  66. case kvs:get(user_etries_count, Uid) of
  67. {ok, UEC} -> UEC#user_etries_count.entries;
  68. {error, _} -> 0 end.
  69. edit_entry(FeedId, EId, NewDescription) ->
  70. case kvs:get(entry,{EId, FeedId}) of
  71. {ok, OldEntry} ->
  72. NewEntryRaw = OldEntry#entry{description = NewDescription},
  73. NewEntry = feedformat:format(NewEntryRaw),
  74. kvs:put(NewEntry);
  75. {error, Reason}-> {error, Reason} end.
  76. like_list(undefined) -> [];
  77. like_list(Id) -> {ok, OneLike} = kvs:get(one_like, Id), [OneLike] ++ like_list(OneLike#one_like.next).
  78. like_list(undefined, _) -> [];
  79. like_list(_, 0) -> [];
  80. like_list(Id, N) -> {ok, OneLike} = kvs:get(one_like, Id), [OneLike] ++ like_list(OneLike#one_like.next, N-1).
  81. entry_likes(Entry_id) ->
  82. case kvs:get(entry_likes, Entry_id) of
  83. {ok, Likes} -> like_list(Likes#entry_likes.one_like_head);
  84. {error, _} -> [] end.
  85. entry_likes_count(Entry_id) ->
  86. case kvs:get(entry_likes, Entry_id) of
  87. {ok, Likes} -> Likes#entry_likes.total_count;
  88. {error, _} -> 0 end.
  89. user_likes_count(UserId) ->
  90. case kvs:get(user_likes, UserId) of
  91. {ok, Likes} -> Likes#user_likes.total_count;
  92. {error, _} -> 0 end.
  93. user_likes(UserId) ->
  94. case kvs:get(user_likes, UserId) of
  95. {ok, Likes} -> like_list(Likes#user_likes.one_like_head);
  96. {error, _} -> [] end.
  97. user_likes(UserId, {Page, PageAmount}) ->
  98. case kvs:get(user_likes, UserId) of
  99. {ok, Likes} -> lists:nthtail((Page-1)*PageAmount, like_list(Likes#user_likes.one_like_head, PageAmount*Page));
  100. {error, _} -> [] end.
  101. %% MQ API
  102. handle_notice([kvs_feed, _, Owner, entry, Eid, add],
  103. [#entry{feed_id=Fid}=Entry|_],
  104. #state{owner=Owner} = S) ->
  105. case lists:keyfind(Fid,2, S#state.feeds) of false -> skip;
  106. {_,_} ->
  107. EntryId = case Eid of new -> kvs:uuid(); _-> Eid end,
  108. E = Entry#entry{id = {EntryId, Fid}, entry_id = EntryId, feeds=[comments]},
  109. kvs:add(E) end,
  110. {noreply, S};
  111. handle_notice([kvs_feed,_, Owner, entry, {_, Fid}, edit],
  112. #entry{entry_id=Eid}=Entry,
  113. #state{owner=Owner, feeds=Feeds}=S) ->
  114. case lists:keyfind(Fid,2,Feeds) of false -> skip;
  115. {_,_} -> case kvs:get(entry, {Eid, Fid}) of {error, not_found}-> skip;
  116. {ok, E} ->
  117. error_logger:info_msg("kvs_feed => Entry ~p updated in feed ~p", [Eid, Fid]),
  118. kvs:put(E#entry{description=Entry#entry.description,
  119. title = Entry#entry.title,
  120. media = Entry#entry.media,
  121. etc = Entry#entry.etc,
  122. type = Entry#entry.type}) end end,
  123. {noreply, S};
  124. handle_notice([kvs_feed,_, Owner, entry, {_,Fid}, delete],
  125. [#entry{id=Id, entry_id=Eid},_], #state{owner=Owner, feeds=Feeds} = State) ->
  126. case lists:keyfind(Fid,2,Feeds) of false -> skip;
  127. {_,_} -> error_logger:info_msg("REMOVE from FID ~p", [Fid]),kvs:remove(entry, Id) end,
  128. {noreply, State};
  129. handle_notice([kvs_feed,_,Owner,comment,_,add],
  130. [#comment{entry_id={_,EFid}}=C,_,_],
  131. #state{owner=Owner, feeds=Feeds} = S) ->
  132. case lists:keyfind(EFid,2,Feeds) of false -> skip; {_,_}-> kvs:add(C) end,
  133. {noreply, S};
  134. handle_notice(["kvs_feed","likes", _, _, "add_like"] = Route, % _, _ is here beacause of the same message used for comet update
  135. Message, #state{owner = Owner, type =Type} = State) ->
  136. error_logger:info_msg("queue_action(~p): add_like: Owner=~p, Route=~p, Message=~p", [self(), {Type, Owner}, Route, Message]),
  137. {UId, E} = Message,
  138. {EId, FId} = E#entry.id,
  139. kvs_feed:add_like(FId, EId, UId),
  140. {noreply, State};
  141. handle_notice(_Route, _Message, State) ->
  142. %error_logger:error_msg("~p ===> Unknown FEED notice ~p", [State#state.owner, Route]),
  143. {noreply, State}.