Implement bellagrams

master
Nikola Forró 7 years ago
parent 5beb6e550f
commit 73b022a826

@ -5,6 +5,7 @@ using [HTTP API](https://gitea.brno.mraveniste.cc/turbotraktor/ladylilia.com/src
## Supported commands
* `!bellagram`, `!bellapics`, `!instabella`, `!instagram` - posts a link to a random Instagram picture of Bella
* `!lastquote` - requests the most recent quote
* `!findquote PATTERN` - searches for quotes matching `PATTERN` and in case multiple matches are found, requests one of them randomly
- `PATTERN` has to be at least 3 characters long and it can be enclosed in double quotes in case it contains spaces

@ -1,6 +1,7 @@
import configparser
import logging
import os
import random
import re
import string
@ -8,6 +9,7 @@ import dateutil.parser
import irc.bot
import requests
from instagram import Instagram
from twitch import Twitch
@ -53,6 +55,10 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
(QUOTE_REMOVED_PATTERN, self.remove_quote),
]
self.commands = [
(re.compile(r'^!bellagram$'), self.bellagram),
(re.compile(r'^!bellapics$'), self.bellagram),
(re.compile(r'^!instabella$'), self.bellagram),
(re.compile(r'^!instagram$'), self.bellagram),
(re.compile(r'^!lastquote$'), self.last_quote),
(re.compile(r'^!findquote\s+(?P<q>")?(?P<filter>.+)(?(q)")$'), self.find_quote),
(re.compile(r'^!sync(\s+(?P<since>.+))?$'), self.sync),
@ -65,10 +71,19 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
self.master_user_id = config['Twitch'].getint('master_user_id')
self.api_url = config['Quotes'].get('api_url')
self.api_key = config['Quotes'].get('api_key')
self.bellagrams = self._get_bellagrams()
log.info('Connecting to %s:%d', self.server, self.port)
super(TwitchBot, self).__init__([(self.server, self.port, self.token)],
self.nickname, self.nickname)
def _get_bellagrams(self):
username = config['Instagram'].get('username')
keywords = config['Instagram'].get('keywords').split(',')
media = Instagram(username, log).get_media()
if not media:
return None
return [m for m in media if [k for k in keywords if k.lower() in m['text'].lower()]]
def on_welcome(self, connection, event):
connection.cap('REQ', ':twitch.tv/membership')
connection.cap('REQ', ':twitch.tv/tags')
@ -111,6 +126,13 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
r.raise_for_status()
return r
def bellagram(self, connection, tags, **kwargs):
if not self.bellagrams:
msg = 'Sorry @{0}, couldn\'t get any media from Instagram'.format(tags['display-name'])
else:
msg = random.choice(self.bellagrams)['url']
connection.privmsg(self.channel, msg)
def last_quote(self, connection, tags, **kwargs):
try:
quotes = self.get(dict(

@ -0,0 +1,83 @@
import hashlib
import json
import re
import requests
BASE_URL = 'https://www.instagram.com'
QUERY_HASH = '42323d64886122307be10013ad2dcc44'
SHARED_DATA = re.compile(r'window\._sharedData = (\{.*\});</script>')
class Instagram(object):
def __init__(self, username, log=None):
self.username = username
self.log = log
shared_data = self._get_shared_data()
try:
self.user_id = shared_data['entry_data']['ProfilePage'][0]['graphql']['user']['id']
self.rhx_gis = shared_data['rhx_gis']
except (IndexError, KeyError, TypeError):
self.user_id = None
self.rhx_gis = None
def _get_shared_data(self):
r = requests.get('{0}/{1}'.format(BASE_URL, self.username))
if not r.ok:
return None
m = SHARED_DATA.search(r.text)
if m:
return json.loads(m.group(1))
return None
def _get_media(self):
def request(count, cursor):
variables = json.dumps(dict(
id=self.user_id,
first=count,
after=cursor))
gis = '{0}:{1}'.format(self.rhx_gis, variables)
gis = hashlib.md5(gis.encode('UTF-8')).hexdigest()
url = '{0}/graphql/query'.format(BASE_URL)
params = dict(
query_hash=QUERY_HASH,
variables=variables)
r = requests.get(url, params=params, headers={'X-Instagram-GIS': gis})
r.raise_for_status()
return r.json()
result = []
try:
count = 50
cursor = ''
while True:
data = request(count, cursor)
data = data['data']['user']['edge_owner_to_timeline_media']
for edge in data['edges']:
result.append(dict(
type=edge['node']['__typename'].split('Graph')[1],
text=edge['node']['edge_media_to_caption']['edges'][0]['node']['text'],
url='{0}/p/{1}'.format(BASE_URL, edge['node']['shortcode']),
display_url=edge['node']['display_url']))
cursor = data['page_info']['end_cursor']
if not cursor:
break
except KeyError:
return None
else:
return result
def get_media(self):
if not self.user_id:
return None
try:
result = self._get_media()
except requests.exceptions.HTTPError as e:
if self.log:
self.log.error('Failed to retrieve media: %s', str(e))
return None
else:
return result

@ -4,6 +4,10 @@ port = 6667
nickname = spooky_lurker
channel = lilialil
[Instagram]
username = lilialovesgames
keywords = bella,teeny,kitty,cat,😹,😻,🐱,🐈
[Twitch]
api_url = https://api.twitch.tv/v5
client_id = __TWITCH_CLIENT_ID__

Loading…
Cancel
Save