irc: add follow command

This commit is contained in:
William Pitcock 2018-08-17 19:53:46 -05:00
parent c6bcbdfd45
commit 3e446bc584
2 changed files with 23 additions and 3 deletions

View file

@ -41,6 +41,7 @@ async def actor(request):
"sharedInbox": "https://{}/inbox".format(request.host) "sharedInbox": "https://{}/inbox".format(request.host)
}, },
"followers": "https://{}/followers".format(request.host), "followers": "https://{}/followers".format(request.host),
"following": "https://{}/following".format(request.host),
"inbox": "https://{}/inbox".format(request.host), "inbox": "https://{}/inbox".format(request.host),
"name": "Viera", "name": "Viera",
"type": "Application", "type": "Application",
@ -76,19 +77,24 @@ async def push_message_to_actor(actor, message, our_key_id):
} }
headers['signature'] = sign_headers(headers, PRIVKEY, our_key_id) headers['signature'] = sign_headers(headers, PRIVKEY, our_key_id)
logging.debug('%r', headers)
logging.debug('%r >> %r', actor['inbox'], message)
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.post(actor['inbox'], data=data, headers=headers) as resp: async with session.post(actor['inbox'], data=data, headers=headers) as resp:
pass pass
async def follow_remote_actor(actor_uri): async def follow_remote_actor(actor_uri):
logging.info('following: %r', actor_uri)
actor = await fetch_actor(actor_uri) actor = await fetch_actor(actor_uri)
message = { message = {
"@context": "https://www.w3.org/ns/activitystreams", "@context": "https://www.w3.org/ns/activitystreams",
"type": "Follow", "type": "Follow",
"to": [actor['id']], "to": [actor['id']],
"object": [actor['id']], "object": actor['id'],
"id": "https://{}/activities/{}".format(AP_CONFIG['host'], uuid.uuid4()), "id": "https://{}/activities/{}".format(AP_CONFIG['host'], uuid.uuid4()),
"actor": "https://{}/actor".format(AP_CONFIG['host']) "actor": "https://{}/actor".format(AP_CONFIG['host'])
} }
@ -106,7 +112,7 @@ from .authreqs import check_reqs, get_irc_bot
async def handle_create(actor, data, request): async def handle_create(actor, data, request):
# for now, we only care about Notes # for now, we only care about Notes
if data['object']['type'] != Note: if data['object']['type'] != 'Note':
return return
# strip the HTML if present # strip the HTML if present
@ -119,7 +125,7 @@ async def handle_create(actor, data, request):
# fetch our IRC bot # fetch our IRC bot
bot = get_irc_bot() bot = get_irc_bot()
bot.relay_message(actor, data['object'], content) bot.relay_message(actor, data['object'], ' '.join(content))
async def handle_follow(actor, data, request): async def handle_follow(actor, data, request):

View file

@ -5,6 +5,7 @@ import base64
from blinker import signal from blinker import signal
from . import CONFIG from . import CONFIG
from .actor import follow_remote_actor
from .irc_envelope import RFC1459Message from .irc_envelope import RFC1459Message
from .authreqs import new_auth_req, set_irc_bot, check_auth, fetch_auth, drop_auth from .authreqs import new_auth_req, set_irc_bot, check_auth, fetch_auth, drop_auth
@ -99,6 +100,10 @@ class IRCProtocol(asyncio.Protocol):
return return
self.say(chan, '\x02{0}\x02: \x02{1}\x02'.format(nickname, data), verb='PRIVMSG') self.say(chan, '\x02{0}\x02: \x02{1}\x02'.format(nickname, data), verb='PRIVMSG')
def follow(self, nickname, actor_uri):
asyncio.ensure_future(follow_remote_actor(actor_uri))
self.say(nickname, 'Following \x02{}\x02'.format(actor_uri))
def set_pending_action(self, nickname, action): def set_pending_action(self, nickname, action):
if nickname not in self.pending_actions: if nickname not in self.pending_actions:
self.pending_actions[nickname] = action self.pending_actions[nickname] = action
@ -117,6 +122,9 @@ class IRCProtocol(asyncio.Protocol):
self.say(nickname, "The association of \x02{0}\x02 with \x02{1}\x02 has been dropped.".format(account, data)) self.say(nickname, "The association of \x02{0}\x02 with \x02{1}\x02 has been dropped.".format(account, data))
elif 'whois' in action: elif 'whois' in action:
self.whois(nickname, action['whois'], account) self.whois(nickname, action['whois'], account)
elif 'follow' in action:
logging.info('allowed follow: %r', action['follow'])
self.follow(nickname, action['follow'])
def handle_auth_req(self, req): def handle_auth_req(self, req):
self.say(req.irc_nickname, "The actor \x02{0}\x02 is now linked to the IRC account \x02{1}\x02.".format(req.actor, req.irc_account)) self.say(req.irc_nickname, "The actor \x02{0}\x02 is now linked to the IRC account \x02{1}\x02.".format(req.actor, req.irc_account))
@ -155,6 +163,12 @@ class IRCProtocol(asyncio.Protocol):
elif message.params[1] in ('voice', 'invite', 'drop'): elif message.params[1] in ('voice', 'invite', 'drop'):
self.set_pending_action(source_nick, message.params[1]) self.set_pending_action(source_nick, message.params[1])
self.fetch_account_whox(message) self.fetch_account_whox(message)
elif message.params[1][0:6] == 'follow':
chunks = message.params[1].split()
logging.info('considering whether to follow: %r', chunks[1])
self.set_pending_action(source_nick, {'follow': chunks[1]})
self.fetch_account_whox(message)
def handle_public_message(self, message): def handle_public_message(self, message):
if not message.params[1].startswith(IRC_CONFIG['nickname']): if not message.params[1].startswith(IRC_CONFIG['nickname']):