Пример #1
0
 async def recv_message(self):
     await asyncio.sleep(0.5)
     return Message(
         body=sys.stdin.readline().rstrip(),
         nick=os.environ['USER'],
         channel='#mock',
     )
Пример #2
0
    async def _recv_messages(self):
        while True:
            # Wait for message from client
            message = await self.client.recv_message()
            logging.debug('Received message: %s', message)

            # Check for matching commands
            async for responses in self.process_message(message):
                if not responses:
                    continue

                if isinstance(responses, (str, Message)):
                    responses = [responses]

                for response in responses:
                    if isinstance(response, str):
                        response = Message(response, message.nick,
                                           message.channel)

                    await self.outgoing.put(response)

            # Add message to history
            self.history.insert(message)

            # Update user last seen
            self.update_user_seen(message.nick, message.timestamp)
Пример #3
0
 async def _handle_motd(self, server):
     logging.debug('Handling MOTD')
     await self.send_message(
         Message(
             nick='NickServ',
             channel=None,
             body=f'IDENTIFY {self.password}',
         ))
Пример #4
0
async def tweets_timer(bot):
    logging.info('Tweets timer starting...')

    # Read configuration
    config = bot.config.load_module_config('tweets')
    templates = config.get('templates', {})
    default_template = templates.get('default', TEMPLATE)

    # Get access token
    access_token = await get_access_token(
        bot.http_client,
        config['consumer_key'],
        config['consumer_secret'],
    )

    # Read tweets
    entries = collections.defaultdict(list)
    cache_path = bot.config.get_config_path('tweets.cache')

    with dbm.open(cache_path, 'c') as cache:
        logging.debug('Processing tweets...')
        for feed in config.get('feeds', []):
            user = feed['user']
            try:
                async for tweet_entry in process_feed(bot.http_client, feed,
                                                      cache, access_token):
                    entries[user].append(tweet_entry)
            except Exception as e:
                logging.warning('Unable to process %s feed: %s', user, e)

        logging.debug('Delivering tweets...')
        for user, entries in entries.items():
            for entry in entries:
                status = entry['status']
                channels = entry['channels']
                status_key = entry['status_key']
                status_id = entry['status_id']
                link = await shorten_url(bot.http_client, entry['link'])

                # Send each entry to the appropriate channel
                for channel in channels:
                    template = templates.get(channel, default_template)
                    await bot.outgoing.put(
                        Message(channel=channel,
                                body=bot.client.format_text(
                                    template,
                                    user=user,
                                    status=status,
                                    link=link,
                                )))

                # Mark entry as delivered
                logging.info('Delivered %s from %s to %s', status, user,
                             ', '.join(channels))
                cache['since_id'] = str(
                    max(int(cache.get('since_id', 1)), status_id))
                cache[status_key] = str(time.time())
Пример #5
0
 async def recv_message(self):
     await asyncio.sleep(0.1)
     sys.stdout.write(f'<= ')
     sys.stdout.flush()
     return Message(
         body    = sys.stdin.readline().rstrip(),
         nick    = os.environ['USER'],
         channel = '#mock',
     )
Пример #6
0
async def feeds_timer(bot):
    logging.info('Feeds timer starting...')

    # Read configuration
    config = bot.config.load_module_config('feeds')
    templates = config.get('templates', {})
    default_template = templates.get('default', TEMPLATE)

    # Read and process results
    entries = collections.defaultdict(list)
    entries_limit = config.get('limit', 5)
    cache_path = bot.config.get_config_path('feeds.cache')

    with dbm.open(cache_path, 'c') as cache:
        logging.debug('Processing feeds...')
        for feed in config['feeds']:
            feed_title = feed['title']

            try:
                async for feed_entry in process_feed(bot.http_client, feed,
                                                     cache):
                    entries[feed_title].append(feed_entry)
            except Exception as e:
                logging.warning('Unable to process feed %s: %s', feed_title, e)

        logging.debug('Delivering feeds...')
        for feed_title, entries in entries.items():
            logging.debug('Delivering %s...', feed_title)
            for index, entry in enumerate(
                    sorted(entries, key=lambda e: e['timestamp'])):
                if index > entries_limit:  # Enforce entries limit
                    break

                title = entry['title'].replace('\r', ' ').replace('\n', ' ')
                key = entry['link'].encode('ascii', 'ignore')
                link = await shorten_url(bot.http_client, entry['link'])
                author = entry['author']
                channels = entry['channels']

                logging.debug('Delivering %s...', title)

                # Send each entry to the appropriate channel
                for channel in channels:
                    template = templates.get(channel, default_template)
                    await bot.outgoing.put(
                        Message(channel=channel,
                                body=bot.client.format_text(template,
                                                            feed=feed_title,
                                                            title=title,
                                                            link=link,
                                                            author=author)))

                # Mark entry as delivered
                logging.info('Delivered %s from %s to %s', title, feed_title,
                             ', '.join(channels))
                cache[key] = str(time.time())
Пример #7
0
    async def recv_message(self):
        message = None
        while not message:
            ws_message   = await self.ws.receive()
            json_message = json.loads(ws_message.data)
            logging.debug('Received JSON: %s', json_message)

            if json_message.get('type') != 'message':
                continue

            try:
                message = Message(
                    body    = json_message['text'],
                    nick    = json_message['user'],
                    channel = json_message['channel'],
                )
            except KeyError:
                pass

        logging.debug('Received message: %s', message)
        return message
Пример #8
0
 async def test_00_echo(self):
     for body in ('hello', 'world', 'quick brown fox'):
         message = await echo(None, Message(body), None)
         self.assertTrue(isinstance(message, Message))
         self.assertEqual(message.body, body)
Пример #9
0
async def events_timer(bot):
    logger = logging.getLogger()
    logger.info('Events timer starting...')

    # Read configuration
    config = bot.config.load_module_config('events')
    timeout = config.get('timeout', 10 * 60)
    templates = config.get('templates', {})
    default_template = templates.get('default', TEMPLATE)

    # Read events feeds
    for feed_config in config.get('feeds', []):
        feed_url = feed_config['url']
        feed_title = feed_config['title']
        feed_channels = feed_config.get('channels', [])

        logger.debug('Fetching %s (%s)', feed_title, feed_url)

        async with bot.http_client.get(feed_url) as response:
            text = await response.text()

        events = icalendar.Calendar.from_ical(text).walk('vevent')
        events = filter(
            lambda e: isinstance(e['DTSTART'].dt, datetime.datetime), events)
        logger.debug('Parsing %s (%s)', feed_title, feed_url)

        # Check each event
        for event in events:
            summary = event.get('summary')
            startdt = event.get('dtstart').dt
            enddt = event.get('dtend').dt
            exclusions = event.get('exdate')
            recurrences = event.get('rrule')
            description = event.get('description', '')
            location = event.get('location', '')
            now = datetime.datetime.now(datetime.timezone.utc)
            later = now + datetime.timedelta(seconds=timeout)

            try:
                channels = re.findall(r'channels:\s(.*)',
                                      description)[0].split(',')
                channels = list(map(str.strip, channels))
            except IndexError:
                channels = feed_channels

            if recurrences:
                recurrences = recurrences.to_ical().decode('utf-8')
                starts = parse_recurrences(recurrences, startdt, exclusions)
            else:
                starts = [startdt]

            for start in starts:
                if not now <= start <= later:
                    continue

                # Send each entry to the appropriate channel
                for channel in channels:
                    template = templates.get(channel, default_template)
                    await bot.outgoing.put(
                        Message(channel=channel,
                                body=bot.client.format_text(
                                    template,
                                    summary=summary,
                                    start_time=start.strftime("%I:%M %p"),
                                    end_time=enddt.strftime("%I:%M %p"),
                                    location=location,
                                )))

                logger.info('Delivered %s to %s', summary, ', '.join(channels))
Пример #10
0
 async def _handle_private_message(self, nick, body):
     logging.debug('Handling Private Message: %s, %s', nick, body)
     return Message(body, nick)
Пример #11
0
 async def _handle_channel_message(self, nick, channel, body):
     logging.debug('Handling Channel Message: %s, %s, %s', nick, channel,
                   body)
     return Message(body, nick, channel)
Пример #12
0
 async def test_00_eightball(self):
     message = await eightball(None, Message('!8ball'), None)
     for _ in range(len(RESPONSES)):
         self.assertTrue(isinstance(message, Message))
         self.assertTrue(any(message.body in r for r in RESPONSES))