⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_pubsub.erl

📁 ejabberd-0.7.5 分布式Jabber服务器
💻 ERL
📖 第 1 页 / 共 2 页
字号:
	    Error;	{atomic, {result, Res}} ->	    broadcast_retract_item(Host, Node, ItemID),	    {result, Res};	_ ->	    {error, ?ERR_INTERNAL_SERVER_ERROR}    end.subscribe_node(Host, From, JID, Node) ->    Sender = jlib:jid_tolower(jlib:jid_remove_resource(From)),    SubscriberJID =	case jlib:string_to_jid(JID) of	    error ->		{"", "", ""};	    J ->		J	end,    Subscriber = jlib:jid_tolower(SubscriberJID),    F = fun() ->		case mnesia:read({pubsub_node, Node}) of		    [#pubsub_node{info = Info} = N] ->			Affiliation = get_affiliation(Info, Subscriber),			if			    Affiliation /= outcast ->				NewInfo =				    add_subscriber(Info, Subscriber),				mnesia:write(				  N#pubsub_node{info = NewInfo}),				{result, []};			    true ->				{error, ?ERR_NOT_ALLOWED}			end;		    [] ->			{error, ?ERR_ITEM_NOT_FOUND}		end	end,    if	Sender == Subscriber ->	    case mnesia:transaction(F) of		{atomic, {error, _} = Error} ->		    Error;		{atomic, {result, Res}} ->		    {result, Res};		_ ->		    {error, ?ERR_INTERNAL_SERVER_ERROR}	    end;	true ->	    {error, ?ERR_NOT_ALLOWED}    end.unsubscribe_node(Host, From, JID, Node) ->    Sender = jlib:jid_tolower(jlib:jid_remove_resource(From)),    SubscriberJID =	case jlib:string_to_jid(JID) of	    error ->		{"", "", ""};	    J ->		J	end,    Subscriber = jlib:jid_tolower(SubscriberJID),    F = fun() ->		case mnesia:read({pubsub_node, Node}) of		    [#pubsub_node{info = Info} = N] ->			Subscription = get_subscription(Info, Subscriber),			if			    Subscription /= none ->				NewInfo =				    remove_subscriber(Info, Subscriber),				mnesia:write(				  N#pubsub_node{info = NewInfo}),				{result, []};			    true ->				{error, ?ERR_NOT_ALLOWED}			end;		    [] ->			{error, ?ERR_ITEM_NOT_FOUND}		end	end,    if	Sender == Subscriber ->	    case mnesia:transaction(F) of		{atomic, {error, _} = Error} ->		    Error;		{atomic, {result, Res}} ->		    {result, Res};		_ ->		    {error, ?ERR_INTERNAL_SERVER_ERROR}	    end;	true ->	    {error, ?ERR_NOT_ALLOWED}    end.get_items(Host, JID, Node, SMaxItems) ->    MaxItems =	if	    SMaxItems == "" ->		?MAXITEMS;	    true ->		case catch list_to_integer(SMaxItems) of		    {'EXIT', _} ->			{error, ?ERR_BAD_REQUEST};		    Val ->			Val		end	end,    case MaxItems of	{error, _} = Error ->	    Error;	_ ->	    case catch mnesia:dirty_read(pubsub_node, Node) of		[#pubsub_node{info = Info}] ->		    Items = lists:sublist(Info#nodeinfo.items, MaxItems),		    ItemsEls =			lists:map(			  fun(#item{id = ItemID,				    payload = Payload}) ->				  ItemAttrs = case ItemID of						  "" -> [];						  _ -> [{"id", ItemID}]					      end,				  {xmlelement, "item", ItemAttrs, Payload}			  end, Items),		    {result, [{xmlelement, "pubsub",			       [{"xmlns", ?NS_PUBSUB_EVENT}],			       [{xmlelement, "items",				 [{"node", node_to_string(Node)}],				 ItemsEls}]}]};		_ ->		    {error, ?ERR_ITEM_NOT_FOUND}	    end    end.delete_node(Host, JID, Node) ->    Owner = jlib:jid_tolower(jlib:jid_remove_resource(JID)),    F = fun() ->		case mnesia:read({pubsub_node, Node}) of		    [#pubsub_node{info = Info}] ->			case get_affiliation(Info, Owner) of			    owner ->				% TODO: don't iterate over all table				Removed =				    mnesia:foldl(				      fun(#pubsub_node{node = N,						       info = #nodeinfo{							 entities = Entities							}}, Acc) ->					      case lists:prefix(Node, N) of						  true ->						      [{N, Entities} | Acc];						  _ ->						      Acc					      end				      end, [], pubsub_node),				lists:foreach(				  fun({N, _}) ->					  mnesia:delete({pubsub_node, N})				  end, Removed),				{removed, Removed};			    _ ->				{error, ?ERR_NOT_ALLOWED}			end;		    [] ->			{error, ?ERR_ITEM_NOT_FOUND}		end	end,    case mnesia:transaction(F) of	{atomic, {error, _} = Error} ->	    Error;	{atomic, {removed, Removed}} ->	    broadcast_removed_node(Host, Removed),	    Lang = "",	    broadcast_retract_item(	      Host, ["pubsub", "nodes"], node_to_string(Node)),	    {result, []};	_ ->	    {error, ?ERR_INTERNAL_SERVER_ERROR}    end.purge_node(Host, JID, Node) ->    Owner = jlib:jid_tolower(jlib:jid_remove_resource(JID)),    F = fun() ->		case mnesia:read({pubsub_node, Node}) of		    [#pubsub_node{info = Info} = N] ->			case get_affiliation(Info, Owner) of			    owner ->				NewInfo = Info#nodeinfo{items = []},				mnesia:write(				  N#pubsub_node{info = NewInfo}),				{result, Info#nodeinfo.items, []};			    _ ->				{error, ?ERR_NOT_ALLOWED}			end;		    [] ->			{error, ?ERR_ITEM_NOT_FOUND}		end	end,    case mnesia:transaction(F) of	{atomic, {error, _} = Error} ->	    Error;	{atomic, {result, Items, Res}} ->	    lists:foreach(	      fun(#item{id = ItemID}) ->		      broadcast_retract_item(Host, Node, ItemID)	      end, Items),	    {result, Res};	_ ->	    {error, ?ERR_INTERNAL_SERVER_ERROR}    end.get_entities(OJID, Node) ->    Owner = jlib:jid_tolower(jlib:jid_remove_resource(OJID)),    case catch mnesia:dirty_read(pubsub_node, Node) of	[#pubsub_node{info = Info}] ->	    case get_affiliation(Info, Owner) of		owner ->		    Entities = Info#nodeinfo.entities,		    EntitiesEls =			?DICT:fold(			  fun(JID,			      #entity{affiliation = Affiliation,				      subscription = Subscription},			      Acc) ->				  [{xmlelement, "entity",				    [{"jid", jlib:jid_to_string(JID)},				     {"affiliation",				      affiliation_to_string(Affiliation)},				     {"subscription",				      subscription_to_string(Subscription)}],				    []} | Acc]			  end, [], Entities),		    {result, [{xmlelement, "pubsub",			       [{"xmlns", ?NS_PUBSUB_EVENT}],			       [{xmlelement, "entities",				 [{"node", node_to_string(Node)}],				 EntitiesEls}]}]};		_ ->		    {error, ?ERR_NOT_ALLOWED}	    end;	_ ->	    {error, ?ERR_ITEM_NOT_FOUND}    end.set_entities(OJID, Node, EntitiesEls) ->    Owner = jlib:jid_tolower(jlib:jid_remove_resource(OJID)),    Entities =	lists:foldl(	  fun(El, Acc) ->		  case Acc of		      error ->			  error;		      _ ->			  case El of			      {xmlelement, "entity", Attrs, _} ->				  JID = jlib:string_to_jid(					  xml:get_attr_s("jid", Attrs)),				  Affiliation =				      case xml:get_attr_s("affiliation",							  Attrs) of					  "owner" -> owner;					  "publisher" -> publisher;					  "outcast" -> outcast;					  "none" -> none;					  _ -> false				      end,				  Subscription =				      case xml:get_attr_s("subscription",							  Attrs) of					  "subscribed" -> subscribed;					  "pending" -> pending;					  "unconfigured" -> unconfigured;					  "none" -> none;					  _ -> false				      end,				  if				      (JID == error) or				      (Affiliation == false) or				      (Subscription == false) ->					  error;				      true ->					  [{jlib:jid_tolower(JID),					    #entity{					      affiliation = Affiliation,					      subscription = Subscription}} |					   Acc]				  end			  end		  end	  end, [], EntitiesEls),    case Entities of	error ->	    {error, ?ERR_BAD_REQUEST};	_ ->	    F = fun() ->			case mnesia:read({pubsub_node, Node}) of			    [#pubsub_node{info = Info} = N] ->				case get_affiliation(Info, Owner) of				    owner ->					NewInfo =					    set_info_entities(Info, Entities),					mnesia:write(					  N#pubsub_node{info = NewInfo}),					{result, []};				    _ ->					{error, ?ERR_NOT_ALLOWED}				end;			    [] ->				{error, ?ERR_ITEM_NOT_FOUND}			end		end,	    case mnesia:transaction(F) of		{atomic, {error, _} = Error} ->		    Error;		{atomic, {result, _}} ->		    {result, []};		_ ->		    {error, ?ERR_INTERNAL_SERVER_ERROR}	    end    end.%get_node_config(OJID, Node) ->%    Owner = jlib:jid_tolower(jlib:jid_remove_resource(OJID)),%    case catch mnesia:dirty_read(pubsub_node, Node) of%	[#pubsub_node{info = Info}] ->%	    case get_affiliation(Info, Owner) of%		owner ->%		    Entities = Info#nodeinfo.entities,%		    EntitiesEls =%			?DICT:fold(%			  fun(JID,%			      #entity{affiliation = Affiliation,%				      subscription = Subscription},%			      Acc) ->%				  [{xmlelement, "entity",%				    [{"jid", jlib:jid_to_string(JID)},%				     {"affiliation",%				      affiliation_to_string(Affiliation)},%				     {"subscription",%				      subscription_to_string(Subscription)}],%				    []} | Acc]%			  end, [], Entities),%		    {result, [{xmlelement, "pubsub",%			       [{"xmlns", ?NS_PUBSUB_EVENT}],%			       [{xmlelement, "entities",%				 [{"node", node_to_string(Node)}],%				 EntitiesEls}]}]};%		_ ->%		    {error, ?ERR_NOT_ALLOWED}%	    end;%	_ ->%	    {error, ?ERR_ITEM_NOT_FOUND}%    end.get_affiliation(#nodeinfo{entities = Entities}, JID) ->    LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),    case ?DICT:find(LJID, Entities) of	{ok, #entity{affiliation = Affiliation}} ->	    Affiliation;	_ ->	    none    end.get_subscription(#nodeinfo{entities = Entities}, JID) ->    LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),    case ?DICT:find(LJID, Entities) of	{ok, #entity{subscription = Subscription}} ->	    Subscription;	_ ->	    none    end.affiliation_to_string(Affiliation) ->    case Affiliation of	owner -> "owner";	publisher -> "publisher";	outcast -> "outcast";	_ -> "none"    end.subscription_to_string(Subscription) ->    case Subscription of	subscribed -> "subscribed";	pending -> "pending";	unconfigured -> "unconfigured";	_ -> "none"    end.check_create_permission(Host, Node, Owner) ->    if	Owner#jid.lserver == Host ->	    true;	true ->	    #jid{luser = User, lserver = Server} = Owner,	    case Node of		["home", Server, User | _] ->		    true;		_ ->		    false	    end    end.insert_item(Info, ItemID, Publisher, Payload) ->    Items = Info#nodeinfo.items,    Items1 = lists:filter(fun(I) ->				  I#item.id /= ItemID			  end, Items),    Items2 = [#item{id = ItemID, publisher = Publisher, payload = Payload} |	      Items1],    Items3 = lists:sublist(Items2, ?MAXITEMS),    Info#nodeinfo{items = Items3}.remove_item(Info, ItemID) ->    Items = Info#nodeinfo.items,    Items1 = lists:filter(fun(I) ->				  I#item.id /= ItemID			  end, Items),    Info#nodeinfo{items = Items1}.check_item_publisher(Info, ItemID, Publisher) ->    Items = Info#nodeinfo.items,    case lists:keysearch(ItemID, #item.id, Items) of	{value, #item{publisher = Publisher}} ->	    true;	_ ->	    false    end.add_subscriber(Info, Subscriber) ->    Entities = Info#nodeinfo.entities,    case ?DICT:find(Subscriber, Entities) of	{ok, Entity} ->	    Info#nodeinfo{	      entities = ?DICT:store(Subscriber,				     Entity#entity{subscription = subscribed},				     Entities)};	_ ->	    Info#nodeinfo{	      entities = ?DICT:store(Subscriber,				     #entity{subscription = subscribed},				     Entities)}    end.remove_subscriber(Info, Subscriber) ->    Entities = Info#nodeinfo.entities,    case ?DICT:find(Subscriber, Entities) of	{ok, #entity{affiliation = none}} ->	    Info#nodeinfo{	      entities = ?DICT:erase(Subscriber, Entities)};	{ok, Entity} ->	    Info#nodeinfo{	      entities = ?DICT:store(Subscriber,				     Entity#entity{subscription = none},				     Entities)};	_ ->	    Info    end.set_info_entities(Info, Entities) ->    NewEntities =	lists:foldl(	  fun({JID, Ent}, Es) ->		  case Ent of		      #entity{affiliation = none, subscription = none} ->			  ?DICT:erase(JID, Es);		      _ ->			  ?DICT:store(JID, Ent, Es)		  end	  end, Info#nodeinfo.entities, Entities),    Info#nodeinfo{entities = NewEntities}.				broadcast_publish_item(Host, Node, ItemID, Payload) ->    case catch mnesia:dirty_read(pubsub_node, Node) of	[#pubsub_node{info = Info}] ->	    ?DICT:fold(	       fun(JID, #entity{subscription = Subscription}, _) ->		       if 			   (Subscription /= none) and			   (Subscription /= pending) ->			       ItemAttrs = case ItemID of					       "" -> [];					       _ -> [{"id", ItemID}]					   end,			       Stanza =				   {xmlelement, "message", [],				    [{xmlelement, "x",				      [{"xmlns", ?NS_PUBSUB_EVENT}],				      [{xmlelement, "items",					[{"node", node_to_string(Node)}],					[{xmlelement, "item",					  ItemAttrs,					  Payload}]}]}]},			       ejabberd_router:route(				 ?MYJID, jlib:make_jid(JID), Stanza);			   true ->			       ok		       end	       end, ok, Info#nodeinfo.entities);	_ ->	    false    end.broadcast_retract_item(Host, Node, ItemID) ->    case catch mnesia:dirty_read(pubsub_node, Node) of	[#pubsub_node{info = Info}] ->	    ?DICT:fold(	       fun(JID, #entity{subscription = Subscription}, _) ->		       if 			   (Subscription /= none) and			   (Subscription /= pending) ->			       ItemAttrs = case ItemID of					       "" -> [];					       _ -> [{"id", ItemID}]					   end,			       Stanza =				   {xmlelement, "message", [],				    [{xmlelement, "x",				      [{"xmlns", ?NS_PUBSUB_EVENT}],				      [{xmlelement, "items",					[{"node", node_to_string(Node)}],					[{xmlelement, "retract",					 ItemAttrs, []}]}]}]},			       ejabberd_router:route(				 ?MYJID, jlib:make_jid(JID), Stanza);			   true ->			       ok		       end	       end, ok, Info#nodeinfo.entities);	_ ->	    false    end.broadcast_removed_node(Host, Removed) ->    lists:foreach(      fun({Node, Entities}) ->	      ?DICT:fold(		 fun(JID, #entity{subscription = Subscription}, _) ->			 if 			     (Subscription /= none) and			     (Subscription /= pending) ->				 Stanza =				     {xmlelement, "message", [],				      [{xmlelement, "x",					[{"xmlns", ?NS_PUBSUB_EVENT}],					[{xmlelement, "delete",					  [{"node", node_to_string(Node)}],					    []}]}]},				 ejabberd_router:route(				   ?MYJID, jlib:make_jid(JID), Stanza);			     true ->				 ok			 end		 end, ok, Entities)      end, Removed).system_continue(Parent, _, State) ->    loop(State, Parent).system_terminate(Reason, Parent, _, State) ->    exit(Reason).system_code_change(State, _Mod, Ver, _Extra) ->    {ok, State}.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -