1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
defmodule LSG.IRC.LinkPlugin.Twitter do
@behaviour LSG.IRC.LinkPlugin
@moduledoc """
# Twitter Link Preview
Configuration:
needs an API key and auth tokens:
```
config :extwitter, :oauth, [
consumer_key: "zzzzz",
consumer_secret: "xxxxxxx",
access_token: "yyyyyy",
access_token_secret: "ssshhhhhh"
]
```
options:
* `expand_quoted`: Add the quoted tweet instead of its URL. Default: true.
"""
def match(uri = %URI{host: twitter, path: path}, _opts) when twitter in ["twitter.com", "m.twitter.com", "mobile.twitter.com"] do
case String.split(path, "/", parts: 4) do
["", _username, "status", status_id] ->
{status_id, _} = Integer.parse(status_id)
{true, %{status_id: status_id}}
_ -> false
end
end
def match(_, _), do: false
def expand(_uri, %{status_id: status_id}, opts) do
expand_tweet(ExTwitter.show(status_id, tweet_mode: "extended"), opts)
end
defp expand_tweet(nil, _opts) do
:error
end
defp expand_tweet(tweet, opts) do
text = expand_twitter_text(tweet)
text = if tweet.quoted_status do
quote_url = "https://twitter.com/#{tweet.quoted_status.user.screen_name}/status/#{tweet.quoted_status.id}"
String.replace(text, quote_url, "")
else
text
end
text = IRC.splitlong(text)
{:ok, at} = Timex.parse(tweet.created_at, "%a %b %e %H:%M:%S %z %Y", :strftime)
{:ok, format} = Timex.format(at, "{relative}", :relative)
replyto = if tweet.in_reply_to_status_id do
replyurl = "https://twitter.com/#{tweet.in_reply_to_screen_name}/status/#{tweet.in_reply_to_status_id}"
if tweet.in_reply_to_screen_name == tweet.user.screen_name do
"— continued from #{replyurl}"
else
"— replying to #{replyurl}"
end
else
""
end
quoted = if tweet.quoted_status do
quote_url = "https://twitter.com/#{tweet.quoted_status.user.screen_name}/status/#{tweet.quoted_status.id}"
full_text = expand_twitter_text(tweet.quoted_status)
|> IRC.splitlong_with_prefix(">")
["> #{tweet.quoted_status.user.name} (@#{tweet.quoted_status.user.screen_name}): #{quote_url}"] ++ full_text
else
[]
end
foot = "— #{format} - #{tweet.retweet_count} retweets - #{tweet.favorite_count} likes"
text = ["#{tweet.user.name} (@#{tweet.user.screen_name}):", replyto] ++ text ++ quoted ++ [foot]
{:ok, text}
end
defp expand_twitter_text(tweet) do
text = Enum.reduce(tweet.entities.urls, tweet.full_text, fn(entity, text) ->
String.replace(text, entity.url, entity.expanded_url)
end)
extended = tweet.extended_entities || %{media: []}
text = Enum.reduce(extended.media, text, fn(entity, text) ->
url = Enum.filter(extended.media, fn(e) -> entity.url == e.url end)
|> Enum.map(fn(e) ->
cond do
e.type == "video" -> e.expanded_url
true -> e.media_url_https
end
end)
|> Enum.join(" ")
String.replace(text, entity.url, url)
end)
end
end
|