kvs_feed.erl 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. -module(kvs_feed).
  2. -copyright('Synrc Research Center, s.r.o.').
  3. -compile(export_all).
  4. -include("config.hrl").
  5. -include("entry.hrl").
  6. -include("feed.hrl").
  7. -include("metainfo.hrl").
  8. -include("comment.hrl").
  9. -include("state.hrl").
  10. metainfo() ->
  11. #schema{name=kvs,tables=[
  12. #table{name=entry,container=feed,fields=record_info(fields,entry),keys=[feed_id,entry_id,from]},
  13. #table{name=comment,container=feed,fields=record_info(fields,comment),keys=[entry_id,author_id]},
  14. #table{name=feed,container=true,fields=record_info(fields,feed)}
  15. ]}.
  16. comments_count(entry, Eid) -> case kvs:get(entry, Eid) of {error,_} -> 0; {ok, E} -> comments_count([E],0) end;
  17. comments_count(product, Pid)->case kvs:get(product, Pid) of {error,_}->0; {ok, P} -> comments_count([P], 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
  23. + comments_count(kvs:entries(Feed, comment, undefined), 0) end end,
  24. comments_count(T, C + Acc).
  25. author_comments(Who) ->
  26. EIDs = [E || #comment{entry_id=E} <- kvs:index(comment,from, Who) ],
  27. lists:flatten([ kvs:index(entry, id,EID) || EID <- EIDs]).
  28. %% MQ API
  29. handle_notice( [kvs_feed,_,Owner,entry,{Eid,Fid},add],
  30. [#entry{feed_id=Fid}=Entry],
  31. #state{owner=Owner}=State) ->
  32. case lists:keyfind(Fid,2, State#state.feeds) of
  33. false -> skip;
  34. {_,_} -> add_entry({Eid,Fid},Entry) end,
  35. {noreply, State};
  36. handle_notice( [kvs_feed,_,_,comment,Cid,add],
  37. [#comment{id={Cid,{_,Fid}, _}}=Comment],
  38. #state{feeds=Feeds}=State) ->
  39. case lists:keyfind(Fid,2,Feeds) of
  40. false -> skip;
  41. {_,_}-> add_comment(Comment) end,
  42. {noreply, State};
  43. handle_notice( [kvs_feed,_,Owner,entry,{Eid,Fid},edit],
  44. [#entry{feed_id=Fid}=Entry],
  45. #state{owner=Owner, feeds=Feeds}=State) ->
  46. case lists:keyfind(Fid,1,Feeds) of
  47. false -> skip;
  48. {_,Fid}-> update_entry({Eid,Fid},Entry) end,
  49. {noreply, State};
  50. handle_notice( [kvs_feed,_,entry,delete],
  51. [#entry{id=Id,feed_id=Fid}=Entry],
  52. #state{feeds=Feeds}=State) ->
  53. kvs:info(?MODULE,"[kvs_feed] delete entry ~p",[Id]),
  54. case lists:keyfind(Fid,2,Feeds) of
  55. false -> ok;
  56. _ -> kvs:info(?MODULE,"[kvs_feed] => Remove entry ~p from feed ~p", [Id, Fid]),
  57. kvs:remove(entry, Id),
  58. ?MQ:notify([kvs_feed, entry, Id, deleted], [Entry]) end,
  59. {noreply,State};
  60. handle_notice( [kvs_feed,Owner,delete],
  61. [#entry{entry_id=Eid}=Entry],
  62. #state{owner=Owner}=State) ->
  63. kvs:info(?MODULE,"[kvs_feed] delete all entries ~p ~p", [Entry#entry.entry_id, Owner]),
  64. [ ?MQ:notify([kvs_feed,To,entry,delete],[Ed])
  65. || #entry{to={_, To}}=Ed <- kvs:index(entry, entry_id, Eid) ],
  66. Fid = element(1,Entry),
  67. kvs:remove(entry,{Eid, Fid}),
  68. Removed = Entry#entry{id={Eid,Fid},feed_id=Fid},
  69. ?MQ:notify([kvs_feed,entry,{Eid, Fid},deleted], [Removed]),
  70. {noreply, State};
  71. handle_notice(_Route, _Message, State) -> {noreply, State}.
  72. notify([Module|_]=Path, Message, State) ->
  73. case kvs:config(feeds) of
  74. enabled -> ?MQ:notify(Path,Message);
  75. _ -> Module:handle_notice(Path,Message,State) end.
  76. add_comment(Comment=#comment{}) ->
  77. kvs:info(?MODULE,"[kvs_feed] add comment: ~p to feed ~p", [Comment#comment.id, Comment#comment.feed_id]),
  78. C = Comment#comment{feeds=[comments]},
  79. Added = case kvs:add(C) of {error, E} -> {error, E}; {ok, Cm} -> Cm end,
  80. ?MQ:notify([kvs_feed, comment, C#comment.id, added], [Added]).
  81. add_entry({Eid,Fid},Entry=#entry{}) ->
  82. kvs:info(?MODULE,"[kvs_feed] add entry: ~p to feed ~p.", [Entry#entry.id, Entry#entry.feed_id]),
  83. E = Entry#entry{id = {Eid, Fid}, entry_id = Eid, feeds=[comments]},
  84. Added = case kvs:add(E) of {error, Err}-> {error,Err}; {ok, En} -> En end,
  85. ?MQ:notify([kvs_feed, entry, E#entry.id, added], [Added]).
  86. update_entry(Key={Eid,Fid},Entry) ->
  87. case kvs:get(entry,Key) of
  88. {error,_} -> skip;
  89. {ok, E} ->
  90. kvs:info(?MODULE,"[kvs_feed] update entry ~p in feed ~p", [Eid,Fid]),
  91. Updated = E#entry{description=Entry#entry.description,
  92. title = Entry#entry.title,
  93. media = Entry#entry.media,
  94. etc = Entry#entry.etc,
  95. type = Entry#entry.type},
  96. kvs:put(Updated),
  97. ?MQ:notify([kvs_feed,entry,Key,updated], [Updated]) end.