mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-20 16:15:59 +01:00
Switch to stand-alone XMPP library
This commit is contained in:
parent
d00a634025
commit
9aff7e52a8
10
Makefile.in
10
Makefile.in
@ -108,14 +108,6 @@ edoc:
|
|||||||
$(ERL) -noinput +B -eval \
|
$(ERL) -noinput +B -eval \
|
||||||
'case edoc:application(ejabberd, ".", []) of ok -> halt(0); error -> halt(1) end.'
|
'case edoc:application(ejabberd, ".", []) of ok -> halt(0); error -> halt(1) end.'
|
||||||
|
|
||||||
spec:
|
|
||||||
$(ERL) -noinput +B -pa ebin -pa deps/*/ebin -eval \
|
|
||||||
'case fxml_gen:compile("specs/xmpp_codec.spec", [{add_type_specs, xmpp_element}, {erl_dir, "src"}, {hrl_dir, "include"}]) of ok -> halt(0); _ -> halt(1) end.'
|
|
||||||
|
|
||||||
xdata:
|
|
||||||
$(ERL) -noinput +B -pa ebin -pa deps/*/ebin -eval \
|
|
||||||
'case xdata_codec:compile("specs", [{erl_dir, "src"}, {hrl_dir, "include"}]) of ok -> halt(0); _ -> halt(1) end.'
|
|
||||||
|
|
||||||
JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wordlist 2,1000,$(1))),$(1))
|
JOIN_PATHS=$(if $(wordlist 2,1000,$(1)),$(firstword $(1))/$(call JOIN_PATHS,$(wordlist 2,1000,$(1))),$(1))
|
||||||
|
|
||||||
VERSIONED_DEP=$(if $(DEP_$(1)_VERSION),$(DEP_$(1)_VERSION),$(1))
|
VERSIONED_DEP=$(if $(DEP_$(1)_VERSION),$(DEP_$(1)_VERSION),$(1))
|
||||||
@ -347,5 +339,5 @@ quicktest:
|
|||||||
$(REBAR) skip_deps=true ct suites=elixir
|
$(REBAR) skip_deps=true ct suites=elixir
|
||||||
|
|
||||||
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean rel \
|
.PHONY: src edoc dialyzer Makefile TAGS clean clean-rel distclean rel \
|
||||||
install uninstall uninstall-binary uninstall-all translations deps test spec \
|
install uninstall uninstall-binary uninstall-all translations deps test \
|
||||||
quicktest erlang_plt deps_plt ejabberd_plt
|
quicktest erlang_plt deps_plt ejabberd_plt
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: flex_offline.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/offline
|
|
||||||
%% Document: XEP-0013
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'number_of_messages', non_neg_integer()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type form() :: [property() | xdata_field()].
|
|
@ -1,17 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%% @copyright (C) 2016, Evgeny Khramtsov
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 10 Jul 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-record(jid, {user = <<"">> :: binary(),
|
|
||||||
server = <<"">> :: binary(),
|
|
||||||
resource = <<"">> :: binary(),
|
|
||||||
luser = <<"">> :: binary(),
|
|
||||||
lserver = <<"">> :: binary(),
|
|
||||||
lresource = <<"">> :: binary()}).
|
|
||||||
|
|
||||||
-type(jid() :: #jid{}).
|
|
||||||
-type(ljid() :: {binary(), binary(), binary()}).
|
|
@ -1,13 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: mam_query.xdata
|
|
||||||
%% Form type: urn:xmpp:mam:1
|
|
||||||
%% Document: XEP-0313
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'with', jid:jid()} |
|
|
||||||
{'start', erlang:timestamp()} |
|
|
||||||
{'end', erlang:timestamp()} |
|
|
||||||
{'withtext', binary()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type form() :: [property() | xdata_field()].
|
|
@ -1,16 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_register.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#register
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'allow', boolean()} |
|
|
||||||
{'email', binary()} |
|
|
||||||
{'faqentry', [binary()]} |
|
|
||||||
{'first', binary()} |
|
|
||||||
{'last', binary()} |
|
|
||||||
{'roomnick', binary()} |
|
|
||||||
{'url', binary()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type form() :: [property() | xdata_field()].
|
|
@ -1,16 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_request.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#request
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'role', participant} |
|
|
||||||
{'jid', jid:jid()} |
|
|
||||||
{'roomnick', binary()} |
|
|
||||||
{'request_allow', boolean()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type options(T) :: [{binary(), T}].
|
|
||||||
-type property_with_options() ::
|
|
||||||
{'role', participant, options(participant)}.
|
|
||||||
-type form() :: [property() | property_with_options() | xdata_field()].
|
|
@ -1,55 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_roomconfig.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#roomconfig
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
-type 'allow_private_messages_from_visitors'() :: nobody | moderators | anyone.
|
|
||||||
-type 'maxusers'() :: none | non_neg_integer().
|
|
||||||
-type 'presencebroadcast'() :: moderator | participant | visitor.
|
|
||||||
-type 'whois'() :: moderators | anyone.
|
|
||||||
|
|
||||||
-type property() :: {'maxhistoryfetch', binary()} |
|
|
||||||
{'allowpm', binary()} |
|
|
||||||
{'allow_private_messages', boolean()} |
|
|
||||||
{'allow_private_messages_from_visitors', 'allow_private_messages_from_visitors'()} |
|
|
||||||
{'allow_visitor_status', boolean()} |
|
|
||||||
{'allow_visitor_nickchange', boolean()} |
|
|
||||||
{'allow_voice_requests', boolean()} |
|
|
||||||
{'allow_subscription', boolean()} |
|
|
||||||
{'voice_request_min_interval', non_neg_integer()} |
|
|
||||||
{'captcha_protected', boolean()} |
|
|
||||||
{'captcha_whitelist', [jid:jid()]} |
|
|
||||||
{'allow_query_users', boolean()} |
|
|
||||||
{'allowinvites', boolean()} |
|
|
||||||
{'changesubject', boolean()} |
|
|
||||||
{'enablelogging', boolean()} |
|
|
||||||
{'getmemberlist', [binary()]} |
|
|
||||||
{'lang', binary()} |
|
|
||||||
{'pubsub', binary()} |
|
|
||||||
{'maxusers', 'maxusers'()} |
|
|
||||||
{'membersonly', boolean()} |
|
|
||||||
{'moderatedroom', boolean()} |
|
|
||||||
{'members_by_default', boolean()} |
|
|
||||||
{'passwordprotectedroom', boolean()} |
|
|
||||||
{'persistentroom', boolean()} |
|
|
||||||
{'presencebroadcast', ['presencebroadcast'()]} |
|
|
||||||
{'publicroom', boolean()} |
|
|
||||||
{'public_list', boolean()} |
|
|
||||||
{'roomadmins', [jid:jid()]} |
|
|
||||||
{'roomdesc', binary()} |
|
|
||||||
{'roomname', binary()} |
|
|
||||||
{'roomowners', [jid:jid()]} |
|
|
||||||
{'roomsecret', binary()} |
|
|
||||||
{'whois', 'whois'()} |
|
|
||||||
{'mam', boolean()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type options(T) :: [{binary(), T}].
|
|
||||||
-type property_with_options() ::
|
|
||||||
{'allowpm', binary(), options(binary())} |
|
|
||||||
{'allow_private_messages_from_visitors', 'allow_private_messages_from_visitors'(), options('allow_private_messages_from_visitors'())} |
|
|
||||||
{'getmemberlist', [binary()], options(binary())} |
|
|
||||||
{'maxusers', 'maxusers'(), options('maxusers'())} |
|
|
||||||
{'presencebroadcast', ['presencebroadcast'()], options('presencebroadcast'())} |
|
|
||||||
{'whois', 'whois'(), options('whois'())}.
|
|
||||||
-type form() :: [property() | property_with_options() | xdata_field()].
|
|
@ -1,18 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_roominfo.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#roominfo
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'maxhistoryfetch', non_neg_integer()} |
|
|
||||||
{'contactjid', [jid:jid()]} |
|
|
||||||
{'description', binary()} |
|
|
||||||
{'lang', binary()} |
|
|
||||||
{'ldapgroup', binary()} |
|
|
||||||
{'logs', binary()} |
|
|
||||||
{'occupants', non_neg_integer()} |
|
|
||||||
{'subject', binary()} |
|
|
||||||
{'subjectmod', boolean()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type form() :: [property() | xdata_field()].
|
|
182
include/ns.hrl
182
include/ns.hrl
@ -1,182 +0,0 @@
|
|||||||
%%%----------------------------------------------------------------------
|
|
||||||
%%%
|
|
||||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
|
||||||
%%%
|
|
||||||
%%% This program is free software; you can redistribute it and/or
|
|
||||||
%%% modify it under the terms of the GNU General Public License as
|
|
||||||
%%% published by the Free Software Foundation; either version 2 of the
|
|
||||||
%%% License, or (at your option) any later version.
|
|
||||||
%%%
|
|
||||||
%%% This program is distributed in the hope that it will be useful,
|
|
||||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
%%% General Public License for more details.
|
|
||||||
%%%
|
|
||||||
%%% You should have received a copy of the GNU General Public License along
|
|
||||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
%%%
|
|
||||||
%%%----------------------------------------------------------------------
|
|
||||||
|
|
||||||
-define(NS_COMPONENT, <<"jabber:component:accept">>).
|
|
||||||
-define(NS_SERVER, <<"jabber:server">>).
|
|
||||||
-define(NS_SERVER_DIALBACK, <<"jabber:server:dialback">>).
|
|
||||||
-define(NS_CLIENT, <<"jabber:client">>).
|
|
||||||
-define(NS_DISCO_ITEMS,
|
|
||||||
<<"http://jabber.org/protocol/disco#items">>).
|
|
||||||
-define(NS_DISCO_INFO,
|
|
||||||
<<"http://jabber.org/protocol/disco#info">>).
|
|
||||||
-define(NS_VCARD, <<"vcard-temp">>).
|
|
||||||
-define(NS_VCARD_UPDATE, <<"vcard-temp:x:update">>).
|
|
||||||
-define(NS_AUTH, <<"jabber:iq:auth">>).
|
|
||||||
-define(NS_AUTH_ERROR, <<"jabber:iq:auth:error">>).
|
|
||||||
-define(NS_REGISTER, <<"jabber:iq:register">>).
|
|
||||||
-define(NS_SEARCH, <<"jabber:iq:search">>).
|
|
||||||
-define(NS_ROSTER, <<"jabber:iq:roster">>).
|
|
||||||
-define(NS_ROSTER_VER,
|
|
||||||
<<"urn:xmpp:features:rosterver">>).
|
|
||||||
-define(NS_PRIVACY, <<"jabber:iq:privacy">>).
|
|
||||||
-define(NS_BLOCKING, <<"urn:xmpp:blocking">>).
|
|
||||||
-define(NS_PRIVATE, <<"jabber:iq:private">>).
|
|
||||||
-define(NS_VERSION, <<"jabber:iq:version">>).
|
|
||||||
-define(NS_TIME, <<"urn:xmpp:time">>).
|
|
||||||
-define(NS_LAST, <<"jabber:iq:last">>).
|
|
||||||
-define(NS_XDATA, <<"jabber:x:data">>).
|
|
||||||
-define(NS_IQDATA, <<"jabber:iq:data">>).
|
|
||||||
-define(NS_DELAY, <<"urn:xmpp:delay">>).
|
|
||||||
-define(NS_HINTS, <<"urn:xmpp:hints">>).
|
|
||||||
-define(NS_EXPIRE, <<"jabber:x:expire">>).
|
|
||||||
-define(NS_EVENT, <<"jabber:x:event">>).
|
|
||||||
-define(NS_CHATSTATES,
|
|
||||||
<<"http://jabber.org/protocol/chatstates">>).
|
|
||||||
-define(NS_XCONFERENCE, <<"jabber:x:conference">>).
|
|
||||||
-define(NS_STATS,
|
|
||||||
<<"http://jabber.org/protocol/stats">>).
|
|
||||||
-define(NS_MUC, <<"http://jabber.org/protocol/muc">>).
|
|
||||||
-define(NS_MUC_USER,
|
|
||||||
<<"http://jabber.org/protocol/muc#user">>).
|
|
||||||
-define(NS_MUC_ADMIN,
|
|
||||||
<<"http://jabber.org/protocol/muc#admin">>).
|
|
||||||
-define(NS_MUC_OWNER,
|
|
||||||
<<"http://jabber.org/protocol/muc#owner">>).
|
|
||||||
-define(NS_MUC_UNIQUE,
|
|
||||||
<<"http://jabber.org/protocol/muc#unique">>).
|
|
||||||
-define(NS_PUBSUB,
|
|
||||||
<<"http://jabber.org/protocol/pubsub">>).
|
|
||||||
-define(NS_PUBSUB_EVENT,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#event">>).
|
|
||||||
-define(NS_PUBSUB_META_DATA,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#meta-data">>).
|
|
||||||
-define(NS_PUBSUB_OWNER,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#owner">>).
|
|
||||||
-define(NS_PUBSUB_NMI,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#node-meta-info">>).
|
|
||||||
-define(NS_PUBSUB_ERRORS,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#errors">>).
|
|
||||||
-define(NS_PUBSUB_NODE_CONFIG,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#node_config">>).
|
|
||||||
-define(NS_PUBSUB_SUB_OPTIONS,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_options">>).
|
|
||||||
-define(NS_PUBSUB_SUBSCRIBE_OPTIONS,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_options">>).
|
|
||||||
-define(NS_PUBSUB_PUBLISH_OPTIONS,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#publish_options">>).
|
|
||||||
-define(NS_PUBSUB_SUB_AUTH,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_authorization">>).
|
|
||||||
-define(NS_PUBSUB_GET_PENDING,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#get-pending">>).
|
|
||||||
-define(NS_COMMANDS,
|
|
||||||
<<"http://jabber.org/protocol/commands">>).
|
|
||||||
-define(NS_BYTESTREAMS,
|
|
||||||
<<"http://jabber.org/protocol/bytestreams">>).
|
|
||||||
-define(NS_ADMIN,
|
|
||||||
<<"http://jabber.org/protocol/admin">>).
|
|
||||||
-define(NS_ADMIN_ANNOUNCE,
|
|
||||||
<<"http://jabber.org/protocol/admin#announce">>).
|
|
||||||
-define(NS_ADMIN_ANNOUNCE_ALL,
|
|
||||||
<<"http://jabber.org/protocol/admin#announce-all">>).
|
|
||||||
-define(NS_ADMIN_SET_MOTD,
|
|
||||||
<<"http://jabber.org/protocol/admin#set-motd">>).
|
|
||||||
-define(NS_ADMIN_EDIT_MOTD,
|
|
||||||
<<"http://jabber.org/protocol/admin#edit-motd">>).
|
|
||||||
-define(NS_ADMIN_DELETE_MOTD,
|
|
||||||
<<"http://jabber.org/protocol/admin#delete-motd">>).
|
|
||||||
-define(NS_ADMIN_ANNOUNCE_ALLHOSTS,
|
|
||||||
<<"http://jabber.org/protocol/admin#announce-allhosts">>).
|
|
||||||
-define(NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS,
|
|
||||||
<<"http://jabber.org/protocol/admin#announce-all-allhosts">>).
|
|
||||||
-define(NS_ADMIN_SET_MOTD_ALLHOSTS,
|
|
||||||
<<"http://jabber.org/protocol/admin#set-motd-allhosts">>).
|
|
||||||
-define(NS_ADMIN_EDIT_MOTD_ALLHOSTS,
|
|
||||||
<<"http://jabber.org/protocol/admin#edit-motd-allhosts">>).
|
|
||||||
-define(NS_ADMIN_DELETE_MOTD_ALLHOSTS,
|
|
||||||
<<"http://jabber.org/protocol/admin#delete-motd-allhosts">>).
|
|
||||||
-define(NS_SERVERINFO,
|
|
||||||
<<"http://jabber.org/network/serverinfo">>).
|
|
||||||
-define(NS_RSM, <<"http://jabber.org/protocol/rsm">>).
|
|
||||||
-define(NS_EJABBERD_CONFIG, <<"ejabberd:config">>).
|
|
||||||
-define(NS_STREAM,
|
|
||||||
<<"http://etherx.jabber.org/streams">>).
|
|
||||||
-define(NS_STANZAS,
|
|
||||||
<<"urn:ietf:params:xml:ns:xmpp-stanzas">>).
|
|
||||||
-define(NS_STREAMS,
|
|
||||||
<<"urn:ietf:params:xml:ns:xmpp-streams">>).
|
|
||||||
-define(NS_TLS, <<"urn:ietf:params:xml:ns:xmpp-tls">>).
|
|
||||||
-define(NS_SASL,
|
|
||||||
<<"urn:ietf:params:xml:ns:xmpp-sasl">>).
|
|
||||||
-define(NS_SESSION,
|
|
||||||
<<"urn:ietf:params:xml:ns:xmpp-session">>).
|
|
||||||
-define(NS_BIND,
|
|
||||||
<<"urn:ietf:params:xml:ns:xmpp-bind">>).
|
|
||||||
-define(NS_FEATURE_IQAUTH,
|
|
||||||
<<"http://jabber.org/features/iq-auth">>).
|
|
||||||
-define(NS_FEATURE_IQREGISTER,
|
|
||||||
<<"http://jabber.org/features/iq-register">>).
|
|
||||||
-define(NS_FEATURE_COMPRESS,
|
|
||||||
<<"http://jabber.org/features/compress">>).
|
|
||||||
-define(NS_FEATURE_MSGOFFLINE, <<"msgoffline">>).
|
|
||||||
-define(NS_FLEX_OFFLINE, <<"http://jabber.org/protocol/offline">>).
|
|
||||||
-define(NS_COMPRESS,
|
|
||||||
<<"http://jabber.org/protocol/compress">>).
|
|
||||||
-define(NS_CAPS, <<"http://jabber.org/protocol/caps">>).
|
|
||||||
-define(NS_SHIM, <<"http://jabber.org/protocol/shim">>).
|
|
||||||
-define(NS_ADDRESS,
|
|
||||||
<<"http://jabber.org/protocol/address">>).
|
|
||||||
-define(NS_OOB, <<"jabber:x:oob">>).
|
|
||||||
-define(NS_CAPTCHA, <<"urn:xmpp:captcha">>).
|
|
||||||
-define(NS_MEDIA, <<"urn:xmpp:media-element">>).
|
|
||||||
-define(NS_BOB, <<"urn:xmpp:bob">>).
|
|
||||||
-define(NS_MAM_TMP, <<"urn:xmpp:mam:tmp">>).
|
|
||||||
-define(NS_MAM_0, <<"urn:xmpp:mam:0">>).
|
|
||||||
-define(NS_MAM_1, <<"urn:xmpp:mam:1">>).
|
|
||||||
-define(NS_SID_0, <<"urn:xmpp:sid:0">>).
|
|
||||||
-define(NS_PING, <<"urn:xmpp:ping">>).
|
|
||||||
-define(NS_CARBONS_2, <<"urn:xmpp:carbons:2">>).
|
|
||||||
-define(NS_CARBONS_1, <<"urn:xmpp:carbons:1">>).
|
|
||||||
-define(NS_FORWARD, <<"urn:xmpp:forward:0">>).
|
|
||||||
-define(NS_CLIENT_STATE, <<"urn:xmpp:csi:0">>).
|
|
||||||
-define(NS_STREAM_MGMT_2, <<"urn:xmpp:sm:2">>).
|
|
||||||
-define(NS_STREAM_MGMT_3, <<"urn:xmpp:sm:3">>).
|
|
||||||
-define(NS_HTTP_UPLOAD, <<"urn:xmpp:http:upload">>).
|
|
||||||
-define(NS_HTTP_UPLOAD_OLD, <<"eu:siacs:conversations:http:upload">>).
|
|
||||||
-define(NS_THUMBS_1, <<"urn:xmpp:thumbs:1">>).
|
|
||||||
-define(NS_NICK, <<"http://jabber.org/protocol/nick">>).
|
|
||||||
-define(NS_SIC_0, <<"urn:xmpp:sic:0">>).
|
|
||||||
-define(NS_SIC_1, <<"urn:xmpp:sic:1">>).
|
|
||||||
-define(NS_MIX_0, <<"urn:xmpp:mix:0">>).
|
|
||||||
-define(NS_MIX_SERVICEINFO_0, <<"urn:xmpp:mix:0#serviceinfo">>).
|
|
||||||
-define(NS_MIX_NODES_MESSAGES, <<"urn:xmpp:mix:nodes:messages">>).
|
|
||||||
-define(NS_MIX_NODES_PRESENCE, <<"urn:xmpp:mix:nodes:presence">>).
|
|
||||||
-define(NS_MIX_NODES_PARTICIPANTS, <<"urn:xmpp:mix:nodes:participants">>).
|
|
||||||
-define(NS_MIX_NODES_SUBJECT, <<"urn:xmpp:mix:nodes:subject">>).
|
|
||||||
-define(NS_MIX_NODES_CONFIG, <<"urn:xmpp:mix:nodes:config">>).
|
|
||||||
-define(NS_PRIVILEGE, <<"urn:xmpp:privilege:1">>).
|
|
||||||
-define(NS_DELEGATION, <<"urn:xmpp:delegation:1">>).
|
|
||||||
-define(NS_MUCSUB, <<"urn:xmpp:mucsub:0">>).
|
|
||||||
-define(NS_MUCSUB_NODES_PRESENCE, <<"urn:xmpp:mucsub:nodes:presence">>).
|
|
||||||
-define(NS_MUCSUB_NODES_MESSAGES, <<"urn:xmpp:mucsub:nodes:messages">>).
|
|
||||||
-define(NS_MUCSUB_NODES_PARTICIPANTS, <<"urn:xmpp:mucsub:nodes:participants">>).
|
|
||||||
-define(NS_MUCSUB_NODES_AFFILIATIONS, <<"urn:xmpp:mucsub:nodes:affiliations">>).
|
|
||||||
-define(NS_MUCSUB_NODES_SUBJECT, <<"urn:xmpp:mucsub:nodes:subject">>).
|
|
||||||
-define(NS_MUCSUB_NODES_CONFIG, <<"urn:xmpp:mucsub:nodes:config">>).
|
|
||||||
-define(NS_MUCSUB_NODES_SYSTEM, <<"urn:xmpp:mucsub:nodes:system">>).
|
|
@ -1,13 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_get_pending.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'node', binary()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type options(T) :: [{binary(), T}].
|
|
||||||
-type property_with_options() ::
|
|
||||||
{'node', binary(), options(binary())}.
|
|
||||||
-type form() :: [property() | property_with_options() | xdata_field()].
|
|
@ -1,60 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_node_config.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#node_config
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-type 'access_model'() :: authorize | open | presence | roster | whitelist.
|
|
||||||
-type 'children_association_policy'() :: all | owners | whitelist.
|
|
||||||
-type 'itemreply'() :: owner | publisher | none.
|
|
||||||
-type 'node_type'() :: leaf | collection.
|
|
||||||
-type 'notification_type'() :: normal | headline.
|
|
||||||
-type 'publish_model'() :: publishers | subscribers | open.
|
|
||||||
-type 'send_last_published_item'() :: never | on_sub | on_sub_and_presence.
|
|
||||||
|
|
||||||
-type property() :: {'access_model', 'access_model'()} |
|
|
||||||
{'body_xslt', binary()} |
|
|
||||||
{'children_association_policy', 'children_association_policy'()} |
|
|
||||||
{'children_association_whitelist', [jid:jid()]} |
|
|
||||||
{'children', [binary()]} |
|
|
||||||
{'children_max', binary()} |
|
|
||||||
{'collection', [binary()]} |
|
|
||||||
{'contact', [jid:jid()]} |
|
|
||||||
{'dataform_xslt', binary()} |
|
|
||||||
{'deliver_notifications', boolean()} |
|
|
||||||
{'deliver_payloads', boolean()} |
|
|
||||||
{'description', binary()} |
|
|
||||||
{'item_expire', binary()} |
|
|
||||||
{'itemreply', 'itemreply'()} |
|
|
||||||
{'language', binary()} |
|
|
||||||
{'max_items', non_neg_integer()} |
|
|
||||||
{'max_payload_size', non_neg_integer()} |
|
|
||||||
{'node_type', 'node_type'()} |
|
|
||||||
{'notification_type', 'notification_type'()} |
|
|
||||||
{'notify_config', boolean()} |
|
|
||||||
{'notify_delete', boolean()} |
|
|
||||||
{'notify_retract', boolean()} |
|
|
||||||
{'notify_sub', boolean()} |
|
|
||||||
{'persist_items', boolean()} |
|
|
||||||
{'presence_based_delivery', boolean()} |
|
|
||||||
{'publish_model', 'publish_model'()} |
|
|
||||||
{'purge_offline', boolean()} |
|
|
||||||
{'roster_groups_allowed', [binary()]} |
|
|
||||||
{'send_last_published_item', 'send_last_published_item'()} |
|
|
||||||
{'tempsub', boolean()} |
|
|
||||||
{'subscribe', boolean()} |
|
|
||||||
{'title', binary()} |
|
|
||||||
{'type', binary()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type options(T) :: [{binary(), T}].
|
|
||||||
-type property_with_options() ::
|
|
||||||
{'access_model', 'access_model'(), options('access_model'())} |
|
|
||||||
{'children_association_policy', 'children_association_policy'(), options('children_association_policy'())} |
|
|
||||||
{'itemreply', 'itemreply'(), options('itemreply'())} |
|
|
||||||
{'language', binary(), options(binary())} |
|
|
||||||
{'node_type', 'node_type'(), options('node_type'())} |
|
|
||||||
{'notification_type', 'notification_type'(), options('notification_type'())} |
|
|
||||||
{'publish_model', 'publish_model'(), options('publish_model'())} |
|
|
||||||
{'roster_groups_allowed', [binary()], options(binary())} |
|
|
||||||
{'send_last_published_item', 'send_last_published_item'(), options('send_last_published_item'())}.
|
|
||||||
-type form() :: [property() | property_with_options() | xdata_field()].
|
|
@ -1,14 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_publish_options.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#publish-options
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-type 'access_model'() :: authorize | open | presence | roster | whitelist.
|
|
||||||
|
|
||||||
-type property() :: {'access_model', 'access_model'()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type options(T) :: [{binary(), T}].
|
|
||||||
-type property_with_options() ::
|
|
||||||
{'access_model', 'access_model'(), options('access_model'())}.
|
|
||||||
-type form() :: [property() | property_with_options() | xdata_field()].
|
|
@ -1,13 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_subscribe_authorization.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
|
|
||||||
-type property() :: {'allow', boolean()} |
|
|
||||||
{'node', binary()} |
|
|
||||||
{'subscriber_jid', jid:jid()} |
|
|
||||||
{'subid', binary()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type form() :: [property() | xdata_field()].
|
|
@ -1,25 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_subscribe_options.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#subscribe_options
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-type 'show-values'() :: away | chat | dnd | online | xa.
|
|
||||||
-type 'subscription_type'() :: items | nodes.
|
|
||||||
-type 'subscription_depth'() :: 1 | all.
|
|
||||||
|
|
||||||
-type property() :: {'deliver', boolean()} |
|
|
||||||
{'digest', boolean()} |
|
|
||||||
{'digest_frequency', binary()} |
|
|
||||||
{'expire', binary()} |
|
|
||||||
{'include_body', boolean()} |
|
|
||||||
{'show-values', ['show-values'()]} |
|
|
||||||
{'subscription_type', 'subscription_type'()} |
|
|
||||||
{'subscription_depth', 'subscription_depth'()}.
|
|
||||||
-type result() :: [property()].
|
|
||||||
|
|
||||||
-type options(T) :: [{binary(), T}].
|
|
||||||
-type property_with_options() ::
|
|
||||||
{'show-values', ['show-values'()], options('show-values'())} |
|
|
||||||
{'subscription_type', 'subscription_type'(), options('subscription_type'())} |
|
|
||||||
{'subscription_depth', 'subscription_depth'(), options('subscription_depth'())}.
|
|
||||||
-type form() :: [property() | property_with_options() | xdata_field()].
|
|
@ -1,25 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%% @copyright (C) 2015, Evgeny Khramtsov
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 10 Dec 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-include("ns.hrl").
|
|
||||||
-include("jid.hrl").
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
-include("fxml.hrl").
|
|
||||||
|
|
||||||
-type iq_type() :: get | set | result | error.
|
|
||||||
-type message_type() :: chat | error | groupchat | headline | normal.
|
|
||||||
-type presence_type() :: available | error | probe | subscribe |
|
|
||||||
subscribed | unavailable | unsubscribe |
|
|
||||||
unsubscribed.
|
|
||||||
|
|
||||||
-type stanza() :: iq() | presence() | message().
|
|
||||||
|
|
||||||
-define(is_stanza(Pkt),
|
|
||||||
(is_record(Pkt, iq) or
|
|
||||||
is_record(Pkt, message) or
|
|
||||||
is_record(Pkt, presence))).
|
|
File diff suppressed because it is too large
Load Diff
12
rebar.config
12
rebar.config
@ -13,6 +13,7 @@
|
|||||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.7"}}},
|
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.7"}}},
|
||||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.6"}}},
|
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.6"}}},
|
||||||
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.16"}}},
|
{fast_xml, ".*", {git, "https://github.com/processone/fast_xml", {tag, "1.1.16"}}},
|
||||||
|
{xmpp, ".*", {git, "https://github.com/processone/xmpp", {tag, "1.0.2"}}},
|
||||||
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.7"}}},
|
{stun, ".*", {git, "https://github.com/processone/stun", {tag, "1.0.7"}}},
|
||||||
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.8"}}},
|
{esip, ".*", {git, "https://github.com/processone/esip", {tag, "1.0.8"}}},
|
||||||
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.6"}}},
|
{fast_yaml, ".*", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.6"}}},
|
||||||
@ -55,6 +56,7 @@
|
|||||||
luerl,
|
luerl,
|
||||||
stun,
|
stun,
|
||||||
fast_yaml,
|
fast_yaml,
|
||||||
|
xmpp,
|
||||||
p1_utils,
|
p1_utils,
|
||||||
p1_mysql,
|
p1_mysql,
|
||||||
p1_pgsql,
|
p1_pgsql,
|
||||||
@ -65,7 +67,9 @@
|
|||||||
{erl_first_files, ["src/ejabberd_config.erl", "src/gen_mod.erl"]}.
|
{erl_first_files, ["src/ejabberd_config.erl", "src/gen_mod.erl"]}.
|
||||||
|
|
||||||
{erl_opts, [nowarn_deprecated_function,
|
{erl_opts, [nowarn_deprecated_function,
|
||||||
{i, "include"}, {i, "deps/fast_xml/include"},
|
{i, "include"},
|
||||||
|
{i, "deps/fast_xml/include"},
|
||||||
|
{i, "deps/xmpp/include"},
|
||||||
{if_var_false, debug, no_debug_info},
|
{if_var_false, debug, no_debug_info},
|
||||||
{if_var_true, debug, debug_info},
|
{if_var_true, debug, debug_info},
|
||||||
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
|
{if_var_true, roster_gateway_workaround, {d, 'ROSTER_GATWAY_WORKAROUND'}},
|
||||||
@ -113,8 +117,10 @@
|
|||||||
{if_var_false, elixir, "(\"Elixir.*\":_/_)"},
|
{if_var_false, elixir, "(\"Elixir.*\":_/_)"},
|
||||||
{if_var_false, redis, "(\"eredis\":_/_)"}]}.
|
{if_var_false, redis, "(\"eredis\":_/_)"}]}.
|
||||||
|
|
||||||
{eunit_compile_opts, [{i, "tools"}, {i, "include"},
|
{eunit_compile_opts, [{i, "tools"},
|
||||||
{i, "deps/fast_xml/include"}]}.
|
{i, "include"},
|
||||||
|
{i, "deps/fast_xml/include"},
|
||||||
|
{i, "deps/xmpp/include"}]}.
|
||||||
|
|
||||||
{if_version_above, "17", {cover_enabled, true}}.
|
{if_version_above, "17", {cover_enabled, true}}.
|
||||||
{cover_export_enabled, true}.
|
{cover_export_enabled, true}.
|
||||||
|
@ -1 +0,0 @@
|
|||||||
[{decode, [{<<"number_of_messages">>, {dec_int, [0, infinity]}}]}].
|
|
@ -1,12 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/offline</name>
|
|
||||||
<doc>XEP-0013</doc>
|
|
||||||
<desc>
|
|
||||||
Service Discovery extension for number of messages
|
|
||||||
in an offline message queue.
|
|
||||||
</desc>
|
|
||||||
<field
|
|
||||||
var='number_of_messages'
|
|
||||||
type='text-single'
|
|
||||||
label='Number of Offline Messages'/>
|
|
||||||
</form_type>
|
|
@ -1,9 +0,0 @@
|
|||||||
[{decode, [{<<"start">>, {xmpp_util, decode_timestamp, []}},
|
|
||||||
{<<"end">>, {xmpp_util, decode_timestamp, []}}]},
|
|
||||||
{specs, [{<<"start">>, "erlang:timestamp()"},
|
|
||||||
{<<"end">>, "erlang:timestamp()"}]}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,23 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>urn:xmpp:mam:1</name>
|
|
||||||
<doc>XEP-0313</doc>
|
|
||||||
<desc>Form to query message archives</desc>
|
|
||||||
<field var='with'
|
|
||||||
type='jid-single'
|
|
||||||
label='User JID'/>
|
|
||||||
<field var='start'
|
|
||||||
type='text-single'
|
|
||||||
label='Search from the date'/>
|
|
||||||
<field var='end'
|
|
||||||
type='text-single'
|
|
||||||
label='Search until the date'/>
|
|
||||||
<field var='withtext'
|
|
||||||
type='text-single'
|
|
||||||
label='Search the text'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,2 +0,0 @@
|
|||||||
[{prefix, <<"muc#register_">>},
|
|
||||||
{required, [<<"muc#register_roomnick">>]}].
|
|
@ -1,37 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/muc#register</name>
|
|
||||||
<doc>XEP-0045</doc>
|
|
||||||
<desc>
|
|
||||||
Forms enabling user registration with a
|
|
||||||
Multi-User Chat (MUC) room or admin approval
|
|
||||||
of user registration requests.
|
|
||||||
</desc>
|
|
||||||
<field
|
|
||||||
var='muc#register_allow'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow this person to register with the room?'/>
|
|
||||||
<field
|
|
||||||
var='muc#register_email'
|
|
||||||
type='text-single'
|
|
||||||
label='Email Address'/>
|
|
||||||
<field
|
|
||||||
var='muc#register_faqentry'
|
|
||||||
type='text-multi'
|
|
||||||
label='FAQ Entry'/>
|
|
||||||
<field
|
|
||||||
var='muc#register_first'
|
|
||||||
type='text-single'
|
|
||||||
label='Given Name'/>
|
|
||||||
<field
|
|
||||||
var='muc#register_last'
|
|
||||||
type='text-single'
|
|
||||||
label='Family Name'/>
|
|
||||||
<field
|
|
||||||
var='muc#register_roomnick'
|
|
||||||
type='text-single'
|
|
||||||
label='Nickname'/>
|
|
||||||
<field
|
|
||||||
var='muc#register_url'
|
|
||||||
type='text-single'
|
|
||||||
label='A Web Page'/>
|
|
||||||
</form_type>
|
|
@ -1,2 +0,0 @@
|
|||||||
[{prefix, <<"muc#">>},
|
|
||||||
{required, [<<"muc#role">>]}].
|
|
@ -1,31 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/muc#request</name>
|
|
||||||
<doc>XEP-0045</doc>
|
|
||||||
<desc>
|
|
||||||
Forms enabling voice requests in a
|
|
||||||
Multi-User Chat (MUC) room or admin
|
|
||||||
approval of such requests.
|
|
||||||
</desc>
|
|
||||||
<field var='muc#role'
|
|
||||||
type='list-single'
|
|
||||||
label='Requested role'>
|
|
||||||
<option label='Participant'>
|
|
||||||
<value>participant</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='muc#jid'
|
|
||||||
type='jid-single'
|
|
||||||
label='User JID'/>
|
|
||||||
<field var='muc#roomnick'
|
|
||||||
type='text-single'
|
|
||||||
label='Nickname'/>
|
|
||||||
<field var='muc#request_allow'
|
|
||||||
type='boolean'
|
|
||||||
label='Grant voice to this person?'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,11 +0,0 @@
|
|||||||
[{prefix, <<"muc#roomconfig_">>},
|
|
||||||
{prefix, <<"muc#">>},
|
|
||||||
{decode, [{<<"muc#roomconfig_maxusers">>,
|
|
||||||
{dec_enum_int, [[none], 0, infinity]}},
|
|
||||||
{<<"voice_request_min_interval">>,
|
|
||||||
{dec_int, [0, infinity]}}]}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,192 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/muc#roomconfig</name>
|
|
||||||
<doc>XEP-0045</doc>
|
|
||||||
<desc>
|
|
||||||
Forms enabling creation and configuration of
|
|
||||||
a Multi-User Chat (MUC) room.
|
|
||||||
</desc>
|
|
||||||
<field
|
|
||||||
var='muc#maxhistoryfetch'
|
|
||||||
type='text-single'
|
|
||||||
label='Maximum Number of History Messages Returned by Room'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_allowpm'
|
|
||||||
type='list-single'
|
|
||||||
label='Roles that May Send Private Messages'/>
|
|
||||||
<field
|
|
||||||
var='allow_private_messages'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow users to send private messages'/>
|
|
||||||
<field
|
|
||||||
var='allow_private_messages_from_visitors'
|
|
||||||
type='list-single'
|
|
||||||
label='Allow visitors to send private messages to'>
|
|
||||||
<option label='nobody'>
|
|
||||||
<value>nobody</value>
|
|
||||||
</option>
|
|
||||||
<option label='moderators only'>
|
|
||||||
<value>moderators</value>
|
|
||||||
</option>
|
|
||||||
<option label='anyone'>
|
|
||||||
<value>anyone</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field
|
|
||||||
var='allow_visitor_status'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow visitors to send status text in presence updates'/>
|
|
||||||
<field
|
|
||||||
var='allow_visitor_nickchange'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow visitors to change nickname'/>
|
|
||||||
<field
|
|
||||||
var='allow_voice_requests'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow visitors to send voice requests'/>
|
|
||||||
<field
|
|
||||||
var='allow_subscription'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow subscription'/>
|
|
||||||
<field
|
|
||||||
var='voice_request_min_interval'
|
|
||||||
type='text-single'
|
|
||||||
label='Minimum interval between voice requests (in seconds)'/>
|
|
||||||
<field
|
|
||||||
var='captcha_protected'
|
|
||||||
type='boolean'
|
|
||||||
label='Make room CAPTCHA protected'/>
|
|
||||||
<field
|
|
||||||
var='captcha_whitelist'
|
|
||||||
type='jid-multi'
|
|
||||||
label='Exclude Jabber IDs from CAPTCHA challenge'/>
|
|
||||||
<field
|
|
||||||
var='allow_query_users'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow users to query other users'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_allowinvites'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow users to send invites'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_changesubject'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow users to change the subject'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_enablelogging'
|
|
||||||
type='boolean'
|
|
||||||
label='Enable logging'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_getmemberlist'
|
|
||||||
type='list-multi'
|
|
||||||
label='Roles and Affiliations that May Retrieve Member List'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_lang'
|
|
||||||
type='text-single'
|
|
||||||
label='Natural Language for Room Discussions'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_pubsub'
|
|
||||||
type='text-single'
|
|
||||||
label='XMPP URI of Associated Publish-Subscribe Node'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_maxusers'
|
|
||||||
type='list-single'
|
|
||||||
label='Maximum Number of Occupants'>
|
|
||||||
<option label='No limit'>
|
|
||||||
<value>none</value>
|
|
||||||
</option>
|
|
||||||
<option><value>5</value></option>
|
|
||||||
<option><value>10</value></option>
|
|
||||||
<option><value>20</value></option>
|
|
||||||
<option><value>30</value></option>
|
|
||||||
<option><value>50</value></option>
|
|
||||||
<option><value>100</value></option>
|
|
||||||
<option><value>200</value></option>
|
|
||||||
<option><value>500</value></option>
|
|
||||||
<option><value>1000</value></option>
|
|
||||||
<option><value>2000</value></option>
|
|
||||||
<option><value>5000</value></option>
|
|
||||||
</field>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_membersonly'
|
|
||||||
type='boolean'
|
|
||||||
label='Make room members-only'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_moderatedroom'
|
|
||||||
type='boolean'
|
|
||||||
label='Make room moderated'/>
|
|
||||||
<field
|
|
||||||
var='members_by_default'
|
|
||||||
type='boolean'
|
|
||||||
label='Default users as participants'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_passwordprotectedroom'
|
|
||||||
type='boolean'
|
|
||||||
label='Make room password protected'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_persistentroom'
|
|
||||||
type='boolean'
|
|
||||||
label='Make room persistent'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_presencebroadcast'
|
|
||||||
type='list-multi'
|
|
||||||
label='Roles for which Presence is Broadcasted'>
|
|
||||||
<option label='Moderator'>
|
|
||||||
<value>moderator</value>
|
|
||||||
</option>
|
|
||||||
<option label='Participant'>
|
|
||||||
<value>participant</value>
|
|
||||||
</option>
|
|
||||||
<option label='Visitor'>
|
|
||||||
<value>visitor</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_publicroom'
|
|
||||||
type='boolean'
|
|
||||||
label='Make room public searchable'/>
|
|
||||||
<field
|
|
||||||
var='public_list'
|
|
||||||
type='boolean'
|
|
||||||
label='Make participants list public'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_roomadmins'
|
|
||||||
type='jid-multi'
|
|
||||||
label='Full List of Room Admins'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_roomdesc'
|
|
||||||
type='text-single'
|
|
||||||
label='Room description'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_roomname'
|
|
||||||
type='text-single'
|
|
||||||
label='Room title'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_roomowners'
|
|
||||||
type='jid-multi'
|
|
||||||
label='Full List of Room Owners'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_roomsecret'
|
|
||||||
type='text-private'
|
|
||||||
label='Password'/>
|
|
||||||
<field
|
|
||||||
var='muc#roomconfig_whois'
|
|
||||||
type='list-single'
|
|
||||||
label='Present real Jabber IDs to'>
|
|
||||||
<option label='moderators only'>
|
|
||||||
<value>moderators</value>
|
|
||||||
</option>
|
|
||||||
<option label='anyone'>
|
|
||||||
<value>anyone</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field
|
|
||||||
var='mam'
|
|
||||||
type='boolean'
|
|
||||||
label='Enable message archiving'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,11 +0,0 @@
|
|||||||
[{prefix, <<"muc#roominfo_">>},
|
|
||||||
{prefix, <<"muc#">>},
|
|
||||||
{decode, [{<<"muc#maxhistoryfetch">>,
|
|
||||||
{dec_int, [0, infinity]}},
|
|
||||||
{<<"muc#roominfo_occupants">>,
|
|
||||||
{dec_int, [0, infinity]}}]}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,55 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/muc#roominfo</name>
|
|
||||||
<doc>XEP-0045</doc>
|
|
||||||
<desc>
|
|
||||||
Forms enabling the communication of extended service discovery
|
|
||||||
information about a Multi-User Chat (MUC) room.
|
|
||||||
</desc>
|
|
||||||
<field
|
|
||||||
var='muc#maxhistoryfetch'
|
|
||||||
type='text-single'
|
|
||||||
label='Maximum Number of History Messages Returned by Room'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_contactjid'
|
|
||||||
type='jid-multi'
|
|
||||||
label='Contact Addresses (normally, room owner or owners)'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_description'
|
|
||||||
type='text-single'
|
|
||||||
label='Room description'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_lang'
|
|
||||||
type='text-single'
|
|
||||||
label='Natural Language for Room Discussions'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_ldapgroup'
|
|
||||||
type='text-single'
|
|
||||||
label='An associated LDAP group that defines
|
|
||||||
room membership; this should be an LDAP
|
|
||||||
Distinguished Name according to an
|
|
||||||
implementation-specific or
|
|
||||||
deployment-specific definition of a
|
|
||||||
group.'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_logs'
|
|
||||||
type='text-single'
|
|
||||||
label='URL for Archived Discussion Logs'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_occupants'
|
|
||||||
type='text-single'
|
|
||||||
label='Number of occupants'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_subject'
|
|
||||||
type='text-single'
|
|
||||||
label='Current Discussion Topic'/>
|
|
||||||
<field
|
|
||||||
var='muc#roominfo_subjectmod'
|
|
||||||
type='boolean'
|
|
||||||
label='The room subject can be modified by participants'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,7 +0,0 @@
|
|||||||
[{prefix, <<"pubsub#">>},
|
|
||||||
{required, [<<"pubsub#node">>]}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,15 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/pubsub#subscribe_authorization</name>
|
|
||||||
<doc>XEP-0060</doc>
|
|
||||||
<desc>Forms enabling authorization of subscriptions to pubsub nodes</desc>
|
|
||||||
<field
|
|
||||||
var='pubsub#node'
|
|
||||||
type='list-single'
|
|
||||||
label='The NodeID of the relevant node'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,8 +0,0 @@
|
|||||||
[{prefix, <<"pubsub#">>},
|
|
||||||
{decode, [{<<"pubsub#max_items">>, {dec_int, [0,infinity]}},
|
|
||||||
{<<"pubsub#max_payload_size">>, {dec_int, [0,infinity]}}]}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,189 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/pubsub#node_config</name>
|
|
||||||
<doc>XEP-0060</doc>
|
|
||||||
<desc>Forms enabling configuration of pubsub nodes</desc>
|
|
||||||
<field var='pubsub#access_model'
|
|
||||||
type='list-single'
|
|
||||||
label='Specify the access model'>
|
|
||||||
<option label='Subscription requests must be approved and only subscribers may retrieve items'>
|
|
||||||
<value>authorize</value>
|
|
||||||
</option>
|
|
||||||
<option label='Anyone may subscribe and retrieve items'>
|
|
||||||
<value>open</value>
|
|
||||||
</option>
|
|
||||||
<option label='Anyone with a presence subscription of both or from may subscribe and retrieve items'>
|
|
||||||
<value>presence</value>
|
|
||||||
</option>
|
|
||||||
<option label='Anyone in the specified roster group(s) may subscribe and retrieve items'>
|
|
||||||
<value>roster</value>
|
|
||||||
</option>
|
|
||||||
<option label='Only those on a whitelist may subscribe and retrieve items'>
|
|
||||||
<value>whitelist</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#body_xslt'
|
|
||||||
type='text-single'
|
|
||||||
label='The URL of an XSL transformation which can be
|
|
||||||
applied to payloads in order to generate an
|
|
||||||
appropriate message body element.'/>
|
|
||||||
<field var='pubsub#children_association_policy'
|
|
||||||
type='list-single'
|
|
||||||
label='Who may associate leaf nodes with a collection'>
|
|
||||||
<option label='Anyone may associate leaf nodes with the collection'>
|
|
||||||
<value>all</value>
|
|
||||||
</option>
|
|
||||||
<option label='Only collection node owners may associate leaf nodes with the collection'>
|
|
||||||
<value>owners</value>
|
|
||||||
</option>
|
|
||||||
<option label='Only those on a whitelist may associate leaf nodes with the collection'>
|
|
||||||
<value>whitelist</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#children_association_whitelist'
|
|
||||||
type='jid-multi'
|
|
||||||
label='The list of JIDs that may associate leaf nodes with a collection'/>
|
|
||||||
<field var='pubsub#children'
|
|
||||||
type='text-multi'
|
|
||||||
label='The child nodes (leaf or collection) associated with a collection'/>
|
|
||||||
<field var='pubsub#children_max'
|
|
||||||
type='text-single'
|
|
||||||
label='The maximum number of child nodes that can be associated with a collection'/>
|
|
||||||
<field var='pubsub#collection'
|
|
||||||
type='text-multi'
|
|
||||||
label='The collections with which a node is affiliated'/>
|
|
||||||
<field var='pubsub#contact'
|
|
||||||
type='jid-multi'
|
|
||||||
label='The JIDs of those to contact with questions'/>
|
|
||||||
<field var='pubsub#dataform_xslt'
|
|
||||||
type='text-single'
|
|
||||||
label='The URL of an XSL transformation which can be
|
|
||||||
applied to the payload format in order to generate
|
|
||||||
a valid Data Forms result that the client could
|
|
||||||
display using a generic Data Forms rendering
|
|
||||||
engine'/>
|
|
||||||
<field var='pubsub#deliver_notifications' type='boolean'
|
|
||||||
label='Deliver event notifications'>
|
|
||||||
<value>true</value>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#deliver_payloads'
|
|
||||||
type='boolean'
|
|
||||||
label='Deliver payloads with event notifications'/>
|
|
||||||
<field var='pubsub#description'
|
|
||||||
type='text-single'
|
|
||||||
label='A description of the node'/>
|
|
||||||
<field var='pubsub#item_expire'
|
|
||||||
type='text-single'
|
|
||||||
label='Number of seconds after which to automatically purge items'/>
|
|
||||||
<field var='pubsub#itemreply'
|
|
||||||
type='list-single'
|
|
||||||
label='Whether owners or publisher should receive replies to items'>
|
|
||||||
<option label='Statically specify a replyto of the node owner(s)'>
|
|
||||||
<value>owner</value>
|
|
||||||
</option>
|
|
||||||
<option label='Dynamically specify a replyto of the item publisher'>
|
|
||||||
<value>publisher</value>
|
|
||||||
</option>
|
|
||||||
<option>
|
|
||||||
<value>none</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#language'
|
|
||||||
type='list-single'
|
|
||||||
label='The default language of the node'/>
|
|
||||||
<field var='pubsub#max_items'
|
|
||||||
type='text-single'
|
|
||||||
label='Max # of items to persist'>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#max_payload_size'
|
|
||||||
type='text-single'
|
|
||||||
label='Max payload size in bytes'/>
|
|
||||||
<field var='pubsub#node_type'
|
|
||||||
type='list-single'
|
|
||||||
label='Whether the node is a leaf (default) or a collection'>
|
|
||||||
<option label='The node is a leaf node (default)'>
|
|
||||||
<value>leaf</value>
|
|
||||||
</option>
|
|
||||||
<option label='The node is a collection node'>
|
|
||||||
<value>collection</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#notification_type' type='list-single'
|
|
||||||
label='Specify the event message type'>
|
|
||||||
<option label='Messages of type normal'>
|
|
||||||
<value>normal</value>
|
|
||||||
</option>
|
|
||||||
<option label='Messages of type headline'>
|
|
||||||
<value>headline</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#notify_config'
|
|
||||||
type='boolean'
|
|
||||||
label='Notify subscribers when the node configuration changes'/>
|
|
||||||
<field var='pubsub#notify_delete'
|
|
||||||
type='boolean'
|
|
||||||
label='Notify subscribers when the node is deleted'/>
|
|
||||||
<field var='pubsub#notify_retract'
|
|
||||||
type='boolean'
|
|
||||||
label='Notify subscribers when items are removed from the node'/>
|
|
||||||
<field var='pubsub#notify_sub'
|
|
||||||
type='boolean'
|
|
||||||
label='Whether to notify owners about new subscribers and unsubscribes'/>
|
|
||||||
<field var='pubsub#persist_items'
|
|
||||||
type='boolean'
|
|
||||||
label='Persist items to storage'/>
|
|
||||||
<field var='pubsub#presence_based_delivery'
|
|
||||||
type='boolean'
|
|
||||||
label='Only deliver notifications to available users'/>
|
|
||||||
<field var='pubsub#publish_model'
|
|
||||||
type='list-single'
|
|
||||||
label='Specify the publisher model'>
|
|
||||||
<option label='Only publishers may publish'>
|
|
||||||
<value>publishers</value>
|
|
||||||
</option>
|
|
||||||
<option label='Subscribers may publish'>
|
|
||||||
<value>subscribers</value>
|
|
||||||
</option>
|
|
||||||
<option label='Anyone may publish'>
|
|
||||||
<value>open</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#purge_offline'
|
|
||||||
type='boolean'
|
|
||||||
label='Purge all items when the relevant publisher goes offline'/>
|
|
||||||
<field var='pubsub#roster_groups_allowed'
|
|
||||||
type='list-multi'
|
|
||||||
label='Roster groups allowed to subscribe'/>
|
|
||||||
<field var='pubsub#send_last_published_item'
|
|
||||||
type='list-single'
|
|
||||||
label='When to send the last published item'>
|
|
||||||
<option label='Never'>
|
|
||||||
<value>never</value>
|
|
||||||
</option>
|
|
||||||
<option label='When a new subscription is processed'>
|
|
||||||
<value>on_sub</value>
|
|
||||||
</option>
|
|
||||||
<option label='When a new subscription is processed and whenever a subscriber comes online'>
|
|
||||||
<value>on_sub_and_presence</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#tempsub'
|
|
||||||
type='boolean'
|
|
||||||
label='Whether to make all subscriptions temporary, based on subscriber presence'/>
|
|
||||||
<field var='pubsub#subscribe' type='boolean'
|
|
||||||
label='Whether to allow subscriptions'>
|
|
||||||
<value>1</value>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#title'
|
|
||||||
type='text-single'
|
|
||||||
label='A friendly name for the node'/>
|
|
||||||
<field var='pubsub#type'
|
|
||||||
type='text-single'
|
|
||||||
label='The type of node data, usually specified by
|
|
||||||
the namespace of the payload (if any)'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,6 +0,0 @@
|
|||||||
[{prefix, <<"pubsub#">>}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,34 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/pubsub#publish-options</name>
|
|
||||||
<doc>XEP-0060</doc>
|
|
||||||
<desc>
|
|
||||||
Forms enabling publication with options; each field must specify whether it
|
|
||||||
defines METADATA to be attached to the item, a per-item OVERRIDE of the node
|
|
||||||
configuration, or a PRECONDITION to be checked against the node configuration.
|
|
||||||
</desc>
|
|
||||||
<field var='pubsub#access_model'
|
|
||||||
type='list-single'
|
|
||||||
label='Specify the access model'>
|
|
||||||
<option label='Access model of authorize'>
|
|
||||||
<value>authorize</value>
|
|
||||||
</option>
|
|
||||||
<option label='Access model of open'>
|
|
||||||
<value>open</value>
|
|
||||||
</option>
|
|
||||||
<option label='Access model of presence'>
|
|
||||||
<value>presence</value>
|
|
||||||
</option>
|
|
||||||
<option label='Access model of roster'>
|
|
||||||
<value>roster</value>
|
|
||||||
</option>
|
|
||||||
<option label='Access model of whitelist'>
|
|
||||||
<value>whitelist</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1,7 +0,0 @@
|
|||||||
[{prefix, <<"pubsub#">>},
|
|
||||||
{required, [<<"pubsub#node">>, <<"pubsub#subscriber_jid">>, <<"pubsub#allow">>]}].
|
|
||||||
|
|
||||||
%% Local Variables:
|
|
||||||
%% mode: erlang
|
|
||||||
%% End:
|
|
||||||
%% vim: set filetype=erlang tabstop=8:
|
|
@ -1,27 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/pubsub#subscribe_authorization</name>
|
|
||||||
<doc>XEP-0060</doc>
|
|
||||||
<desc>Forms enabling authorization of subscriptions to pubsub nodes</desc>
|
|
||||||
<field
|
|
||||||
var='pubsub#allow'
|
|
||||||
type='boolean'
|
|
||||||
label='Allow this Jabber ID to subscribe to this pubsub node?'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#node'
|
|
||||||
type='text-single'
|
|
||||||
label='Node ID'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#subscriber_jid'
|
|
||||||
type='jid-single'
|
|
||||||
label='Subscriber Address'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#subid'
|
|
||||||
type='text-single'
|
|
||||||
label='The subscription identifier associated with the subscription request'/>
|
|
||||||
</form_type>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Local Variables:
|
|
||||||
mode: xml
|
|
||||||
End:
|
|
||||||
-->
|
|
@ -1 +0,0 @@
|
|||||||
[{prefix, <<"pubsub#">>}].
|
|
@ -1,70 +0,0 @@
|
|||||||
<form_type>
|
|
||||||
<name>http://jabber.org/protocol/pubsub#subscribe_options</name>
|
|
||||||
<doc>XEP-0060</doc>
|
|
||||||
<desc>Forms enabling configuration of subscription options for pubsub nodes</desc>
|
|
||||||
<field
|
|
||||||
var='pubsub#deliver'
|
|
||||||
type='boolean'
|
|
||||||
label='Whether an entity wants to receive
|
|
||||||
or disable notifications'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#digest'
|
|
||||||
type='boolean'
|
|
||||||
label='Whether an entity wants to receive digests
|
|
||||||
(aggregations) of notifications or all
|
|
||||||
notifications individually'/>
|
|
||||||
<field var='pubsub#digest_frequency'
|
|
||||||
type='text-single'
|
|
||||||
label='The minimum number of milliseconds between
|
|
||||||
sending any two notification digests'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#expire'
|
|
||||||
type='text-single'
|
|
||||||
label='The DateTime at which a leased subscription
|
|
||||||
will end or has ended'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#include_body'
|
|
||||||
type='boolean'
|
|
||||||
label='Whether an entity wants to receive an XMPP
|
|
||||||
message body in addition to the payload
|
|
||||||
format'/>
|
|
||||||
<field
|
|
||||||
var='pubsub#show-values'
|
|
||||||
type='list-multi'
|
|
||||||
label='The presence states for which an entity
|
|
||||||
wants to receive notifications'>
|
|
||||||
<option label='XMPP Show Value of Away'>
|
|
||||||
<value>away</value>
|
|
||||||
</option>
|
|
||||||
<option label='XMPP Show Value of Chat'>
|
|
||||||
<value>chat</value>
|
|
||||||
</option>
|
|
||||||
<option label='XMPP Show Value of DND (Do Not Disturb)'>
|
|
||||||
<value>dnd</value>
|
|
||||||
</option>
|
|
||||||
<option label='Mere Availability in XMPP (No Show Value)'>
|
|
||||||
<value>online</value>
|
|
||||||
</option>
|
|
||||||
<option label='XMPP Show Value of XA (Extended Away)'>
|
|
||||||
<value>xa</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#subscription_type'
|
|
||||||
type='list-single'>
|
|
||||||
<option label='Receive notification of new items only'>
|
|
||||||
<value>items</value>
|
|
||||||
</option>
|
|
||||||
<option label='Receive notification of new nodes only'>
|
|
||||||
<value>nodes</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
<field var='pubsub#subscription_depth'
|
|
||||||
type='list-single'>
|
|
||||||
<option label='Receive notification from direct child nodes only'>
|
|
||||||
<value>1</value>
|
|
||||||
</option>
|
|
||||||
<option label='Receive notification from all descendent nodes'>
|
|
||||||
<value>all</value>
|
|
||||||
</option>
|
|
||||||
</field>
|
|
||||||
</form_type>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,128 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: flex_offline.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/offline
|
|
||||||
%% Document: XEP-0013
|
|
||||||
|
|
||||||
-module(flex_offline).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("flex_offline.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_int(Val, Min, Max) ->
|
|
||||||
case list_to_integer(binary_to_list(Val)) of
|
|
||||||
Int when Int =< Max, Min == infinity -> Int;
|
|
||||||
Int when Int =< Max, Int >= Min -> Int
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_int(Int) -> integer_to_binary(Int).
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, []);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/offline">>]} ->
|
|
||||||
decode(Fs, Acc, []);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/offline">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{number_of_messages, Val} ->
|
|
||||||
[encode_number_of_messages(Val, Translate)];
|
|
||||||
{number_of_messages, _, _} ->
|
|
||||||
erlang:error({badarg, Opt});
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/offline">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"number_of_messages">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_int(Value, 0, infinity) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{number_of_messages, Result} | Acc],
|
|
||||||
lists:delete(<<"number_of_messages">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"number_of_messages">>,
|
|
||||||
<<"http://jabber.org/protocol/offline">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"number_of_messages">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"number_of_messages">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"number_of_messages">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"number_of_messages">>,
|
|
||||||
<<"http://jabber.org/protocol/offline">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/offline">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/offline">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_number_of_messages(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_int(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"number_of_messages">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Number of Offline Messages">>)}.
|
|
266
src/jid.erl
266
src/jid.erl
@ -1,266 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%% @doc
|
|
||||||
%%% JID processing library
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 24 Nov 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%%
|
|
||||||
%%%
|
|
||||||
%%% ejabberd, Copyright (C) 2002-2016 ProcessOne
|
|
||||||
%%%
|
|
||||||
%%% This program is free software; you can redistribute it and/or
|
|
||||||
%%% modify it under the terms of the GNU General Public License as
|
|
||||||
%%% published by the Free Software Foundation; either version 2 of the
|
|
||||||
%%% License, or (at your option) any later version.
|
|
||||||
%%%
|
|
||||||
%%% This program is distributed in the hope that it will be useful,
|
|
||||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
%%% General Public License for more details.
|
|
||||||
%%%
|
|
||||||
%%% You should have received a copy of the GNU General Public License along
|
|
||||||
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
%%%
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(jid).
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([start/0,
|
|
||||||
make/1,
|
|
||||||
make/2,
|
|
||||||
make/3,
|
|
||||||
split/1,
|
|
||||||
from_string/1,
|
|
||||||
to_string/1,
|
|
||||||
is_nodename/1,
|
|
||||||
nodeprep/1,
|
|
||||||
nameprep/1,
|
|
||||||
resourceprep/1,
|
|
||||||
tolower/1,
|
|
||||||
remove_resource/1,
|
|
||||||
replace_resource/2]).
|
|
||||||
|
|
||||||
-include("jid.hrl").
|
|
||||||
|
|
||||||
-export_type([jid/0]).
|
|
||||||
-export_type([ljid/0]).
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% API
|
|
||||||
%%%===================================================================
|
|
||||||
-spec start() -> ok.
|
|
||||||
|
|
||||||
start() ->
|
|
||||||
{ok, Owner} = ets_owner(),
|
|
||||||
SplitPattern = binary:compile_pattern([<<"@">>, <<"/">>]),
|
|
||||||
%% Table is public to allow ETS insert to fix / update the table even if table already exist
|
|
||||||
%% with another owner.
|
|
||||||
catch ets:new(jlib, [named_table, public, set, {keypos, 1}, {heir, Owner, undefined}]),
|
|
||||||
ets:insert(jlib, {string_to_jid_pattern, SplitPattern}),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
ets_owner() ->
|
|
||||||
case whereis(jlib_ets) of
|
|
||||||
undefined ->
|
|
||||||
Pid = spawn(fun() -> ets_keepalive() end),
|
|
||||||
case catch register(jlib_ets, Pid) of
|
|
||||||
true ->
|
|
||||||
{ok, Pid};
|
|
||||||
Error -> Error
|
|
||||||
end;
|
|
||||||
Pid ->
|
|
||||||
{ok,Pid}
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% Process used to keep jlib ETS table alive in case the original owner dies.
|
|
||||||
%% The table need to be public, otherwise subsequent inserts would fail.
|
|
||||||
ets_keepalive() ->
|
|
||||||
receive
|
|
||||||
_ ->
|
|
||||||
ets_keepalive()
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec make(binary(), binary(), binary()) -> jid() | error.
|
|
||||||
|
|
||||||
make(User, Server, Resource) ->
|
|
||||||
case nodeprep(User) of
|
|
||||||
error -> error;
|
|
||||||
LUser ->
|
|
||||||
case nameprep(Server) of
|
|
||||||
error -> error;
|
|
||||||
LServer ->
|
|
||||||
case resourceprep(Resource) of
|
|
||||||
error -> error;
|
|
||||||
LResource ->
|
|
||||||
#jid{user = User, server = Server, resource = Resource,
|
|
||||||
luser = LUser, lserver = LServer,
|
|
||||||
lresource = LResource}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec make(binary(), binary()) -> jid() | error.
|
|
||||||
make(User, Server) ->
|
|
||||||
make(User, Server, <<"">>).
|
|
||||||
|
|
||||||
-spec make({binary(), binary(), binary()} | binary()) -> jid() | error.
|
|
||||||
|
|
||||||
make({User, Server, Resource}) ->
|
|
||||||
make(User, Server, Resource);
|
|
||||||
make(Server) ->
|
|
||||||
make(<<"">>, Server, <<"">>).
|
|
||||||
|
|
||||||
%% This is the reverse of make_jid/1
|
|
||||||
-spec split(jid()) -> {binary(), binary(), binary()} | error.
|
|
||||||
|
|
||||||
split(#jid{user = U, server = S, resource = R}) ->
|
|
||||||
{U, S, R};
|
|
||||||
split(_) ->
|
|
||||||
error.
|
|
||||||
|
|
||||||
-spec from_string(binary() | string()) -> jid() | error.
|
|
||||||
from_string(S) when is_list(S) ->
|
|
||||||
%% We do not accept list because we want to enforce good practice of
|
|
||||||
%% using binaries for string. However, we do not let it crash to avoid
|
|
||||||
%% losing associated ets table.
|
|
||||||
{error, need_jid_as_binary};
|
|
||||||
from_string(<<>>) ->
|
|
||||||
error;
|
|
||||||
from_string(S) when is_binary(S) ->
|
|
||||||
SplitPattern = ets:lookup_element(jlib, string_to_jid_pattern, 2),
|
|
||||||
Size = size(S),
|
|
||||||
End = Size-1,
|
|
||||||
case binary:match(S, SplitPattern) of
|
|
||||||
{0, _} ->
|
|
||||||
error;
|
|
||||||
{End, _} ->
|
|
||||||
error;
|
|
||||||
{Pos1, _} ->
|
|
||||||
case binary:at(S, Pos1) of
|
|
||||||
$/ ->
|
|
||||||
make(<<>>,
|
|
||||||
binary:part(S, 0, Pos1),
|
|
||||||
binary:part(S, Pos1+1, Size-Pos1-1));
|
|
||||||
_ ->
|
|
||||||
Pos1N = Pos1+1,
|
|
||||||
case binary:match(S, SplitPattern, [{scope, {Pos1+1, Size-Pos1-1}}]) of
|
|
||||||
{End, _} ->
|
|
||||||
error;
|
|
||||||
{Pos1N, _} ->
|
|
||||||
error;
|
|
||||||
{Pos2, _} ->
|
|
||||||
case binary:at(S, Pos2) of
|
|
||||||
$/ ->
|
|
||||||
make(binary:part(S, 0, Pos1),
|
|
||||||
binary:part(S, Pos1+1, Pos2-Pos1-1),
|
|
||||||
binary:part(S, Pos2+1, Size-Pos2-1));
|
|
||||||
_ -> error
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
make(binary:part(S, 0, Pos1),
|
|
||||||
binary:part(S, Pos1+1, Size-Pos1-1),
|
|
||||||
<<>>)
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
make(<<>>, S, <<>>)
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec to_string(jid() | ljid()) -> binary().
|
|
||||||
|
|
||||||
to_string(#jid{user = User, server = Server,
|
|
||||||
resource = Resource}) ->
|
|
||||||
to_string({User, Server, Resource});
|
|
||||||
to_string({N, S, R}) ->
|
|
||||||
Node = iolist_to_binary(N),
|
|
||||||
Server = iolist_to_binary(S),
|
|
||||||
Resource = iolist_to_binary(R),
|
|
||||||
S1 = case Node of
|
|
||||||
<<"">> -> <<"">>;
|
|
||||||
_ -> <<Node/binary, "@">>
|
|
||||||
end,
|
|
||||||
S2 = <<S1/binary, Server/binary>>,
|
|
||||||
S3 = case Resource of
|
|
||||||
<<"">> -> S2;
|
|
||||||
_ -> <<S2/binary, "/", Resource/binary>>
|
|
||||||
end,
|
|
||||||
S3.
|
|
||||||
|
|
||||||
-spec is_nodename(binary()) -> boolean().
|
|
||||||
|
|
||||||
is_nodename(Node) ->
|
|
||||||
N = nodeprep(Node),
|
|
||||||
(N /= error) and (N /= <<>>).
|
|
||||||
|
|
||||||
-define(LOWER(Char),
|
|
||||||
if Char >= $A, Char =< $Z -> Char + 32;
|
|
||||||
true -> Char
|
|
||||||
end).
|
|
||||||
|
|
||||||
-spec nodeprep(binary()) -> binary() | error.
|
|
||||||
|
|
||||||
nodeprep("") -> <<>>;
|
|
||||||
nodeprep(S) when byte_size(S) < 1024 ->
|
|
||||||
R = stringprep:nodeprep(S),
|
|
||||||
if byte_size(R) < 1024 -> R;
|
|
||||||
true -> error
|
|
||||||
end;
|
|
||||||
nodeprep(_) -> error.
|
|
||||||
|
|
||||||
-spec nameprep(binary()) -> binary() | error.
|
|
||||||
|
|
||||||
nameprep(S) when byte_size(S) < 1024 ->
|
|
||||||
R = stringprep:nameprep(S),
|
|
||||||
if byte_size(R) < 1024 -> R;
|
|
||||||
true -> error
|
|
||||||
end;
|
|
||||||
nameprep(_) -> error.
|
|
||||||
|
|
||||||
-spec resourceprep(binary()) -> binary() | error.
|
|
||||||
|
|
||||||
resourceprep(S) when byte_size(S) < 1024 ->
|
|
||||||
R = stringprep:resourceprep(S),
|
|
||||||
if byte_size(R) < 1024 -> R;
|
|
||||||
true -> error
|
|
||||||
end;
|
|
||||||
resourceprep(_) -> error.
|
|
||||||
|
|
||||||
-spec tolower(jid() | ljid()) -> error | ljid().
|
|
||||||
|
|
||||||
tolower(#jid{luser = U, lserver = S,
|
|
||||||
lresource = R}) ->
|
|
||||||
{U, S, R};
|
|
||||||
tolower({U, S, R}) ->
|
|
||||||
case nodeprep(U) of
|
|
||||||
error -> error;
|
|
||||||
LUser ->
|
|
||||||
case nameprep(S) of
|
|
||||||
error -> error;
|
|
||||||
LServer ->
|
|
||||||
case resourceprep(R) of
|
|
||||||
error -> error;
|
|
||||||
LResource -> {LUser, LServer, LResource}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec remove_resource(jid()) -> jid();
|
|
||||||
(ljid()) -> ljid().
|
|
||||||
|
|
||||||
remove_resource(#jid{} = JID) ->
|
|
||||||
JID#jid{resource = <<"">>, lresource = <<"">>};
|
|
||||||
remove_resource({U, S, _R}) -> {U, S, <<"">>}.
|
|
||||||
|
|
||||||
-spec replace_resource(jid(), binary()) -> error | jid().
|
|
||||||
|
|
||||||
replace_resource(JID, Resource) ->
|
|
||||||
case resourceprep(Resource) of
|
|
||||||
error -> error;
|
|
||||||
LResource ->
|
|
||||||
JID#jid{resource = Resource, lresource = LResource}
|
|
||||||
end.
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Internal functions
|
|
||||||
%%%===================================================================
|
|
@ -1,220 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: mam_query.xdata
|
|
||||||
%% Form type: urn:xmpp:mam:1
|
|
||||||
%% Document: XEP-0313
|
|
||||||
|
|
||||||
-module(mam_query).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("mam_query.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
enc_jid(J) -> jid:to_string(J).
|
|
||||||
|
|
||||||
dec_jid(Val) ->
|
|
||||||
case jid:from_string(Val) of
|
|
||||||
error -> erlang:error(badarg);
|
|
||||||
J -> J
|
|
||||||
end.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, []);
|
|
||||||
#xdata_field{values = [<<"urn:xmpp:mam:1">>]} ->
|
|
||||||
decode(Fs, Acc, []);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch, <<"urn:xmpp:mam:1">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{with, Val} -> [encode_with(Val, Translate)];
|
|
||||||
{with, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{start, Val} -> [encode_start(Val, Translate)];
|
|
||||||
{start, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{'end', Val} -> [encode_end(Val, Translate)];
|
|
||||||
{'end', _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{withtext, Val} -> [encode_withtext(Val, Translate)];
|
|
||||||
{withtext, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden, values = [<<"urn:xmpp:mam:1">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"with">>, values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_jid(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{with, Result} | Acc],
|
|
||||||
lists:delete(<<"with">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"with">>, <<"urn:xmpp:mam:1">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"with">>, values = []} = F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"with">>, values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"with">>} | _], _, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"with">>, <<"urn:xmpp:mam:1">>}});
|
|
||||||
decode([#xdata_field{var = <<"start">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try xmpp_util:decode_timestamp(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{start, Result} | Acc],
|
|
||||||
lists:delete(<<"start">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"start">>, <<"urn:xmpp:mam:1">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"start">>, values = []} = F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"start">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"start">>} | _], _, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"start">>, <<"urn:xmpp:mam:1">>}});
|
|
||||||
decode([#xdata_field{var = <<"end">>, values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try xmpp_util:decode_timestamp(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{'end', Result} | Acc],
|
|
||||||
lists:delete(<<"end">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"end">>, <<"urn:xmpp:mam:1">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"end">>, values = []} = F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"end">>, values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"end">>} | _], _, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"end">>, <<"urn:xmpp:mam:1">>}});
|
|
||||||
decode([#xdata_field{var = <<"withtext">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{withtext, Result} | Acc],
|
|
||||||
lists:delete(<<"withtext">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"withtext">>, <<"urn:xmpp:mam:1">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"withtext">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"withtext">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"withtext">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"withtext">>,
|
|
||||||
<<"urn:xmpp:mam:1">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var, <<"urn:xmpp:mam:1">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var, <<"urn:xmpp:mam:1">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_with(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_jid(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"with">>, values = Values,
|
|
||||||
required = false, type = 'jid-single', options = Opts,
|
|
||||||
desc = <<>>, label = Translate(<<"User JID">>)}.
|
|
||||||
|
|
||||||
encode_start(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"start">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label = Translate(<<"Search from the date">>)}.
|
|
||||||
|
|
||||||
encode_end(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"end">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label = Translate(<<"Search until the date">>)}.
|
|
||||||
|
|
||||||
encode_withtext(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"withtext">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>, label = Translate(<<"Search the text">>)}.
|
|
@ -1,364 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_register.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#register
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
-module(muc_register).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("muc_register.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_bool(<<"1">>) -> true;
|
|
||||||
dec_bool(<<"0">>) -> false;
|
|
||||||
dec_bool(<<"true">>) -> true;
|
|
||||||
dec_bool(<<"false">>) -> false.
|
|
||||||
|
|
||||||
enc_bool(true) -> <<"1">>;
|
|
||||||
enc_bool(false) -> <<"0">>.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, [<<"muc#register_roomnick">>]);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/muc#register">>]} ->
|
|
||||||
decode(Fs, Acc, [<<"muc#register_roomnick">>]);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{allow, Val} -> [encode_allow(Val, Translate)];
|
|
||||||
{allow, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{email, Val} -> [encode_email(Val, Translate)];
|
|
||||||
{email, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{faqentry, Val} -> [encode_faqentry(Val, Translate)];
|
|
||||||
{faqentry, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{first, Val} -> [encode_first(Val, Translate)];
|
|
||||||
{first, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{last, Val} -> [encode_last(Val, Translate)];
|
|
||||||
{last, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{roomnick, Val} -> [encode_roomnick(Val, Translate)];
|
|
||||||
{roomnick, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{url, Val} -> [encode_url(Val, Translate)];
|
|
||||||
{url, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/muc#register">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"muc#register_allow">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{allow, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_allow">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_allow">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_allow">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#register_allow">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#register_allow">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#register_allow">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#register_email">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{email, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_email">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_email">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_email">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#register_email">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#register_email">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#register_email">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#register_faqentry">>,
|
|
||||||
values = Values}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try [Value || Value <- Values] of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{faqentry, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_faqentry">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_faqentry">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_first">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{first, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_first">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_first">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_first">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#register_first">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#register_first">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#register_first">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#register_last">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{last, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_last">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_last">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_last">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#register_last">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#register_last">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#register_last">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#register_roomnick">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{roomnick, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_roomnick">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_roomnick">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_roomnick">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#register_roomnick">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#register_roomnick">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#register_roomnick">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#register_url">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{url, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#register_url">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#register_url">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#register_url">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#register_url">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#register_url">>} | _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#register_url">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/muc#register">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_allow(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_allow">>,
|
|
||||||
values = Values, required = false, type = boolean,
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Allow this person to register with the "
|
|
||||||
"room?">>)}.
|
|
||||||
|
|
||||||
encode_email(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_email">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Email Address">>)}.
|
|
||||||
|
|
||||||
encode_faqentry(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
[] -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_faqentry">>,
|
|
||||||
values = Values, required = false, type = 'text-multi',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"FAQ Entry">>)}.
|
|
||||||
|
|
||||||
encode_first(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_first">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Given Name">>)}.
|
|
||||||
|
|
||||||
encode_last(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_last">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Family Name">>)}.
|
|
||||||
|
|
||||||
encode_roomnick(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_roomnick">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Nickname">>)}.
|
|
||||||
|
|
||||||
encode_url(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#register_url">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"A Web Page">>)}.
|
|
@ -1,269 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_request.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#request
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
-module(muc_request).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("muc_request.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_enum(Val, Enums) ->
|
|
||||||
AtomVal = erlang:binary_to_existing_atom(Val, utf8),
|
|
||||||
case lists:member(AtomVal, Enums) of
|
|
||||||
true -> AtomVal
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8).
|
|
||||||
|
|
||||||
dec_bool(<<"1">>) -> true;
|
|
||||||
dec_bool(<<"0">>) -> false;
|
|
||||||
dec_bool(<<"true">>) -> true;
|
|
||||||
dec_bool(<<"false">>) -> false.
|
|
||||||
|
|
||||||
enc_bool(true) -> <<"1">>;
|
|
||||||
enc_bool(false) -> <<"0">>.
|
|
||||||
|
|
||||||
enc_jid(J) -> jid:to_string(J).
|
|
||||||
|
|
||||||
dec_jid(Val) ->
|
|
||||||
case jid:from_string(Val) of
|
|
||||||
error -> erlang:error(badarg);
|
|
||||||
J -> J
|
|
||||||
end.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, [<<"muc#role">>]);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/muc#request">>]} ->
|
|
||||||
decode(Fs, Acc, [<<"muc#role">>]);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{role, Val} -> [encode_role(Val, default, Translate)];
|
|
||||||
{role, Val, Opts} ->
|
|
||||||
[encode_role(Val, Opts, Translate)];
|
|
||||||
{jid, Val} -> [encode_jid(Val, Translate)];
|
|
||||||
{jid, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{roomnick, Val} -> [encode_roomnick(Val, Translate)];
|
|
||||||
{roomnick, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{request_allow, Val} ->
|
|
||||||
[encode_request_allow(Val, Translate)];
|
|
||||||
{request_allow, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/muc#request">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"muc#role">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_enum(Value, [participant]) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{role, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#role">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#role">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#role">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#role">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#role">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#role">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#jid">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_jid(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{jid, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#jid">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#jid">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#jid">>, values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#jid">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#jid">>} | _], _, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#jid">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#roomnick">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{roomnick, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roomnick">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roomnick">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#roomnick">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#roomnick">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#roomnick">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roomnick">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#request_allow">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{request_allow, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#request_allow">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#request_allow">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#request_allow">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#request_allow">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#request_allow">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#request_allow">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/muc#request">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_role(Value, Options, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_enum(Value)]
|
|
||||||
end,
|
|
||||||
Opts = if Options == default ->
|
|
||||||
[#xdata_option{label = Translate(<<"Participant">>),
|
|
||||||
value = <<"participant">>}];
|
|
||||||
true ->
|
|
||||||
[#xdata_option{label = Translate(L),
|
|
||||||
value = enc_enum(V)}
|
|
||||||
|| {L, V} <- Options]
|
|
||||||
end,
|
|
||||||
#xdata_field{var = <<"muc#role">>, values = Values,
|
|
||||||
required = false, type = 'list-single', options = Opts,
|
|
||||||
desc = <<>>, label = Translate(<<"Requested role">>)}.
|
|
||||||
|
|
||||||
encode_jid(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_jid(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#jid">>, values = Values,
|
|
||||||
required = false, type = 'jid-single', options = Opts,
|
|
||||||
desc = <<>>, label = Translate(<<"User JID">>)}.
|
|
||||||
|
|
||||||
encode_roomnick(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roomnick">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>, label = Translate(<<"Nickname">>)}.
|
|
||||||
|
|
||||||
encode_request_allow(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#request_allow">>,
|
|
||||||
values = Values, required = false, type = boolean,
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Grant voice to this person?">>)}.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,491 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: muc_roominfo.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/muc#roominfo
|
|
||||||
%% Document: XEP-0045
|
|
||||||
|
|
||||||
-module(muc_roominfo).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("muc_roominfo.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_int(Val, Min, Max) ->
|
|
||||||
case list_to_integer(binary_to_list(Val)) of
|
|
||||||
Int when Int =< Max, Min == infinity -> Int;
|
|
||||||
Int when Int =< Max, Int >= Min -> Int
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_int(Int) -> integer_to_binary(Int).
|
|
||||||
|
|
||||||
dec_bool(<<"1">>) -> true;
|
|
||||||
dec_bool(<<"0">>) -> false;
|
|
||||||
dec_bool(<<"true">>) -> true;
|
|
||||||
dec_bool(<<"false">>) -> false.
|
|
||||||
|
|
||||||
enc_bool(true) -> <<"1">>;
|
|
||||||
enc_bool(false) -> <<"0">>.
|
|
||||||
|
|
||||||
enc_jid(J) -> jid:to_string(J).
|
|
||||||
|
|
||||||
dec_jid(Val) ->
|
|
||||||
case jid:from_string(Val) of
|
|
||||||
error -> erlang:error(badarg);
|
|
||||||
J -> J
|
|
||||||
end.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, []);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/muc#roominfo">>]} ->
|
|
||||||
decode(Fs, Acc, []);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{maxhistoryfetch, Val} ->
|
|
||||||
[encode_maxhistoryfetch(Val, Translate)];
|
|
||||||
{maxhistoryfetch, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{contactjid, Val} ->
|
|
||||||
[encode_contactjid(Val, Translate)];
|
|
||||||
{contactjid, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{description, Val} ->
|
|
||||||
[encode_description(Val, Translate)];
|
|
||||||
{description, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{lang, Val} -> [encode_lang(Val, Translate)];
|
|
||||||
{lang, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{ldapgroup, Val} -> [encode_ldapgroup(Val, Translate)];
|
|
||||||
{ldapgroup, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{logs, Val} -> [encode_logs(Val, Translate)];
|
|
||||||
{logs, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{occupants, Val} -> [encode_occupants(Val, Translate)];
|
|
||||||
{occupants, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{subject, Val} -> [encode_subject(Val, Translate)];
|
|
||||||
{subject, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{subjectmod, Val} ->
|
|
||||||
[encode_subjectmod(Val, Translate)];
|
|
||||||
{subjectmod, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/muc#roominfo">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"muc#maxhistoryfetch">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_int(Value, 0, infinity) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{maxhistoryfetch, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#maxhistoryfetch">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#maxhistoryfetch">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#maxhistoryfetch">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#maxhistoryfetch">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#maxhistoryfetch">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#maxhistoryfetch">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_contactjid">>,
|
|
||||||
values = Values}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try [dec_jid(Value) || Value <- Values] of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{contactjid, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_contactjid">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_contactjid">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_description">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{description, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_description">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_description">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_description">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"muc#roominfo_description">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_description">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_description">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_lang">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{lang, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_lang">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_lang">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_lang">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#roominfo_lang">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_lang">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_lang">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{ldapgroup, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_ldapgroup">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_ldapgroup">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"muc#roominfo_ldapgroup">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_ldapgroup">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_ldapgroup">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_logs">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{logs, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_logs">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_logs">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_logs">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#roominfo_logs">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_logs">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_logs">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_occupants">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_int(Value, 0, infinity) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{occupants, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_occupants">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_occupants">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_occupants">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"muc#roominfo_occupants">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_occupants">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_occupants">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_subject">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{subject, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_subject">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_subject">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_subject">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"muc#roominfo_subject">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"muc#roominfo_subject">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_subject">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_subjectmod">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{subjectmod, Result} | Acc],
|
|
||||||
lists:delete(<<"muc#roominfo_subjectmod">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"muc#roominfo_subjectmod">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_subjectmod">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"muc#roominfo_subjectmod">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"muc#roominfo_subjectmod">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"muc#roominfo_subjectmod">>,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/muc#roominfo">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_maxhistoryfetch(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_int(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#maxhistoryfetch">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Maximum Number of History Messages Returned "
|
|
||||||
"by Room">>)}.
|
|
||||||
|
|
||||||
encode_contactjid(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
[] -> [];
|
|
||||||
Value -> [enc_jid(V) || V <- Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_contactjid">>,
|
|
||||||
values = Values, required = false, type = 'jid-multi',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Contact Addresses (normally, room owner "
|
|
||||||
"or owners)">>)}.
|
|
||||||
|
|
||||||
encode_description(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_description">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Room description">>)}.
|
|
||||||
|
|
||||||
encode_lang(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_lang">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Natural Language for Room Discussions">>)}.
|
|
||||||
|
|
||||||
encode_ldapgroup(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_ldapgroup">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"An associated LDAP group that defines "
|
|
||||||
"room membership; this should be an LDAP "
|
|
||||||
"Distinguished Name according to an implementa"
|
|
||||||
"tion-specific or deployment-specific "
|
|
||||||
"definition of a group.">>)}.
|
|
||||||
|
|
||||||
encode_logs(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_logs">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"URL for Archived Discussion Logs">>)}.
|
|
||||||
|
|
||||||
encode_occupants(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_int(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_occupants">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Number of occupants">>)}.
|
|
||||||
|
|
||||||
encode_subject(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_subject">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Current Discussion Topic">>)}.
|
|
||||||
|
|
||||||
encode_subjectmod(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"muc#roominfo_subjectmod">>,
|
|
||||||
values = Values, required = false, type = boolean,
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"The room subject can be modified by "
|
|
||||||
"participants">>)}.
|
|
@ -1,130 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_get_pending.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-module(pubsub_get_pending).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("pubsub_get_pending.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, [<<"pubsub#node">>]);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>]} ->
|
|
||||||
decode(Fs, Acc, [<<"pubsub#node">>]);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{node, Val} -> [encode_node(Val, default, Translate)];
|
|
||||||
{node, Val, Opts} ->
|
|
||||||
[encode_node(Val, Opts, Translate)];
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"pubsub#node">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{node, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#node">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#node">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#node">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#node">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#node">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#node">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_node(Value, Options, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = if Options == default -> [];
|
|
||||||
true ->
|
|
||||||
[#xdata_option{label = Translate(L), value = V}
|
|
||||||
|| {L, V} <- Options]
|
|
||||||
end,
|
|
||||||
#xdata_field{var = <<"pubsub#node">>, values = Values,
|
|
||||||
required = false, type = 'list-single', options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"The NodeID of the relevant node">>)}.
|
|
File diff suppressed because it is too large
Load Diff
@ -1,157 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_publish_options.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#publish-options
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-module(pubsub_publish_options).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("pubsub_publish_options.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_enum(Val, Enums) ->
|
|
||||||
AtomVal = erlang:binary_to_existing_atom(Val, utf8),
|
|
||||||
case lists:member(AtomVal, Enums) of
|
|
||||||
true -> AtomVal
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8).
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, []);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>]} ->
|
|
||||||
decode(Fs, Acc, []);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{access_model, Val} ->
|
|
||||||
[encode_access_model(Val, default, Translate)];
|
|
||||||
{access_model, Val, Opts} ->
|
|
||||||
[encode_access_model(Val, Opts, Translate)];
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"pubsub#access_model">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_enum(Value,
|
|
||||||
[authorize, open, presence, roster, whitelist])
|
|
||||||
of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{access_model, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#access_model">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#access_model">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#access_model">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#access_model">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#access_model">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#access_model">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#publish-opt"
|
|
||||||
"ions">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_access_model(Value, Options, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_enum(Value)]
|
|
||||||
end,
|
|
||||||
Opts = if Options == default ->
|
|
||||||
[#xdata_option{label =
|
|
||||||
Translate(<<"Access model of authorize">>),
|
|
||||||
value = <<"authorize">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Access model of open">>),
|
|
||||||
value = <<"open">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Access model of presence">>),
|
|
||||||
value = <<"presence">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Access model of roster">>),
|
|
||||||
value = <<"roster">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Access model of whitelist">>),
|
|
||||||
value = <<"whitelist">>}];
|
|
||||||
true ->
|
|
||||||
[#xdata_option{label = Translate(L),
|
|
||||||
value = enc_enum(V)}
|
|
||||||
|| {L, V} <- Options]
|
|
||||||
end,
|
|
||||||
#xdata_field{var = <<"pubsub#access_model">>,
|
|
||||||
values = Values, required = false, type = 'list-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Specify the access model">>)}.
|
|
@ -1,279 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_subscribe_authorization.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#subscribe_authorization
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-module(pubsub_subscribe_authorization).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("pubsub_subscribe_authorization.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_bool(<<"1">>) -> true;
|
|
||||||
dec_bool(<<"0">>) -> false;
|
|
||||||
dec_bool(<<"true">>) -> true;
|
|
||||||
dec_bool(<<"false">>) -> false.
|
|
||||||
|
|
||||||
enc_bool(true) -> <<"1">>;
|
|
||||||
enc_bool(false) -> <<"0">>.
|
|
||||||
|
|
||||||
enc_jid(J) -> jid:to_string(J).
|
|
||||||
|
|
||||||
dec_jid(Val) ->
|
|
||||||
case jid:from_string(Val) of
|
|
||||||
error -> erlang:error(badarg);
|
|
||||||
J -> J
|
|
||||||
end.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false ->
|
|
||||||
decode(Fs, Acc,
|
|
||||||
[<<"pubsub#allow">>, <<"pubsub#node">>,
|
|
||||||
<<"pubsub#subscriber_jid">>]);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>]} ->
|
|
||||||
decode(Fs, Acc,
|
|
||||||
[<<"pubsub#allow">>, <<"pubsub#node">>,
|
|
||||||
<<"pubsub#subscriber_jid">>]);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{allow, Val} -> [encode_allow(Val, Translate)];
|
|
||||||
{allow, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{node, Val} -> [encode_node(Val, Translate)];
|
|
||||||
{node, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{subscriber_jid, Val} ->
|
|
||||||
[encode_subscriber_jid(Val, Translate)];
|
|
||||||
{subscriber_jid, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{subid, Val} -> [encode_subid(Val, Translate)];
|
|
||||||
{subid, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"pubsub#allow">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{allow, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#allow">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#allow">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#allow">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#allow">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#allow">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#allow">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#node">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{node, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#node">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#node">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#node">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#node">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#node">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#node">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#subscriber_jid">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_jid(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{subscriber_jid, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#subscriber_jid">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#subscriber_jid">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#subscriber_jid">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#subscriber_jid">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#subscriber_jid">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#subscriber_jid">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#subid">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{subid, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#subid">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#subid">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#subid">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#subid">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#subid">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#subid">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_a"
|
|
||||||
"uthorization">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_allow(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#allow">>, values = Values,
|
|
||||||
required = false, type = boolean, options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Allow this Jabber ID to subscribe to "
|
|
||||||
"this pubsub node?">>)}.
|
|
||||||
|
|
||||||
encode_node(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#node">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>, label = Translate(<<"Node ID">>)}.
|
|
||||||
|
|
||||||
encode_subscriber_jid(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_jid(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#subscriber_jid">>,
|
|
||||||
values = Values, required = false, type = 'jid-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label = Translate(<<"Subscriber Address">>)}.
|
|
||||||
|
|
||||||
encode_subid(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#subid">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"The subscription identifier associated "
|
|
||||||
"with the subscription request">>)}.
|
|
@ -1,508 +0,0 @@
|
|||||||
%% Created automatically by xdata generator (xdata_codec.erl)
|
|
||||||
%% Source: pubsub_subscribe_options.xdata
|
|
||||||
%% Form type: http://jabber.org/protocol/pubsub#subscribe_options
|
|
||||||
%% Document: XEP-0060
|
|
||||||
|
|
||||||
-module(pubsub_subscribe_options).
|
|
||||||
|
|
||||||
-export([decode/1, decode/2, encode/1, encode/2,
|
|
||||||
format_error/1]).
|
|
||||||
|
|
||||||
-include("xmpp_codec.hrl").
|
|
||||||
|
|
||||||
-include("pubsub_subscribe_options.hrl").
|
|
||||||
|
|
||||||
-export_type([property/0, result/0, form/0]).
|
|
||||||
|
|
||||||
dec_enum(Val, Enums) ->
|
|
||||||
AtomVal = erlang:binary_to_existing_atom(Val, utf8),
|
|
||||||
case lists:member(AtomVal, Enums) of
|
|
||||||
true -> AtomVal
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_enum(Atom) -> erlang:atom_to_binary(Atom, utf8).
|
|
||||||
|
|
||||||
dec_bool(<<"1">>) -> true;
|
|
||||||
dec_bool(<<"0">>) -> false;
|
|
||||||
dec_bool(<<"true">>) -> true;
|
|
||||||
dec_bool(<<"false">>) -> false.
|
|
||||||
|
|
||||||
enc_bool(true) -> <<"1">>;
|
|
||||||
enc_bool(false) -> <<"0">>.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary,
|
|
||||||
"' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '",
|
|
||||||
Type/binary, "'">>.
|
|
||||||
|
|
||||||
decode(Fs) -> decode(Fs, []).
|
|
||||||
|
|
||||||
decode(Fs, Acc) ->
|
|
||||||
case lists:keyfind(<<"FORM_TYPE">>, #xdata_field.var,
|
|
||||||
Fs)
|
|
||||||
of
|
|
||||||
false -> decode(Fs, Acc, []);
|
|
||||||
#xdata_field{values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>]} ->
|
|
||||||
decode(Fs, Acc, []);
|
|
||||||
_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{form_type_mismatch,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end.
|
|
||||||
|
|
||||||
encode(Cfg) -> encode(Cfg, fun (Text) -> Text end).
|
|
||||||
|
|
||||||
encode(List, Translate) when is_list(List) ->
|
|
||||||
Fs = [case Opt of
|
|
||||||
{deliver, Val} -> [encode_deliver(Val, Translate)];
|
|
||||||
{deliver, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{digest, Val} -> [encode_digest(Val, Translate)];
|
|
||||||
{digest, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{digest_frequency, Val} ->
|
|
||||||
[encode_digest_frequency(Val, Translate)];
|
|
||||||
{digest_frequency, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{expire, Val} -> [encode_expire(Val, Translate)];
|
|
||||||
{expire, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{include_body, Val} ->
|
|
||||||
[encode_include_body(Val, Translate)];
|
|
||||||
{include_body, _, _} -> erlang:error({badarg, Opt});
|
|
||||||
{'show-values', Val} ->
|
|
||||||
['encode_show-values'(Val, default, Translate)];
|
|
||||||
{'show-values', Val, Opts} ->
|
|
||||||
['encode_show-values'(Val, Opts, Translate)];
|
|
||||||
{subscription_type, Val} ->
|
|
||||||
[encode_subscription_type(Val, default, Translate)];
|
|
||||||
{subscription_type, Val, Opts} ->
|
|
||||||
[encode_subscription_type(Val, Opts, Translate)];
|
|
||||||
{subscription_depth, Val} ->
|
|
||||||
[encode_subscription_depth(Val, default, Translate)];
|
|
||||||
{subscription_depth, Val, Opts} ->
|
|
||||||
[encode_subscription_depth(Val, Opts, Translate)];
|
|
||||||
#xdata_field{} -> [Opt];
|
|
||||||
_ -> []
|
|
||||||
end
|
|
||||||
|| Opt <- List],
|
|
||||||
FormType = #xdata_field{var = <<"FORM_TYPE">>,
|
|
||||||
type = hidden,
|
|
||||||
values =
|
|
||||||
[<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>]},
|
|
||||||
[FormType | lists:flatten(Fs)].
|
|
||||||
|
|
||||||
decode([#xdata_field{var = <<"pubsub#deliver">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{deliver, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#deliver">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#deliver">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#deliver">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#deliver">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#deliver">>} | _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#deliver">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#digest">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{digest, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#digest">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#digest">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#digest">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#digest">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#digest">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#digest">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#digest_frequency">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{digest_frequency, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#digest_frequency">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#digest_frequency">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#digest_frequency">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"pubsub#digest_frequency">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#digest_frequency">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#digest_frequency">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#expire">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try Value of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{expire, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#expire">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#expire">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#expire">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#expire">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#expire">>} | _], _,
|
|
||||||
_) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#expire">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#include_body">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_bool(Value) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{include_body, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#include_body">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#include_body">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var = <<"pubsub#include_body">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var = <<"pubsub#include_body">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var = <<"pubsub#include_body">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#include_body">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var = <<"pubsub#show-values">>,
|
|
||||||
values = Values}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try [dec_enum(Value, [away, chat, dnd, online, xa])
|
|
||||||
|| Value <- Values]
|
|
||||||
of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{'show-values', Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#show-values">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#show-values">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_type">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_enum(Value, [items, nodes]) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{subscription_type, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#subscription_type">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#subscription_type">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_type">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_type">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_type">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#subscription_type">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_depth">>,
|
|
||||||
values = [Value]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
try dec_enum(Value, ['1', all]) of
|
|
||||||
Result ->
|
|
||||||
decode(Fs, [{subscription_depth, Result} | Acc],
|
|
||||||
lists:delete(<<"pubsub#subscription_depth">>, Required))
|
|
||||||
catch
|
|
||||||
_:_ ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{bad_var_value, <<"pubsub#subscription_depth">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}})
|
|
||||||
end;
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_depth">>,
|
|
||||||
values = []} =
|
|
||||||
F
|
|
||||||
| Fs],
|
|
||||||
Acc, Required) ->
|
|
||||||
decode([F#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_depth">>,
|
|
||||||
values = [<<>>]}
|
|
||||||
| Fs],
|
|
||||||
Acc, Required);
|
|
||||||
decode([#xdata_field{var =
|
|
||||||
<<"pubsub#subscription_depth">>}
|
|
||||||
| _],
|
|
||||||
_, _) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{too_many_values, <<"pubsub#subscription_depth">>,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([#xdata_field{var = Var} | Fs], Acc, Required) ->
|
|
||||||
if Var /= <<"FORM_TYPE">> ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{unknown_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
true -> decode(Fs, Acc, Required)
|
|
||||||
end;
|
|
||||||
decode([], _, [Var | _]) ->
|
|
||||||
erlang:error({?MODULE,
|
|
||||||
{missing_required_var, Var,
|
|
||||||
<<"http://jabber.org/protocol/pubsub#subscribe_o"
|
|
||||||
"ptions">>}});
|
|
||||||
decode([], Acc, []) -> Acc.
|
|
||||||
|
|
||||||
encode_deliver(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#deliver">>,
|
|
||||||
values = Values, required = false, type = boolean,
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Whether an entity wants to receive or "
|
|
||||||
"disable notifications">>)}.
|
|
||||||
|
|
||||||
encode_digest(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#digest">>, values = Values,
|
|
||||||
required = false, type = boolean, options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Whether an entity wants to receive digests "
|
|
||||||
"(aggregations) of notifications or all "
|
|
||||||
"notifications individually">>)}.
|
|
||||||
|
|
||||||
encode_digest_frequency(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#digest_frequency">>,
|
|
||||||
values = Values, required = false, type = 'text-single',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"The minimum number of milliseconds between "
|
|
||||||
"sending any two notification digests">>)}.
|
|
||||||
|
|
||||||
encode_expire(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
<<>> -> [];
|
|
||||||
Value -> [Value]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#expire">>, values = Values,
|
|
||||||
required = false, type = 'text-single', options = Opts,
|
|
||||||
desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"The DateTime at which a leased subscription "
|
|
||||||
"will end or has ended">>)}.
|
|
||||||
|
|
||||||
encode_include_body(Value, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_bool(Value)]
|
|
||||||
end,
|
|
||||||
Opts = [],
|
|
||||||
#xdata_field{var = <<"pubsub#include_body">>,
|
|
||||||
values = Values, required = false, type = boolean,
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"Whether an entity wants to receive an "
|
|
||||||
"XMPP message body in addition to the "
|
|
||||||
"payload format">>)}.
|
|
||||||
|
|
||||||
'encode_show-values'(Value, Options, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
[] -> [];
|
|
||||||
Value -> [enc_enum(V) || V <- Value]
|
|
||||||
end,
|
|
||||||
Opts = if Options == default ->
|
|
||||||
[#xdata_option{label =
|
|
||||||
Translate(<<"XMPP Show Value of Away">>),
|
|
||||||
value = <<"away">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"XMPP Show Value of Chat">>),
|
|
||||||
value = <<"chat">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"XMPP Show Value of DND (Do Not Disturb)">>),
|
|
||||||
value = <<"dnd">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Mere Availability in XMPP (No Show Value)">>),
|
|
||||||
value = <<"online">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"XMPP Show Value of XA (Extended Away)">>),
|
|
||||||
value = <<"xa">>}];
|
|
||||||
true ->
|
|
||||||
[#xdata_option{label = Translate(L),
|
|
||||||
value = enc_enum(V)}
|
|
||||||
|| {L, V} <- Options]
|
|
||||||
end,
|
|
||||||
#xdata_field{var = <<"pubsub#show-values">>,
|
|
||||||
values = Values, required = false, type = 'list-multi',
|
|
||||||
options = Opts, desc = <<>>,
|
|
||||||
label =
|
|
||||||
Translate(<<"The presence states for which an entity "
|
|
||||||
"wants to receive notifications">>)}.
|
|
||||||
|
|
||||||
encode_subscription_type(Value, Options, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_enum(Value)]
|
|
||||||
end,
|
|
||||||
Opts = if Options == default ->
|
|
||||||
[#xdata_option{label =
|
|
||||||
Translate(<<"Receive notification of new items only">>),
|
|
||||||
value = <<"items">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Receive notification of new nodes only">>),
|
|
||||||
value = <<"nodes">>}];
|
|
||||||
true ->
|
|
||||||
[#xdata_option{label = Translate(L),
|
|
||||||
value = enc_enum(V)}
|
|
||||||
|| {L, V} <- Options]
|
|
||||||
end,
|
|
||||||
#xdata_field{var = <<"pubsub#subscription_type">>,
|
|
||||||
values = Values, required = false, type = 'list-single',
|
|
||||||
options = Opts, desc = <<>>, label = <<>>}.
|
|
||||||
|
|
||||||
encode_subscription_depth(Value, Options, Translate) ->
|
|
||||||
Values = case Value of
|
|
||||||
undefined -> [];
|
|
||||||
Value -> [enc_enum(Value)]
|
|
||||||
end,
|
|
||||||
Opts = if Options == default ->
|
|
||||||
[#xdata_option{label =
|
|
||||||
Translate(<<"Receive notification from direct child "
|
|
||||||
"nodes only">>),
|
|
||||||
value = <<"1">>},
|
|
||||||
#xdata_option{label =
|
|
||||||
Translate(<<"Receive notification from all descendent "
|
|
||||||
"nodes">>),
|
|
||||||
value = <<"all">>}];
|
|
||||||
true ->
|
|
||||||
[#xdata_option{label = Translate(L),
|
|
||||||
value = enc_enum(V)}
|
|
||||||
|| {L, V} <- Options]
|
|
||||||
end,
|
|
||||||
#xdata_field{var = <<"pubsub#subscription_depth">>,
|
|
||||||
values = Values, required = false, type = 'list-single',
|
|
||||||
options = Opts, desc = <<>>, label = <<>>}.
|
|
@ -1,648 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%% @copyright (C) 2016, Evgeny Khramtsov
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 27 Sep 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(xdata_codec).
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([compile/1, compile/2]).
|
|
||||||
-export([dec_int/1, dec_int/3, dec_enum/2, dec_bool/1, not_empty/1,
|
|
||||||
dec_enum_int/2, dec_enum_int/4, enc_int/1, enc_enum/1,
|
|
||||||
enc_bool/1, enc_enum_int/1, format_error/1, enc_jid/1, dec_jid/1]).
|
|
||||||
-include("xmpp.hrl").
|
|
||||||
|
|
||||||
-record(state, {mod_name :: atom(),
|
|
||||||
file_name :: string(),
|
|
||||||
erl = "" :: string(),
|
|
||||||
hrl = "" :: string(),
|
|
||||||
dir = "" :: string(),
|
|
||||||
ns = <<>> :: binary(),
|
|
||||||
doc = <<>> :: binary(),
|
|
||||||
erl_dir = "" :: string(),
|
|
||||||
hrl_dir = "" :: string(),
|
|
||||||
prefix = [] :: [binary()],
|
|
||||||
dec_mfas = [] :: [{binary(), mfa()}],
|
|
||||||
enc_mfas = [] :: [{binary(), mfa()}],
|
|
||||||
specs = [] :: [{binary(), string()}],
|
|
||||||
required = [] :: [{binary(), boolean()} | binary()],
|
|
||||||
defaults = [] :: [{binary(), any()}]}).
|
|
||||||
|
|
||||||
-define(is_multi_type(T),
|
|
||||||
((T == 'list-multi') or (T == 'jid-multi') or (T == 'text-multi'))).
|
|
||||||
|
|
||||||
-define(is_list_type(T),
|
|
||||||
((T == 'list-single') or (T == 'list-multi'))).
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% API
|
|
||||||
%%%===================================================================
|
|
||||||
compile(Path) ->
|
|
||||||
compile(Path, []).
|
|
||||||
|
|
||||||
compile(Path, Opts) ->
|
|
||||||
case filelib:is_dir(Path) of
|
|
||||||
true ->
|
|
||||||
filelib:fold_files(
|
|
||||||
Path, ".*.xdata", false,
|
|
||||||
fun(File, ok) ->
|
|
||||||
compile_file(File, Opts);
|
|
||||||
(_, Err) ->
|
|
||||||
Err
|
|
||||||
end, ok);
|
|
||||||
false ->
|
|
||||||
compile_file(Path, Opts)
|
|
||||||
end.
|
|
||||||
|
|
||||||
compile_file(Path, Opts) ->
|
|
||||||
try
|
|
||||||
ok = application:ensure_started(fast_xml),
|
|
||||||
DirName = filename:dirname(Path),
|
|
||||||
FileName = filename:basename(Path),
|
|
||||||
RootName = filename:rootname(FileName),
|
|
||||||
ConfigPath = filename:join(DirName, RootName) ++ ".cfg",
|
|
||||||
ModName = list_to_atom(RootName),
|
|
||||||
{ok, Data} = file:read_file(Path),
|
|
||||||
Config = case file:consult(ConfigPath) of
|
|
||||||
{ok, Terms} -> lists:flatten(Terms);
|
|
||||||
{error, enoent} -> []
|
|
||||||
end,
|
|
||||||
State = #state{mod_name = ModName,
|
|
||||||
file_name = FileName,
|
|
||||||
erl = filename:rootname(FileName) ++ ".erl",
|
|
||||||
hrl = filename:rootname(FileName) ++ ".hrl",
|
|
||||||
dir = DirName,
|
|
||||||
prefix = proplists:get_all_values(prefix, Config),
|
|
||||||
erl_dir = proplists:get_value(erl_dir, Opts, DirName),
|
|
||||||
hrl_dir = proplists:get_value(hrl_dir, Opts, DirName),
|
|
||||||
dec_mfas = proplists:get_value(decode, Config, []),
|
|
||||||
enc_mfas = proplists:get_value(encode, Config, []),
|
|
||||||
specs = proplists:get_value(specs, Config, []),
|
|
||||||
required = proplists:get_value(required, Config, []),
|
|
||||||
defaults = proplists:get_value(defaults, Config, [])},
|
|
||||||
#xmlel{} = El = fxml_stream:parse_element(Data),
|
|
||||||
ok = compile_element(normalize(El), State),
|
|
||||||
io:format("Compiled ~s~n", [Path])
|
|
||||||
catch _:{badmatch, Err} ->
|
|
||||||
io:format(standard_error, "Failed to compile ~s: ~p~n",
|
|
||||||
[Path, Err]),
|
|
||||||
Err
|
|
||||||
end.
|
|
||||||
|
|
||||||
emit(Format) ->
|
|
||||||
emit(Format, []).
|
|
||||||
|
|
||||||
emit(Format, Args) ->
|
|
||||||
put(outbuf, get(outbuf) ++ io_lib:format(Format, Args)).
|
|
||||||
|
|
||||||
dec_int(Val) ->
|
|
||||||
dec_int(Val, infinity, infinity).
|
|
||||||
|
|
||||||
dec_int(Val, Min, Max) ->
|
|
||||||
case list_to_integer(binary_to_list(Val)) of
|
|
||||||
Int when Int =< Max, Min == infinity ->
|
|
||||||
Int;
|
|
||||||
Int when Int =< Max, Int >= Min ->
|
|
||||||
Int
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_int(Int) ->
|
|
||||||
integer_to_binary(Int).
|
|
||||||
|
|
||||||
dec_enum(Val, Enums) ->
|
|
||||||
AtomVal = erlang:binary_to_existing_atom(Val, utf8),
|
|
||||||
case lists:member(AtomVal, Enums) of
|
|
||||||
true ->
|
|
||||||
AtomVal
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_enum(Atom) ->
|
|
||||||
erlang:atom_to_binary(Atom, utf8).
|
|
||||||
|
|
||||||
dec_enum_int(Val, Enums) ->
|
|
||||||
try dec_int(Val)
|
|
||||||
catch _:_ -> dec_enum(Val, Enums)
|
|
||||||
end.
|
|
||||||
|
|
||||||
dec_enum_int(Val, Enums, Min, Max) ->
|
|
||||||
try dec_int(Val, Min, Max)
|
|
||||||
catch _:_ -> dec_enum(Val, Enums)
|
|
||||||
end.
|
|
||||||
|
|
||||||
enc_enum_int(Int) when is_integer(Int) ->
|
|
||||||
enc_int(Int);
|
|
||||||
enc_enum_int(Atom) ->
|
|
||||||
enc_enum(Atom).
|
|
||||||
|
|
||||||
dec_bool(<<"1">>) -> true;
|
|
||||||
dec_bool(<<"0">>) -> false;
|
|
||||||
dec_bool(<<"true">>) -> true;
|
|
||||||
dec_bool(<<"false">>) -> false.
|
|
||||||
|
|
||||||
enc_bool(true) -> <<"1">>;
|
|
||||||
enc_bool(false) -> <<"0">>.
|
|
||||||
|
|
||||||
enc_jid(J) -> jid:to_string(J).
|
|
||||||
|
|
||||||
dec_jid(Val) ->
|
|
||||||
case jid:from_string(Val) of
|
|
||||||
error -> erlang:error(badarg);
|
|
||||||
J -> J
|
|
||||||
end.
|
|
||||||
|
|
||||||
not_empty(<<_, _/binary>> = Val) ->
|
|
||||||
Val.
|
|
||||||
|
|
||||||
format_error({form_type_mismatch, Type}) ->
|
|
||||||
<<"FORM_TYPE doesn't match '", Type/binary, "'">>;
|
|
||||||
format_error({bad_var_value, Var, Type}) ->
|
|
||||||
<<"Bad value of field '", Var/binary, "' of type '", Type/binary, "'">>;
|
|
||||||
format_error({missing_value, Var, Type}) ->
|
|
||||||
<<"Missing value of field '", Var/binary, "' of type '", Type/binary, "'">>;
|
|
||||||
format_error({too_many_values, Var, Type}) ->
|
|
||||||
<<"Too many values for field '", Var/binary, "' of type '", Type/binary, "'">>;
|
|
||||||
format_error({unknown_var, Var, Type}) ->
|
|
||||||
<<"Unknown field '", Var/binary, "' of type '", Type/binary, "'">>;
|
|
||||||
format_error({missing_required_var, Var, Type}) ->
|
|
||||||
<<"Missing required field '", Var/binary, "' of type '", Type/binary, "'">>.
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Internal functions
|
|
||||||
%%%===================================================================
|
|
||||||
compile_element(#xmlel{name = <<"form_type">>, children = Els} = Form,
|
|
||||||
#state{erl = OutErl, erl_dir = ErlDir,
|
|
||||||
hrl = OutHrl, hrl_dir = HrlDir} = State0) ->
|
|
||||||
try
|
|
||||||
Name = fxml:get_subtag_cdata(Form, <<"name">>),
|
|
||||||
Doc = fxml:get_subtag_cdata(Form, <<"doc">>),
|
|
||||||
X = #xmlel{name = <<"x">>,
|
|
||||||
attrs = [{<<"type">>, <<"form">>},
|
|
||||||
{<<"xmlns">>, <<"jabber:x:data">>}],
|
|
||||||
children = Els},
|
|
||||||
State = State0#state{ns = Name, doc = Doc},
|
|
||||||
#xdata{fields = Fs} = xmpp_codec:decode(X),
|
|
||||||
put(outbuf, []),
|
|
||||||
mk_header(State),
|
|
||||||
mk_aux_funs(),
|
|
||||||
mk_top_decoder(Fs, State),
|
|
||||||
mk_top_encoder(Fs, State),
|
|
||||||
mk_decoder(Fs, State),
|
|
||||||
mk_encoders(Fs, State),
|
|
||||||
ErlData = get(outbuf),
|
|
||||||
ok = file:write_file(filename:join(ErlDir, OutErl), ErlData),
|
|
||||||
ok = erl_tidy:file(filename:join(ErlDir, OutErl), [{backups, false}]),
|
|
||||||
put(outbuf, []),
|
|
||||||
mk_type_definitions(Fs, State),
|
|
||||||
HrlData = get(outbuf),
|
|
||||||
ok = file:write_file(filename:join(HrlDir, OutHrl), HrlData)
|
|
||||||
catch _:{badmatch, Err} ->
|
|
||||||
Err
|
|
||||||
end.
|
|
||||||
|
|
||||||
mk_aux_funs() ->
|
|
||||||
case get_abstract_code_from_myself() of
|
|
||||||
{ok, AbsCode} ->
|
|
||||||
AST = lists:filter(
|
|
||||||
fun(T) ->
|
|
||||||
case catch erl_syntax_lib:analyze_function(T) of
|
|
||||||
{format_error, 1} -> true;
|
|
||||||
{dec_int, 3} -> true;
|
|
||||||
{dec_int, 1} -> true;
|
|
||||||
{dec_enum, 2} -> true;
|
|
||||||
{dec_enum_int, 2} -> true;
|
|
||||||
{dec_enum_int, 4} -> true;
|
|
||||||
{enc_int, 1} -> true;
|
|
||||||
{enc_enum, 1} -> true;
|
|
||||||
{enc_enum_int, 1} -> true;
|
|
||||||
{not_empty, 1} -> true;
|
|
||||||
{dec_bool, 1} -> true;
|
|
||||||
{enc_bool, 1} -> true;
|
|
||||||
{enc_jid, 1} -> true;
|
|
||||||
{dec_jid, 1} -> true;
|
|
||||||
_ -> false
|
|
||||||
end
|
|
||||||
end, AbsCode),
|
|
||||||
emit(erl_prettypr:format(erl_syntax:form_list(AST)) ++ io_lib:nl());
|
|
||||||
error ->
|
|
||||||
erlang:error({no_abstract_code_found, ?MODULE})
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_abstract_code_from_myself() ->
|
|
||||||
{file, File} = code:is_loaded(?MODULE),
|
|
||||||
case beam_lib:chunks(File, [abstract_code]) of
|
|
||||||
{ok, {_, List}} ->
|
|
||||||
case lists:keyfind(abstract_code, 1, List) of
|
|
||||||
{abstract_code, {raw_abstract_v1, Abstr}} ->
|
|
||||||
{ok, Abstr};
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
error
|
|
||||||
end.
|
|
||||||
|
|
||||||
mk_comment_header(#state{file_name = Source, ns = NS, doc = Doc}) ->
|
|
||||||
emit("%% Created automatically by xdata generator (xdata_codec.erl)~n"
|
|
||||||
"%% Source: ~s~n"
|
|
||||||
"%% Form type: ~s~n", [Source, NS]),
|
|
||||||
if Doc /= <<>> -> emit("%% Document: ~s~n~n", [Doc]);
|
|
||||||
true -> emit("~n")
|
|
||||||
end.
|
|
||||||
|
|
||||||
mk_header(#state{mod_name = Mod, hrl = Include} = State) ->
|
|
||||||
mk_comment_header(State),
|
|
||||||
emit("~n-module(~s).~n", [Mod]),
|
|
||||||
emit("-export([decode/1, decode/2, encode/1, encode/2, format_error/1]).~n"),
|
|
||||||
emit("-include(\"xmpp_codec.hrl\").~n"),
|
|
||||||
emit("-include(\"~s\").~n", [Include]),
|
|
||||||
emit("-export_type([property/0, result/0, form/0]).~n").
|
|
||||||
|
|
||||||
mk_type_definitions(Fs, State) ->
|
|
||||||
mk_comment_header(State),
|
|
||||||
lists:foreach(
|
|
||||||
fun(#xdata_field{var = Var} = F) ->
|
|
||||||
Spec = get_typespec(F, State),
|
|
||||||
case is_complex_type(Spec) of
|
|
||||||
true ->
|
|
||||||
emit("-type '~s'() :: ~s.~n",
|
|
||||||
[var_to_rec_field(Var, State), Spec]);
|
|
||||||
false ->
|
|
||||||
ok
|
|
||||||
end
|
|
||||||
end, Fs),
|
|
||||||
emit("~n-type property() :: "),
|
|
||||||
Fields = lists:map(
|
|
||||||
fun(#xdata_field{var = Var} = F) ->
|
|
||||||
RecField = var_to_rec_field(Var, State),
|
|
||||||
[io_lib:format("{'~s', ~s}",
|
|
||||||
[RecField, mk_typespec(F, State)])]
|
|
||||||
end, Fs),
|
|
||||||
emit(string:join(Fields, " |~n ") ++ ".~n"),
|
|
||||||
emit("-type result() :: [property()].~n~n"),
|
|
||||||
VarsWithSpec = lists:flatmap(
|
|
||||||
fun(#xdata_field{type = T, var = Var} = F)
|
|
||||||
when ?is_list_type(T) ->
|
|
||||||
RecName = var_to_rec_field(Var, State),
|
|
||||||
Spec0 = get_typespec(F, State),
|
|
||||||
Spec = case is_complex_type(Spec0) of
|
|
||||||
true ->
|
|
||||||
io_lib:format("'~s'()", [RecName]);
|
|
||||||
false ->
|
|
||||||
Spec0
|
|
||||||
end,
|
|
||||||
[{RecName, mk_typespec(F, State), Spec}];
|
|
||||||
(_) ->
|
|
||||||
[]
|
|
||||||
end, Fs),
|
|
||||||
case VarsWithSpec of
|
|
||||||
[] ->
|
|
||||||
emit("-type form() :: [property() | xdata_field()].~n");
|
|
||||||
_ ->
|
|
||||||
emit("-type options(T) :: [{binary(), T}].~n"),
|
|
||||||
emit("-type property_with_options() ::~n "),
|
|
||||||
Options = [io_lib:format("{'~s', ~s, options(~s)}",
|
|
||||||
[Var, Spec1, Spec2])
|
|
||||||
|| {Var, Spec1, Spec2} <- VarsWithSpec],
|
|
||||||
emit(string:join(Options, " |~n ") ++ ".~n"),
|
|
||||||
emit("-type form() :: [property() | property_with_options() | xdata_field()].~n")
|
|
||||||
end.
|
|
||||||
|
|
||||||
mk_top_decoder(Fs, State) ->
|
|
||||||
Required = [Var || #xdata_field{var = Var} <- Fs, is_required(Var, State)],
|
|
||||||
emit("decode(Fs) -> decode(Fs, []).~n"),
|
|
||||||
emit("decode(Fs, Acc) ->"
|
|
||||||
" case lists:keyfind(<<\"FORM_TYPE\">>, #xdata_field.var, Fs) of"
|
|
||||||
" false ->"
|
|
||||||
" decode(Fs, Acc, ~p);"
|
|
||||||
" #xdata_field{values = [~p]} ->"
|
|
||||||
" decode(Fs, Acc, ~p);"
|
|
||||||
" _ ->"
|
|
||||||
" erlang:error({?MODULE, {form_type_mismatch, ~p}})~n"
|
|
||||||
" end.~n",
|
|
||||||
[Required, State#state.ns, Required, State#state.ns]).
|
|
||||||
|
|
||||||
mk_top_encoder(Fs, State) ->
|
|
||||||
Clauses = string:join(
|
|
||||||
lists:map(
|
|
||||||
fun(#xdata_field{var = Var, type = T}) when ?is_list_type(T) ->
|
|
||||||
Field = var_to_rec_field(Var, State),
|
|
||||||
io_lib:format(
|
|
||||||
"{'~s', Val} -> ['encode_~s'(Val, default, Translate)];"
|
|
||||||
"{'~s', Val, Opts} -> ['encode_~s'(Val, Opts, Translate)]",
|
|
||||||
[Field, Field, Field, Field]);
|
|
||||||
(#xdata_field{var = Var}) ->
|
|
||||||
Field = var_to_rec_field(Var, State),
|
|
||||||
io_lib:format(
|
|
||||||
"{'~s', Val} -> ['encode_~s'(Val, Translate)];"
|
|
||||||
"{'~s', _, _} -> erlang:error({badarg, Opt})",
|
|
||||||
[Field, Field, Field])
|
|
||||||
end, Fs) ++ ["#xdata_field{} -> [Opt]; _ -> []"],
|
|
||||||
";"),
|
|
||||||
emit("encode(Cfg) -> encode(Cfg, fun(Text) -> Text end).~n"),
|
|
||||||
emit("encode(List, Translate) when is_list(List) ->"
|
|
||||||
" Fs = [case Opt of ~s end || Opt <- List],"
|
|
||||||
" FormType = #xdata_field{var = <<\"FORM_TYPE\">>, type = hidden,"
|
|
||||||
" values = [~p]},"
|
|
||||||
" [FormType|lists:flatten(Fs)].~n",
|
|
||||||
[Clauses, State#state.ns]).
|
|
||||||
|
|
||||||
mk_decoder([#xdata_field{var = Var, type = Type} = F|Fs], State) ->
|
|
||||||
ValVar = if ?is_multi_type(Type) -> "Values";
|
|
||||||
true -> "[Value]"
|
|
||||||
end,
|
|
||||||
DecFun = if ?is_multi_type(Type) ->
|
|
||||||
["[", mk_decoding_fun(F, State), " || Value <- Values]"];
|
|
||||||
true ->
|
|
||||||
mk_decoding_fun(F, State)
|
|
||||||
end,
|
|
||||||
emit("decode([#xdata_field{var = ~p, values = ~s}|Fs], Acc, Required) ->"
|
|
||||||
" try ~s of"
|
|
||||||
" Result -> decode(Fs, [{'~s', Result}|Acc],"
|
|
||||||
" lists:delete(~p, Required))"
|
|
||||||
" catch _:_ ->"
|
|
||||||
" erlang:error({?MODULE, {bad_var_value, ~p, ~p}})"
|
|
||||||
" end;",
|
|
||||||
[Var, ValVar, DecFun, var_to_rec_field(Var, State),
|
|
||||||
Var, Var, State#state.ns]),
|
|
||||||
if not ?is_multi_type(Type) ->
|
|
||||||
emit("decode([#xdata_field{var = ~p, values = []} = F|Fs],"
|
|
||||||
" Acc, Required) ->"
|
|
||||||
" decode([F#xdata_field{var = ~p, values = [<<>>]}|Fs],"
|
|
||||||
" Acc, Required);",
|
|
||||||
[Var, Var]),
|
|
||||||
emit("decode([#xdata_field{var = ~p}|_], _, _) ->"
|
|
||||||
" erlang:error({?MODULE, {too_many_values, ~p, ~p}});",
|
|
||||||
[Var, Var, State#state.ns]);
|
|
||||||
true ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
mk_decoder(Fs, State);
|
|
||||||
mk_decoder([], State) ->
|
|
||||||
emit("decode([#xdata_field{var = Var}|Fs], Acc, Required) ->"
|
|
||||||
" if Var /= <<\"FORM_TYPE\">> ->"
|
|
||||||
" erlang:error({?MODULE, {unknown_var, Var, ~p}});"
|
|
||||||
" true ->"
|
|
||||||
" decode(Fs, Acc, Required)"
|
|
||||||
" end;",
|
|
||||||
[State#state.ns]),
|
|
||||||
emit("decode([], _, [Var|_]) ->"
|
|
||||||
" erlang:error({?MODULE, {missing_required_var, Var, ~p}});~n",
|
|
||||||
[State#state.ns]),
|
|
||||||
emit("decode([], Acc, []) -> Acc.~n").
|
|
||||||
|
|
||||||
mk_encoders(Fs, State) ->
|
|
||||||
lists:foreach(
|
|
||||||
fun(#xdata_field{var = Var, required = IsRequired, desc = Desc,
|
|
||||||
label = Label, type = Type} = F) ->
|
|
||||||
EncVals = mk_encoded_values(F, State),
|
|
||||||
EncOpts = mk_encoded_options(F, State),
|
|
||||||
FieldName = var_to_rec_field(Var, State),
|
|
||||||
DescStr = if Desc == <<>> -> "<<>>";
|
|
||||||
true -> io_lib:format("Translate(~p)", [Desc])
|
|
||||||
end,
|
|
||||||
LabelStr = if Label == <<>> -> "<<>>";
|
|
||||||
true -> io_lib:format("Translate(~p)", [Label])
|
|
||||||
end,
|
|
||||||
if ?is_list_type(Type) ->
|
|
||||||
emit("'encode_~s'(Value, Options, Translate) ->", [FieldName]);
|
|
||||||
true ->
|
|
||||||
emit("'encode_~s'(Value, Translate) ->", [FieldName])
|
|
||||||
end,
|
|
||||||
emit(" Values = ~s,"
|
|
||||||
" Opts = ~s,"
|
|
||||||
" #xdata_field{var = ~p,"
|
|
||||||
" values = Values,"
|
|
||||||
" required = ~p,"
|
|
||||||
" type = ~p,"
|
|
||||||
" options = Opts,"
|
|
||||||
" desc = ~s,"
|
|
||||||
" label = ~s}.~n",
|
|
||||||
[EncVals, EncOpts, Var, IsRequired, Type, DescStr, LabelStr])
|
|
||||||
end, Fs).
|
|
||||||
|
|
||||||
mk_encoded_values(#xdata_field{var = Var, type = Type,
|
|
||||||
options = Options}, State) ->
|
|
||||||
EncFun =
|
|
||||||
case get_enc_fun(Var, Type, Options, State) of
|
|
||||||
{M, Fun, Args} ->
|
|
||||||
Mod = if M == undefined -> "";
|
|
||||||
true -> io_lib:format("~s:", [M])
|
|
||||||
end,
|
|
||||||
FArgs = [io_lib:format(", ~p", [A]) || A <- Args],
|
|
||||||
if ?is_multi_type(Type) ->
|
|
||||||
"[" ++ io_lib:format("~s~s(V~s)", [Mod, Fun, FArgs]) ++
|
|
||||||
" || V <- Value]";
|
|
||||||
true ->
|
|
||||||
"[" ++ io_lib:format("~s~s(Value~s)", [Mod, Fun, FArgs])
|
|
||||||
++ "]"
|
|
||||||
end;
|
|
||||||
undefined ->
|
|
||||||
"[Value]"
|
|
||||||
end,
|
|
||||||
Default = case get_dec_fun(Var, Type, Options, State) of
|
|
||||||
_ when ?is_multi_type(Type) -> "[]";
|
|
||||||
undefined -> "<<>>";
|
|
||||||
_MFA -> "undefined"
|
|
||||||
end,
|
|
||||||
io_lib:format(
|
|
||||||
"case Value of"
|
|
||||||
" ~s -> [];~n"
|
|
||||||
" Value -> ~s~n"
|
|
||||||
"end",
|
|
||||||
[Default, EncFun]).
|
|
||||||
|
|
||||||
mk_encoded_options(#xdata_field{var = Var, type = Type,
|
|
||||||
options = Options}, State) ->
|
|
||||||
EncFun = case get_enc_fun(Var, Type, Options, State) of
|
|
||||||
{M, Fun, Args} ->
|
|
||||||
Mod = if M == undefined -> "";
|
|
||||||
true -> io_lib:format("~s:", [M])
|
|
||||||
end,
|
|
||||||
FArgs = [io_lib:format(", ~p", [A]) || A <- Args],
|
|
||||||
io_lib:format("~s~s(V~s)", [Mod, Fun, FArgs]);
|
|
||||||
undefined ->
|
|
||||||
"V"
|
|
||||||
end,
|
|
||||||
EncOpts = string:join(
|
|
||||||
[case L of
|
|
||||||
<<>> ->
|
|
||||||
io_lib:format("#xdata_option{value = ~p}", [V]);
|
|
||||||
_ ->
|
|
||||||
io_lib:format(
|
|
||||||
"#xdata_option{label = Translate(~p), value = ~p}",
|
|
||||||
[L, V])
|
|
||||||
end || #xdata_option{label = L, value = V} <- Options],
|
|
||||||
","),
|
|
||||||
if ?is_list_type(Type) ->
|
|
||||||
io_lib:format(
|
|
||||||
"if Options == default ->"
|
|
||||||
" [~s];"
|
|
||||||
"true ->"
|
|
||||||
" [#xdata_option{label = Translate(L), value = ~s}"
|
|
||||||
" || {L, V} <- Options]"
|
|
||||||
"end",
|
|
||||||
[EncOpts, EncFun]);
|
|
||||||
true ->
|
|
||||||
"[]"
|
|
||||||
end.
|
|
||||||
|
|
||||||
mk_decoding_fun(#xdata_field{var = Var, type = Type,
|
|
||||||
options = Options}, State) ->
|
|
||||||
case get_dec_fun(Var, Type, Options, State) of
|
|
||||||
{M, Fun, Args} ->
|
|
||||||
Mod = if M == undefined -> "";
|
|
||||||
true -> io_lib:format("~s:", [M])
|
|
||||||
end,
|
|
||||||
FArgs = [io_lib:format(", ~p", [A]) || A <- Args],
|
|
||||||
io_lib:format("~s~s(Value~s)", [Mod, Fun, FArgs]);
|
|
||||||
undefined ->
|
|
||||||
"Value"
|
|
||||||
end.
|
|
||||||
|
|
||||||
var_to_rec_field(Var, #state{prefix = [Prefix|T]} = State) ->
|
|
||||||
Size = size(Prefix),
|
|
||||||
case Var of
|
|
||||||
<<(Prefix):Size/binary, Rest/binary>> ->
|
|
||||||
binary_to_atom(Rest, utf8);
|
|
||||||
_ ->
|
|
||||||
var_to_rec_field(Var, State#state{prefix = T})
|
|
||||||
end;
|
|
||||||
var_to_rec_field(Var, #state{prefix = []}) ->
|
|
||||||
Var.
|
|
||||||
|
|
||||||
get_dec_fun(Var, Type, Options, State) ->
|
|
||||||
case lists:keyfind(Var, 1, State#state.dec_mfas) of
|
|
||||||
false when Type == 'list-multi'; Type == 'list-single' ->
|
|
||||||
if Options /= [] ->
|
|
||||||
Variants = [binary_to_atom(V, utf8)
|
|
||||||
|| #xdata_option{value = V} <- Options],
|
|
||||||
{undefined, dec_enum, [Variants]};
|
|
||||||
true ->
|
|
||||||
undefined
|
|
||||||
end;
|
|
||||||
false when Type == 'jid-multi'; Type == 'jid-single' ->
|
|
||||||
{undefined, dec_jid, []};
|
|
||||||
false when Type == boolean ->
|
|
||||||
{undefined, dec_bool, []};
|
|
||||||
false ->
|
|
||||||
undefined;
|
|
||||||
{Var, {M, F, A}} ->
|
|
||||||
{M, F, A};
|
|
||||||
{Var, {dec_bool, []}} ->
|
|
||||||
{undefined, dec_bool, []};
|
|
||||||
{Var, {not_empty, []}} ->
|
|
||||||
{undefined, not_empty, []};
|
|
||||||
{Var, {dec_enum, [Variants]}} ->
|
|
||||||
{undefined, dec_enum, [Variants]};
|
|
||||||
{Var, {dec_int, Args}} ->
|
|
||||||
{undefined, dec_int, Args};
|
|
||||||
{Var, {dec_enum_int, Args}} ->
|
|
||||||
{undefined, dec_enum_int, Args};
|
|
||||||
{Var, {dec_jid, []}} ->
|
|
||||||
{undefined, dec_jid, []}
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_enc_fun(Var, Type, Options, State) ->
|
|
||||||
case get_dec_fun(Var, Type, Options, State) of
|
|
||||||
{undefined, dec_enum, _} ->
|
|
||||||
{undefined, enc_enum, []};
|
|
||||||
{undefined, dec_bool, _} ->
|
|
||||||
{undefined, enc_bool, []};
|
|
||||||
{undefined, dec_int, _} ->
|
|
||||||
{undefined, enc_int, []};
|
|
||||||
{undefined, dec_enum_int, _} ->
|
|
||||||
{undefined, enc_enum_int, []};
|
|
||||||
{undefined, dec_jid, _} ->
|
|
||||||
{undefined, enc_jid, []};
|
|
||||||
_ ->
|
|
||||||
case lists:keyfind(Var, 1, State#state.enc_mfas) of
|
|
||||||
false ->
|
|
||||||
undefined;
|
|
||||||
{Var, {M, F, A}} ->
|
|
||||||
{M, F, A};
|
|
||||||
{Var, {enc_bool, []}} ->
|
|
||||||
{undefined, enc_bool, []};
|
|
||||||
{Var, {dec_enum, _}} ->
|
|
||||||
{undefined, enc_enum, []};
|
|
||||||
{Var, {enc_int, _}} ->
|
|
||||||
{undefined, enc_int, []};
|
|
||||||
{Var, {dec_enum_int, _}} ->
|
|
||||||
{undefined, enc_enum_int, []};
|
|
||||||
{Var, {enc_jid, _}} ->
|
|
||||||
{undefined, enc_jid, []}
|
|
||||||
end
|
|
||||||
end.
|
|
||||||
|
|
||||||
mk_typespec(#xdata_field{type = Type, var = Var} = Field, State) ->
|
|
||||||
Spec0 = get_typespec(Field, State),
|
|
||||||
Spec1 = case is_complex_type(Spec0) of
|
|
||||||
true ->
|
|
||||||
io_lib:format("'~s'()", [var_to_rec_field(Var, State)]);
|
|
||||||
false ->
|
|
||||||
Spec0
|
|
||||||
end,
|
|
||||||
if ?is_multi_type(Type) -> "[" ++ Spec1 ++ "]";
|
|
||||||
true -> Spec1
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_typespec(#xdata_field{var = Var, type = Type, options = Options}, State) ->
|
|
||||||
case lists:keyfind(Var, 1, State#state.specs) of
|
|
||||||
false ->
|
|
||||||
case get_dec_fun(Var, Type, Options, State) of
|
|
||||||
{undefined, dec_enum, Args} ->
|
|
||||||
enum_spec(Args);
|
|
||||||
{undefined, dec_bool, _} ->
|
|
||||||
"boolean()";
|
|
||||||
{undefined, dec_jid, _} ->
|
|
||||||
"jid:jid()";
|
|
||||||
{undefined, dec_int, Args} ->
|
|
||||||
int_spec(Args);
|
|
||||||
{undefined, dec_enum_int, [Variants|T]} ->
|
|
||||||
enum_spec([Variants]) ++ " | " ++ int_spec(T);
|
|
||||||
_ ->
|
|
||||||
"binary()"
|
|
||||||
end;
|
|
||||||
{Var, Spec} ->
|
|
||||||
Spec
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec is_complex_type(string()) -> boolean().
|
|
||||||
is_complex_type(Spec) ->
|
|
||||||
string:chr(Spec, $|) /= 0.
|
|
||||||
|
|
||||||
int_spec([]) ->
|
|
||||||
"integer()";
|
|
||||||
int_spec([From, To]) ->
|
|
||||||
if From /= infinity, To /= infinity ->
|
|
||||||
io_lib:format("~p..~p", [From, To]);
|
|
||||||
From > 0 ->
|
|
||||||
"pos_integer()";
|
|
||||||
From == 0 ->
|
|
||||||
"non_neg_integer()";
|
|
||||||
true ->
|
|
||||||
"integer()"
|
|
||||||
end.
|
|
||||||
|
|
||||||
enum_spec([Variants]) ->
|
|
||||||
string:join([atom_to_list(V) || V <- Variants], " | ").
|
|
||||||
|
|
||||||
is_required(Var, State) ->
|
|
||||||
lists:member(Var, State#state.required) orelse
|
|
||||||
proplists:get_bool(Var, State#state.required).
|
|
||||||
|
|
||||||
normalize(#xmlel{name = Name, attrs = Attrs, children = Els}) ->
|
|
||||||
#xmlel{name = Name,
|
|
||||||
attrs = [normalize(Attr) || Attr <- Attrs],
|
|
||||||
children = [normalize(El) || El <- Els]};
|
|
||||||
normalize({Key, Data}) ->
|
|
||||||
{Key, normalize(Data)};
|
|
||||||
normalize(Txt) when is_binary(Txt) ->
|
|
||||||
case re:split(Txt, "[\\s\\r\\n\\t]+", [trim, {return, list}]) of
|
|
||||||
[""|T] ->
|
|
||||||
list_to_binary(string:join(T, " "));
|
|
||||||
T ->
|
|
||||||
list_to_binary(string:join(T, " "))
|
|
||||||
end.
|
|
827
src/xmpp.erl
827
src/xmpp.erl
@ -1,827 +0,0 @@
|
|||||||
%%%-------------------------------------------------------------------
|
|
||||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%% @copyright (C) 2015, Evgeny Khramtsov
|
|
||||||
%%% @doc
|
|
||||||
%%%
|
|
||||||
%%% @end
|
|
||||||
%%% Created : 9 Dec 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
|
||||||
%%%-------------------------------------------------------------------
|
|
||||||
-module(xmpp).
|
|
||||||
|
|
||||||
%% API
|
|
||||||
-export([make_iq_result/1, make_iq_result/2, make_error/2,
|
|
||||||
decode/1, decode/3, encode/1, encode/2,
|
|
||||||
get_type/1, get_to/1, get_from/1, get_id/1,
|
|
||||||
get_lang/1, get_error/1, get_els/1, get_ns/1,
|
|
||||||
set_type/2, set_to/2, set_from/2, set_id/2,
|
|
||||||
set_lang/2, set_error/2, set_els/2, set_from_to/3,
|
|
||||||
format_error/1, is_stanza/1, set_subtag/2, get_subtag/2,
|
|
||||||
remove_subtag/2, has_subtag/2, decode_els/1, decode_els/3,
|
|
||||||
pp/1, get_name/1, get_text/1, mk_text/1, mk_text/2,
|
|
||||||
is_known_tag/1, is_known_tag/2, append_subtags/2]).
|
|
||||||
|
|
||||||
%% XMPP errors
|
|
||||||
-export([err_bad_request/0, err_bad_request/2,
|
|
||||||
err_conflict/0, err_conflict/2,
|
|
||||||
err_feature_not_implemented/0, err_feature_not_implemented/2,
|
|
||||||
err_forbidden/0, err_forbidden/2,
|
|
||||||
err_gone/0, err_gone/2,
|
|
||||||
err_internal_server_error/0, err_internal_server_error/2,
|
|
||||||
err_item_not_found/0, err_item_not_found/2,
|
|
||||||
err_jid_malformed/0, err_jid_malformed/2,
|
|
||||||
err_not_acceptable/0, err_not_acceptable/2,
|
|
||||||
err_not_allowed/0, err_not_allowed/2,
|
|
||||||
err_not_authorized/0, err_not_authorized/2,
|
|
||||||
err_payment_required/0, err_payment_required/2,
|
|
||||||
err_policy_violation/0, err_policy_violation/2,
|
|
||||||
err_recipient_unavailable/0, err_recipient_unavailable/2,
|
|
||||||
err_redirect/0, err_redirect/2,
|
|
||||||
err_registration_required/0, err_registration_required/2,
|
|
||||||
err_remote_server_not_found/0, err_remote_server_not_found/2,
|
|
||||||
err_remote_server_timeout/0, err_remote_server_timeout/2,
|
|
||||||
err_resource_constraint/0, err_resource_constraint/2,
|
|
||||||
err_service_unavailable/0, err_service_unavailable/2,
|
|
||||||
err_subscription_required/0, err_subscription_required/2,
|
|
||||||
err_undefined_condition/1, err_undefined_condition/3,
|
|
||||||
err_unexpected_request/0, err_unexpected_request/2]).
|
|
||||||
|
|
||||||
%% XMPP stream errors
|
|
||||||
-export([serr_bad_format/0, serr_bad_format/2,
|
|
||||||
serr_bad_namespace_prefix/0, serr_bad_namespace_prefix/2,
|
|
||||||
serr_conflict/0, serr_conflict/2,
|
|
||||||
serr_connection_timeout/0, serr_connection_timeout/2,
|
|
||||||
serr_host_gone/0, serr_host_gone/2,
|
|
||||||
serr_host_unknown/0, serr_host_unknown/2,
|
|
||||||
serr_improper_addressing/0, serr_improper_addressing/2,
|
|
||||||
serr_internal_server_error/0, serr_internal_server_error/2,
|
|
||||||
serr_invalid_from/0, serr_invalid_from/2,
|
|
||||||
serr_invalid_id/0, serr_invalid_id/2,
|
|
||||||
serr_invalid_namespace/0, serr_invalid_namespace/2,
|
|
||||||
serr_invalid_xml/0, serr_invalid_xml/2,
|
|
||||||
serr_not_authorized/0, serr_not_authorized/2,
|
|
||||||
serr_not_well_formed/0, serr_not_well_formed/2,
|
|
||||||
serr_policy_violation/0, serr_policy_violation/2,
|
|
||||||
serr_remote_connection_failed/0, serr_remote_connection_failed/2,
|
|
||||||
serr_reset/0, serr_reset/2,
|
|
||||||
serr_resource_constraint/0, serr_resource_constraint/2,
|
|
||||||
serr_restricted_xml/0, serr_restricted_xml/2,
|
|
||||||
serr_see_other_host/0, serr_see_other_host/2,
|
|
||||||
serr_system_shutdown/0, serr_system_shutdown/2,
|
|
||||||
serr_undefined_condition/0, serr_undefined_condition/2,
|
|
||||||
serr_unsupported_encoding/0, serr_unsupported_encoding/2,
|
|
||||||
serr_unsupported_stanza_type/0, serr_unsupported_stanza_type/2,
|
|
||||||
serr_unsupported_version/0, serr_unsupported_version/2]).
|
|
||||||
|
|
||||||
-include("xmpp.hrl").
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% API
|
|
||||||
%%%===================================================================
|
|
||||||
-spec make_iq_result(iq()) -> iq().
|
|
||||||
make_iq_result(IQ) ->
|
|
||||||
make_iq_result(IQ, undefined).
|
|
||||||
|
|
||||||
-spec make_iq_result(iq(), xmpp_element() | xmlel() | undefined) -> iq().
|
|
||||||
make_iq_result(#iq{type = Type, from = From, to = To} = IQ, El)
|
|
||||||
when Type == get; Type == set ->
|
|
||||||
SubEls = if El == undefined -> [];
|
|
||||||
true -> [El]
|
|
||||||
end,
|
|
||||||
IQ#iq{type = result, to = From, from = To, sub_els = SubEls}.
|
|
||||||
|
|
||||||
-spec make_error(message(), stanza_error() | xmlel()) -> message();
|
|
||||||
(presence(), stanza_error() | xmlel()) -> presence();
|
|
||||||
(iq(), stanza_error() | xmlel()) -> iq();
|
|
||||||
(xmlel(), stanza_error() | xmlel()) -> xmlel().
|
|
||||||
make_error(#message{type = Type, from = From, to = To, sub_els = Els} = Msg,
|
|
||||||
Err) when Type /= error ->
|
|
||||||
Msg#message{type = error, from = To, to = From, sub_els = Els ++ [Err]};
|
|
||||||
make_error(#presence{type = Type, from = From, to = To, sub_els = Els} = Pres,
|
|
||||||
Err) when Type /= error ->
|
|
||||||
Pres#presence{type = error, from = To, to = From, sub_els = Els ++ [Err]};
|
|
||||||
make_error(#iq{type = Type, from = From, to = To, sub_els = Els} = IQ,
|
|
||||||
Err) when Type /= result, Type /= error ->
|
|
||||||
IQ#iq{type = error, from = To, to = From, sub_els = Els ++ [Err]};
|
|
||||||
make_error(#xmlel{attrs = Attrs, children = Els} = El, Err) ->
|
|
||||||
To = fxml:get_attr(<<"to">>, Attrs),
|
|
||||||
From = fxml:get_attr(<<"from">>, Attrs),
|
|
||||||
Attrs1 = case To of
|
|
||||||
{value, T} ->
|
|
||||||
lists:keystore(<<"from">>, 1, Attrs, {<<"from">>, T});
|
|
||||||
_ ->
|
|
||||||
Attrs
|
|
||||||
end,
|
|
||||||
Attrs2 = case From of
|
|
||||||
{value, F} ->
|
|
||||||
lists:keystore(<<"to">>, 1, Attrs1, {<<"to">>, F});
|
|
||||||
_ ->
|
|
||||||
Attrs
|
|
||||||
end,
|
|
||||||
Attrs3 = lists:keystore(<<"type">>, 1, Attrs2, {<<"type">>, <<"error">>}),
|
|
||||||
El#xmlel{attrs = Attrs3, children = Els ++ [encode(Err, ?NS_CLIENT)]}.
|
|
||||||
|
|
||||||
-spec get_id(iq() | message() | presence() | xmlel()) -> binary().
|
|
||||||
get_id(#iq{id = ID}) -> ID;
|
|
||||||
get_id(#message{id = ID}) -> ID;
|
|
||||||
get_id(#presence{id = ID}) -> ID;
|
|
||||||
get_id(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"id">>, Attrs).
|
|
||||||
|
|
||||||
-spec get_type(iq()) -> iq_type();
|
|
||||||
(message()) -> message_type();
|
|
||||||
(presence()) -> presence_type();
|
|
||||||
(xmlel()) -> binary().
|
|
||||||
get_type(#iq{type = T}) -> T;
|
|
||||||
get_type(#message{type = T}) -> T;
|
|
||||||
get_type(#presence{type = T}) -> T;
|
|
||||||
get_type(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"type">>, Attrs).
|
|
||||||
|
|
||||||
-spec get_lang(iq() | message() | presence() | xmlel()) -> binary().
|
|
||||||
get_lang(#iq{lang = L}) -> L;
|
|
||||||
get_lang(#message{lang = L}) -> L;
|
|
||||||
get_lang(#presence{lang = L}) -> L;
|
|
||||||
get_lang(#xmlel{attrs = Attrs}) -> fxml:get_attr_s(<<"xml:lang">>, Attrs).
|
|
||||||
|
|
||||||
-spec get_from(iq() | message() | presence()) -> undefined | jid:jid().
|
|
||||||
get_from(#iq{from = J}) -> J;
|
|
||||||
get_from(#message{from = J}) -> J;
|
|
||||||
get_from(#presence{from = J}) -> J.
|
|
||||||
|
|
||||||
-spec get_to(iq() | message() | presence()) -> undefined | jid:jid().
|
|
||||||
get_to(#iq{to = J}) -> J;
|
|
||||||
get_to(#message{to = J}) -> J;
|
|
||||||
get_to(#presence{to = J}) -> J.
|
|
||||||
|
|
||||||
-spec get_error(iq() | message() | presence()) -> undefined | stanza_error().
|
|
||||||
get_error(Stanza) ->
|
|
||||||
case get_subtag(Stanza, #stanza_error{}) of
|
|
||||||
false -> undefined;
|
|
||||||
Error -> Error
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_els(iq() | message() | presence()) -> [xmpp_element() | xmlel()];
|
|
||||||
(xmlel()) -> [xmlel()].
|
|
||||||
get_els(#iq{sub_els = Els}) -> Els;
|
|
||||||
get_els(#message{sub_els = Els}) -> Els;
|
|
||||||
get_els(#presence{sub_els = Els}) -> Els;
|
|
||||||
get_els(#xmlel{children = Els}) -> [El || El = #xmlel{} <- Els].
|
|
||||||
|
|
||||||
-spec set_id(iq(), binary()) -> iq();
|
|
||||||
(message(), binary()) -> message();
|
|
||||||
(presence(), binary()) -> presence().
|
|
||||||
set_id(#iq{} = IQ, I) -> IQ#iq{id = I};
|
|
||||||
set_id(#message{} = Msg, I) -> Msg#message{id = I};
|
|
||||||
set_id(#presence{} = Pres, I) -> Pres#presence{id = I}.
|
|
||||||
|
|
||||||
-spec set_type(iq(), iq_type()) -> iq();
|
|
||||||
(message(), message_type()) -> message();
|
|
||||||
(presence(), presence_type()) -> presence().
|
|
||||||
set_type(#iq{} = IQ, T) -> IQ#iq{type = T};
|
|
||||||
set_type(#message{} = Msg, T) -> Msg#message{type = T};
|
|
||||||
set_type(#presence{} = Pres, T) -> Pres#presence{type = T}.
|
|
||||||
|
|
||||||
-spec set_lang(iq(), binary()) -> iq();
|
|
||||||
(message(), binary()) -> message();
|
|
||||||
(presence(), binary()) -> presence().
|
|
||||||
set_lang(#iq{} = IQ, L) -> IQ#iq{lang = L};
|
|
||||||
set_lang(#message{} = Msg, L) -> Msg#message{lang = L};
|
|
||||||
set_lang(#presence{} = Pres, L) -> Pres#presence{lang = L}.
|
|
||||||
|
|
||||||
-spec set_from(iq(), jid:jid()) -> iq();
|
|
||||||
(message(), jid:jid()) -> message();
|
|
||||||
(presence(), jid:jid()) -> presence().
|
|
||||||
set_from(#iq{} = IQ, J) -> IQ#iq{from = J};
|
|
||||||
set_from(#message{} = Msg, J) -> Msg#message{from = J};
|
|
||||||
set_from(#presence{} = Pres, J) -> Pres#presence{from = J}.
|
|
||||||
|
|
||||||
-spec set_to(iq(), jid:jid()) -> iq();
|
|
||||||
(message(), jid:jid()) -> message();
|
|
||||||
(presence(), jid:jid()) -> presence().
|
|
||||||
set_to(#iq{} = IQ, J) -> IQ#iq{to = J};
|
|
||||||
set_to(#message{} = Msg, J) -> Msg#message{to = J};
|
|
||||||
set_to(#presence{} = Pres, J) -> Pres#presence{to = J}.
|
|
||||||
|
|
||||||
-spec set_from_to(iq(), undefined | jid:jid(), undefined | jid:jid()) -> iq();
|
|
||||||
(message(), undefined | jid:jid(), undefined | jid:jid()) -> message();
|
|
||||||
(presence(), undefined | jid:jid(), undefined | jid:jid()) -> presence().
|
|
||||||
set_from_to(#iq{} = IQ, F, T) -> IQ#iq{from = F, to = T};
|
|
||||||
set_from_to(#message{} = Msg, F, T) -> Msg#message{from = F, to = T};
|
|
||||||
set_from_to(#presence{} = Pres, F, T) -> Pres#presence{from = F, to = T}.
|
|
||||||
|
|
||||||
-spec set_error(iq(), stanza_error()) -> iq();
|
|
||||||
(message(), stanza_error()) -> message();
|
|
||||||
(presence(), stanza_error()) -> presence().
|
|
||||||
set_error(Stanza, E) -> set_subtag(Stanza, E).
|
|
||||||
|
|
||||||
-spec set_els(iq(), [xmpp_element() | xmlel()]) -> iq();
|
|
||||||
(message(), [xmpp_element() | xmlel()]) -> message();
|
|
||||||
(presence(), [xmpp_element() | xmlel()]) -> presence().
|
|
||||||
set_els(#iq{} = IQ, Els) -> IQ#iq{sub_els = Els};
|
|
||||||
set_els(#message{} = Msg, Els) -> Msg#message{sub_els = Els};
|
|
||||||
set_els(#presence{} = Pres, Els) -> Pres#presence{sub_els = Els}.
|
|
||||||
|
|
||||||
-spec get_ns(xmpp_element() | xmlel()) -> binary().
|
|
||||||
get_ns(#xmlel{attrs = Attrs}) ->
|
|
||||||
fxml:get_attr_s(<<"xmlns">>, Attrs);
|
|
||||||
get_ns(Pkt) ->
|
|
||||||
xmpp_codec:get_ns(Pkt).
|
|
||||||
|
|
||||||
-spec get_name(xmpp_element() | xmlel()) -> binary().
|
|
||||||
get_name(#xmlel{name = Name}) ->
|
|
||||||
Name;
|
|
||||||
get_name(Pkt) ->
|
|
||||||
xmpp_codec:get_name(Pkt).
|
|
||||||
|
|
||||||
-spec decode(xmlel() | xmpp_element()) -> {ok, xmpp_element()} | {error, any()}.
|
|
||||||
decode(El) ->
|
|
||||||
decode(El, ?NS_CLIENT, []).
|
|
||||||
|
|
||||||
-spec decode(xmlel() | xmpp_element(), binary(), [proplists:property()]) ->
|
|
||||||
{ok, xmpp_element()} | {error, any()}.
|
|
||||||
decode(#xmlel{} = El, TopXMLNS, Opts) ->
|
|
||||||
xmpp_codec:decode(El, TopXMLNS, Opts);
|
|
||||||
decode(Pkt, _, _) ->
|
|
||||||
Pkt.
|
|
||||||
|
|
||||||
-spec decode_els(iq()) -> iq();
|
|
||||||
(message()) -> message();
|
|
||||||
(presence()) -> presence().
|
|
||||||
decode_els(Stanza) ->
|
|
||||||
decode_els(Stanza, ?NS_CLIENT, fun is_known_tag/1).
|
|
||||||
|
|
||||||
-type match_fun() :: fun((xmlel()) -> boolean()).
|
|
||||||
-spec decode_els(iq(), binary(), match_fun()) -> iq();
|
|
||||||
(message(), binary(), match_fun()) -> message();
|
|
||||||
(presence(), binary(), match_fun()) -> presence().
|
|
||||||
decode_els(Stanza, TopXMLNS, MatchFun) ->
|
|
||||||
Els = lists:map(
|
|
||||||
fun(#xmlel{} = El) ->
|
|
||||||
case MatchFun(El) of
|
|
||||||
true -> decode(El, TopXMLNS, []);
|
|
||||||
false -> El
|
|
||||||
end;
|
|
||||||
(Pkt) ->
|
|
||||||
Pkt
|
|
||||||
end, get_els(Stanza)),
|
|
||||||
set_els(Stanza, Els).
|
|
||||||
|
|
||||||
-spec encode(xmpp_element() | xmlel()) -> xmlel().
|
|
||||||
encode(Pkt) ->
|
|
||||||
encode(Pkt, <<>>).
|
|
||||||
|
|
||||||
-spec encode(xmpp_element() | xmlel(), binary()) -> xmlel().
|
|
||||||
encode(Pkt, TopXMLNS) ->
|
|
||||||
xmpp_codec:encode(Pkt, TopXMLNS).
|
|
||||||
|
|
||||||
-spec is_known_tag(xmlel()) -> boolean().
|
|
||||||
is_known_tag(El) ->
|
|
||||||
is_known_tag(El, ?NS_CLIENT).
|
|
||||||
|
|
||||||
-spec is_known_tag(xmlel(), binary()) -> boolean().
|
|
||||||
is_known_tag(El, TopXMLNS) ->
|
|
||||||
xmpp_codec:is_known_tag(El, TopXMLNS).
|
|
||||||
|
|
||||||
format_error(Reason) ->
|
|
||||||
xmpp_codec:format_error(Reason).
|
|
||||||
|
|
||||||
-spec is_stanza(any()) -> boolean().
|
|
||||||
is_stanza(#message{}) -> true;
|
|
||||||
is_stanza(#iq{}) -> true;
|
|
||||||
is_stanza(#presence{}) -> true;
|
|
||||||
is_stanza(#xmlel{name = Name}) ->
|
|
||||||
(Name == <<"iq">>) or (Name == <<"message">>) or (Name == <<"presence">>);
|
|
||||||
is_stanza(_) -> false.
|
|
||||||
|
|
||||||
-spec set_subtag(iq(), xmpp_element()) -> iq();
|
|
||||||
(message(), xmpp_element()) -> message();
|
|
||||||
(presence(), xmpp_element()) -> presence().
|
|
||||||
set_subtag(Stanza, Tag) ->
|
|
||||||
TagName = xmpp_codec:get_name(Tag),
|
|
||||||
XMLNS = xmpp_codec:get_ns(Tag),
|
|
||||||
Els = get_els(Stanza),
|
|
||||||
NewEls = set_subtag(Els, Tag, TagName, XMLNS),
|
|
||||||
set_els(Stanza, NewEls).
|
|
||||||
|
|
||||||
set_subtag([El|Els], Tag, TagName, XMLNS) ->
|
|
||||||
case match_tag(El, TagName, XMLNS) of
|
|
||||||
true ->
|
|
||||||
[Tag|Els];
|
|
||||||
false ->
|
|
||||||
[El|set_subtag(Els, Tag, TagName, XMLNS)]
|
|
||||||
end;
|
|
||||||
set_subtag([], Tag, _, _) ->
|
|
||||||
[Tag].
|
|
||||||
|
|
||||||
-spec get_subtag(stanza(), xmpp_element()) -> xmpp_element() | false.
|
|
||||||
get_subtag(Stanza, Tag) ->
|
|
||||||
Els = get_els(Stanza),
|
|
||||||
TagName = xmpp_codec:get_name(Tag),
|
|
||||||
XMLNS = xmpp_codec:get_ns(Tag),
|
|
||||||
get_subtag(Els, TagName, XMLNS).
|
|
||||||
|
|
||||||
get_subtag([El|Els], TagName, XMLNS) ->
|
|
||||||
case match_tag(El, TagName, XMLNS) of
|
|
||||||
true ->
|
|
||||||
try
|
|
||||||
decode(El)
|
|
||||||
catch _:{xmpp_codec, _Why} ->
|
|
||||||
get_subtag(Els, TagName, XMLNS)
|
|
||||||
end;
|
|
||||||
false ->
|
|
||||||
get_subtag(Els, TagName, XMLNS)
|
|
||||||
end;
|
|
||||||
get_subtag([], _, _) ->
|
|
||||||
false.
|
|
||||||
|
|
||||||
-spec remove_subtag(iq(), xmpp_element()) -> iq();
|
|
||||||
(message(), xmpp_element()) -> message();
|
|
||||||
(presence(), xmpp_element()) -> presence().
|
|
||||||
remove_subtag(Stanza, Tag) ->
|
|
||||||
Els = get_els(Stanza),
|
|
||||||
TagName = xmpp_codec:get_name(Tag),
|
|
||||||
XMLNS = xmpp_codec:get_ns(Tag),
|
|
||||||
NewEls = remove_subtag(Els, TagName, XMLNS),
|
|
||||||
set_els(Stanza, NewEls).
|
|
||||||
|
|
||||||
remove_subtag([El|Els], TagName, XMLNS) ->
|
|
||||||
case match_tag(El, TagName, XMLNS) of
|
|
||||||
true ->
|
|
||||||
remove_subtag(Els, TagName, XMLNS);
|
|
||||||
false ->
|
|
||||||
[El|remove_subtag(Els, TagName, XMLNS)]
|
|
||||||
end;
|
|
||||||
remove_subtag([], _, _) ->
|
|
||||||
[].
|
|
||||||
|
|
||||||
-spec has_subtag(stanza(), xmpp_element()) -> boolean().
|
|
||||||
has_subtag(Stanza, Tag) ->
|
|
||||||
Els = get_els(Stanza),
|
|
||||||
TagName = xmpp_codec:get_name(Tag),
|
|
||||||
XMLNS = xmpp_codec:get_ns(Tag),
|
|
||||||
has_subtag(Els, TagName, XMLNS).
|
|
||||||
|
|
||||||
has_subtag([El|Els], TagName, XMLNS) ->
|
|
||||||
case match_tag(El, TagName, XMLNS) of
|
|
||||||
true ->
|
|
||||||
true;
|
|
||||||
false ->
|
|
||||||
has_subtag(Els, TagName, XMLNS)
|
|
||||||
end;
|
|
||||||
has_subtag([], _, _) ->
|
|
||||||
false.
|
|
||||||
|
|
||||||
-spec append_subtags(stanza(), [xmpp_element() | xmlel()]) -> stanza().
|
|
||||||
append_subtags(Stanza, Tags) ->
|
|
||||||
Els = get_els(Stanza),
|
|
||||||
set_els(Stanza, Els ++ Tags).
|
|
||||||
|
|
||||||
-spec get_text([text()]) -> binary().
|
|
||||||
get_text([]) -> <<"">>;
|
|
||||||
get_text([#text{data = Data}|_]) -> Data.
|
|
||||||
|
|
||||||
-spec mk_text(binary()) -> [text()].
|
|
||||||
mk_text(Text) ->
|
|
||||||
mk_text(Text, <<"">>).
|
|
||||||
|
|
||||||
-spec mk_text(binary(), binary()) -> [text()].
|
|
||||||
mk_text(<<"">>, _) ->
|
|
||||||
[];
|
|
||||||
mk_text(Text, Lang) ->
|
|
||||||
[#text{lang = Lang,
|
|
||||||
data = translate:translate(Lang, Text)}].
|
|
||||||
|
|
||||||
-spec pp(any()) -> iodata().
|
|
||||||
pp(Term) ->
|
|
||||||
xmpp_codec:pp(Term).
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Functions to construct general XMPP errors
|
|
||||||
%%%===================================================================
|
|
||||||
-spec err_bad_request() -> stanza_error().
|
|
||||||
err_bad_request() ->
|
|
||||||
err(modify, 'bad-request', 400).
|
|
||||||
|
|
||||||
-spec err_bad_request(binary(), binary()) -> stanza_error().
|
|
||||||
err_bad_request(Text, Lang) ->
|
|
||||||
err(modify, 'bad-request', 400, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_conflict() -> stanza_error().
|
|
||||||
err_conflict() ->
|
|
||||||
err(cancel, 'conflict', 409).
|
|
||||||
|
|
||||||
-spec err_conflict(binary(), binary()) -> stanza_error().
|
|
||||||
err_conflict(Text, Lang) ->
|
|
||||||
err(cancel, 'conflict', 409, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_feature_not_implemented() -> stanza_error().
|
|
||||||
err_feature_not_implemented() ->
|
|
||||||
err(cancel, 'feature-not-implemented', 501).
|
|
||||||
|
|
||||||
-spec err_feature_not_implemented(binary(), binary()) -> stanza_error().
|
|
||||||
err_feature_not_implemented(Text, Lang) ->
|
|
||||||
err(cancel, 'feature-not-implemented', 501, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_forbidden() -> stanza_error().
|
|
||||||
err_forbidden() ->
|
|
||||||
err(auth, 'forbidden', 403).
|
|
||||||
|
|
||||||
-spec err_forbidden(binary(), binary()) -> stanza_error().
|
|
||||||
err_forbidden(Text, Lang) ->
|
|
||||||
err(auth, 'forbidden', 403, Text, Lang).
|
|
||||||
|
|
||||||
%% RFC 6120 says error type SHOULD be "cancel".
|
|
||||||
%% RFC 3920 and XEP-0082 says it SHOULD be "modify".
|
|
||||||
-spec err_gone() -> stanza_error().
|
|
||||||
err_gone() ->
|
|
||||||
err(modify, 'gone', 302).
|
|
||||||
|
|
||||||
-spec err_gone(binary(), binary()) -> stanza_error().
|
|
||||||
err_gone(Text, Lang) ->
|
|
||||||
err(modify, 'gone', 302, Text, Lang).
|
|
||||||
|
|
||||||
%% RFC 6120 sasy error type SHOULD be "cancel".
|
|
||||||
%% RFC 3920 and XEP-0082 says it SHOULD be "wait".
|
|
||||||
-spec err_internal_server_error() -> stanza_error().
|
|
||||||
err_internal_server_error() ->
|
|
||||||
err(wait, 'internal-server-error', 500).
|
|
||||||
|
|
||||||
-spec err_internal_server_error(binary(), binary()) -> stanza_error().
|
|
||||||
err_internal_server_error(Text, Lang) ->
|
|
||||||
err(wait, 'internal-server-error', 500, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_item_not_found() -> stanza_error().
|
|
||||||
err_item_not_found() ->
|
|
||||||
err(cancel, 'item-not-found', 404).
|
|
||||||
|
|
||||||
-spec err_item_not_found(binary(), binary()) -> stanza_error().
|
|
||||||
err_item_not_found(Text, Lang) ->
|
|
||||||
err(cancel, 'item-not-found', 404, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_jid_malformed() -> stanza_error().
|
|
||||||
err_jid_malformed() ->
|
|
||||||
err(modify, 'jid-malformed', 400).
|
|
||||||
|
|
||||||
-spec err_jid_malformed(binary(), binary()) -> stanza_error().
|
|
||||||
err_jid_malformed(Text, Lang) ->
|
|
||||||
err(modify, 'jid-malformed', 400, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_not_acceptable() -> stanza_error().
|
|
||||||
err_not_acceptable() ->
|
|
||||||
err(modify, 'not-acceptable', 406).
|
|
||||||
|
|
||||||
-spec err_not_acceptable(binary(), binary()) -> stanza_error().
|
|
||||||
err_not_acceptable(Text, Lang) ->
|
|
||||||
err(modify, 'not-acceptable', 406, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_not_allowed() -> stanza_error().
|
|
||||||
err_not_allowed() ->
|
|
||||||
err(cancel, 'not-allowed', 405).
|
|
||||||
|
|
||||||
-spec err_not_allowed(binary(), binary()) -> stanza_error().
|
|
||||||
err_not_allowed(Text, Lang) ->
|
|
||||||
err(cancel, 'not-allowed', 405, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_not_authorized() -> stanza_error().
|
|
||||||
err_not_authorized() ->
|
|
||||||
err(auth, 'not-authorized', 401).
|
|
||||||
|
|
||||||
-spec err_not_authorized(binary(), binary()) -> stanza_error().
|
|
||||||
err_not_authorized(Text, Lang) ->
|
|
||||||
err(auth, 'not-authorized', 401, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_payment_required() -> stanza_error().
|
|
||||||
err_payment_required() ->
|
|
||||||
err(auth, 'not-authorized', 402).
|
|
||||||
|
|
||||||
-spec err_payment_required(binary(), binary()) -> stanza_error().
|
|
||||||
err_payment_required(Text, Lang) ->
|
|
||||||
err(auth, 'not-authorized', 402, Text, Lang).
|
|
||||||
|
|
||||||
%% <policy-violation/> is defined in neither RFC 3920 nor XEP-0086.
|
|
||||||
%% We choose '403' error code (as in <forbidden/>).
|
|
||||||
-spec err_policy_violation() -> stanza_error().
|
|
||||||
err_policy_violation() ->
|
|
||||||
err(modify, 'policy-violation', 403).
|
|
||||||
|
|
||||||
-spec err_policy_violation(binary(), binary()) -> stanza_error().
|
|
||||||
err_policy_violation(Text, Lang) ->
|
|
||||||
err(modify, 'policy-violation', 403, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_recipient_unavailable() -> stanza_error().
|
|
||||||
err_recipient_unavailable() ->
|
|
||||||
err(wait, 'recipient-unavailable', 404).
|
|
||||||
|
|
||||||
-spec err_recipient_unavailable(binary(), binary()) -> stanza_error().
|
|
||||||
err_recipient_unavailable(Text, Lang) ->
|
|
||||||
err(wait, 'recipient-unavailable', 404, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_redirect() -> stanza_error().
|
|
||||||
err_redirect() ->
|
|
||||||
err(modify, 'redirect', 302).
|
|
||||||
|
|
||||||
-spec err_redirect(binary(), binary()) -> stanza_error().
|
|
||||||
err_redirect(Text, Lang) ->
|
|
||||||
err(modify, 'redirect', 302, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_registration_required() -> stanza_error().
|
|
||||||
err_registration_required() ->
|
|
||||||
err(auth, 'registration-required', 407).
|
|
||||||
|
|
||||||
-spec err_registration_required(binary(), binary()) -> stanza_error().
|
|
||||||
err_registration_required(Text, Lang) ->
|
|
||||||
err(auth, 'registration-required', 407, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_remote_server_not_found() -> stanza_error().
|
|
||||||
err_remote_server_not_found() ->
|
|
||||||
err(cancel, 'remote-server-not-found', 404).
|
|
||||||
|
|
||||||
-spec err_remote_server_not_found(binary(), binary()) -> stanza_error().
|
|
||||||
err_remote_server_not_found(Text, Lang) ->
|
|
||||||
err(cancel, 'remote-server-not-found', 404, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_remote_server_timeout() -> stanza_error().
|
|
||||||
err_remote_server_timeout() ->
|
|
||||||
err(wait, 'remote-server-timeout', 504).
|
|
||||||
|
|
||||||
-spec err_remote_server_timeout(binary(), binary()) -> stanza_error().
|
|
||||||
err_remote_server_timeout(Text, Lang) ->
|
|
||||||
err(wait, 'remote-server-timeout', 504, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_resource_constraint() -> stanza_error().
|
|
||||||
err_resource_constraint() ->
|
|
||||||
err(wait, 'resource-constraint', 500).
|
|
||||||
|
|
||||||
-spec err_resource_constraint(binary(), binary()) -> stanza_error().
|
|
||||||
err_resource_constraint(Text, Lang) ->
|
|
||||||
err(wait, 'resource-constraint', 500, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_service_unavailable() -> stanza_error().
|
|
||||||
err_service_unavailable() ->
|
|
||||||
err(cancel, 'service-unavailable', 503).
|
|
||||||
|
|
||||||
-spec err_service_unavailable(binary(), binary()) -> stanza_error().
|
|
||||||
err_service_unavailable(Text, Lang) ->
|
|
||||||
err(cancel, 'service-unavailable', 503, Text, Lang).
|
|
||||||
|
|
||||||
-spec err_subscription_required() -> stanza_error().
|
|
||||||
err_subscription_required() ->
|
|
||||||
err(auth, 'subscription-required', 407).
|
|
||||||
|
|
||||||
-spec err_subscription_required(binary(), binary()) -> stanza_error().
|
|
||||||
err_subscription_required(Text, Lang) ->
|
|
||||||
err(auth, 'subscription-required', 407, Text, Lang).
|
|
||||||
|
|
||||||
%% No error type is defined for <undefined-confition/>.
|
|
||||||
%% Let user provide the type.
|
|
||||||
-spec err_undefined_condition('auth' | 'cancel' | 'continue' |
|
|
||||||
'modify' | 'wait') -> stanza_error().
|
|
||||||
err_undefined_condition(Type) ->
|
|
||||||
err(Type, 'undefined-condition', 500).
|
|
||||||
|
|
||||||
-spec err_undefined_condition('auth' | 'cancel' | 'continue' | 'modify' | 'wait',
|
|
||||||
binary(), binary()) -> stanza_error().
|
|
||||||
err_undefined_condition(Type, Text, Lang) ->
|
|
||||||
err(Type, 'undefined-condition', 500, Text, Lang).
|
|
||||||
|
|
||||||
%% RFC 6120 says error type SHOULD be "wait" or "modify".
|
|
||||||
%% RFC 3920 and XEP-0082 says it SHOULD be "wait".
|
|
||||||
-spec err_unexpected_request() -> stanza_error().
|
|
||||||
err_unexpected_request() ->
|
|
||||||
err(wait, 'unexpected-request', 400).
|
|
||||||
|
|
||||||
-spec err_unexpected_request(binary(), binary()) -> stanza_error().
|
|
||||||
err_unexpected_request(Text, Lang) ->
|
|
||||||
err(wait, 'unexpected-request', 400, Text, Lang).
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Functions to construct stream errors
|
|
||||||
%%%===================================================================
|
|
||||||
-spec serr_bad_format() -> stream_error().
|
|
||||||
serr_bad_format() ->
|
|
||||||
serr('bad-format').
|
|
||||||
|
|
||||||
-spec serr_bad_format(binary(), binary()) -> stream_error().
|
|
||||||
serr_bad_format(Text, Lang) ->
|
|
||||||
serr('bad-format', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_bad_namespace_prefix() -> stream_error().
|
|
||||||
serr_bad_namespace_prefix() ->
|
|
||||||
serr('bad-namespace-prefix').
|
|
||||||
|
|
||||||
-spec serr_bad_namespace_prefix(binary(), binary()) -> stream_error().
|
|
||||||
serr_bad_namespace_prefix(Text, Lang) ->
|
|
||||||
serr('bad-namespace-prefix', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_conflict() -> stream_error().
|
|
||||||
serr_conflict() ->
|
|
||||||
serr('conflict').
|
|
||||||
|
|
||||||
-spec serr_conflict(binary(), binary()) -> stream_error().
|
|
||||||
serr_conflict(Text, Lang) ->
|
|
||||||
serr('conflict', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_connection_timeout() -> stream_error().
|
|
||||||
serr_connection_timeout() ->
|
|
||||||
serr('connection-timeout').
|
|
||||||
|
|
||||||
-spec serr_connection_timeout(binary(), binary()) -> stream_error().
|
|
||||||
serr_connection_timeout(Text, Lang) ->
|
|
||||||
serr('connection-timeout', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_host_gone() -> stream_error().
|
|
||||||
serr_host_gone() ->
|
|
||||||
serr('host-gone').
|
|
||||||
|
|
||||||
-spec serr_host_gone(binary(), binary()) -> stream_error().
|
|
||||||
serr_host_gone(Text, Lang) ->
|
|
||||||
serr('host-gone', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_host_unknown() -> stream_error().
|
|
||||||
serr_host_unknown() ->
|
|
||||||
serr('host-unknown').
|
|
||||||
|
|
||||||
-spec serr_host_unknown(binary(), binary()) -> stream_error().
|
|
||||||
serr_host_unknown(Text, Lang) ->
|
|
||||||
serr('host-unknown', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_improper_addressing() -> stream_error().
|
|
||||||
serr_improper_addressing() ->
|
|
||||||
serr('improper-addressing').
|
|
||||||
|
|
||||||
-spec serr_improper_addressing(binary(), binary()) -> stream_error().
|
|
||||||
serr_improper_addressing(Text, Lang) ->
|
|
||||||
serr('improper-addressing', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_internal_server_error() -> stream_error().
|
|
||||||
serr_internal_server_error() ->
|
|
||||||
serr('internal-server-error').
|
|
||||||
|
|
||||||
-spec serr_internal_server_error(binary(), binary()) -> stream_error().
|
|
||||||
serr_internal_server_error(Text, Lang) ->
|
|
||||||
serr('internal-server-error', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_invalid_from() -> stream_error().
|
|
||||||
serr_invalid_from() ->
|
|
||||||
serr('invalid-from').
|
|
||||||
|
|
||||||
-spec serr_invalid_from(binary(), binary()) -> stream_error().
|
|
||||||
serr_invalid_from(Text, Lang) ->
|
|
||||||
serr('invalid-from', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_invalid_id() -> stream_error().
|
|
||||||
serr_invalid_id() ->
|
|
||||||
serr('invalid-id').
|
|
||||||
|
|
||||||
-spec serr_invalid_id(binary(), binary()) -> stream_error().
|
|
||||||
serr_invalid_id(Text, Lang) ->
|
|
||||||
serr('invalid-id', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_invalid_namespace() -> stream_error().
|
|
||||||
serr_invalid_namespace() ->
|
|
||||||
serr('invalid-namespace').
|
|
||||||
|
|
||||||
-spec serr_invalid_namespace(binary(), binary()) -> stream_error().
|
|
||||||
serr_invalid_namespace(Text, Lang) ->
|
|
||||||
serr('invalid-namespace', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_invalid_xml() -> stream_error().
|
|
||||||
serr_invalid_xml() ->
|
|
||||||
serr('invalid-xml').
|
|
||||||
|
|
||||||
-spec serr_invalid_xml(binary(), binary()) -> stream_error().
|
|
||||||
serr_invalid_xml(Text, Lang) ->
|
|
||||||
serr('invalid-xml', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_not_authorized() -> stream_error().
|
|
||||||
serr_not_authorized() ->
|
|
||||||
serr('not-authorized').
|
|
||||||
|
|
||||||
-spec serr_not_authorized(binary(), binary()) -> stream_error().
|
|
||||||
serr_not_authorized(Text, Lang) ->
|
|
||||||
serr('not-authorized', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_not_well_formed() -> stream_error().
|
|
||||||
serr_not_well_formed() ->
|
|
||||||
serr('not-well-formed').
|
|
||||||
|
|
||||||
-spec serr_not_well_formed(binary(), binary()) -> stream_error().
|
|
||||||
serr_not_well_formed(Text, Lang) ->
|
|
||||||
serr('not-well-formed', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_policy_violation() -> stream_error().
|
|
||||||
serr_policy_violation() ->
|
|
||||||
serr('policy-violation').
|
|
||||||
|
|
||||||
-spec serr_policy_violation(binary(), binary()) -> stream_error().
|
|
||||||
serr_policy_violation(Text, Lang) ->
|
|
||||||
serr('policy-violation', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_remote_connection_failed() -> stream_error().
|
|
||||||
serr_remote_connection_failed() ->
|
|
||||||
serr('remote-connection-failed').
|
|
||||||
|
|
||||||
-spec serr_remote_connection_failed(binary(), binary()) -> stream_error().
|
|
||||||
serr_remote_connection_failed(Text, Lang) ->
|
|
||||||
serr('remote-connection-failed', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_reset() -> stream_error().
|
|
||||||
serr_reset() ->
|
|
||||||
serr('reset').
|
|
||||||
|
|
||||||
-spec serr_reset(binary(), binary()) -> stream_error().
|
|
||||||
serr_reset(Text, Lang) ->
|
|
||||||
serr('reset', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_resource_constraint() -> stream_error().
|
|
||||||
serr_resource_constraint() ->
|
|
||||||
serr('resource-constraint').
|
|
||||||
|
|
||||||
-spec serr_resource_constraint(binary(), binary()) -> stream_error().
|
|
||||||
serr_resource_constraint(Text, Lang) ->
|
|
||||||
serr('resource-constraint', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_restricted_xml() -> stream_error().
|
|
||||||
serr_restricted_xml() ->
|
|
||||||
serr('restricted-xml').
|
|
||||||
|
|
||||||
-spec serr_restricted_xml(binary(), binary()) -> stream_error().
|
|
||||||
serr_restricted_xml(Text, Lang) ->
|
|
||||||
serr('restricted-xml', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_see_other_host() -> stream_error().
|
|
||||||
serr_see_other_host() ->
|
|
||||||
serr('see-other-host').
|
|
||||||
|
|
||||||
-spec serr_see_other_host(binary(), binary()) -> stream_error().
|
|
||||||
serr_see_other_host(Text, Lang) ->
|
|
||||||
serr('see-other-host', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_system_shutdown() -> stream_error().
|
|
||||||
serr_system_shutdown() ->
|
|
||||||
serr('system-shutdown').
|
|
||||||
|
|
||||||
-spec serr_system_shutdown(binary(), binary()) -> stream_error().
|
|
||||||
serr_system_shutdown(Text, Lang) ->
|
|
||||||
serr('system-shutdown', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_undefined_condition() -> stream_error().
|
|
||||||
serr_undefined_condition() ->
|
|
||||||
serr('undefined-condition').
|
|
||||||
|
|
||||||
-spec serr_undefined_condition(binary(), binary()) -> stream_error().
|
|
||||||
serr_undefined_condition(Text, Lang) ->
|
|
||||||
serr('undefined-condition', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_unsupported_encoding() -> stream_error().
|
|
||||||
serr_unsupported_encoding() ->
|
|
||||||
serr('unsupported-encoding').
|
|
||||||
|
|
||||||
-spec serr_unsupported_encoding(binary(), binary()) -> stream_error().
|
|
||||||
serr_unsupported_encoding(Text, Lang) ->
|
|
||||||
serr('unsupported-encoding', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_unsupported_stanza_type() -> stream_error().
|
|
||||||
serr_unsupported_stanza_type() ->
|
|
||||||
serr('unsupported-stanza-type').
|
|
||||||
|
|
||||||
-spec serr_unsupported_stanza_type(binary(), binary()) -> stream_error().
|
|
||||||
serr_unsupported_stanza_type(Text, Lang) ->
|
|
||||||
serr('unsupported-stanza-type', Text, Lang).
|
|
||||||
|
|
||||||
-spec serr_unsupported_version() -> stream_error().
|
|
||||||
serr_unsupported_version() ->
|
|
||||||
serr('unsupported-version').
|
|
||||||
|
|
||||||
-spec serr_unsupported_version(binary(), binary()) -> stream_error().
|
|
||||||
serr_unsupported_version(Text, Lang) ->
|
|
||||||
serr('unsupported-version', Text, Lang).
|
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Internal functions
|
|
||||||
%%%===================================================================
|
|
||||||
-spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait',
|
|
||||||
atom() | gone() | redirect(), non_neg_integer()) -> stanza_error().
|
|
||||||
err(Type, Reason, Code) ->
|
|
||||||
#stanza_error{type = Type, reason = Reason, code = Code}.
|
|
||||||
|
|
||||||
-spec err('auth' | 'cancel' | 'continue' | 'modify' | 'wait',
|
|
||||||
atom() | gone() | redirect(), non_neg_integer(),
|
|
||||||
binary(), binary()) -> stanza_error().
|
|
||||||
err(Type, Reason, Code, Text, Lang) ->
|
|
||||||
#stanza_error{type = Type, reason = Reason, code = Code,
|
|
||||||
text = #text{lang = Lang,
|
|
||||||
data = translate:translate(Lang, Text)}}.
|
|
||||||
|
|
||||||
-spec serr(atom() | 'see-other-host'()) -> stream_error().
|
|
||||||
serr(Reason) ->
|
|
||||||
#stream_error{reason = Reason}.
|
|
||||||
|
|
||||||
-spec serr(atom() | 'see-other-host'(), binary(),
|
|
||||||
binary()) -> stream_error().
|
|
||||||
serr(Reason, Text, Lang) ->
|
|
||||||
#stream_error{reason = Reason,
|
|
||||||
text = #text{lang = Lang,
|
|
||||||
data = translate:translate(Lang, Text)}}.
|
|
||||||
|
|
||||||
-spec match_tag(xmlel() | xmpp_element(), binary(), binary()) -> boolean().
|
|
||||||
match_tag(El, TagName, XMLNS) ->
|
|
||||||
get_name(El) == TagName andalso get_ns(El) == XMLNS.
|
|
34647
src/xmpp_codec.erl
34647
src/xmpp_codec.erl
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user