Browse Source

store progress: gather the feeds. refactor add_entry

Andrii Zadorozhnii 12 years ago
parent
commit
7b4cad4a1f
11 changed files with 145 additions and 228 deletions
  1. 2 13
      include/feed_state.hrl
  2. 2 3
      include/groups.hrl
  3. 3 15
      include/products.hrl
  4. 1 4
      include/users.hrl
  5. 22 11
      src/kvs.erl
  6. 86 99
      src/kvs_feed.erl
  7. 6 19
      src/kvs_group.erl
  8. 8 20
      src/kvs_products.erl
  9. 3 3
      src/kvs_purchase.erl
  10. 10 39
      src/kvs_user.erl
  11. 2 2
      src/store_mnesia.erl

+ 2 - 13
include/feed_state.hrl

@@ -1,17 +1,6 @@
 -record(state, {
 -record(state, {
         owner = "feed_owner",
         owner = "feed_owner",
         type :: user | group | system | product,
         type :: user | group | system | product,
-        feed,
-        direct,
-        blog,
-        features,
-        specs,
-        gallery,
-        videos,
-        bundles,
-        products,
+        feeds = [],
         callback=feed_server_api,  % tmp field\part of behaviour callback state
         callback=feed_server_api,  % tmp field\part of behaviour callback state
-        cached_feed,
-        cached_direct,
-        cached_friends,
-        cached_groups }).
+        cached_feeds=[]}).

+ 2 - 3
include/groups.hrl

@@ -8,10 +8,9 @@
         creator,
         creator,
         created,
         created,
         owner,
         owner,
-        feed,
-        products,
+        feeds,
         users_count = 0 :: integer(),   % we have to store this, counting would be very expensive and this number is sufficient for sorting and stuff
         users_count = 0 :: integer(),   % we have to store this, counting would be very expensive and this number is sufficient for sorting and stuff
-        entries_count = 0 :: integer() }).
+        entries_count = 0}).
 
 
 -record(group_subscription, {
 -record(group_subscription, {
         key,
         key,

+ 3 - 15
include/products.hrl

@@ -2,13 +2,10 @@
         vendor_id,
         vendor_id,
         id,
         id,
         active,
         active,
-        name,
+        title,
+        brief,
         category,
         category,
         category_name,
         category_name,
-        short_descr,
-        long_descr,
-        small_image_url,
-        big_image_url,
         in_stock,
         in_stock,
         retailer_price,
         retailer_price,
         user_price }).
         user_price }).
@@ -16,20 +13,11 @@
 -record(product, {
 -record(product, {
         id,
         id,
         ext_id                 :: term(),    % ext
         ext_id                 :: term(),    % ext
-        name                   :: string(),  % name
-        display_name           :: binary(),  % admin (based on ext)
-        ext_name               :: binary(),  % ext
         vendor_id              :: integer(), % auto
         vendor_id              :: integer(), % auto
         categories             :: list(integer()), % admin
         categories             :: list(integer()), % admin
         creator,
         creator,
         owner,
         owner,
-        feed,
-        blog,
-        features,
-        specs,
-        gallery,
-        videos,
-        bundles,
+        feeds,
         title,
         title,
         brief,
         brief,
         cover,
         cover,

+ 1 - 4
include/users.hrl

@@ -22,10 +22,7 @@
         verification_code :: string() | '_',
         verification_code :: string() | '_',
         zone,
         zone,
         type,
         type,
-        feed,
-        direct,
-        starred,
-        pinned,
+        feeds=[],
         comments,
         comments,
         discussions,
         discussions,
         transactions,
         transactions,

+ 22 - 11
src/kvs.erl

@@ -40,7 +40,7 @@ init_db() ->
         {error,_} ->
         {error,_} ->
             add_seq_ids(),
             add_seq_ids(),
             kvs_account:create_account(system),
             kvs_account:create_account(system),
-            add_sample_users(),
+            %add_sample_users(),
             add_sample_packages(),
             add_sample_packages(),
             add_sample_payments(),
             add_sample_payments(),
             add_translations();
             add_translations();
@@ -91,22 +91,17 @@ add_translations() ->
 
 
 add_sample_users() ->
 add_sample_users() ->
 
 
-    Groups = [ #group{id="Clojure"},
-               #group{id="Haskell"},
-               #group{id="Erlang"} ],
+    Groups = [],
 
 
     UserList = [
     UserList = [
         #user{username = "maxim", password="pass", name = "Maxim", surname = "Sokhatsky",
         #user{username = "maxim", password="pass", name = "Maxim", surname = "Sokhatsky",
-            feed = kvs_feed:create(), type = admin, direct = kvs_feed:create(),
+            feeds=[{feed, kvs_feed:create()}, {direct, kvs_feed:create()},{starred,kvs_feed:create()},{pinned,kvs_feed:create()}], type = admin,
             sex=m, status=ok, team = kvs_meeting:create_team("tours"),  email="maxim@synrc.com"},
             sex=m, status=ok, team = kvs_meeting:create_team("tours"),  email="maxim@synrc.com"},
         #user{username = "doxtop", password="pass", name = "Andrii", surname = "Zadorozhnii",
         #user{username = "doxtop", password="pass", name = "Andrii", surname = "Zadorozhnii",
-            feed = kvs_feed:create(), type = admin, direct = kvs_feed:create(),
+            feeds=[{feed, kvs_feed:create()}, {direct, kvs_feed:create()},{starred,kvs_feed:create()},{pinned,kvs_feed:create()}], type = admin,
             sex=m, status=ok, team = kvs_meeting:create_team("tours"),  email="doxtop@synrc.com"},
             sex=m, status=ok, team = kvs_meeting:create_team("tours"),  email="doxtop@synrc.com"},
-        #user{username = "alice", password="pass", name = "Alice", surname = "Imagionary",
-            feed = kvs_feed:create(), type = admin, direct = kvs_feed:create(),
-            sex=f, status=ok, team = kvs_meeting:create_team("tours"),  email="alice@synrc.com"},
         #user{username = "akalenuk", password="pass", name = "Alexander", surname = "Kalenuk",
         #user{username = "akalenuk", password="pass", name = "Alexander", surname = "Kalenuk",
-            feed = kvs_feed:create(), type = admin, direct = kvs_feed:create(),
+            feeds=[{feed, kvs_feed:create()}, {direct, kvs_feed:create()},{starred,kvs_feed:create()},{pinned,kvs_feed:create()}], type = admin,
             sex=m, status=ok, team = kvs_meeting:create_team("tours"),  email="akalenuk@gmail.com"}
             sex=m, status=ok, team = kvs_meeting:create_team("tours"),  email="akalenuk@gmail.com"}
     ],
     ],
 
 
@@ -118,7 +113,7 @@ add_sample_users() ->
         [ kvs_group:join(Me#user.username,G#group.id) || G <- Groups ],
         [ kvs_group:join(Me#user.username,G#group.id) || G <- Groups ],
           kvs_account:create_account(Me#user.username),
           kvs_account:create_account(Me#user.username),
           kvs_account:transaction(Me#user.username, quota, Quota, #tx_default_assignment{}),
           kvs_account:transaction(Me#user.username, quota, Quota, #tx_default_assignment{}),
-          kvs:put(Me#user{password = kvs:sha(Me#user.password), starred = kvs_feed:create(), pinned = kvs_feed:create()})
+          kvs:put(Me#user{password = kvs:sha(Me#user.password)})
       end || Me <- UserList ],
       end || Me <- UserList ],
 
 
     kvs_acl:define_access({user, "maxim"},    {feature, admin}, allow),
     kvs_acl:define_access({user, "maxim"},    {feature, admin}, allow),
@@ -236,6 +231,22 @@ load(Key) ->
 coalesce(undefined, B) -> B;
 coalesce(undefined, B) -> B;
 coalesce(A, _) -> A.
 coalesce(A, _) -> A.
 
 
+
+uuid() ->
+  R1 = random:uniform(round(math:pow(2, 48))) - 1,
+  R2 = random:uniform(round(math:pow(2, 12))) - 1,
+  R3 = random:uniform(round(math:pow(2, 32))) - 1,
+  R4 = random:uniform(round(math:pow(2, 30))) - 1,
+  R5 = erlang:phash({node(), now()}, round(math:pow(2, 32))),
+
+  UUIDBin = <<R1:48, 4:4, R2:12, 2:2, R3:32, R4: 30>>,
+  <<TL:32, TM:16, THV:16, CSR:8, CSL:8, N:48>> = UUIDBin,
+
+  lists:flatten(io_lib:format("~8.16.0b-~4.16.0b-~4.16.0b-~2.16.0b~2.16.0b-~12.16.0b-~8.16.0b",
+                              [TL, TM, THV, CSR, CSL, N, R5])).
+uuname() ->
+  lists:flatten(io_lib:format("~8.16.0b",[erlang:phash2({node(), now()}, round(math:pow(2, 32)))])).
+
 sha(Raw) ->
 sha(Raw) ->
     lists:flatten([io_lib:format("~2.16.0b", [N]) || <<N>> <= crypto:sha(Raw)]).
     lists:flatten([io_lib:format("~2.16.0b", [N]) || <<N>> <= crypto:sha(Raw)]).
 
 

+ 86 - 99
src/kvs_feed.erl

@@ -17,28 +17,20 @@ create() ->
     ok = kvs:put(#feed{id = FId} ),
     ok = kvs:put(#feed{id = FId} ),
     FId.
     FId.
 
 
-add_entry(FId, From, To, EntryId, Title, Desc, Medias, Type, SharedBy) ->
-  case kvs:get(feed, FId) of
-    {ok,Feed} ->
-      Id = {EntryId, FId},
+add_entry(E=#entry{}) ->
+  case kvs:get(feed, E#entry.feed_id) of
+    {error, not_found} -> error_logger:info_msg("Add entry failed, no feed ~p", [E#entry.feed_id]);
+    {ok, Feed} ->
       Next = undefined,
       Next = undefined,
-      Prev = case Feed#feed.top of
-        undefined -> undefined;
-        X -> case kvs:get(entry, X) of
-          {ok, TopEntry} -> EditedEntry = TopEntry#entry{next = Id}, kvs:put(EditedEntry), TopEntry#entry.id;
-          {error, _} -> undefined end end,
-
-      kvs:put(#feed{id = FId, top = {EntryId, FId}}), % update feed top with current
-
-      Entry  = #entry{id = {EntryId, FId}, entry_id = EntryId, feed_id = FId, from = From,
-                    to = To, type = Type, media = Medias, created = now(),
-                    title=Title, description = Desc, shared = SharedBy,
-                    next = Next, prev = Prev},
+      Prev = case Feed#feed.top of undefined -> undefined;
+        X -> case kvs:get(entry, X) of {error,_} -> undefined;
+          {ok, Top} -> Edited = Top#entry{next=E#entry.id}, kvs:put(Edited), Top#entry.id end end,
+      kvs:put(#feed{id=E#entry.feed_id, top=E#entry.id}),
 
 
+      Entry  = E#entry{next = Next, prev = Prev},
       kvs:put(Entry),
       kvs:put(Entry),
-      error_logger:info_msg("PUT entry: ~p", [Entry]),
-      {ok, Entry};
-    {error, not_found} -> error_logger:info_msg("Add entry failed. No feed ~p", [FId])
+      error_logger:info_msg("PUT entry: ~p", [Entry#entry.id]),
+      {ok, Entry}
   end.
   end.
 
 
 entry_traversal(undefined, _) -> [];
 entry_traversal(undefined, _) -> [];
@@ -56,11 +48,11 @@ entry_traversal(Next, Count)->
                 _-> Count end,
                 _-> Count end,
             [R | entry_traversal(Prev, Count1)] end.
             [R | entry_traversal(Prev, Count1)] end.
 
 
-entries(FeedId, undefined, PageAmount) ->
+entries({_, FeedId}, undefined, PageAmount) ->
     case kvs:get(feed, FeedId) of
     case kvs:get(feed, FeedId) of
         {ok, O} -> entry_traversal(O#feed.top, PageAmount);
         {ok, O} -> entry_traversal(O#feed.top, PageAmount);
         {error, _} -> [] end;
         {error, _} -> [] end;
-entries(FeedId, StartFrom, PageAmount) ->
+entries({_, FeedId}, StartFrom, PageAmount) ->
     case kvs:get(entry,{StartFrom, FeedId}) of
     case kvs:get(entry,{StartFrom, FeedId}) of
         {ok, #entry{prev = Prev}} -> entry_traversal(Prev, PageAmount);
         {ok, #entry{prev = Prev}} -> entry_traversal(Prev, PageAmount);
         _ -> [] end.
         _ -> [] end.
@@ -174,104 +166,97 @@ purge_feed(FeedId) ->
     kvs:put(Feed#feed{top=undefined}).
     kvs:put(Feed#feed{top=undefined}).
 
 
 purge_unverified_feeds() ->
 purge_unverified_feeds() ->
-    [purge_feed(FeedId) || #user{feed=FeedId, email=E} <- kvs:all(user), E==undefined].
+    [ [purge_feed(Fid)|| {_, Fid} <- Feeds ] || #user{feeds=Feeds, email=E} <- kvs:all(user), E==undefined].
 
 
 %% MQ API
 %% MQ API
 
 
-handle_notice([kvs_feed, Totype, Toid, entry, EntryId, add],
-              [Fid, From, Title, Desc, Medias, EntryType, _, _, _],
-              #state{owner=Owner, feed=Feed, products=Products}=State)->
-  if Owner == Toid ->
-    % handle user direct feed
-    error_logger:info_msg("Add: entry ~p worker ~p feed ~p type ~p", [EntryId, Owner, Feed, Totype]),
-    add_entry(case Totype of product -> Fid; user-> Fid; {group, products}-> error_logger:info_msg("==>Group prods: ~p", [Products]),Products; _ -> Feed end, From, {Toid, Totype}, EntryId, Title, Desc, Medias, EntryType, ""),
-    case Totype of
-      group ->
-          {ok, Group} = kvs:get(group, Toid),
+handle_notice([kvs_feed, _, Owner, entry, Eid, add],
+              [#entry{feed_id=Fid, to={RouteType, _}}=Entry,_,_,_,_],
+              #state{owner=Owner, feeds=Feeds} = S) ->
+    case lists:keyfind(Fid,2,Feeds) of false -> skip;
+      {_,_} ->
+        EntryId = case Eid of new -> kvs:uuid(); _-> Eid end,
+        E = Entry#entry{id = {EntryId, Fid}, entry_id = EntryId },
+        add_entry(E),
+
+        % todo: group entry counts should be counted for each feed
+        case RouteType of group ->
+          {ok, Group} = kvs:get(group, Owner),
           GE = Group#group.entries_count,
           GE = Group#group.entries_count,
+          error_logger:info_msg("count: ~p", [GE]),
           kvs:put(Group#group{entries_count = GE+1}),
           kvs:put(Group#group{entries_count = GE+1}),
-          {ok, Subs} = kvs:get(group_subscription, {From, Toid}),
+
+          {ok, Subs} = kvs:get(group_subscription, {E#entry.from, Owner}),
           SE = Subs#group_subscription.posts_count,
           SE = Subs#group_subscription.posts_count,
           kvs:put(Subs#group_subscription{posts_count = SE+1});
           kvs:put(Subs#group_subscription{posts_count = SE+1});
-      _ -> skip
-    end,
-    self() ! {feed_refresh, Fid, ?CACHED_ENTRIES};
-    true -> skip end,
-  {noreply, State};
+          _ -> skip end
+ end,
+% self() ! {feed_refresh, Fid, ?CACHED_ENTRIES};
+  {noreply, S};
 
 
-handle_notice([kvs_feed, Totype, Toid, entry, {Eid, Fid}, edit],
+handle_notice([kvs_feed, _To, Worker, entry, {Eid, _}, edit, Feed],
               [_, _, Title, Desc],
               [_, _, Title, Desc],
-              #state{owner=Owner, feed=Feed}=State) ->
-  if Owner == Toid ->
-    error_logger:info_msg("Edit: worker ~p entry ~p feed ~p" , [Owner, Eid, Fid] ),
-    case kvs:get(entry, {Eid, case Totype of product -> Fid; _ -> Feed end}) of {error, not_found}-> skip; {ok, Entry} -> error_logger:info_msg("ok!"),kvs:put(Entry#entry{title=Title, description=Desc}) end;
-    true -> skip end,
-  {noreply, State};
-
-handle_notice([kvs_feed, Totype, Toid, entry, {Eid,Fid}, delete],
-              [_From|_], #state{owner=Owner, feed=Feed} = State) ->
-  if Owner == Toid ->
-    error_logger:info_msg("Delete: worker ~p entry ~p feed ~p", [Owner, Eid, Fid]),
-    FeedId = case Totype of product -> Fid; _ -> Feed end, %kvs_acl:check_access(From, {feature, admin})
-    kvs_feed:remove_entry(FeedId, Eid),
-    self() ! {feed_refresh, FeedId, ?CACHED_ENTRIES};
-    true-> skip
-  end,
+              #state{owner=Owner, feeds=Feeds}=S) ->
+
+  case lists:keyfind(Feed,1,Feeds) of false -> skip;
+    {_, Fid} when Owner == Worker ->
+      error_logger:info_msg("Edit: worker ~p entry ~p feed ~p" , [Owner, Eid, Fid] ),
+      case kvs:get(entry, {Eid, Fid}) of {error, not_found}-> skip; {ok, Entry} -> kvs:put(Entry#entry{title=Title, description=Desc}) end end,
+
+  {noreply, S};
+
+handle_notice([kvs_feed, _To, Worker, entry, {Eid,_}, delete, Feed],
+              [_|_], #state{owner=Owner, feeds=Feeds} = State) ->
+  case lists:keyfind(Feed,1,Feeds) of false -> skip;
+    {_,Fid} when Owner == Worker ->
+      error_logger:info_msg("Delete: worker ~p entry ~p feed ~p", [Owner, Eid, Fid]),
+      kvs_feed:remove_entry(Fid, Eid) end,
+  %    self() ! {feed_refresh, FeedId, ?CACHED_ENTRIES};
   {noreply, State};
   {noreply, State};
 
 
-handle_notice([kvs_feed, entry, {Eid, FeedId}, comment, Cid, add],
+handle_notice([kvs_feed, entry, {Eid, FeedId}, comment, add],
               [From, Parent, Content, Medias, _, _],
               [From, Parent, Content, Medias, _, _],
-              #state{owner=Owner, feed=Fid} = State) ->
-  if FeedId == Fid ->
-    [begin error_logger:info_msg("Comment: worker ~p entry ~p cid ~p",[Owner, Eid, Cid]),
-      kvs_comment:add(E#entry.feed_id, From, E#entry.entry_id, Parent, Cid, Content, Medias)
+              #state{owner=Owner, feeds=Feeds} = State) ->
+  HasFeed = lists:keyfind(FeedId,2,Feeds) /= false,
+  if HasFeed ->
+    [begin error_logger:info_msg("Comment: worker ~p entry ~p cid ",[Owner, Eid]),
+      kvs_comment:add(E#entry.feed_id, From, E#entry.entry_id, Parent, kvs:uuid(), Content, Medias)
     end || E <- kvs:all_by_index(entry, entry_id, Eid)];
     end || E <- kvs:all_by_index(entry, entry_id, Eid)];
 
 
     true -> skip end,
     true -> skip end,
-  {noreply, State};
 
 
-handle_notice(["feed", "user", UId, "post_note"] = Route,
-    Message, #state{owner = Owner, feed = Feed} = State) ->
-     error_logger:info_msg("feed(~p): post_note: Owner=~p, Route=~p, Message=~p", [self(), Owner, Route, Message]),
-    Note = Message,
-    Id = utils:uuid_ex(),
-    kvs_feed:add_entry(Feed, UId, [], Id, Note, [], {user, system_note}, ""),
-    {noreply, State};
+  {noreply, State};
 
 
-handle_notice(["kvs_feed", _, WhoShares, "entry", NewEntryId, "share"],
-                #entry{entry_id = _EntryId, description = Desc, media = Medias, to = Destinations,
-                from = From} = E, #state{feed = Feed, type = user} = State) ->
-    %% FIXME: sharing is like posting to the wall
-    error_logger:info_msg("share: ~p, WhoShares: ~p", [E, WhoShares]),
-    kvs_feed:add_entry(Feed, From, Destinations, NewEntryId, Desc, Medias, {user, normal}, WhoShares),
-    {noreply, State};
+%["feed", "user", UId, "post_note"], Note, #state{owner = Owner} = State)
+%["kvs_feed", _, WhoShares, "entry", NewEntryId, "share"],
+%  #entry{entry_id = _EntryId, description = Desc, media = Medias, to = Destinations, from = From} = E, #state{type = user} = State)
 
 
-handle_notice(["kvs_feed", "group", _Group, "entry", EntryId, "delete"] = Route,
-              Message, #state{owner = Owner, feed = Feed} = State) ->
-    error_logger:info_msg("feed(~p): remove entry: Owner=~p, Route=~p, Message=~p",
-          [self(), Owner, Route, Message]),
+%handle_notice(["kvs_feed", "group", _Group, "entry", EntryId, "delete"] = Route,
+%              Message, #state{owner = Owner} = State) ->
+%    error_logger:info_msg("feed(~p): remove entry: Owner=~p, Route=~p, Message=~p",
+%          [self(), Owner, Route, Message]),
     %% all group subscribers shold delete entry from their feeds
     %% all group subscribers shold delete entry from their feeds
-    kvs_feed:remove_entry(Feed, EntryId),
-    self() ! {feed_refresh,Feed, ?CACHED_ENTRIES},
-    {noreply, State};
-
-handle_notice(["kvs_feed", _Type, EntryOwner, "entry", EntryId, "delete"] = Route,
-              Message, #state{owner = Owner, feed=Feed, direct=Direct} = State) ->
-    case {EntryOwner, Message} of
-        %% owner of the antry has deleted entry, we will delete it too
-        {_, [EntryOwner|_]} ->
-            error_logger:info_msg("feed(~p): remove entry: Owner=~p, Route=~p, Message=~p", [self(), Owner, Route, Message]),
-            kvs_feed:remove_entry(Feed, EntryId),
-            kvs_feed:remove_entry(Direct, EntryId);
+%    kvs_feed:remove_entry(Feed, EntryId),
+%    self() ! {feed_refresh,Feed, ?CACHED_ENTRIES},
+%    {noreply, State};
+
+%handle_notice(["kvs_feed", _Type, EntryOwner, "entry", EntryId, "delete"] = Route,
+%              Message, #state{owner = Owner} = State) ->
+%    case {EntryOwner, Message} of
+%        %% owner of the antry has deleted entry, we will delete it too
+%        {_, [EntryOwner|_]} ->
+%            error_logger:info_msg("feed(~p): remove entry: Owner=~p, Route=~p, Message=~p", [self(), Owner, Route, Message]),
+%            kvs_feed:remove_entry(Feed, EntryId),
+%            kvs_feed:remove_entry(Direct, EntryId);
         %% we are owner of the entry - delete it
         %% we are owner of the entry - delete it
-        {Owner, _} ->
-            error_logger:info_msg("feed(~p): remove entry: Owner=~p, Route=~p, Message=~p", [self(), Owner, Route, Message]),
-            kvs_feed:remove_entry(Feed, EntryId),
-            kvs_feed:remove_entry(Direct, EntryId);
+%        {Owner, _} ->
+%            error_logger:info_msg("feed(~p): remove entry: Owner=~p, Route=~p, Message=~p", [self(), Owner, Route, Message]),
+%            kvs_feed:remove_entry(Feed, EntryId),
+%            kvs_feed:remove_entry(Direct, EntryId);
         %% one of the friends has deleted some entry from his feed. Ignore
         %% one of the friends has deleted some entry from his feed. Ignore
-        _ -> ok end,
-    self() ! {feed_refresh, State#state.feed, ?CACHED_ENTRIES},
-    {noreply, State};
+%        _ -> ok end,
+%    self() ! {feed_refresh, State#state.feed, ?CACHED_ENTRIES},
+%    {noreply, State};
 
 
 handle_notice(["kvs_feed", "user", UId, "count_entry_in_statistics"] = Route, 
 handle_notice(["kvs_feed", "user", UId, "count_entry_in_statistics"] = Route, 
     Message, #state{owner = Owner, type =Type} = State) ->
     Message, #state{owner = Owner, type =Type} = State) ->
@@ -301,4 +286,6 @@ handle_notice(["kvs_feed","likes", _, _, "add_like"] = Route,  % _, _ is here be
     kvs_feed:add_like(FId, EId, UId),
     kvs_feed:add_like(FId, EId, UId),
     {noreply, State};
     {noreply, State};
 
 
-handle_notice(Route, _Message, State) -> error_logger:error_msg("Unknown FEED notice ~p", [Route]), {noreply, State}.
+handle_notice(_Route, _Message, State) -> 
+  %error_logger:error_msg("~p ===> Unknown FEED notice ~p", [State#state.owner, Route]), 
+  {noreply, State}.

+ 6 - 19
src/kvs_group.erl

@@ -17,26 +17,20 @@ retrieve_groups(User) ->
                                    _ -> undefined end end || {UC, GId} <- UC_GId],
                                    _ -> undefined end end || {UC, GId} <- UC_GId],
                [X||X<-Result,X/=undefined] end.
                [X||X<-Result,X/=undefined] end.
 
 
-create(Creator, Id, Name, Desc, Publicity) ->
-    Feed = kvs_feed:create(),
-    Time = erlang:now(),
-    Group = #group{id = Id, name = Name, description = Desc, scope = Publicity,
-                   creator = Creator, created = Time, owner = Creator, feed = Feed, products=kvs_feed:create()},
-    error_logger:info_msg("PUT ~p", [Group]),
-    kvs:put(Group),
-%    init_mq(Group),
-%    mqs:notify([group, init], {GroupName, Feed}),
-    add(Creator, Id, member),
+register(#group{} = Register) ->
+  Group = Register#group{id = kvs:uuid(), created = erlang:now(), feeds=[{Feed, kvs_feed:create()} || Feed <- Register#group.feeds]},
+  kvs:put(Group),
+  error_logger:info_msg("PUT ~p", [Group]),
+  add(Group#group.creator, Group#group.id, member),
   {ok, Group}.
   {ok, Group}.
 
 
-
 delete(GroupName) ->
 delete(GroupName) ->
     case kvs:get(group,GroupName) of 
     case kvs:get(group,GroupName) of 
         {error,_} -> ok;
         {error,_} -> ok;
         {ok, Group} ->
         {ok, Group} ->
 %            mqs:notify([feed, delete, GroupName], empty),
 %            mqs:notify([feed, delete, GroupName], empty),
             kvs:delete_by_index(group_subscription, <<"where_bin">>, GroupName),
             kvs:delete_by_index(group_subscription, <<"where_bin">>, GroupName),
-            kvs:delete(feed, Group#group.feed),
+            [kvs:delete(Feed, Fid) || {Feed, Fid} <- Group#group.feeds],
             kvs:delete(group, GroupName),
             kvs:delete(group, GroupName),
             case mqs:open([]) of
             case mqs:open([]) of
                 {ok, Channel} ->
                 {ok, Channel} ->
@@ -119,13 +113,6 @@ user_has_access(UserName, GroupName) ->
                 {private, member} -> true;
                 {private, member} -> true;
                 _ -> false end end.
                 _ -> false end end.
 
 
-handle_notice([kvs_group, create] = Route,
-    Message, #state{owner = Owner, type =Type} = State) ->
-    ?INFO("queue_action(~p): create_group: Owner=~p, Route=~p, Message=~p", [self(), {Type, Owner}, Route, Message]),
-    {Creator, GroupName, FullName, Desc, Publicity} = Message,
-    create(Creator, GroupName, FullName, Desc, Publicity),
-    {noreply, State};
-
 handle_notice(["kvs_group", "update", GroupName] = Route, 
 handle_notice(["kvs_group", "update", GroupName] = Route, 
     Message, #state{owner=ThisGroupOwner, type=Type} = State) ->
     Message, #state{owner=ThisGroupOwner, type=Type} = State) ->
     ?INFO("queue_action(~p): update_group: Owner=~p, Route=~p, Message=~p", [self(), {Type, ThisGroupOwner}, Route, Message]),    
     ?INFO("queue_action(~p): update_group: Owner=~p, Route=~p, Message=~p", [self(), {Type, ThisGroupOwner}, Route, Message]),    

+ 8 - 20
src/kvs_products.erl

@@ -10,23 +10,11 @@
 -include_lib("mqs/include/mqs.hrl").
 -include_lib("mqs/include/mqs.hrl").
 -compile(export_all).
 -compile(export_all).
 
 
-register(#product{} = Registration) ->
-    Id = kvs:next_id("product", 1),
-    Product = Registration#product{id = Id,
-      name = "product"++integer_to_list(Id),
-      feed = kvs_feed:create(),
-      blog = kvs_feed:create(),
-      features = kvs_feed:create(),
-      specs = kvs_feed:create(),
-      gallery = kvs_feed:create(),
-      videos = kvs_feed:create(),
-      bundles = kvs_feed:create(),
-      creation_date = erlang:now()
-    },
-    error_logger:info_msg("PUT PRODUCT ~p", [Product]),
-    kvs:put(Product),
-%    init_mq(Product),
-    {ok, Product}.
+register(#product{feeds=Ch} = Registration) ->
+  P = Registration#product{id = kvs:uuid(), feeds= [{Feed, kvs_feed:create()} || Feed <- Ch], creation_date = erlang:now()},
+  kvs:put(P),
+  error_logger:info_msg("PUT PRODUCT: ~p feeds:~p", [P#product.id, P#product.feeds]),
+  {ok, P}.
 
 
 delete(Name) ->
 delete(Name) ->
     case kvs:get(product, Name) of
     case kvs:get(product, Name) of
@@ -51,7 +39,7 @@ unsubscribe(Who, Whom) ->
         false -> skip end.
         false -> skip end.
 
 
 subscriptions(undefined)-> [];
 subscriptions(undefined)-> [];
-subscriptions(#product{name = UId}) -> subscriptions(UId);
+subscriptions(#product{id = UId}) -> subscriptions(UId);
 
 
 subscriptions(UId) -> DBA=?DBA, DBA:subscriptions(UId).
 subscriptions(UId) -> DBA=?DBA, DBA:subscriptions(UId).
 subscribed(Who) -> DBA=?DBA, DBA:subscribed(Who).
 subscribed(Who) -> DBA=?DBA, DBA:subscribed(Who).
@@ -72,14 +60,14 @@ subscription_mq(Type, Action, Who, Whom) ->
 
 
 init_mq(Product=#product{}) ->
 init_mq(Product=#product{}) ->
     Groups = kvs_group:participate(Product),
     Groups = kvs_group:participate(Product),
-    ProductExchange = ?USER_EXCHANGE(Product#product.name),
+    ProductExchange = ?USER_EXCHANGE(Product#product.id),
     ExchangeOptions = [{type, <<"fanout">>}, durable, {auto_delete, false}],
     ExchangeOptions = [{type, <<"fanout">>}, durable, {auto_delete, false}],
     case mqs:open([]) of
     case mqs:open([]) of
         {ok, Channel} ->
         {ok, Channel} ->
             ?INFO("Cration Exchange: ~p,",[{Channel,ProductExchange,ExchangeOptions}]),
             ?INFO("Cration Exchange: ~p,",[{Channel,ProductExchange,ExchangeOptions}]),
             mqs_channel:create_exchange(Channel, ProductExchange, ExchangeOptions),
             mqs_channel:create_exchange(Channel, ProductExchange, ExchangeOptions),
             Relations = build_user_relations(Product, Groups),
             Relations = build_user_relations(Product, Groups),
-            [ mqs_channel:bind_exchange(Channel, ?USER_EXCHANGE(Product#product.name), ?NOTIFICATIONS_EX, Route) || Route <- Relations],
+            [ mqs_channel:bind_exchange(Channel, ?USER_EXCHANGE(Product#product.id), ?NOTIFICATIONS_EX, Route) || Route <- Relations],
             mqs_channel:close(Channel);
             mqs_channel:close(Channel);
         {error,Reason} -> ?ERROR("init_mq error: ~p",[Reason]) end.
         {error,Reason} -> ?ERROR("init_mq error: ~p",[Reason]) end.
 
 

+ 3 - 3
src/kvs_purchase.erl

@@ -14,8 +14,8 @@ solvent(UId, ProductId) ->
     Credit >= Price.
     Credit >= Price.
 
 
 buy(UId, ProductId) ->
 buy(UId, ProductId) ->
-    {ok, #product{price = Price, name = Name}} = kvs:get(product, ProductId),
-    kvs_accounts:transaction(UId, currency, -Price, "Buy " ++ Name ++ " for "++ integer_to_list(Price)),
+    {ok, #product{price = Price}} = kvs:get(product, ProductId),
+    kvs_accounts:transaction(UId, currency, -Price, "Buy " ++ ProductId ++ " for "++ integer_to_list(Price)),
     kvs:put(#user_product{username=UId, timestamp=now(), product_id = ProductId}).
     kvs:put(#user_product{username=UId, timestamp=now(), product_id = ProductId}).
 
 
 give(UId, ProductId) ->
 give(UId, ProductId) ->
@@ -37,4 +37,4 @@ handle_notice(["kvs_purchase", "user", UId, "give"] = Route,
     give(UId, GId),
     give(UId, GId),
     {noreply, State};
     {noreply, State};
 
 
-handle_notice(Route, Message, State) -> error_logger:info_msg("Unknown PURCHASE notice").
+handle_notice(_,_,_) -> error_logger:info_msg("Unknown PURCHASE notice").

+ 10 - 39
src/kvs_user.erl

@@ -9,46 +9,17 @@
 -include_lib("mqs/include/mqs.hrl").
 -include_lib("mqs/include/mqs.hrl").
 -compile(export_all).
 -compile(export_all).
 
 
-register(#user{username=UserName, email=Email} = Registration) ->
-    EmailUser = case check_username(UserName) of
-        {error, Reason} -> {error, Reason};
-        {ok, Name} -> case kvs_user:get({email, Email}) of
-            {error, _} -> {ok, Name};
-            {ok, _} -> {error, email_taken} end end,
-
-    GroupUser = case EmailUser of
-        {error, Reason2} -> {error, Reason2};
-        {ok, Name2} -> case kvs:get(group, Name2) of
-            {error, _} -> {ok, Name2};
-            {ok,_} -> {error, username_taken} end end,
-
-    case GroupUser of
-        {ok, Name3} -> process_register(Registration#user{username=Name3});
-        Error -> Error end.
-
-process_register(#user{email=E} = RegisterData0) ->
-    HashedPassword = case RegisterData0#user.password of
-        undefined -> undefined;
-        PlainPassword -> kvs:sha(PlainPassword) end,
-    RegisterData = RegisterData0#user {
-        feed     = kvs_feed:create(),
-        direct   = kvs_feed:create(),
-        pinned   = kvs_feed:create(),
-        starred  = kvs_feed:create(),
-        password = HashedPassword },
-    error_logger:info_msg("PUT USER ~p", [E]),
+register(#user{email=Email, feeds=Ch} = Registration) ->
+  case kvs_user:get({email, Email}) of {ok, _} -> {error, email_taken};
+  {error, _} ->
+    HashedPassword = case Registration#user.password of undefined -> undefined; PlainPassword -> kvs:sha(PlainPassword) end,
+    RegisterData = Registration#user{name=kvs:uuname(), feeds=[{Feed, kvs_feed:create()} || Feed <- Ch], password = HashedPassword},
     kvs:put(RegisterData),
     kvs:put(RegisterData),
-%    kvs_account:create_account(E),
-%    {ok, DefaultQuota} = kvs:get(config, "accounts/default_quota",  300),
-%    kvs_account:transaction(E, quota, DefaultQuota, #tx_default_assignment{}),
-%    init_mq(RegisterData),
-%    mqs:notify([user, init], {E, RegisterData#user.feed}),
-    {ok, RegisterData}.
-
-check_username(Name) ->
-    case kvs_user:get(Name) of
-        {error, _} -> {ok, Name};
-        {ok, User} -> check_username(Name ++ integer_to_list(crypto:rand_uniform(0,10))) end.
+    error_logger:info_msg("PUT USER: ~p", [RegisterData]),
+    kvs_account:create_account(Email),
+    {ok, DefaultQuota} = kvs:get(config, "accounts/default_quota",  300),
+    kvs_account:transaction(Email, quota, DefaultQuota, #tx_default_assignment{}),
+    {ok, RegisterData} end.
 
 
 delete(UserName) ->
 delete(UserName) ->
     case kvs_user:get(UserName) of
     case kvs_user:get(UserName) of

+ 2 - 2
src/store_mnesia.erl

@@ -69,10 +69,10 @@ initialize() ->
     ?CREATE_TAB(group),
     ?CREATE_TAB(group),
     ?CREATE_TAB(id_seq),
     ?CREATE_TAB(id_seq),
     ?CREATE_TAB(transaction),
     ?CREATE_TAB(transaction),
-    ?CREATE_TAB(translation),
+%    ?CREATE_TAB(translation),
     ?CREATE_TAB(product),
     ?CREATE_TAB(product),
     ?CREATE_TAB(product_category),
     ?CREATE_TAB(product_category),
-    mnesia:wait_for_tables([comment,subscription,group,group_subscription,user,entry],5000),
+    mnesia:wait_for_tables([comment,subscription,group,group_subscription,user,entry,product],5000),
     add_indexes(),
     add_indexes(),
     ok.
     ok.