diff --git a/.circleci/template.yml b/.circleci/template.yml index 4e045f79c7..a5e0ea5a62 100644 --- a/.circleci/template.yml +++ b/.circleci/template.yml @@ -460,6 +460,7 @@ jobs: command: | pip3 install mkdocs pip3 install mkdocs-material + pip3 install mkdocs-include-markdown-plugin mkdocs build --strict - when: condition: @@ -540,7 +541,7 @@ jobs: - run: make rel - cache_prod_build: {arch: amd64} - run: - name: Generate DOAP file for xmpp.org + name: Generate DOAP and Markdown files with supported XEPs command: make xeplist - run: name: Build Big Tests diff --git a/.gitignore b/.gitignore index f5b235a81f..697cdfd699 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,7 @@ big_tests/auto_big_tests.spec *.rpm tools/pkg/packages/ +tools/xep_tool/xeplist.xml + +doc/mongooseim.doap +doc/user-guide/Supported-XEPs.md diff --git a/Makefile b/Makefile index 5c7a07187c..18ba1787ac 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,7 @@ certs: maybe_clean_certs xeplist: $(XEP_TOOL)/xep_tool.escript doap doc/mongooseim.doap + $(XEP_TOOL)/xep_tool.escript markdown doc/user-guide/Supported-XEPs.md install: configure.out rel @. ./configure.out && tools/install diff --git a/doc/developers-guide/xep_tool.md b/doc/developers-guide/xep_tool.md index 1ca3bab14b..7f7800065d 100644 --- a/doc/developers-guide/xep_tool.md +++ b/doc/developers-guide/xep_tool.md @@ -79,25 +79,16 @@ To save the output to a file, you can just provide the file name as the second a ```bash tools/xep_tool/xep_tool.escript doap doc/mongooseim.doap +tools/xep_tool/xep_tool.escript markdown doc/user-guide/Supported-XEPs.md ``` -The last command has a shortcut in the Makefile: +The last two commands have a shortcut in the Makefile: ```bash make xeplist ``` -## Generated markdown file example - -||||| -| ------------- | ------------- | ------------- |------------- | -|[XEP-0012: Last Activity](http://www.xmpp.org/extensions/xep-0012.html) | [XEP-0016: Privacy Lists](http://www.xmpp.org/extensions/xep-0016.html) | [XEP-0018: Invisible Presence](http://www.xmpp.org/extensions/xep-0018.html) | [XEP-0022: Message Events](http://www.xmpp.org/extensions/xep-0022.html) | -[XEP-0023: Message Expiration](http://www.xmpp.org/extensions/xep-0023.html) | [XEP-0030: Service Discovery](http://www.xmpp.org/extensions/xep-0030.html) | [XEP-0045: Multi-User Chat](http://www.xmpp.org/extensions/xep-0045.html) | [XEP-0049: Private XML Storage](http://www.xmpp.org/extensions/xep-0049.html) | -[XEP-0050: Ad-Hoc Commands](http://www.xmpp.org/extensions/xep-0050.html) | [XEP-0054: vcard-temp](http://www.xmpp.org/extensions/xep-0054.html) | [XEP-0055: Jabber Search](http://www.xmpp.org/extensions/xep-0055.html) | [XEP-0059: Result Set Management](http://www.xmpp.org/extensions/xep-0059.html) | -[XEP-0068: Field Standardization for Data Forms](http://www.xmpp.org/extensions/xep-0068.html) | [XEP-0077: In-Band Registration](http://www.xmpp.org/extensions/xep-0077.html) | [XEP-0078: Non-SASL Authentication](http://www.xmpp.org/extensions/xep-0078.html) | [XEP-0079: Advanced Message Processing](http://www.xmpp.org/extensions/xep-0079.html) | -[XEP-0082: XMPP Date and Time Profiles](http://www.xmpp.org/extensions/xep-0082.html) | [XEP-0083: Nested Roster Groups](http://www.xmpp.org/extensions/xep-0083.html) | [XEP-0085: Chat State Notifications](http://www.xmpp.org/extensions/xep-0085.html) | [XEP-0086: Error Condition Mappings](http://www.xmpp.org/extensions/xep-0086.html) | -[XEP-0093: Roster Item Exchange](http://www.xmpp.org/extensions/xep-0093.html) | [XEP-0114: Jabber Component Protocol](http://www.xmpp.org/extensions/xep-0114.html) | [XEP-0124: Bidirectional-streams Over Synchronous HTTP (BOSH)](http://www.xmpp.org/extensions/xep-0124.html) | [XEP-0126: Invisibility](http://www.xmpp.org/extensions/xep-0126.html) | -[XEP-0138: Stream Compression](http://www.xmpp.org/extensions/xep-0138.html) | [XEP-0157: Contact Addresses for XMPP Services](http://www.xmpp.org/extensions/xep-0157.html) | [XEP-0160: Best Practices for Handling Offline Messages](http://www.xmpp.org/extensions/xep-0160.html) | [XEP-0170: Recommended Order of Stream Feature Negotiation](http://www.xmpp.org/extensions/xep-0170.html) | -[XEP-0175: Best Practices for Use of SASL ANONYMOUS](http://www.xmpp.org/extensions/xep-0175.html) | [XEP-0198: Stream Management](http://www.xmpp.org/extensions/xep-0198.html) | [XEP-0199: XMPP Ping](http://www.xmpp.org/extensions/xep-0199.html) | [XEP-0202: Entity Time](http://www.xmpp.org/extensions/xep-0202.html) | -[XEP-0206: XMPP Over BOSH](http://www.xmpp.org/extensions/xep-0206.html) | [XEP-0212: XMPP Basic Server 2008](http://www.xmpp.org/extensions/xep-0212.html) | [XEP-0237: Roster Versioning](http://www.xmpp.org/extensions/xep-0237.html) | [XEP-0279: Server IP Check](http://www.xmpp.org/extensions/xep-0279.html) | -[XEP-0280: Message Carbons](http://www.xmpp.org/extensions/xep-0280.html) | [XEP-0313: Message Archive Management](http://xmpp.org/extensions/xep-0313.html) | +## Examples of generated content + +* [Markdown table](../../user-guide/Supported-XEPs/) +* [DOAP file](https://raw.githubusercontent.com/esl/MongooseDocs/gh-pages/latest/mongooseim.doap) diff --git a/doc/user-guide/Supported-standards.md b/doc/user-guide/Supported-standards.md index 22742a1d3f..56e6718619 100644 --- a/doc/user-guide/Supported-standards.md +++ b/doc/user-guide/Supported-standards.md @@ -35,61 +35,9 @@ ## Supported XEPs -|XEP Number|Name|Module| -| ------------- | ------------- | ------------- | -|0004|[Data Forms](http://xmpp.org/extensions/xep-0004.html)|| -|0012|[Last Activity](http://xmpp.org/extensions/xep-0012.html)|[`mod_last`](../modules/mod_last.md)| -|0016|[Privacy Lists](http://xmpp.org/extensions/xep-0016.html)|[`mod_privacy`](../modules/mod_privacy.md)| -|0018|[Invisible Presence](http://xmpp.org/extensions/xep-0018.html)|| -|0022|[Message Events](http://xmpp.org/extensions/xep-0022.html)|[`mod_offline`](../modules/mod_offline.md)| -|0023|[Message Expiration](http://xmpp.org/extensions/xep-0023.html)|[`mod_offline`](../modules/mod_offline.md)| -|0030|[Service Discovery](http://xmpp.org/extensions/xep-0030.html)|[`mod_disco`](../modules/mod_disco.md)| -|0045|[Multi-User Chat](http://xmpp.org/extensions/xep-0045.html)|[`mod_muc`](../modules/mod_muc.md)| -|0049|[Private XML Storage](http://xmpp.org/extensions/xep-0049.html)|[`mod_private`](../modules/mod_private.md)| -|0050|[Ad-Hoc Commands](http://xmpp.org/extensions/xep-0050.html)|[`mod_adhoc`](../modules/mod_adhoc.md)| -|0054|[vcard-temp](http://xmpp.org/extensions/xep-0054.html)|[`mod_vcard`](../modules/mod_vcard.md)| -|0055|[Jabber Search](http://xmpp.org/extensions/xep-0055.html)|[`mod_vcard`](../modules/mod_vcard.md)| -|0059|[Result Set Management](http://xmpp.org/extensions/xep-0059.html)|| -|0060|[Publish-Subscribe](http://xmpp.org/extensions/xep-0060.html)|[`mod_pubsub`](../modules/mod_pubsub.md)| -|0068|[Field Standardization for Data Forms](http://xmpp.org/extensions/xep-0068.html)|| -|0073|[Basic IM Protocol Suite](http://xmpp.org/extensions/xep-0073.html)|| -|0077|[In-Band Registration](http://xmpp.org/extensions/xep-0077.html)|[`mod_register`](../modules/mod_register.md)| -|0079|[Advanced Message Processing](http://xmpp.org/extensions/xep-0079.html)|[`mod_amp`](../modules/mod_amp.md) (partial support)| -|0082|[XMPP Date and Time Profiles](http://xmpp.org/extensions/xep-0082.html)|| -|0085|[Chat State Notifications](http://xmpp.org/extensions/xep-0085.html)|| -|0086|[Error Condition Mappings](http://xmpp.org/extensions/xep-0086.html)|| -|0106|[JID Escaping](http://xmpp.org/extensions/xep-0106.html)|| -|0114|[Jabber Component Protocol](http://xmpp.org/extensions/xep-0114.html)|`ejabberd_service`| -|0115|[Entity Capabilities](http://xmpp.org/extensions/xep-0115.html)|[`mod_caps`](../modules/mod_caps.md)| -|0124|[Bidirectional-streams Over Synchronous HTTP (BOSH)](http://xmpp.org/extensions/xep-0124.html)|[`mod_bosh`](../modules/mod_bosh.md)| -|0126|[Invisibility](http://xmpp.org/extensions/xep-0126.html)|[`mod_privacy`](../modules/mod_privacy.md)| -|0138|[Stream Compression](http://xmpp.org/extensions/xep-0138.html)|| -|0153|[vCard-Based Avatars](http://xmpp.org/extensions/xep-0153.html)|[`mod_vcard`](../modules/mod_vcard.md)| -|0157|[Contact Addresses for XMPP Services](http://xmpp.org/extensions/xep-0157.html)|[`mod_disco`](../modules/mod_disco.md)| -|0160|[Best Practices for Handling Offline Messages](http://xmpp.org/extensions/xep-0160.html)|[`mod_offline`](../modules/mod_offline.md)| -|0163|[Personal Eventing Protocol](http://xmpp.org/extensions/xep-0163.html)|[`mod_pubsub`](../modules/mod_pubsub.md)| -|0170|[Recommended Order of Stream Feature Negotiation](http://xmpp.org/extensions/xep-0170.html)|| -|0175|[Best Practices for Use of SASL ANONYMOUS](http://xmpp.org/extensions/xep-0175.html)|| -|0185|[Dialback Key Generation and Validation](http://www.xmpp.org/extensions/xep-0185.html)|| -|0191|[Blocking Command](http://xmpp.org/extensions/xep-0191.html)|[`mod_blocking`](../modules/mod_blocking.md)| -|0198|[Stream Management](http://xmpp.org/extensions/xep-0198.html)|[`mod_stream_management`](../modules/mod_stream_management.md)| -|0199|[XMPP Ping](http://xmpp.org/extensions/xep-0199.html)|[`mod_ping`](../modules/mod_ping.md)| -|0202|[Entity Time](http://www.xmpp.org/extensions/xep-0202.html)|| -|0203|[Delayed Delivery](http://xmpp.org/extensions/xep-0203.html)|| -|0206|[XMPP Over BOSH](http://xmpp.org/extensions/xep-0206.html)|[`mod_bosh`](../modules/mod_bosh.md)| -|0215|[External Service Discovery](http://xmpp.org/extensions/xep-0215.html)|[`mod_extdisco`](../modules/mod_extdisco.md) -|0237|[Roster Versioning](http://xmpp.org/extensions/xep-0237.html)|[`mod_roster`](../modules/mod_roster.md) -|0270|[XMPP Advanced Server 2010](http://xmpp.org/extensions/xep-0270.html)|| -|0279|[Server IP Check](http://xmpp.org/extensions/xep-0279.html)|[`mod_sic`](../modules/mod_sic.md)| -|0280|[Message Carbons](http://xmpp.org/extensions/xep-0280.html)|[`mod_carboncopy`](../modules/mod_carboncopy.md)| -|0313|[Message Archive Management](http://xmpp.org/extensions/xep-0313.html)|[`mod_mam`](../modules/mod_mam.md)| -|0333|[Chat Markers](https://xmpp.org/extensions/xep-0333.html)|| -|0352|[Client State Indication](http://www.xmpp.org/extensions/xep-0352.html)|[`mod_csi`](../modules/mod_csi.md)| -|0357|[Push Notifications](http://www.xmpp.org/extensions/xep-0357.html)|[`mod_event_pusher_push`](../modules/mod_event_pusher_push.md)| -|0363|[HTTP File Upload](https://xmpp.org/extensions/xep-0363.html)|[`mod_http_upload`](../modules/mod_http_upload.md)| -|0384|[OMEMO Encryption](https://xmpp.org/extensions/xep-0384.html) (MongooseIM supports PEP, which is required by this extension)|| -|0387|[XMPP Compliance Suites 2018 - all suites, Advanced Server level](https://xmpp.org/extensions/xep-0387.html)| -|0424|[Message Retraction](https://xmpp.org/extensions/xep-0424.html)|[`mod_mam`](../modules/mod_mam.md)| +{% + include-markdown "Supported-XEPs.md" +%} ## Supported Open Extensions diff --git a/mkdocs.yml b/mkdocs.yml index b61f6a8f7a..24d52ad768 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ extra: - icon: fontawesome/brands/github link: https://github.com/esl/MongooseIM plugins: + - include-markdown - search: lang: en extra_css: [css/custom.css] diff --git a/src/c2s/mongoose_c2s.erl b/src/c2s/mongoose_c2s.erl index fbd98da2b1..4ed2887d10 100644 --- a/src/c2s/mongoose_c2s.erl +++ b/src/c2s/mongoose_c2s.erl @@ -1,4 +1,5 @@ -module(mongoose_c2s). +-xep([{xep, 170}, {version, "1.0"}]). -behaviour(gen_statem). -include("mongoose_logger.hrl"). diff --git a/src/ejabberd.erl b/src/ejabberd.erl index 4011dee79d..8bb5029e64 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -25,7 +25,6 @@ -module(ejabberd). -author('alexey@process-one.net'). --xep([{xep, 212}, {version, "1.0"}]). -export([start/0, stop/0, get_pid_file/0, diff --git a/src/jlib.erl b/src/jlib.erl index 9b06610deb..4a836cf69c 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -25,6 +25,7 @@ -module(jlib). -author('alexey@process-one.net'). +-xep([{xep, 4}, {version, "2.13.1"}]). -xep([{xep, 59}, {version, "1.0"}]). -xep([{xep, 68}, {version, "1.2"}]). -xep([{xep, 86}, {version, "1.0"}]). diff --git a/src/mam/mod_mam.erl b/src/mam/mod_mam.erl index 1e14c27735..dcba54e8f7 100644 --- a/src/mam/mod_mam.erl +++ b/src/mam/mod_mam.erl @@ -18,6 +18,7 @@ -behaviour(gen_mod). -behaviour(mongoose_module_metrics). -xep([{xep, 313}, {version, "0.6"}, {legacy_versions, ["0.5"]}]). +-xep([{xep, 424}, {version, "0.3.0"}]). -include("mod_mam.hrl"). -include("mongoose_config_spec.hrl"). diff --git a/src/pubsub/mod_pubsub.erl b/src/pubsub/mod_pubsub.erl index 32a465bdb6..f2b2c83739 100644 --- a/src/pubsub/mod_pubsub.erl +++ b/src/pubsub/mod_pubsub.erl @@ -52,6 +52,9 @@ -xep([{xep, 248}, {version, "0.2"}]). -xep([{xep, 277}, {version, "0.6.1"}]). +%% https://xmpp.org/extensions/xep-0384.html#server-side +-xep([{xep, 384}, {version, "0.8.3"}]). + -include("mongoose.hrl"). -include("adhoc.hrl"). -include("jlib.hrl"). diff --git a/tools/xep_tool/xep_tool.escript b/tools/xep_tool/xep_tool.escript index a807f8ad33..8ff7ae7f05 100755 --- a/tools/xep_tool/xep_tool.escript +++ b/tools/xep_tool/xep_tool.escript @@ -23,6 +23,8 @@ -type name() :: string(). -type status() :: complete | partial. % subset of the values from XEP-0453 +-include_lib("kernel/include/file.hrl"). + -record(xep, {xep :: xep(), name :: name(), url :: url(), @@ -103,10 +105,32 @@ modules_to_record_list(Modules) -> -spec all_xep_map() -> #{xep() => {name(), ver()}}. all_xep_map() -> - {ok, {{_, 200, _}, _, Body}} = httpc:request("https://xmpp.org/extensions/xeplist.xml"), - {ok, Root} = exml:parse(iolist_to_binary(Body)), + {ok, Root} = exml:parse(iolist_to_binary(get_xep_list())), maps:from_list([extract_xep(XepElem) || XepElem <- exml_query:subelements(Root, <<"xep">>)]). +-spec get_xep_list() -> iodata(). +get_xep_list() -> + Dir = filename:dirname(escript:script_name()), + FileName = filename:join(Dir, "xeplist.xml"), + case file:read_file_info(FileName) of + {ok, #file_info{mtime = {Date, _Time}}} -> + case date() of + Date -> + {ok, Content} = file:read_file(FileName), + Content; + _ -> + download_xep_list(FileName) % XEP list is updated daily, download the new one + end; + {error, enoent} -> + download_xep_list(FileName) + end. + +-spec download_xep_list(file:filename_all()) -> iodata(). +download_xep_list(FileName) -> + {ok, {{_, 200, _}, _, Body}} = httpc:request("https://xmpp.org/extensions/xeplist.xml"), + file:write_file(FileName, Body), + Body. + -spec extract_xep(exml:element()) -> {xep(), {name(), ver()}}. extract_xep(Element) -> Name = binary_to_list(exml_query:path(Element, [{element, <<"title">>}, cdata])), @@ -195,23 +219,19 @@ generate_output(_, _Records) -> usage(). -spec generate_table([#xep{}]) -> iodata(). generate_table(List) -> - F = fun(#xep{name = Name, url = Url}, {Num, BuildingTable}) -> - Add = case Num rem 4 of - 0 -> - "\n"; - _ -> - " " - end, - {Num + 1, [BuildingTable, "[", Name, "](", Url, ") |", Add]} - end, - {_, TableListElement} = lists:foldl(F, {1, ""}, List), - [generate_prefix(), TableListElement]. + [generate_prefix(), [generate_row(Record) || Record <- List]]. -spec generate_prefix() -> string(). generate_prefix() -> - "|||||\n" - "|-------------|-------------|-------------|-------------|\n" - "|". + "|XEP|Name|Version|Status|Modules|\n" + "|---|----|-------|------|-------|\n". + +-spec generate_row(#xep{}) -> iodata(). +generate_row(#xep{xep = XepId, url = URL, name = Name, version = Version, + status = Status, modules = Modules}) -> + FormatStr = "|`~4..0B`|[~s](~s)|~s|~p|`~s`|~n", + ModuleStr = [string:join(lists:map(fun atom_to_list/1, Modules), "`, `")], + io_lib:format(FormatStr, [XepId, Name, URL, Version, Status, ModuleStr]). -spec generate_list([#xep{}]) -> iodata(). generate_list(RecordList) ->