/modules/mod_twitter/filters/filter_twitter.erl

http://github.com/zotonic/zotonic · Erlang · 153 lines · 114 code · 20 blank · 19 comment · 0 complexity · 0e64ecf338876d39ac449404c02aeaa6 MD5 · raw file

  1. %% @author Arjan Scherpenisse <arjan@scherpenisse.net>
  2. %% @copyright 2010-2012 Arjan Scherpenisse
  3. %% @doc 'twitter' filter, make a tweet from twitter look nice
  4. %% Copyright 2010-2012 Arjan Scherpenisse
  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(filter_twitter).
  18. -export([
  19. twitter/2,
  20. twitter/3
  21. ]).
  22. %% Number of characters for truncating an url
  23. -define(URL_TRUNCATE, 50).
  24. twitter(undefined, _Context) -> undefined;
  25. twitter(<<"<p>", _/binary>> = Input, _Context) -> Input;
  26. twitter(Input, Context) when is_list(Input) ->
  27. twitter(z_convert:to_binary(Input), Context);
  28. twitter(Input, Context) when is_binary(Input) -> iolist_to_binary(twitter1(Input, 0, [], Context));
  29. twitter(Input, _Context) -> Input.
  30. %% @doc filter with options, only option for now: url_location (follows url shorteners)
  31. twitter(Input, Options, Context) ->
  32. twitter1(Input, 0, Options, Context).
  33. twitter1(Input, Index, Opts, Context) when is_binary(Input) ->
  34. case Input of
  35. <<Pre:Index/binary, "http://", Post/binary>> -> [Pre, twitter1_url(<<"http://">>, Post, 0, Opts, Context)];
  36. <<Pre:Index/binary, "https://", Post/binary>> -> [Pre, twitter1_url(<<"https://">>, Post, 0, Opts, Context)];
  37. <<Pre:Index/binary, "ftp://", Post/binary>> -> [Pre, twitter1_url(<<"ftp://">>, Post, 0, Opts, Context)];
  38. <<Pre:Index/binary, "ftps://", Post/binary>> -> [Pre, twitter1_url(<<"ftps://">>, Post, 0, Opts, Context)];
  39. <<Pre:Index/binary, "mailto:", Post/binary>> -> [Pre, twitter1_url(<<"mailto:">>, Post, 0, Opts, Context)];
  40. <<Pre:Index/binary, $&, $#, Post/binary>> -> [Pre, $&, $#, twitter1(Post, 0, Opts, Context)];
  41. <<Pre:Index/binary, $@, Post/binary>> -> [Pre, twitter1_at(Post, 0, Opts, Context)];
  42. <<Pre:Index/binary, $#, Post/binary>> -> [Pre, twitter1_hash(Post, 0, Opts, Context)];
  43. <<_:Index/binary, _/binary>> -> twitter1(Input, Index + 1, Opts, Context);
  44. _ -> Input
  45. end.
  46. twitter1_url(Pre, Input, Index, Opts, Context) ->
  47. case Input of
  48. <<_:Index/binary, "&#38;", _/binary>> ->
  49. twitter1_url(Pre, Input, Index + 5, Opts, Context);
  50. <<_:Index/binary, "&amp;", _/binary>> ->
  51. twitter1_url(Pre, Input, Index + 5, Opts, Context);
  52. <<Url:Index/binary, Char, Post/binary>> ->
  53. case Char /= $& andalso z_url:url_valid_char(Char) of
  54. true -> twitter1_url(Pre, Input, Index + 1, Opts, Context);
  55. false -> twitter1_url_anchor(Pre, Url, <<Char, Post/binary>>, Opts, Context)
  56. end;
  57. <<Url:Index/binary>> ->
  58. twitter1_url_anchor(Pre, Url, <<>>, Opts, Context);
  59. _ ->
  60. Input
  61. end.
  62. twitter1_url_anchor(Pre, <<>>, Post, Opts, Context) ->
  63. [Pre, twitter1(Post, 0, Opts, Context)];
  64. twitter1_url_anchor(Pre, Url, Post, Opts, Context) ->
  65. Length1 = size(Url) - 1,
  66. <<Url1:Length1/binary,LastChar>> = Url,
  67. Html = case is_url_truncatable(LastChar) of
  68. true -> [ twitter1_url_html(Pre, Url1, Opts), LastChar];
  69. false -> twitter1_url_html(Pre, Url, Opts)
  70. end,
  71. [Html, twitter1(Post, 0, Opts, Context)].
  72. % Create the html link, follow the url to remove any url shortener.
  73. twitter1_url_html(Pre, Url, Opts) ->
  74. case proplists:get_value(url_location, Opts, false) of
  75. true ->
  76. Url2 = z_url:location(<<Pre/binary,Url/binary>>),
  77. Text = z_string:truncate(z_url:remove_protocol(Url2), ?URL_TRUNCATE),
  78. ["<a href=\"", Url2, "\">", Text, "</a>"];
  79. false ->
  80. ["<a href=\"", Pre, Url, "\">", Url, "</a>"]
  81. end.
  82. is_url_truncatable($.) -> true;
  83. is_url_truncatable($;) -> true;
  84. is_url_truncatable($#) -> true;
  85. is_url_truncatable($,) -> true;
  86. is_url_truncatable($') -> true;
  87. is_url_truncatable($") -> true;
  88. is_url_truncatable($?) -> true;
  89. is_url_truncatable($!) -> true;
  90. is_url_truncatable($/) -> true;
  91. is_url_truncatable($+) -> true;
  92. is_url_truncatable($%) -> true;
  93. is_url_truncatable(_) -> false.
  94. twitter1_at(Input, Index, Opts, Context) ->
  95. case Input of
  96. <<Name:Index/binary, Char, Post/binary>> when not(Char >= $a andalso Char =< $z
  97. orelse
  98. Char >= $A andalso Char =< $Z
  99. orelse
  100. Char >= $0 andalso Char =< $9
  101. orelse Char =:= $_ orelse Char =:= $.
  102. ) ->
  103. Html = twitter_at_url(Name),
  104. [Html, twitter1(<<Char, Post/binary>>, 0, Opts, Context)];
  105. <<Name:Index/binary>> ->
  106. twitter_at_url(Name);
  107. <<_:Index/binary, _/binary>> ->
  108. twitter1_at(Input, Index + 1, Opts, Context);
  109. _ ->
  110. Input
  111. end.
  112. twitter_at_url(Name) ->
  113. ["<a href=\"http://twitter.com/", Name, "\">@", Name, "</a>"].
  114. twitter1_hash(Input, Index, Opts, Context) ->
  115. case Input of
  116. <<Name:Index/binary, Char, Post/binary>> when not(Char >= $a andalso Char =< $z
  117. orelse
  118. Char >= $A andalso Char =< $Z
  119. orelse
  120. Char >= $0 andalso Char =< $9
  121. orelse Char =:= $_ orelse Char =:= $.
  122. ) ->
  123. Html = twitter_hash_url(Name),
  124. [[Html, Char], twitter1(Post, 0, Opts, Context)];
  125. <<Name:Index/binary>> ->
  126. twitter_hash_url(Name);
  127. <<_:Index/binary, _/binary>> ->
  128. twitter1_hash(Input, Index + 1, Opts, Context);
  129. _ ->
  130. Input
  131. end.
  132. twitter_hash_url(Hash) ->
  133. ["<a href=\"http://twitter.com/#search?q=%23", Hash, "\">#", Hash, "</a>"].