2013-04-15 12:03:14 +02:00
%%%----------------------------------------------------------------------
%%% File : mod_webpresence.erl
2014-04-08 00:10:05 +02:00
%%% Author : Igor Goryachev <igor@goryachev.org>, Badlop, runcom <antonio.murdaca@gmail.com>
2013-04-15 12:03:14 +02:00
%%% Purpose : Allow user to show presence in the web
%%% Created : 30 Apr 2006 by Igor Goryachev <igor@goryachev.org>
%%% Id : $Id: mod_webpresence.erl 1083 2010-06-01 18:32:55Z badlop $
%%%----------------------------------------------------------------------
- module ( mod_webpresence ) .
- behaviour ( gen_server ) .
- behaviour ( gen_mod ) .
%% API
2018-04-28 11:27:31 +02:00
- export ( [ start / 2 ,
2013-04-15 12:03:14 +02:00
stop / 1 ,
remove_user / 2 ,
web_menu_host / 3 , web_page_host / 3 ,
2018-04-28 11:27:31 +02:00
process_disco_info / 1 ,
process_disco_items / 1 ,
process_vcard / 1 ,
process_register / 1 ,
2014-04-08 00:10:05 +02:00
process / 2
] ) .
2013-04-15 12:03:14 +02:00
%% gen_server callbacks
- export ( [ init / 1 , handle_call / 3 , handle_cast / 2 , handle_info / 2 ,
2018-04-28 11:27:31 +02:00
terminate / 2 , code_change / 3 ,
mod_opt_type / 1 , mod_options / 1 , depends / 2 ] ) .
%% API
- export ( [ start_link / 0 ] ) .
2013-04-15 12:03:14 +02:00
2018-04-28 11:27:31 +02:00
- include ( " xmpp.hrl " ) .
2014-04-08 00:10:05 +02:00
- include ( " logger.hrl " ) .
2019-08-19 20:42:03 +02:00
- include ( " translate.hrl " ) .
2014-04-08 00:10:05 +02:00
- include ( " ejabberd_web_admin.hrl " ) .
- include ( " ejabberd_http.hrl " ) .
2013-04-15 12:03:14 +02:00
2018-04-28 11:27:31 +02:00
- record ( webpresence , { us , ridurl = false , jidurl = false , xml = false , avatar = false , js = false , text = false , icon = " jsf-text " } ) .
2013-04-15 12:03:14 +02:00
- record ( state , { host , server_host , base_url , access } ) .
2018-04-28 11:27:31 +02:00
- record ( presence2 , { resource , show , priority , status } ) .
2013-04-15 12:03:14 +02:00
%% Copied from ejabberd_sm.erl
- record ( session , { sid , usr , us , priority , info } ) .
2014-04-08 00:10:05 +02:00
- define ( PIXMAPS_DIR , < < " pixmaps " > > ) .
2013-04-15 12:03:14 +02:00
- define ( AUTO_ACL , webpresence_auto ) .
%%====================================================================
%% API
%%====================================================================
2018-04-28 11:27:31 +02:00
start_link ( ) - >
gen_server : start_link ( { local , ? MODULE } , ? MODULE , [ ] , [ ] ) .
2013-04-15 12:03:14 +02:00
start ( Host , Opts ) - >
2019-08-19 20:42:03 +02:00
Dir = gen_mod : get_opt ( pixmaps_path , Opts ) ,
2013-04-15 12:03:14 +02:00
catch ets : new ( pixmaps_dirs , [ named_table , public ] ) ,
ets : insert ( pixmaps_dirs , { directory , Dir } ) ,
2018-04-28 11:27:31 +02:00
case gen_mod : start_child ( ? MODULE , Host , Opts ) of
{ ok , Ref } - >
{ ok , Ref } ;
{ error , { already_started , Ref } } - >
{ ok , Ref } ;
{ error , Reason } - >
{ error , Reason }
end .
2013-04-15 12:03:14 +02:00
stop ( Host ) - >
2018-04-28 11:27:31 +02:00
Proc = gen_mod : get_module_proc ( Host , ? MODULE ) ,
2013-04-15 12:03:14 +02:00
gen_server : call ( Proc , stop ) ,
2018-04-28 11:27:31 +02:00
gen_mod : stop_child ( ? MODULE , Host ) ,
ok .
2019-08-19 20:42:03 +02:00
mod_opt_type ( host ) - >
econf : host ( ) ;
mod_opt_type ( access ) - >
econf : acl ( ) ;
mod_opt_type ( pixmaps_path ) - >
econf : directory ( ) ;
2018-04-28 11:27:31 +02:00
mod_opt_type ( port ) - >
2019-08-19 20:42:03 +02:00
econf : pos_int ( ) ;
mod_opt_type ( path ) - >
econf : binary ( ) ;
mod_opt_type ( baseurl ) - >
econf : binary ( ) .
2018-04-28 11:27:31 +02:00
- spec mod_options ( binary ( ) ) - > [ { atom ( ) , any ( ) } ] .
mod_options ( Host ) - >
2019-08-19 20:42:03 +02:00
[ { host , < < " webpresence. " , Host / binary > > } ,
{ access , local } ,
2018-04-28 11:27:31 +02:00
{ pixmaps_path , ? PIXMAPS_DIR } ,
{ port , 5280 } ,
{ path , < < " presence " > > } ,
{ baseurl , iolist_to_binary ( io_lib : format ( < < " http:// ~s :5280/presence/ " > > , [ Host ] ) ) } ] .
- spec depends ( binary ( ) , gen_mod : opts ( ) ) - > [ { module ( ) , hard | soft } ] .
depends ( _ Host , _ Opts ) - >
[ ] .
2013-04-15 12:03:14 +02:00
%%====================================================================
%% gen_server callbacks
%%====================================================================
%%--------------------------------------------------------------------
%% Function: init(Args) -> {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
init ( [ Host , Opts ] ) - >
mnesia : create_table ( webpresence ,
[ { disc_copies , [ node ( ) ] } ,
{ attributes , record_info ( fields , webpresence ) } ] ) ,
mnesia : add_table_index ( webpresence , ridurl ) ,
update_table ( ) ,
2019-08-19 20:42:03 +02:00
MyHost = gen_mod : get_opt ( host , Opts ) ,
Access = gen_mod : get_opt ( access , Opts ) ,
BaseURL1 = gen_mod : get_opt ( baseurl , Opts ) ,
2014-09-14 22:45:05 +02:00
BaseURL2 = ejabberd_regexp : greplace ( BaseURL1 , < < " @HOST@ " > > , Host ) ,
2018-04-28 11:27:31 +02:00
register_iq_handlers ( MyHost ) ,
ejabberd_router : register_route ( MyHost , Host ) ,
2013-04-15 12:03:14 +02:00
ejabberd_hooks : add ( remove_user , Host , ? MODULE , remove_user , 50 ) ,
ejabberd_hooks : add ( webadmin_menu_host , Host , ? MODULE , web_menu_host , 50 ) ,
ejabberd_hooks : add ( webadmin_page_host , Host , ? MODULE , web_page_host , 50 ) ,
{ ok , #state { host = MyHost ,
server_host = Host ,
2014-09-14 22:45:05 +02:00
base_url = BaseURL2 ,
2013-04-15 12:03:14 +02:00
access = Access } } .
2018-04-28 11:27:31 +02:00
register_iq_handlers ( Host ) - >
gen_iq_handler : add_iq_handler ( ejabberd_local , Host , ? NS_REGISTER ,
? MODULE , process_register ) ,
gen_iq_handler : add_iq_handler ( ejabberd_local , Host , ? NS_VCARD ,
? MODULE , process_vcard ) ,
gen_iq_handler : add_iq_handler ( ejabberd_local , Host , ? NS_DISCO_INFO ,
? MODULE , process_disco_info ) ,
gen_iq_handler : add_iq_handler ( ejabberd_local , Host , ? NS_DISCO_ITEMS ,
? MODULE , process_disco_items ) .
unregister_iq_handlers ( Host ) - >
gen_iq_handler : remove_iq_handler ( ejabberd_local , Host , ? NS_REGISTER ) ,
gen_iq_handler : remove_iq_handler ( ejabberd_local , Host , ? NS_VCARD ) ,
gen_iq_handler : remove_iq_handler ( ejabberd_local , Host , ? NS_DISCO_INFO ) ,
gen_iq_handler : remove_iq_handler ( ejabberd_local , Host , ? NS_DISCO_ITEMS ) .
2013-04-15 12:03:14 +02:00
%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} |
%% {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call ( stop , _ From , State ) - >
{ stop , normal , ok , State } .
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling cast messages
%%--------------------------------------------------------------------
handle_cast ( _ Msg , State ) - >
{ noreply , State } .
%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
2018-04-28 11:27:31 +02:00
handle_info ( { route , Packet } ,
2013-04-15 12:03:14 +02:00
#state { host = Host ,
server_host = ServerHost ,
base_url = BaseURL ,
access = Access } = State ) - >
2018-04-28 11:27:31 +02:00
From = xmpp : get_from ( Packet ) ,
To = xmpp : get_to ( Packet ) ,
2013-04-15 12:03:14 +02:00
case catch do_route ( Host , ServerHost , Access , From , To , Packet , BaseURL ) of
{ 'EXIT' , Reason } - >
? ERROR_MSG ( " ~p " , [ Reason ] ) ;
_ - >
ok
end ,
{ noreply , State } .
%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate ( _ Reason , #state { host = Host } ) - >
ejabberd_router : unregister_route ( Host ) ,
2018-04-28 11:27:31 +02:00
unregister_iq_handlers ( Host ) ,
2013-04-15 12:03:14 +02:00
ejabberd_hooks : delete ( remove_user , Host , ? MODULE , remove_user , 50 ) ,
ejabberd_hooks : delete ( webadmin_menu_host , Host , ? MODULE , web_menu_host , 50 ) ,
ejabberd_hooks : delete ( webadmin_page_host , Host , ? MODULE , web_page_host , 50 ) ,
ok .
%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change ( _ OldVsn , State , _ Extra ) - >
{ ok , State } .
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
do_route ( Host , ServerHost , Access , From , To , Packet , BaseURL ) - >
case acl : match_rule ( ServerHost , Access , From ) of
allow - >
do_route1 ( Host , From , To , Packet , BaseURL ) ;
_ - >
2018-04-28 11:27:31 +02:00
Lang = xmpp : get_lang ( Packet ) ,
2014-04-08 00:10:05 +02:00
ErrText = < < " Access denied by service policy " > > ,
2018-04-28 11:27:31 +02:00
Err = xmpp : err_forbidden ( ErrText , Lang ) ,
ejabberd_router : route_error ( Packet , Err )
2013-04-15 12:03:14 +02:00
end .
2018-04-28 11:27:31 +02:00
- spec process_vcard ( iq ( ) ) - > iq ( ) .
process_vcard ( #iq { type = get , lang = Lang , sub_els = [ #vcard_temp { } ] } = IQ ) - >
Desc = translate : translate ( Lang , < < " ejabberd Web Presence module " > > ) ,
xmpp : make_iq_result (
IQ , #vcard_temp { fn = < < " ejabberd/mod_webpresence " > > ,
2018-07-13 16:17:59 +02:00
url = ejabberd_config : get_uri ( ) ,
desc = Desc } ) ;
2018-04-28 11:27:31 +02:00
process_vcard ( #iq { type = set , lang = Lang } = IQ ) - >
Txt = < < " Value 'set' of 'type' attribute is not allowed " > > ,
xmpp : make_error ( IQ , xmpp : err_not_allowed ( Txt , Lang ) ) ;
process_vcard ( #iq { lang = Lang } = IQ ) - >
Txt = < < " No module is handling this query " > > ,
xmpp : make_error ( IQ , xmpp : err_service_unavailable ( Txt , Lang ) ) .
do_route1 ( _ Host , _ From , _ To , #iq { } = IQ , _ BaseURL ) - >
2018-08-21 12:27:44 +02:00
ejabberd_router : process_iq ( IQ ) ;
2018-04-28 11:27:31 +02:00
do_route1 ( _ Host , _ From , _ To , Packet , _ BaseURL ) - >
case xmpp : get_type ( Packet ) of
error - > ok ;
_ - >
Err = xmpp : err_item_not_found ( ) ,
ejabberd_router : route_error ( Packet , Err )
2013-04-15 12:03:14 +02:00
end .
2018-04-28 11:27:31 +02:00
- spec process_register ( iq ( ) ) - > iq ( ) .
process_register ( #iq { type = get , from = From , to = To , lang = Lang ,
sub_els = [ #register { } ] } = IQ ) - >
Host = To #jid.lserver ,
xmpp : make_iq_result ( IQ , iq_get_register_info ( Host , From , Lang ) ) ;
process_register ( #iq { type = set , from = From , to = To ,
lang = Lang , sub_els = [ El = #register { } ] } = IQ ) - >
Host = To #jid.lserver ,
ServerHost = ejabberd_router : host_of_route ( Host ) ,
case process_iq_register_set ( ServerHost , Host , From , El , Lang ) of
{ result , Result } - >
xmpp : make_iq_result ( IQ , Result ) ;
{ error , Err } - >
xmpp : make_error ( IQ , Err )
end .
2013-04-15 12:03:14 +02:00
2018-04-28 11:27:31 +02:00
- spec process_disco_info ( iq ( ) ) - > iq ( ) .
process_disco_info ( #iq { type = set , lang = Lang } = IQ ) - >
Txt = < < " Value 'set' of 'type' attribute is not allowed " > > ,
xmpp : make_error ( IQ , xmpp : err_not_allowed ( Txt , Lang ) ) ;
process_disco_info ( #iq { type = get , lang = Lang ,
sub_els = [ #disco_info { node = < < " " > > } ] } = IQ ) - >
Features = [ ? NS_DISCO_INFO , ? NS_DISCO_ITEMS ,
? NS_REGISTER , ? NS_VCARD ] ,
Identity = #identity { category = < < " component " > > ,
type = < < " presence " > > ,
name = translate : translate ( Lang , < < " Web Presence " > > ) } ,
xmpp : make_iq_result (
IQ , #disco_info { features = Features ,
identities = [ Identity ] } ) ;
process_disco_info ( #iq { type = get , lang = Lang ,
sub_els = [ #disco_info { } ] } = IQ ) - >
xmpp : make_error ( IQ , xmpp : err_item_not_found ( < < " Node not found " > > , Lang ) ) ;
process_disco_info ( #iq { lang = Lang } = IQ ) - >
Txt = < < " No module is handling this query " > > ,
xmpp : make_error ( IQ , xmpp : err_service_unavailable ( Txt , Lang ) ) .
- spec process_disco_items ( iq ( ) ) - > iq ( ) .
process_disco_items ( #iq { type = set , lang = Lang } = IQ ) - >
Txt = < < " Value 'set' of 'type' attribute is not allowed " > > ,
xmpp : make_error ( IQ , xmpp : err_not_allowed ( Txt , Lang ) ) ;
process_disco_items ( #iq { type = get ,
sub_els = [ #disco_items { } ] } = IQ ) - >
xmpp : make_iq_result ( IQ , #disco_items { } ) ;
process_disco_items ( #iq { lang = Lang } = IQ ) - >
Txt = < < " No module is handling this query " > > ,
xmpp : make_error ( IQ , xmpp : err_service_unavailable ( Txt , Lang ) ) .
2013-04-15 12:03:14 +02:00
- define ( XFIELDS ( Type , Label , Var , Vals ) ,
2014-04-08 00:10:05 +02:00
#xmlel {
name = < < " field " > > ,
attrs = [
{ < < " type " > > , Type } ,
2019-08-19 20:42:03 +02:00
{ < < " label " > > , translate : translate ( Lang , ? T ( Label ) ) } ,
2014-04-08 00:10:05 +02:00
{ < < " var " > > , Var }
] ,
children = Vals
} ) .
2013-04-15 12:03:14 +02:00
- define ( XFIELD ( Type , Label , Var , Val ) ,
2014-04-08 00:10:05 +02:00
? XFIELDS ( Type , Label , Var ,
[
#xmlel {
name = < < " value " > > ,
attrs = [ ] ,
children = [ { xmlcdata , Val } ]
} ] )
2013-04-15 12:03:14 +02:00
) .
- define ( XFIELDFIXED ( Val ) ,
2014-04-08 00:10:05 +02:00
#xmlel {
name = < < " field " > > ,
attrs = [ { < < " type " > > , < < " fixed " > > } ] ,
children = [
#xmlel {
name = < < " value " > > ,
attrs = [ ] ,
children = [ { xmlcdata , Val } ]
}
]
}
2013-04-15 12:03:14 +02:00
) .
2014-04-08 00:10:05 +02:00
- define ( ATOM2BINARY ( Val ) , iolist_to_binary ( atom_to_list ( Val ) ) ) .
- define ( BC ( L ) , iolist_to_binary ( L ) ) .
ridurl_out ( false ) - > < < " false " > > ;
ridurl_out ( Id ) when is_binary ( Id ) - > < < " true " > > .
2013-04-15 12:03:14 +02:00
get_pr ( LUS ) - >
case catch mnesia : dirty_read ( webpresence , LUS ) of
2018-04-28 11:27:31 +02:00
[ #webpresence { jidurl = J , ridurl = H , xml = X , avatar = A , js = S , text = T , icon = I } ] - >
{ J , H , X , A , S , T , I , true } ;
_ - >
{ true , false , false , false , false , false , < < " " > > , false }
2013-04-15 12:03:14 +02:00
end .
2018-04-28 11:27:31 +02:00
iq_get_register_info ( Host , From , Lang ) - >
LUS = { From #jid.luser , From #jid.lserver } ,
{ _ JidUrl , _ RidUrl , _ XML , _ Avatar , _ JS , _ Text , Icon , Registered } = get_pr ( LUS ) ,
Nick = Icon ,
Title = < < ( translate : translate (
Lang , < < " Web Presence Registration at " > > ) ) / binary , Host / binary > > ,
Inst = translate : translate ( Lang , < < " Enter iconset you want to use by default " > > ) ,
Fields = muc_register : encode ( [ { roomnick , Nick } ] , Lang ) ,
X = #xdata { type = form , title = Title ,
instructions = [ Inst ] , fields = Fields } ,
#register { nick = Nick ,
registered = Registered ,
instructions =
translate : translate (
Lang , < < " You need a client that supports x:data "
" to register to Web Presence " > > ) ,
xdata = X } .
2018-08-21 12:27:44 +02:00
process_iq_register_set ( _ ServerHost , Host , From ,
2018-04-28 11:27:31 +02:00
#register { remove = true } , Lang ) - >
unregister_webpresence ( From , Host , Lang ) ;
process_iq_register_set ( _ ServerHost , _ Host , _ From ,
#register { xdata = #xdata { type = cancel } } , _ Lang ) - >
{ result , undefined } ;
process_iq_register_set ( ServerHost , Host , From ,
#register { nick = Nick , xdata = XData } , Lang ) - >
case XData of
#xdata { type = submit , fields = Fs } - >
try
Options = muc_register : decode ( Fs ) ,
N = proplists : get_value ( roomnick , Options ) ,
iq_set_register_info ( ServerHost , Host , From , N , Lang )
catch _ : { muc_register , Why } - >
ErrText = muc_register : format_error ( Why ) ,
{ error , xmpp : err_bad_request ( ErrText , Lang ) }
end ;
#xdata { } - >
Txt = < < " Incorrect data form " > > ,
{ error , xmpp : err_bad_request ( Txt , Lang ) } ;
_ when is_binary ( Nick ) , Nick / = < < " " > > - >
iq_set_register_info ( ServerHost , Host , From , Nick , Lang ) ;
_ - >
ErrText = < < " You must fill in field \" Nickname \" in the form " > > ,
{ error , xmpp : err_not_acceptable ( ErrText , Lang ) }
end .
2014-04-08 00:10:05 +02:00
2018-04-28 11:27:31 +02:00
iq_set_register_info ( ServerHost , Host , From , Nick ,
Lang ) - >
case iq_set_register_info2 ( ServerHost , Host , From , Nick , Lang ) of
{ atomic , ok } - > { result , undefined } ;
_ - >
Txt = < < " Database failure " > > ,
{ error , xmpp : err_internal_server_error ( Txt , Lang ) }
2013-04-15 12:03:14 +02:00
end .
2018-04-28 11:27:31 +02:00
iq_set_register_info2 ( ServerHost , Host , From , Icon , Lang ) - >
%% RidUrl2 = get_rid_final_value(RidUrl, LUS),
LUS = { From #jid.luser , From #jid.lserver } ,
2013-04-15 12:03:14 +02:00
WP = #webpresence { us = LUS ,
2018-04-28 11:27:31 +02:00
jidurl = true ,
ridurl = false ,
xml = true ,
2018-08-21 12:27:44 +02:00
avatar = true ,
2018-04-28 11:27:31 +02:00
js = true ,
text = true ,
2013-04-15 12:03:14 +02:00
icon = Icon } ,
F = fun ( ) - > mnesia : write ( WP ) end ,
case mnesia : transaction ( F ) of
{ atomic , ok } - >
2018-04-28 11:27:31 +02:00
BaseURL = get_baseurl ( ServerHost ) ,
2013-04-15 12:03:14 +02:00
send_message_registered ( WP , From , Host , BaseURL , Lang ) ,
2018-04-28 11:27:31 +02:00
{ atomic , ok } ;
2013-04-15 12:03:14 +02:00
_ - >
2018-04-28 11:27:31 +02:00
{ error , xmpp : err_internal_server_error ( ) }
2013-04-15 12:03:14 +02:00
end .
send_message_registered ( WP , To , Host , BaseURL , Lang ) - >
{ User , Server } = WP #webpresence.us ,
2018-08-21 12:27:44 +02:00
JIDS = jid : encode ( { User , Server , < < " " > > } ) ,
2013-04-15 12:03:14 +02:00
Oavatar = case WP #webpresence.avatar of
2014-04-08 00:10:05 +02:00
false - > < < " " > > ;
true - > < < " avatar \n "
" avatar/my.png \n " > >
2013-04-15 12:03:14 +02:00
end ,
Ojs = case WP #webpresence.js of
2014-04-08 00:10:05 +02:00
false - > < < " " > > ;
true - > < < " js \n " > >
2013-04-15 12:03:14 +02:00
end ,
Otext = case WP #webpresence.text of
2014-04-08 00:10:05 +02:00
false - > < < " " > > ;
true - > ? BC ( [
< < " text \n "
2019-08-19 20:42:03 +02:00
" text/res/< " > > , translate : translate ( Lang , ? T ( " Resource " ) ) , < < " > \n " > >
2014-04-08 00:10:05 +02:00
] )
2013-04-15 12:03:14 +02:00
end ,
Oimage = case WP #webpresence.icon of
2014-04-08 00:10:05 +02:00
< < " --- " > > - > " " ;
I when is_binary ( I ) - >
? BC ( [
< < " image \n "
" image/example.php \n "
" image/mypresence.png \n "
2019-08-19 20:42:03 +02:00
" image/res/< " > > , translate : translate ( Lang , ? T ( " Resource " ) ) , < < " > \n "
" image/theme/< " > > , translate : translate ( Lang , ? T ( " Icon Theme " ) ) , < < " > \n "
" image/theme/< " > > , translate : translate ( Lang , ? T ( " Icon Theme " ) ) , < < " >/res/< " > > , translate : translate ( Lang , ? T ( " Resource " ) ) , < < " > \n " > >
2014-04-08 00:10:05 +02:00
] )
2013-04-15 12:03:14 +02:00
end ,
Oxml = case WP #webpresence.xml of
2014-04-08 00:10:05 +02:00
false - > < < " " > > ;
true - > < < " xml \n " > >
2013-04-15 12:03:14 +02:00
end ,
Allowed_type = case { Oimage , Oxml , Oavatar , Otext , Ojs } of
2014-04-08 00:10:05 +02:00
{ < < " " > > , < < " " > > , < < " " > > , < < " " > > , _ } - > < < " js " > > ;
{ < < " " > > , < < " " > > , < < " " > > , _ , _ } - > < < " text " > > ;
{ < < " " > > , < < " " > > , _ , _ , _ } - > < < " avatar " > > ;
{ < < " " > > , _ , _ , _ , _ } - > < < " xml " > > ;
{ _ , _ , _ , _ , _ } - > < < " image " > >
2013-04-15 12:03:14 +02:00
end ,
{ USERID_jid , Example_jid } = case WP #webpresence.jidurl of
2014-04-08 00:10:05 +02:00
false - > { < < " " > > , < < " " > > } ;
true - >
JIDT = ? BC ( [ < < " jid/ " > > , User , < < " / " > > , Server ] ) ,
{ ? BC ( [ < < " " > > , JIDT , < < " \n " > > ] ) ,
? BC ( [ < < " " > > , BaseURL , JIDT , < < " / " > > , Allowed_type , < < " / \n " > > ] ) }
2013-04-15 12:03:14 +02:00
end ,
{ USERID_rid , Example_rid , Text_rid } = case WP #webpresence.ridurl of
2014-04-08 00:10:05 +02:00
false - > { < < " " > > , < < " " > > , < < " " > > } ;
RID when is_binary ( RID ) - >
RIDT = ? BC ( [ < < " rid/ " > > , RID ] ) ,
{ ? BC ( [ < < " " > > , RIDT , < < " \n " > > ] ) ,
? BC ( [ < < " " > > , BaseURL , RIDT , < < " / " > > , Allowed_type , < < " / \n " > > ] ) ,
2019-08-19 20:42:03 +02:00
? BC ( [ translate : translate ( Lang , ? T ( " If you forget your RandomID, register again to receive this message. " ) ) , < < " \n " > > ,
translate : translate ( Lang , ? T ( " To get a new RandomID, disable the option and register again. " ) ) , < < " \n " > > ] )
2013-04-15 12:03:14 +02:00
}
end ,
2019-08-19 20:42:03 +02:00
Subject = ? BC ( [ translate : translate ( Lang , ? T ( " Web Presence " ) ) , < < " : " > > , translate : translate ( Lang , ? T ( " registered " ) ) ] ) ,
Body = ? BC ( [ translate : translate ( Lang , ? T ( " You have registered: " ) ) , < < " " > > , JIDS , < < " \n \n " > > ,
translate : translate ( Lang , ? T ( " Use URLs like: " ) ) , < < " \n " > > ,
2014-04-08 00:10:05 +02:00
< < " " > > , BaseURL , < < " USERID/OUTPUT/ \n " > > ,
< < " \n " > > ,
< < " USERID: \n " > > , USERID_jid , USERID_rid , < < " \n " > > ,
< < " OUTPUT: \n " > > , Oimage , Oxml , Ojs , Otext , Oavatar , < < " \n " > > ,
2019-08-19 20:42:03 +02:00
translate : translate ( Lang , ? T ( " Example: " ) ) , < < " \n " > > , Example_jid , Example_rid , < < " \n " > > ,
2014-04-08 00:10:05 +02:00
Text_rid ] ) ,
2013-04-15 12:03:14 +02:00
send_headline ( Host , To , Subject , Body ) .
send_message_unregistered ( To , Host , Lang ) - >
2019-08-19 20:42:03 +02:00
Subject = ? BC ( [ translate : translate ( Lang , ? T ( " Web Presence " ) ) , < < " : " > > , translate : translate ( Lang , ? T ( " unregistered " ) ) ] ) ,
Body = ? BC ( [ translate : translate ( Lang , ? T ( " You have unregistered. " ) ) , < < " \n \n " > > ] ) ,
2013-04-15 12:03:14 +02:00
send_headline ( Host , To , Subject , Body ) .
send_headline ( Host , To , Subject , Body ) - >
2019-08-28 16:09:37 +02:00
Packet = #message { type = headline ,
from = jid : make ( Host ) ,
to = To ,
body = xmpp : mk_text ( Body ) ,
subject = xmpp : mk_text ( Subject ) } ,
ejabberd_router : route ( Packet ) .
2013-04-15 12:03:14 +02:00
unregister_webpresence ( From , Host , Lang ) - >
2018-04-28 11:27:31 +02:00
remove_user ( From #jid.luser , From #jid.lserver ) ,
2013-04-15 12:03:14 +02:00
send_message_unregistered ( From , Host , Lang ) ,
2018-04-28 11:27:31 +02:00
{ result , undefined } .
2013-04-15 12:03:14 +02:00
remove_user ( User , Server ) - >
mnesia : dirty_delete ( webpresence , { User , Server } ) .
get_wp ( LUser , LServer ) - >
LUS = { LUser , LServer } ,
case catch mnesia : dirty_read ( webpresence , LUS ) of
2014-04-08 00:10:05 +02:00
{ 'EXIT' , _ Reason } - >
2013-04-15 12:03:14 +02:00
try_auto_webpresence ( LUser , LServer ) ;
2014-04-08 00:10:05 +02:00
[ ] - >
2013-04-15 12:03:14 +02:00
try_auto_webpresence ( LUser , LServer ) ;
[ WP ] when is_record ( WP , webpresence ) - >
WP
end .
try_auto_webpresence ( LUser , LServer ) - >
2018-08-21 12:27:44 +02:00
From = jid : make ( LUser , LServer , < < " " > > ) ,
2013-04-15 12:03:14 +02:00
case acl : match_rule ( LServer , ? AUTO_ACL , From ) of
2014-04-08 00:10:05 +02:00
deny - >
2013-04-15 12:03:14 +02:00
#webpresence { } ;
2014-04-08 00:10:05 +02:00
allow - >
#webpresence { us = { LUser , LServer } ,
ridurl = false ,
jidurl = true ,
xml = true ,
2018-08-21 12:27:44 +02:00
avatar = true ,
2014-04-08 00:10:05 +02:00
js = true ,
text = true ,
2018-04-28 11:27:31 +02:00
icon = " jsf-jabber-text " }
2014-04-08 00:10:05 +02:00
end .
2013-04-15 12:03:14 +02:00
get_status_weight ( Show ) - >
case Show of
2014-04-08 00:10:05 +02:00
< < " chat " > > - > 0 ;
< < " available " > > - > 1 ;
< < " away " > > - > 2 ;
< < " xa " > > - > 3 ;
< < " dnd " > > - > 4 ;
_ - > 9
2013-04-15 12:03:14 +02:00
end .
2018-04-28 11:27:31 +02:00
session_to_presence ( #session { sid = { _ , Pid } } ) - >
P = ejabberd_c2s : get_presence ( Pid ) ,
#presence2 { resource = ( P #presence.from ) #jid.resource ,
2018-10-19 18:08:10 +02:00
show = misc : atom_to_binary ( humanize_show ( P #presence.show ) ) ,
2018-04-28 11:27:31 +02:00
priority = P #presence.priority ,
status = xmpp : get_text ( P #presence.status ) } .
2013-04-15 12:03:14 +02:00
2018-10-19 18:08:10 +02:00
humanize_show ( undefined ) - >
available ;
humanize_show ( Show ) - >
Show .
2013-04-15 12:03:14 +02:00
get_presences ( { bare , LUser , LServer } ) - >
[ session_to_presence ( Session ) | |
Session < - mnesia : dirty_index_read ( session , { LUser , LServer } , #session.us ) ] ;
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
get_presences ( { sorted , LUser , LServer } ) - >
lists : sort (
fun ( A , B ) - >
if
2018-04-28 11:27:31 +02:00
A #presence2.priority == B #presence2.priority - >
WA = get_status_weight ( A #presence2.show ) ,
WB = get_status_weight ( B #presence2.show ) ,
2013-04-15 12:03:14 +02:00
WA < WB ;
true - >
2018-04-28 11:27:31 +02:00
A #presence2.priority > B #presence2.priority
2013-04-15 12:03:14 +02:00
end
end ,
get_presences ( { bare , LUser , LServer } ) ) ;
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
get_presences ( { xml , LUser , LServer , Show_us } ) - >
2014-04-08 00:10:05 +02:00
#xmlel {
name = < < " presence " > > ,
attrs = case Show_us of
true - > [ { < < " user " > > , LUser } , { < < " server " > > , LServer } ] ;
false - > [ ]
end ,
children = lists : map (
fun ( Presence ) - >
#xmlel {
name = < < " resource " > > ,
attrs = [
2018-04-28 11:27:31 +02:00
{ < < " name " > > , Presence #presence2.resource } ,
{ < < " show " > > , Presence #presence2.show } ,
2018-11-07 13:00:33 +01:00
{ < < " priority " > > , intund2string ( Presence #presence2.priority ) }
2014-04-08 00:10:05 +02:00
] ,
2018-04-28 11:27:31 +02:00
children = [ { xmlcdata , Presence #presence2.status } ]
2014-04-08 00:10:05 +02:00
}
end ,
get_presences ( { sorted , LUser , LServer } )
)
} ;
2013-04-15 12:03:14 +02:00
get_presences ( { status , LUser , LServer , LResource } ) - >
case get_presences ( { sorted , LUser , LServer } ) of
2014-04-08 00:10:05 +02:00
[ ] - > < < " unavailable " > > ;
Rs - >
2013-04-15 12:03:14 +02:00
{ value , R } = lists : keysearch ( LResource , 2 , Rs ) ,
2018-04-28 11:27:31 +02:00
R #presence2.status
2013-04-15 12:03:14 +02:00
end ;
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
get_presences ( { status , LUser , LServer } ) - >
case get_presences ( { sorted , LUser , LServer } ) of
[ Highest | _ Rest ] - >
2018-04-28 11:27:31 +02:00
Highest #presence2.status ;
2013-04-15 12:03:14 +02:00
_ - >
2014-04-08 00:10:05 +02:00
< < " unavailable " > >
2013-04-15 12:03:14 +02:00
end ;
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
get_presences ( { show , LUser , LServer , LResource } ) - >
case get_presences ( { sorted , LUser , LServer } ) of
2014-04-08 00:10:05 +02:00
[ ] - > < < " unavailable " > > ;
Rs - >
2013-04-15 12:03:14 +02:00
{ value , R } = lists : keysearch ( LResource , 2 , Rs ) ,
2018-04-28 11:27:31 +02:00
R #presence2.show
2013-04-15 12:03:14 +02:00
end ;
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
get_presences ( { show , LUser , LServer } ) - >
case get_presences ( { sorted , LUser , LServer } ) of
[ Highest | _ Rest ] - >
2018-04-28 11:27:31 +02:00
Highest #presence2.show ;
2013-04-15 12:03:14 +02:00
_ - >
2014-04-08 00:10:05 +02:00
< < " unavailable " > >
2013-04-15 12:03:14 +02:00
end .
make_js ( WP , Prs , Show_us , Lang , Q ) - >
{ User , Server } = WP #webpresence.us ,
BaseURL = get_baseurl ( Server ) ,
US_string = case Show_us of
2014-04-08 00:10:05 +02:00
true - >
? BC ( [ < < " var jabber_user=' " > > , User , < < " '; \n " > > , < < " var jabber_server=' " > > , Server , < < " '; \n " > > ] ) ; false - > < < " " > >
2013-04-15 12:03:14 +02:00
end ,
FunImage = fun ( I , S ) - >
case I of
2014-04-08 00:10:05 +02:00
< < " --- " > > - > < < " " > > ;
Icon - > ? BC ( [ < < " image:' " > > , BaseURL , < < " image/ " > > , Icon , < < " / " > > , S , < < " ' \n " > > ] )
2013-04-15 12:03:14 +02:00
end
end ,
R_string_list = case Prs of
2014-04-08 00:10:05 +02:00
[ ] - >
Show = < < " unavailable " > > ,
[ ? BC ( [ < < " {show:' " > > , Show , < < " ', \n " > > ,
< < " long_show:' " > > , long_show ( Show , Lang ) , < < " ', \n " > > ,
< < " status:'', \n " > > , % TODO
FunImage ( WP #webpresence.icon , Show ) ,
< < " } " > > ] ) ] ;
2013-04-15 12:03:14 +02:00
_ - > lists : map (
fun ( Pr ) - >
2018-04-28 11:27:31 +02:00
Show = Pr #presence2.show ,
? BC ( [ < < " {name:' " > > , Pr #presence2.resource , < < " ', \n " > > ,
< < " priority: " > > , intund2string ( Pr #presence2.priority ) , < < " , \n " > > ,
2014-04-08 00:10:05 +02:00
< < " show:' " > > , Show , < < " ', \n " > > ,
< < " long_show:' " > > , long_show ( Show , Lang ) , < < " ', \n " > > ,
2018-04-28 11:27:31 +02:00
< < " status:' " > > , escape ( Pr #presence2.status ) , < < " ', \n " > > ,
2014-04-08 00:10:05 +02:00
FunImage ( WP #webpresence.icon , Show ) ,
< < " } " > > ] )
2013-04-15 12:03:14 +02:00
end ,
Prs )
end ,
R_string = lists : foldl (
fun ( RS , Res ) - >
case Res of
2014-04-08 00:10:05 +02:00
< < " " > > - > RS ;
_ - > ? BC ( [ Res , < < " , \n " > > , RS ] )
2013-04-15 12:03:14 +02:00
end
end ,
2014-04-08 00:10:05 +02:00
< < " " > > ,
2013-04-15 12:03:14 +02:00
R_string_list ) ,
2014-04-08 00:10:05 +02:00
CB_string = case lists : keysearch ( < < " cb " > > , 1 , Q ) of
{ value , { _ , CB } } - > ? BC ( [ < < " " > > , CB , < < " (); " > > ] ) ;
_ - > < < " " > >
2013-04-15 12:03:14 +02:00
end ,
2014-04-08 00:10:05 +02:00
? BC ( [ US_string , < < " var jabber_resources=[ \n " > > , R_string , < < " ]; " > > , CB_string ] ) .
2013-04-15 12:03:14 +02:00
2019-08-19 20:42:03 +02:00
long_show ( < < " available " > > , Lang ) - > translate : translate ( Lang , ? T ( " available " ) ) ;
long_show ( < < " chat " > > , Lang ) - > translate : translate ( Lang , ? T ( " free for chat " ) ) ;
long_show ( < < " away " > > , Lang ) - > translate : translate ( Lang , ? T ( " away " ) ) ;
long_show ( < < " xa " > > , Lang ) - > translate : translate ( Lang , ? T ( " extended away " ) ) ;
long_show ( < < " dnd " > > , Lang ) - > translate : translate ( Lang , ? T ( " do not disturb " ) ) ;
long_show ( _ , Lang ) - > translate : translate ( Lang , ? T ( " unavailable " ) ) .
2013-04-15 12:03:14 +02:00
2018-11-07 13:00:33 +01:00
intund2string ( undefined ) - > intund2string ( 0 ) ;
2014-04-08 00:10:05 +02:00
intund2string ( Int ) when is_integer ( Int ) - > list_to_binary ( integer_to_list ( Int ) ) .
2013-04-15 12:03:14 +02:00
escape ( S1 ) - >
2013-09-10 18:34:38 +02:00
S2 = re : replace ( S1 , " \' " , " \\ ' " , [ global , { return , list } ] ) ,
re : replace ( S2 , " \n " , " \\ n " , [ global , { return , list } ] ) .
2013-04-15 12:03:14 +02:00
get_baseurl ( Host ) - >
2018-04-28 11:27:31 +02:00
BaseURL1 = gen_mod : get_module_opt ( Host , ? MODULE , baseurl ) ,
ejabberd_regexp : greplace ( BaseURL1 , < < " @HOST@ " > > , Host ) .
2013-04-15 12:03:14 +02:00
2014-04-08 00:10:05 +02:00
- define ( XML_HEADER , < < " <?xml version='1.0' encoding='utf-8'?> " > > ) .
2013-04-15 12:03:14 +02:00
get_pixmaps_directory ( ) - >
[ { directory , Path } | _ ] = ets : lookup ( pixmaps_dirs , directory ) ,
Path .
available_themes ( list ) - >
case file : list_dir ( get_pixmaps_directory ( ) ) of
{ ok , List } - >
L2 = lists : sort ( List ) ,
%% Remove from the list of themes the directories that start with a dot
[ T | | T < - L2 , hd ( T ) =/= 46 ] ;
{ error , _ } - >
[ ]
end ;
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
available_themes ( xdata ) - >
lists : map (
fun ( Theme ) - >
2014-04-08 00:10:05 +02:00
#xmlel {
name = < < " option " > > ,
attrs = [ { < < " label " > > , iolist_to_binary ( Theme ) } ] ,
children = [
#xmlel {
name = < < " value " > > ,
attrs = [ ] ,
children = [ { xmlcdata , iolist_to_binary ( Theme ) } ]
}
]
}
2013-04-15 12:03:14 +02:00
end , available_themes ( list ) ) .
show_presence ( { image_no_check , Theme , Pr } ) - >
Dir = get_pixmaps_directory ( ) ,
2014-04-08 00:10:05 +02:00
Image = ? BC ( [ Pr , < < " .{gif,png,jpg} " > > ] ) ,
[ First | _ Rest ] = filelib : wildcard ( binary_to_list ( filename : join ( [ Dir , Theme , Image ] ) ) ) ,
2013-04-15 12:03:14 +02:00
Mime = string : substr ( First , string : len ( First ) - 2 , 3 ) ,
{ ok , Content } = file : read_file ( First ) ,
2014-04-08 00:10:05 +02:00
{ 200 , [ { < < " Content-Type " > > , ? BC ( [ < < " image/ " > > , ? BC ( Mime ) ] ) } ] , binary_to_list ( Content ) } ;
2013-04-15 12:03:14 +02:00
show_presence ( { image , WP , LUser , LServer } ) - >
Icon = WP #webpresence.icon ,
2014-04-08 00:10:05 +02:00
false = ( < < " --- " > > == Icon ) ,
2013-04-15 12:03:14 +02:00
Pr = get_presences ( { show , LUser , LServer } ) ,
show_presence ( { image_no_check , Icon , Pr } ) ;
show_presence ( { image , WP , LUser , LServer , Theme } ) - >
2014-04-08 00:10:05 +02:00
false = ( < < " --- " > > == WP #webpresence.icon ) ,
2013-04-15 12:03:14 +02:00
Pr = get_presences ( { show , LUser , LServer } ) ,
show_presence ( { image_no_check , Theme , Pr } ) ;
show_presence ( { image_res , WP , LUser , LServer , LResource } ) - >
Icon = WP #webpresence.icon ,
2014-04-08 00:10:05 +02:00
false = ( < < " --- " > > == Icon ) ,
2013-04-15 12:03:14 +02:00
Pr = get_presences ( { show , LUser , LServer , LResource } ) ,
show_presence ( { image_no_check , Icon , Pr } ) ;
show_presence ( { image_res , WP , LUser , LServer , Theme , LResource } ) - >
2014-04-08 00:10:05 +02:00
false = ( < < " --- " > > == WP #webpresence.icon ) ,
2013-04-15 12:03:14 +02:00
Pr = get_presences ( { show , LUser , LServer , LResource } ) ,
show_presence ( { image_no_check , Theme , Pr } ) ;
show_presence ( { xml , WP , LUser , LServer , Show_us } ) - >
true = WP #webpresence.xml ,
2016-03-08 00:39:50 +01:00
Presence_xml = fxml : element_to_binary ( get_presences ( { xml , LUser , LServer , Show_us } ) ) ,
2014-04-08 00:10:05 +02:00
{ 200 , [ { " Content-Type " , " text/xml; charset=utf-8 " } ] , ? BC ( [ ? XML_HEADER , Presence_xml ] ) } ;
2013-04-15 12:03:14 +02:00
show_presence ( { js , WP , LUser , LServer , Show_us , Lang , Q } ) - >
true = WP #webpresence.js ,
Prs = get_presences ( { sorted , LUser , LServer } ) ,
Js = make_js ( WP , Prs , Show_us , Lang , Q ) ,
{ 200 , [ { " Content-Type " , " text/html; charset=utf-8 " } ] , Js } ;
show_presence ( { text , WP , LUser , LServer } ) - >
true = WP #webpresence.text ,
Presence_text = get_presences ( { status , LUser , LServer } ) ,
{ 200 , [ { " Content-Type " , " text/html; charset=utf-8 " } ] , Presence_text } ;
show_presence ( { text , WP , LUser , LServer , LResource } ) - >
true = WP #webpresence.text ,
Presence_text = get_presences ( { status , LUser , LServer , LResource } ) ,
{ 200 , [ { " Content-Type " , " text/html; charset=utf-8 " } ] , Presence_text } ;
show_presence ( { avatar , WP , LUser , LServer } ) - >
true = WP #webpresence.avatar ,
2018-08-21 12:27:44 +02:00
[ { _ , Module , Function } ] = ets : lookup ( ejabberd_sm , { LServer , ? NS_VCARD } ) ,
JID = jid : make ( LUser , LServer , < < " " > > ) ,
IQ = #iq { type = get , from = JID , to = JID } ,
IQr = Module : Function ( IQ ) ,
[ VCard ] = IQr #iq.sub_els ,
2019-08-28 16:09:37 +02:00
VCard2 = xmpp : decode ( VCard ) ,
Mime = ( VCard2 #vcard_temp.photo ) #vcard_photo.type ,
Photo = ( VCard2 #vcard_temp.photo ) #vcard_photo.binval ,
2013-04-15 12:03:14 +02:00
{ 200 , [ { " Content-Type " , Mime } ] , Photo } ;
show_presence ( { image_example , Theme , Show } ) - >
Dir = get_pixmaps_directory ( ) ,
2014-04-08 00:10:05 +02:00
Image = ? BC ( [ Show , < < " .{gif,png,jpg} " > > ] ) ,
[ First | _ Rest ] = filelib : wildcard ( binary_to_list ( filename : join ( [ Dir , Theme , Image ] ) ) ) ,
2013-04-15 12:03:14 +02:00
Mime = string : substr ( First , string : len ( First ) - 2 , 3 ) ,
{ ok , Content } = file : read_file ( First ) ,
2014-04-08 00:10:05 +02:00
{ 200 , [ { < < " Content-Type " > > , ? BC ( [ < < " image/ " > > , ? BC ( Mime ) ] ) } ] , binary_to_list ( Content ) } .
2013-04-15 12:03:14 +02:00
%% ---------------------
%% Web Publish
%% ---------------------
make_xhtml ( Els ) - > make_xhtml ( [ ] , Els ) .
make_xhtml ( Title , Els ) - >
2014-04-08 00:10:05 +02:00
#xmlel {
name = < < " html " > > ,
attrs = [
{ < < " xmlns " > > , < < " http://www.w3.org/1999/xhtml " > > } ,
{ < < " xml:lang " > > , < < " en " > > } ,
{ < < " lang " > > , < < " en " > > }
] ,
children = [
#xmlel {
name = < < " head " > > ,
attrs = [ ] ,
children = [
#xmlel {
name = < < " meta " > > ,
attrs = [
{ < < " http-equiv " > > , < < " Content-Type " > > } ,
{ < < " content " > > , < < " text/html; charset=utf-8 " > > }
] ,
children = [ ]
}
] ++ Title
} ,
#xmlel {
name = < < " body " > > ,
attrs = [ ] ,
children = Els
}
]
} .
2013-04-15 12:03:14 +02:00
themes_to_xhtml ( Themes ) - >
ShowL = [ " available " , " chat " , " dnd " , " away " , " xa " , " unavailable " ] ,
THeadL = [ " " ] ++ ShowL ,
2014-04-08 00:10:05 +02:00
[ ? XAE ( < < " table " > > , [ ] ,
[ ? XE ( < < " tr " > > , [ ? XC ( < < " th " > > , ? BC ( T ) ) | | T < - THeadL ] ) ] ++
[ ? XE ( < < " tr " > > , [ ? XC ( < < " td " > > , ? BC ( Theme ) ) |
[ ? XE ( < < " td " > > , [ ? XA ( < < " img " > > , [ { < < " src " > > , ? BC ( [ < < " image/ " > > , ? BC ( Theme ) , < < " / " > > , ? BC ( T ) ] ) } ] ) ] ) | | T < - ShowL ]
2013-04-15 12:03:14 +02:00
]
) | | Theme < - Themes ]
)
] .
2014-04-08 00:10:05 +02:00
parse_lang ( Lang ) - > iolist_to_binary ( hd ( string : tokens ( binary_to_list ( Lang ) , " - " ) ) ) .
2013-04-15 12:03:14 +02:00
process ( LocalPath , Request ) - >
case catch process2 ( LocalPath , Request ) of
{ 'EXIT' , Reason } - >
2014-04-08 00:10:05 +02:00
? DEBUG ( " ~p " , [ Request ] ) ,
2013-04-15 12:03:14 +02:00
? DEBUG ( " The call to path ~p in the ~n request: ~p ~n crashed with error: ~p " , [ LocalPath , Request , Reason ] ) ,
2014-04-08 00:10:05 +02:00
{ 404 , [ ] , make_xhtml ( [ ? XC ( < < " h1 " > > , < < " Not found " > > ) ] ) } ;
2013-04-15 12:03:14 +02:00
Res - >
Res
end .
process2 ( [ ] , #request { lang = Lang1 } ) - >
Lang = parse_lang ( Lang1 ) ,
2019-08-19 20:42:03 +02:00
Title = [ ? XC ( < < " title " > > , translate : translate ( Lang , ? T ( " Web Presence " ) ) ) ] ,
Desc = [ ? XC ( < < " p " > > , ? BC ( [ translate : translate ( Lang , ? T ( " To publish your presence using this system you need a Jabber account in this Jabber server. " ) ) , < < " " > > ,
translate : translate ( Lang , ? T ( " Login with a Jabber client, open the Service Discovery and register in Web Presence. " ) ) ,
translate : translate ( Lang , ? T ( " You will receive a message with further instructions. " ) ) ] ) ) ] ,
Link_themes = [ ? AC ( < < " themes " > > , translate : translate ( Lang , ? T ( " Icon Theme " ) ) ) ] ,
Body = [ ? XC ( < < " h1 " > > , translate : translate ( Lang , ? T ( " Web Presence " ) ) ) ] ++ Desc ++ Link_themes ,
2013-04-15 12:03:14 +02:00
make_xhtml ( Title , Body ) ;
2014-04-08 00:10:05 +02:00
process2 ( [ < < " themes " > > ] , #request { lang = Lang1 } ) - >
2013-04-15 12:03:14 +02:00
Lang = parse_lang ( Lang1 ) ,
2019-08-19 20:42:03 +02:00
Title = [ ? XC ( < < " title " > > , ? BC ( [ translate : translate ( Lang , ? T ( " Web Presence " ) ) , < < " - " > > , translate : translate ( Lang , ? T ( " Icon Theme " ) ) ] ) ) ] ,
2013-04-15 12:03:14 +02:00
Themes = available_themes ( list ) ,
Icon_themes = themes_to_xhtml ( Themes ) ,
2019-08-19 20:42:03 +02:00
Body = [ ? XC ( < < " h1 " > > , translate : translate ( Lang , ? T ( " Icon Theme " ) ) ) ] ++ Icon_themes ,
2013-04-15 12:03:14 +02:00
make_xhtml ( Title , Body ) ;
2014-04-08 00:10:05 +02:00
process2 ( [ < < " image " > > , Theme , Show ] , #request { } = _ Request ) - >
2013-04-15 12:03:14 +02:00
Args = { image_example , Theme , Show } ,
show_presence ( Args ) ;
2014-04-08 00:10:05 +02:00
process2 ( [ < < " jid " > > , User , Server | Tail ] , Request ) - >
2013-04-15 12:03:14 +02:00
serve_web_presence ( jid , User , Server , Tail , Request ) ;
2014-04-08 00:10:05 +02:00
process2 ( [ < < " rid " > > , Rid | Tail ] , Request ) - >
2013-04-15 12:03:14 +02:00
[ Pr ] = mnesia : dirty_index_read ( webpresence , Rid , #webpresence.ridurl ) ,
{ User , Server } = Pr #webpresence.us ,
serve_web_presence ( rid , User , Server , Tail , Request ) ;
%% Compatibility with old mod_presence
process2 ( [ User , Server | Tail ] , Request ) - >
serve_web_presence ( jid , User , Server , Tail , Request ) .
serve_web_presence ( TypeURL , User , Server , Tail , #request { lang = Lang1 , q = Q } ) - >
2018-08-21 12:27:44 +02:00
LServer = jid : nameprep ( Server ) ,
2019-08-23 12:59:53 +02:00
true = lists : member ( Server , ejabberd_config : get_option ( hosts ) ) ,
2018-08-21 12:27:44 +02:00
LUser = jid : nodeprep ( User ) ,
2013-04-15 12:03:14 +02:00
WP = get_wp ( LUser , LServer ) ,
case TypeURL of
jid - > true = WP #webpresence.jidurl ;
2014-04-08 00:10:05 +02:00
rid - > true = is_binary ( WP #webpresence.ridurl )
2013-04-15 12:03:14 +02:00
end ,
Show_us = ( TypeURL == jid ) ,
Lang = parse_lang ( Lang1 ) ,
Args = case Tail of
2014-04-08 00:10:05 +02:00
[ < < " image " > > , < < " theme " > > , Theme , < < " res " > > , Resource | _ ] - >
{ image_res , WP , LUser , LServer , Theme , Resource } ;
[ < < " image " > > , < < " theme " > > , Theme | _ ] - >
{ image , WP , LUser , LServer , Theme } ;
[ < < " image " > > , < < " res " > > , Resource | _ ] - >
{ image_res , WP , LUser , LServer , Resource } ;
[ < < " image " > > | _ ] - >
{ image , WP , LUser , LServer } ;
[ < < " xml " > > ] - >
{ xml , WP , LUser , LServer , Show_us } ;
[ < < " js " > > ] - >
{ js , WP , LUser , LServer , Show_us , Lang , Q } ;
[ < < " text " > > ] - >
{ text , WP , LUser , LServer } ;
[ < < " text " > > , < < " res " > > , Resource ] - >
{ text , WP , LUser , LServer , Resource } ;
[ < < " avatar " > > | _ ] - >
{ avatar , WP , LUser , LServer }
2013-04-15 12:03:14 +02:00
end ,
show_presence ( Args ) .
2014-04-08 00:10:05 +02:00
%%%% ---------------------
%%%% Web Admin
%%%% ---------------------
2013-04-15 12:03:14 +02:00
web_menu_host ( Acc , _ Host , Lang ) - >
2019-08-19 20:42:03 +02:00
[ { < < " webpresence " > > , translate : translate ( Lang , ? T ( " Web Presence " ) ) } | Acc ] .
2013-04-15 12:03:14 +02:00
2014-04-08 00:10:05 +02:00
web_page_host ( _ , _ Host ,
#request { path = [ < < " webpresence " > > ] ,
2013-04-15 12:03:14 +02:00
lang = Lang } = _ Request ) - >
2014-04-08 00:10:05 +02:00
Res = [ ? XCT ( < < " h1 " > > , < < " Web Presence " > > ) ,
? XE ( < < " ul " > > , [
2019-10-02 13:08:35 +02:00
? LI ( [ ? ACT ( < < " stats/ " > > , < < " Statistics " > > ) ] ) ,
? LI ( [ ? ACT ( < < " users/ " > > , < < " Registered Users " > > ) ] ) ] ) ] ,
2013-04-15 12:03:14 +02:00
{ stop , Res } ;
2014-04-08 00:10:05 +02:00
web_page_host ( _ , Host ,
#request { path = [ < < " webpresence " > > , < < " users " > > ] ,
2013-04-15 12:03:14 +02:00
lang = Lang } = _ Request ) - >
Users = get_users ( Host ) ,
Table = make_users_table ( Users , Lang ) ,
2014-04-08 00:10:05 +02:00
Res = [ ? XCT ( < < " h1 " > > , < < " Web Presence " > > ) ,
? XCT ( < < " h2 " > > , < < " Registered Users " > > ) ] ++ Table ,
2013-04-15 12:03:14 +02:00
{ stop , Res } ;
2014-04-08 00:10:05 +02:00
web_page_host ( _ , Host ,
#request { path = [ < < " webpresence " > > , < < " stats " > > ] ,
2013-04-15 12:03:14 +02:00
lang = Lang } = _ Request ) - >
Users = get_users ( Host ) ,
2014-04-08 00:10:05 +02:00
Res = [ ? XCT ( < < " h1 " > > , < < " Web Presence " > > ) ,
2013-04-15 12:03:14 +02:00
css_table ( ) ,
2014-04-08 00:10:05 +02:00
? XCT ( < < " h2 " > > , < < " Statistics " > > ) ]
2013-04-15 12:03:14 +02:00
++ make_stats_options ( Users , Lang )
++ make_stats_iconthemes ( Users , Lang ) ,
{ stop , Res } ;
2014-04-08 00:10:05 +02:00
web_page_host ( Acc , _ , _ ) - > Acc .
2013-04-15 12:03:14 +02:00
get_users ( Host ) - >
Select = [ { { webpresence , { '$1' , Host } , '$2' , '$3' , '$4' , '$5' , '$6' , '$7' , '$8' } , [ ] , [ '$$' ] } ] ,
mnesia : dirty_select ( webpresence , Select ) .
make_users_table ( Records , Lang ) - >
TList = lists : map (
fun ( [ User , RidUrl , JIDUrl , XML , Avatar , JS , Text , Icon ] ) - >
2014-04-08 00:10:05 +02:00
? XE ( < < " tr " > > ,
2019-10-02 13:08:35 +02:00
[ ? XE ( < < " td " > > , [ ? AC ( ? BC ( [ < < " ../../user/ " > > , User , < < " / " > > ] ) , User ) ] ) ,
2014-04-08 00:10:05 +02:00
? XC ( < < " td " > > , iolist_to_binary ( atom_to_list ( JIDUrl ) ) ) ,
? XC ( < < " td " > > , ridurl_out ( RidUrl ) ) ,
? XC ( < < " td " > > , Icon ) ,
? XC ( < < " td " > > , iolist_to_binary ( atom_to_list ( XML ) ) ) ,
? XC ( < < " td " > > , iolist_to_binary ( atom_to_list ( JS ) ) ) ,
? XC ( < < " td " > > , iolist_to_binary ( atom_to_list ( Text ) ) ) ,
? XC ( < < " td " > > , iolist_to_binary ( atom_to_list ( Avatar ) ) ) ] )
2013-04-15 12:03:14 +02:00
end , Records ) ,
2014-04-08 00:10:05 +02:00
[ ? XE ( < < " table " > > ,
[ ? XE ( < < " thead " > > ,
[ ? XE ( < < " tr " > > ,
[ ? XCT ( < < " td " > > , < < " User " > > ) ,
? XCT ( < < " td " > > , < < " Jabber ID " > > ) ,
? XCT ( < < " td " > > , < < " Random ID " > > ) ,
? XCT ( < < " td " > > , < < " Icon Theme " > > ) ,
? XC ( < < " td " > > , < < " XML " > > ) ,
? XC ( < < " td " > > , < < " JS " > > ) ,
? XCT ( < < " td " > > , < < " Text " > > ) ,
? XCT ( < < " td " > > , < < " Avatar " > > )
2013-04-15 12:03:14 +02:00
] ) ] ) ,
2014-04-08 00:10:05 +02:00
? XE ( < < " tbody " > > , TList ) ] ) ] .
2013-04-15 12:03:14 +02:00
make_stats_options ( Records , Lang ) - >
[ RegUsers , JJ , RR , XX , AA , SS , TT , II ] = lists : foldl (
fun ( [ _ User , RidUrl , JidUrl , XML , Avatar , JS , Text , Icon ] , [ N , J , R , X , A , S , T , I ] ) - >
J2 = J + case JidUrl of false - > 0 ; true - > 1 end ,
R2 = R + case RidUrl of false - > 0 ; _ - > 1 end ,
X2 = X + case XML of false - > 0 ; true - > 1 end ,
A2 = A + case Avatar of false - > 0 ; true - > 1 end ,
S2 = S + case JS of false - > 0 ; true - > 1 end ,
T2 = T + case Text of false - > 0 ; true - > 1 end ,
2014-04-08 00:10:05 +02:00
I2 = I + case Icon of < < " --- " > > - > 0 ; _ - > 1 end ,
2013-04-15 12:03:14 +02:00
[ N + 1 , J2 , R2 , X2 , A2 , S2 , T2 , I2 ]
2014-04-08 00:10:05 +02:00
end ,
2013-04-15 12:03:14 +02:00
[ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ,
Records ) ,
2014-04-08 00:10:05 +02:00
URLTList = [ { < < " Jabber ID " > > , JJ } , { < < " Random ID " > > , RR } ] ,
OutputTList = [ { < < " Icon Theme " > > , II } , { < < " XML " > > , XX } , { < < " JavaScript " > > , SS } , { < < " Text " > > , TT } , { < < " Avatar " > > , AA } ] ,
2013-04-15 12:03:14 +02:00
[
2014-04-08 00:10:05 +02:00
? C ( ? BC ( [ < < " Registered Users " > > , < < " : " > > , iolist_to_binary ( integer_to_list ( RegUsers ) ) ] ) ) ,
? XCT ( < < " h3 " > > , < < " URL Type " > > ) ,
? XAE ( < < " table " > > , [ { < < " class " > > , < < " stats " > > } ] ,
[ ? XE ( < < " tbody " > > , do_stat_table_with ( URLTList , RegUsers ) ) ]
2013-04-15 12:03:14 +02:00
) ,
2014-04-08 00:10:05 +02:00
? XCT ( < < " h3 " > > , < < " Output Type " > > ) ,
? XAE ( < < " table " > > , [ { < < " class " > > , < < " stats " > > } ] ,
[ ? XE ( < < " tbody " > > , do_stat_table_with ( OutputTList , RegUsers ) ) ]
2013-04-15 12:03:14 +02:00
) ] .
make_stats_iconthemes ( Records , Lang ) - >
Themes1 = [ { T , 0 } | | T < - available_themes ( list ) ] ,
Dict = lists : foldl (
fun ( [ _ , _ , _ , _ , _ , _ , _ , Icon ] , D ) - >
dict : update_counter ( Icon , 1 , D )
2014-04-08 00:10:05 +02:00
end ,
2013-04-15 12:03:14 +02:00
dict : from_list ( Themes1 ) ,
Records ) ,
Themes = lists : keysort ( 1 , dict : to_list ( Dict ) ) ,
2014-04-08 00:10:05 +02:00
[ ? XCT ( < < " h3 " > > , < < " Icon Theme " > > ) ,
? XAE ( < < " table " > > , [ { < < " class " > > , < < " stats " > > } ] ,
[ ? XE ( < < " tbody " > > , do_stat_table_with ( Themes ) ) ]
2013-04-15 12:03:14 +02:00
) ] .
%% Do table with bars
do_stat_table_with ( Values ) - >
Ns = [ Ni | | { _ , Ni } < - Values ] ,
Total = lists : sum ( Ns ) ,
do_stat_table_with ( Values , Total ) .
do_stat_table_with ( Values , Total ) - >
lists : map (
2014-04-08 00:10:05 +02:00
fun ( { L , N } ) - >
2013-04-15 12:03:14 +02:00
Perc = case Total of
2014-04-08 00:10:05 +02:00
0 - > < < " 0 " > > ;
_ - > iolist_to_binary ( integer_to_list ( trunc ( 100 * N / Total ) ) )
2013-04-15 12:03:14 +02:00
end ,
do_table_element ( ? C ( L ) , io_lib : format ( " ~p " , [ N ] ) , Perc )
end ,
Values ) .
do_table_element ( L , [ N ] , Perc ) - >
2014-04-08 00:10:05 +02:00
? XE ( < < " tr " > > ,
[ ? XE ( < < " td " > > , [ L ] ) ,
? XAC ( < < " td " > > , [ { < < " class " > > , < < " alignright " > > } ] , [ N ] ) ,
? XE ( < < " td " > > ,
[ ? XAE ( < < " div " > > ,
[ { < < " class " > > , < < " graph " > > } ] ,
[ ? XAC ( < < " div " > > ,
[ { < < " class " > > , < < " bar " > > } , { < < " style " > > , ? BC ( [ < < " width: " > > , Perc , < < " %; " > > ] ) } ] ,
2013-04-15 12:03:14 +02:00
[ ]
) ]
) ]
) ,
2014-04-08 00:10:05 +02:00
? XAC ( < < " td " > > , [ { < < " class " > > , < < " alignright " > > } ] , [ ? BC ( [ Perc , < < " % " > > ] ) ] )
2013-04-15 12:03:14 +02:00
] ) .
2014-04-08 00:10:05 +02:00
2013-04-15 12:03:14 +02:00
css_table ( ) - >
2014-04-08 00:10:05 +02:00
? XAE ( < < " style " > > , [ { < < " type " > > , < < " text/css " > > } ] ,
[ ? C ( < < " .stats {
2013-04-15 12:03:14 +02:00
padding - left : 20 px ;
padding - top : 10 px ;
}
. graph {
position : relative ;
width : 200 px ;
border : 1 px solid # D47911 ;
padding : 1 px ;
}
. graph . bar {
display : block ;
position : relative ;
background : # FFE3C9 ;
text - align : center ;
color : # 333 ;
height : 1 . 5 em ;
line - height : 1 . 5 em ;
}
2014-04-08 00:10:05 +02:00
. graph . bar span { position : absolute ; left : 1 em ; } " >>)]).
2013-04-15 12:03:14 +02:00
%%%--------------------------------
%%% Update table schema and content from older versions
%%%--------------------------------
update_table ( ) - >
case catch mnesia : table_info ( presence_registered , size ) of
Size when is_integer ( Size ) - > catch migrate_data_mod_presence ( Size ) ;
_ - > ok
end .
migrate_data_mod_presence ( Size ) - >
Migrate = fun ( Old , S ) - >
{ presence_registered , { US , _ Host } , XML , Icon } = Old ,
New = #webpresence { us = US ,
ridurl = false ,
jidurl = true ,
xml = list_to_atom ( XML ) ,
avatar = false ,
js = false ,
text = false ,
icon = Icon } ,
mnesia : write ( New ) ,
mnesia : delete_object ( Old ) ,
S - 1
end ,
F = fun ( ) - > mnesia : foldl ( Migrate , Size , presence_registered ) end ,
{ atomic , 0 } = mnesia : transaction ( F ) ,
{ atomic , ok } = mnesia : delete_table ( presence_registered ) .