|
1
|
|
|
from base import BotPlugin |
|
2
|
|
|
from tweepy import OAuthHandler, API as TWITTER_API |
|
3
|
|
|
from settings import TWITTER as T |
|
4
|
|
|
from response import random_response |
|
5
|
|
|
from urllib2 import urlopen |
|
6
|
|
|
import re |
|
7
|
|
|
import json |
|
8
|
|
|
import requests |
|
9
|
|
|
import lxml.html |
|
10
|
|
|
import regex |
|
11
|
|
|
|
|
12
|
|
|
TWITTER_OAUTH = OAuthHandler(T['consumer_key'], T['consumer_secret']) |
|
13
|
|
|
TWITTER_OAUTH.set_access_token(T['access_token_key'], T['access_token_secret']) |
|
14
|
|
|
TWITTER = TWITTER_API(TWITTER_OAUTH) |
|
15
|
|
|
|
|
16
|
|
|
# These will be filtered out in _read_webistes |
|
17
|
|
|
__all_non_web__ = [regex.TWITTER, regex.YOUTUBE, regex.VIMEO] |
|
18
|
|
|
|
|
19
|
|
|
VIDEO_RESPONSES = [ |
|
20
|
|
|
"That video is titled '%(title)s'. " |
|
21
|
|
|
+ "You will waste %(seconds)ss of your life watching it. ", |
|
22
|
|
|
"The title of that %(service)s video is '%(title)s'. " |
|
23
|
|
|
+ "It has been viewed %(views)s times. ", |
|
24
|
|
|
"Title: '%(title)s', Views: %(views)s, duration: %(seconds)ss.", |
|
25
|
|
|
"Title of that %(service)s video is '%(title)s'.", |
|
26
|
|
|
"%(service)s video is titled '%(title)s' and has %(rating)s.", |
|
27
|
|
|
"Here is the title of that %(service)s video: '%(title)s'.", |
|
28
|
|
|
"I found the title of that %(service)s video, here it is: '%(title)s'", |
|
29
|
|
|
"If you click that link you will watch a video titled '%(title)s'. " |
|
30
|
|
|
+ "Good luck!", |
|
31
|
|
|
] |
|
32
|
|
|
|
|
33
|
|
|
WEB_RESPONSES = [ |
|
34
|
|
|
"The title of that page is '%(title)s'", |
|
35
|
|
|
"That page might be about %(title)s", |
|
36
|
|
|
"That page has an interesting title: '%(title)s'", |
|
37
|
|
|
"The title of that page makes me want to read the whole thing '%(title)s'", |
|
38
|
|
|
"%(title)s", |
|
39
|
|
|
] |
|
40
|
|
|
|
|
41
|
|
|
|
|
42
|
|
|
class ReadLinks(BotPlugin): |
|
43
|
|
|
|
|
44
|
|
|
def _get_tweet_info(self, status_id): |
|
45
|
|
|
status = TWITTER.get_status(status_id) |
|
46
|
|
|
name = status.user.screen_name |
|
47
|
|
|
text = status.text.replace('\n', ' ') |
|
48
|
|
|
return name, text |
|
49
|
|
|
|
|
50
|
|
|
def _read_twitter(self, channel, msg): |
|
51
|
|
|
twt_res = regex.TWITTER.search(msg) |
|
52
|
|
|
if not twt_res: |
|
53
|
|
|
return |
|
54
|
|
|
try: |
|
55
|
|
|
(name, text) = self._get_tweet_info(twt_res.group('id')) |
|
56
|
|
|
response = unicode("@" + name + " on Twitter says: " + text) |
|
57
|
|
|
response = response.encode('utf8') |
|
58
|
|
|
self.bot.say(response, channel) |
|
59
|
|
|
except: |
|
60
|
|
|
self.bot.log_error('Could not get tweet from: "' + msg + '"') |
|
61
|
|
|
self.bot.say('Sorry, I wasn\'t able to read the last tweet :(', |
|
62
|
|
|
channel) |
|
63
|
|
|
|
|
64
|
|
|
def _get_vimeo_info(self, video_id): |
|
65
|
|
|
api_url = "https://vimeo.com/api/v2/video/" + video_id + ".json" |
|
66
|
|
|
r = requests.get(api_url) |
|
67
|
|
|
video = json.loads(r.text)[0] |
|
68
|
|
|
if "stats_number_of_likes" in video: |
|
69
|
|
|
likes = ("%d likes." % video["stats_number_of_likes"]) |
|
70
|
|
|
else: |
|
71
|
|
|
likes = "an unknown number of likes" |
|
72
|
|
|
return { |
|
73
|
|
|
'service': "vimeo", |
|
74
|
|
|
'title': video["title"].encode('utf8'), |
|
75
|
|
|
'seconds': str(video["duration"]), |
|
76
|
|
|
'views': str(video["stats_number_of_plays"]), |
|
77
|
|
|
'rating': likes |
|
78
|
|
|
} |
|
79
|
|
|
|
|
80
|
|
|
def _read_vimeo(self, channel, msg): |
|
81
|
|
|
vimeo_res = regex.VIMEO.search(msg) |
|
82
|
|
|
if not vimeo_res: |
|
83
|
|
|
return |
|
84
|
|
|
try: |
|
85
|
|
|
video_info = self._get_vimeo_info(vimeo_res.group('id')) |
|
86
|
|
|
self.bot.say(random_response(VIDEO_RESPONSES) % video_info, |
|
87
|
|
|
channel) |
|
88
|
|
|
except: |
|
89
|
|
|
self.bot.log_error('Could not get title of vimeo link from: "' |
|
90
|
|
|
+ msg + '"') |
|
91
|
|
|
self.bot.say('For some reason I couldn\'t read the title of that ' |
|
92
|
|
|
+ 'vimeo link.', channel) |
|
93
|
|
|
|
|
94
|
|
|
def _get_youtube_info(self, video_id): |
|
95
|
|
|
import pafy |
|
96
|
|
|
url = "https://www.youtube.com/watch?v={0}".format(video_id) |
|
97
|
|
|
video = pafy.new(url) |
|
98
|
|
|
|
|
99
|
|
|
if video.rating is not None: |
|
100
|
|
|
average_rating = float(video.rating) |
|
101
|
|
|
rating = ("an average rating of %.2f" % average_rating) |
|
102
|
|
|
else: |
|
103
|
|
|
rating = "no rating" |
|
104
|
|
|
return { |
|
105
|
|
|
'service': "youtube", |
|
106
|
|
|
'title': video.title.encode('utf-8'), |
|
107
|
|
|
'seconds': video.length, |
|
108
|
|
|
'views': video.viewcount, |
|
109
|
|
|
'rating': rating |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
def _read_youtube(self, channel, msg): |
|
113
|
|
|
yt_res = regex.YOUTUBE.search(msg) |
|
114
|
|
|
if not yt_res: |
|
115
|
|
|
return |
|
116
|
|
|
try: |
|
117
|
|
|
video_info = self._get_youtube_info(yt_res.group('id')) |
|
118
|
|
|
self.bot.say(random_response(VIDEO_RESPONSES) % video_info, |
|
119
|
|
|
channel) |
|
120
|
|
|
except: |
|
121
|
|
|
self.bot.log_error('Could not get title of youtube link from: "' |
|
122
|
|
|
+ msg + '"') |
|
123
|
|
|
self.bot.say('For some reason I couldn\'t read the title of that ' |
|
124
|
|
|
+ 'youtube link.', channel) |
|
125
|
|
|
|
|
126
|
|
|
def _read_websites(self, channel, msg): |
|
127
|
|
|
links = regex.WEB_URL.findall(msg) |
|
128
|
|
|
for link in links: |
|
129
|
|
|
if [r for r in __all_non_web__ if r.search(link)]: |
|
130
|
|
|
continue |
|
131
|
|
|
try: |
|
132
|
|
|
t = lxml.html.parse(urlopen(link)) # nopep8 # nosec: regex.WEB_URL only allows http(s) |
|
133
|
|
|
t = t.find(".//title").text |
|
134
|
|
|
t = t.strip().replace('\n', ' ') |
|
135
|
|
|
if len(re.sub("[^a-zA-Z0-9]", "", t)) >= 5: |
|
136
|
|
|
self.bot.say(random_response(WEB_RESPONSES) % {'title': t}, |
|
137
|
|
|
channel) |
|
138
|
|
|
except: |
|
139
|
|
|
self.bot.log_error('Could not get title of webpage: "' |
|
140
|
|
|
+ msg + '"') |
|
141
|
|
|
|
|
142
|
|
|
def handle_message(self, channel, nick, msg, line=None): |
|
143
|
|
|
if "PRIVMSG" in line: |
|
144
|
|
|
self._read_twitter(channel, msg) |
|
145
|
|
|
self._read_youtube(channel, msg) |
|
146
|
|
|
self._read_vimeo(channel, msg) |
|
147
|
|
|
self._read_websites(channel, msg) |
|
148
|
|
|
|