Official Everybody Edits Forums

Do you think I could just leave this part blank and it'd be okay? We're just going to replace the whole thing with a header image anyway, right?

You are not logged in.

#1 2017-05-02 00:02:57

XxAtillaxX
Member
Joined: 2015-11-28
Posts: 4,202

GergBot for Slack

import os
import re
import time
import json
import hashlib
import calendar
import requests
import threading
import html2text

from datetime import datetime, date
from slackclient import SlackClient
from BeautifulSoup import BeautifulSoup as Soup
from BeautifulSoup import NavigableString

SLACK_BOT_TOKEN = 'CHANGE_THIS'
BOT_ID = 'CHANGE_THIS'

# constants
AT_BOT = "<@" + BOT_ID + ">"
COMMANDS = [ 'silence', 'listen', 'ping' ]
SILENCED = False

# instantiate Slack & Twilio clients
slack_client = SlackClient(SLACK_BOT_TOKEN)

def handle_command(command, channel):
    response = "No such command found. For a list of commands, use 'commands'."

    if command.startswith('commands') or command.startswith('help'):
        response = "Available commands: " + ', '.join(COMMANDS)
    elif command.startswith('silence'):
        SILENCED = True
        response = "Silence mode is now enabled."
    elif command.startswith('listen'):
        SILENCED = False
        response = "Silence mode is now disabled."
    elif command.startswith('ping'):
        response = "Pong."

    slack_client.api_call("chat.postMessage", channel=channel,
                          text=response, as_user=True)

def parse_slack_output(slack_rtm_output):
    output_list = slack_rtm_output
    if output_list and len(output_list) > 0:
        for output in output_list:
            if output and 'text' in output and AT_BOT in output['text']:
                # return text after the @ mention, whitespace removed
                return output['text'].split(AT_BOT)[1].strip().lower(), \
                       output['channel']
    return None, None

def strip_html(html):
    soup = Soup(html)
    [div.extract() for div in soup.findAll('div')]
    [span.extract() for span in soup.findAll('span')]
    [br.extract() for br in soup.findAll('br')]

    result = ''

    try:
        result = html2text.html2text(str(soup))
    except:
        result = str(soup)
    re.sub(r'(\r\n){2,}','\r\n', result)

    return result
 
def parse_forums():
    READ_FORUM_FEED_DELAY = 10
    PREVIOUS_POSTS = []
    FULLY_PARSED = False

    while True:
        req = requests.request('GET', 'http://forums.everybodyedits.com/extern.php?action=feed&type=xml')
        soup = Soup(req.content)

        posts = []
        for message in soup.findAll('topic'):
            post_id = message.attrs[0][1]
            title = message.find('title').text
            author_name = message.find('author').find('name').text
            author_profile = message.find('author').find('uri').text
            timestamp = datetime.strptime(message.find('posted').text, "%a, %d %b %Y %H:%M:%S +0000")
            content = strip_html(message.find('content').text)
            digest = hashlib.sha1(str.format('{}{}{}', post_id, author_profile, timestamp)).hexdigest()
            
            post = { 'post_id': post_id, 'title': title, 'author_name': author_name, 'author_profile': author_profile,
                     'timestamp': timestamp, 'content': content, 'digest': digest }
            posts.append(post)

        if FULLY_PARSED:
            found_posts = []

            for first in posts:
                found = False

                for second in PREVIOUS_POSTS:
                    if first['digest'] == second['digest']:
                        found = True
                        break

                if not found:
                    found_posts.append(first)

            for post in found_posts:
                print(post)

                channel_list = slack_client.api_call(
                    "channels.list",
                    exclude_archived=1
                )

                attachment = {
                    "fallback": str.format('[EEForums] {} replied to {}...', post['title'], 
                                str.format("http://forums.everybodyedits.com/viewtopic.php?id={}&action=new", post['post_id'])),
                    "color": "#36a64f",
                    "author_name": post['author_name'],
                    "author_link": post['author_profile'],
                    "author_icon": str.format("http://forums.everybodyedits.com/img/avatars/{}.png", post['author_profile'].split("?id=",1)[1]),
                    "title": post['title'],
                    "title_link": str.format("http://forums.everybodyedits.com/viewtopic.php?id={}&action=new", post['post_id']),
                    "text": post['content'][:150] + (post['content'][150:] and '..'),
                    "footer": "Everybody Edits Forums",
                    "footer_icon": "https://forums.everybodyedits.com/favicon.png",
                    "ts": int(calendar.timegm(post['timestamp'].timetuple()))
                }

                for channel in channel_list['channels']:
                    if channel['is_member'] and not SILENCED:
                            slack_client.api_call("chat.postMessage", channel=channel['id'], attachments=json.dumps( [attachment] ), as_user=True)

            PREVIOUS_POSTS = posts
        else:
            PREVIOUS_POSTS = posts
            FULLY_PARSED = True

        time.sleep(READ_FORUM_FEED_DELAY)

if __name__ == "__main__":
    READ_WEBSOCKET_DELAY = 1

    forum_parse_thread = threading.Thread(target=parse_forums, args=())
    forum_parse_thread.daemon = True
    forum_parse_thread.start()

    if slack_client.rtm_connect():
        print("BeefBot connected and running!")

        while True:
            command, channel = parse_slack_output(slack_client.rtm_read())
            if command and channel:
                handle_command(command, channel)
            time.sleep(READ_WEBSOCKET_DELAY)
    else:
        print("Connection failed. Invalid Slack token or bot ID?")

signature.png
*u stinky*

Offline

Wooted by: (2)

#2 2017-05-02 01:54:32

AlphaJon
Member
From: Who knows
Joined: 2015-07-21
Posts: 1,297

Re: GergBot for Slack

XxAtillaxX wrote:

GergBot

Not sure if typo or GregBot's retarded brother revealed himself.

---
I don't use Slack so that's about as far as I can contribute to this topic.

Offline

#3 2017-05-02 02:45:54

Pingohits
Banned
From: aids lizard
Joined: 2015-02-15
Posts: 7,591

Re: GergBot for Slack

AlphaJon wrote:
XxAtillaxX wrote:

GergBot

Not sure if typo or GregBot's retarded brother revealed himself.

---
I don't use Slack so that's about as far as I can contribute to this topic.

IT IS THE ALMIGHTY GERG IT IS BACK THE GERG THE GERG IS BACK


791mAP8.png

Offline

Wooted by:

#4 2017-05-02 14:36:16

XxAtillaxX
Member
Joined: 2015-11-28
Posts: 4,202

Re: GergBot for Slack

AlphaJon wrote:
XxAtillaxX wrote:

GergBot

Not sure if typo or GregBot's retarded brother revealed himself.

---
I don't use Slack so that's about as far as I can contribute to this topic.

GergBot is indeed the retarded brother of GregBot, which unfortunately left the IRC for the span of several months unexpectedly. GergBot was asked to show up in his place.

This could fairly easily be customized to suit a Discord bot, or anything for that matter,, so I think it should be useful to those who'd like notifications of new posts on the forums.


signature.png
*u stinky*

Offline

XxAtillaxX1493732176657954

Board footer

Powered by FluxBB

[ Started around 1732960292.2485 - Generated in 0.100 seconds, 12 queries executed - Memory usage: 1.45 MiB (Peak: 1.57 MiB) ]