/priv/sites/zotonic_status/resources/resource_zotonic_status.erl

https://code.google.com/p/zotonic/ · Erlang · 136 lines · 91 code · 22 blank · 23 comment · 3 complexity · c62af4999c734537ea52282883e3c959 MD5 · raw file

  1. %% @author Marc Worrell <marc@worrell.nl>
  2. %% @copyright 2010 Marc Worrell
  3. %% @doc Resource to serve the zotonic fallback site templates.
  4. %% Copyright 2010 Marc Worrell
  5. %%
  6. %% Licensed under the Apache License, Version 2.0 (the "License");
  7. %% you may not use this file except in compliance with the License.
  8. %% You may obtain a copy of the License at
  9. %%
  10. %% http://www.apache.org/licenses/LICENSE-2.0
  11. %%
  12. %% Unless required by applicable law or agreed to in writing, software
  13. %% distributed under the License is distributed on an "AS IS" BASIS,
  14. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. %% See the License for the specific language governing permissions and
  16. %% limitations under the License.
  17. -module(resource_zotonic_status).
  18. -author("Marc Worrell <marc@worrell.nl>").
  19. -export([init/1, service_available/2, charsets_provided/2, content_types_provided/2]).
  20. -export([
  21. provide_content/2,
  22. event/2,
  23. updater/2
  24. ]).
  25. -include_lib("webmachine_resource.hrl").
  26. -include_lib("include/zotonic.hrl").
  27. init(DispatchArgs) -> {ok, DispatchArgs}.
  28. service_available(ReqData, DispatchArgs) when is_list(DispatchArgs) ->
  29. Context = z_context:new(ReqData, ?MODULE),
  30. Context1 = z_context:set(DispatchArgs, Context),
  31. ?WM_REPLY(true, Context1).
  32. charsets_provided(ReqData, Context) ->
  33. {[{"utf-8", fun(X) -> X end}], ReqData, Context}.
  34. content_types_provided(ReqData, Context) ->
  35. case z_context:get(content_type, Context) of
  36. undefined ->
  37. {[{"text/html", provide_content}], ReqData, Context};
  38. Mime ->
  39. {[{Mime, provide_content}], ReqData, Context}
  40. end.
  41. provide_content(ReqData, Context) ->
  42. Context1 = ?WM_REQ(ReqData, Context),
  43. Context2 = z_context:ensure_all(Context1),
  44. Template = z_context:get(template, Context2),
  45. SitesStatus = z_sites_manager:get_sites_status(),
  46. Vars = [
  47. {has_user, z_acl:user(Context2)},
  48. {configs, [ {Site, z_sites_manager:get_site_config(Site)} || Site <- z_sites_manager:get_sites_all(), Site /= zotonic_status ]},
  49. {sites, SitesStatus}
  50. | z_context:get_all(Context2)
  51. ],
  52. Vars1 = z_notifier:foldl(zotonic_status_init, Vars, Context),
  53. Rendered = z_template:render(Template, Vars1, Context2),
  54. {Output, OutputContext} = z_context:output(Rendered, Context2),
  55. start_stream(SitesStatus, OutputContext),
  56. ?WM_REPLY(Output, OutputContext).
  57. %% -----------------------------------------------------------------------------------------------
  58. %% Handle all events
  59. %% -----------------------------------------------------------------------------------------------
  60. event({submit, [], TriggerId, _TargetId}, Context) ->
  61. case z_context:get_q(password, Context) == z_config:get(password) of
  62. true ->
  63. {ok, ContextAuth} = z_auth:logon(1, Context),
  64. z_render:wire({reload, []}, ContextAuth);
  65. false ->
  66. z_render:wire([
  67. {set_class, [{target,TriggerId},{class,"error-pw"}]},
  68. {set_value, [{target,"password"},{value, ""}]}], Context)
  69. end;
  70. event({postback, {logoff, []}, _TriggerId, _TargetId}, Context) ->
  71. z_render:wire({reload, []}, z_auth:logoff(Context));
  72. event({postback, {site_start, [{site, Site}]}, _TriggerId, _TargetId}, Context) ->
  73. true = z_auth:is_auth(Context),
  74. z_sites_manager:start(Site),
  75. Context;
  76. event({postback, {site_restart, [{site, Site}]}, _TriggerId, _TargetId}, Context) ->
  77. true = z_auth:is_auth(Context),
  78. z_sites_manager:restart(Site),
  79. Context;
  80. event({postback, {site_stop, [{site, Site}]}, _TriggerId, _TargetId}, Context) ->
  81. true = z_auth:is_auth(Context),
  82. z_sites_manager:stop(Site),
  83. Context;
  84. event({postback, {site_flush, [{site, Site}]}, _TriggerId, _TargetId}, Context) ->
  85. true = z_auth:is_auth(Context),
  86. z:flush(z_context:new(Site)),
  87. Context.
  88. %% -----------------------------------------------------------------------------------------------
  89. %% Stream process to update the page when data changes
  90. %% -----------------------------------------------------------------------------------------------
  91. start_stream(SitesStatus, Context) ->
  92. z_session_page:spawn_link(?MODULE, updater, [SitesStatus, Context], Context).
  93. % @todo Instead of polling we should observe the system wide notifications (that will be implemented)
  94. updater(SitesStatus, Context) ->
  95. Context1 = z_auth:logon_from_session(Context),
  96. timer:sleep(1000),
  97. z_sites_manager:upgrade(),
  98. NewStatus = z_sites_manager:get_sites_status(),
  99. case NewStatus /= SitesStatus of
  100. true ->
  101. Context2 = render_update(NewStatus, Context1),
  102. ?MODULE:updater(NewStatus, Context2);
  103. false ->
  104. ?MODULE:updater(SitesStatus, Context1)
  105. end.
  106. render_update(SitesStatus, Context) ->
  107. Vars = [
  108. {has_user, z_acl:user(Context)},
  109. {configs, [ {Site, z_sites_manager:get_site_config(Site)} || Site <- z_sites_manager:get_sites_all(), Site /= zotonic_status ]},
  110. {sites, SitesStatus}
  111. ],
  112. Vars1 = z_notifier:foldl(zotonic_status_init, Vars, Context),
  113. Context1 = z_render:update("sites", #render{template="_sites.tpl", vars=Vars1}, Context),
  114. z_session_page:add_script(Context1).