GithubHelp home page GithubHelp logo

piperbot's Introduction

PiperBot

A multithreaded, multi-server IRC bot written in Python.

Pre-requisites

  • Python 3.4
  • MongoDB for the mongo backend.
  • dill for various things related to pickling and multiproccess
  • dateutil for reminders
  • requests for sane html stuff
  • BeautifulSoup4 for sane html parsing (see this for information on lxml for Windows)
  • PyPDF2 for reading PDF titles
  • patience it might not work completely...

Running

To run PiperBot, edit the settings.json file with your own settings, and do

python3.4 piperbot.py settings.json

Piping

One of the main features of PiperBot is the piping functionality. Different commands may be joined together, for example:

#echo Hello, World! || sed s/World/You/

Outputs: Hello, You!.

Commands should put their output in a variable called message.data. This variable may be accessed from within seval.

#echo 12 || > int(message.data) * 2

Outputs: 24.

Aliasing

With such a large set of tools for building commands, it makes sense to alias them into short hand commands for later calling. For example:

#alias ping = echo pong

#ping

Outputs: pong.

Aliases may be piped commands too.

#alias o = sed s/([aiue])/\1/i || sed s/[aiue]/o/g || sed s/[AIUE]/O/g
Hello, World
#o

Outputs: Hollo, World.

Plugins

Notice: # is the default "command character". This is required for the 1st invokation of pipable command. Commands after pipes shall not use # in their calling.

#nicks || 
 > message.data + ["Pengwin","C"] || 
 karma || 
 filter message.data[1] != 0 || 
 > {"d":json.dumps(sorted(message.data,reverse=True,key=lambda x: x[1]))} || 
 burl https://graymalk.in/ircstats/karma-graph.html? || 
 shurl

Note also that new lines are being added. These are only for readablity. Piperbot will not allow for line continuations, and you must strip new lines when building commands.

List of available plugins and their funtion:

general

General functions of the bot.

  • #echo <text> : echo format the text with any piped data, or just echo the text
  • #reverse <text> : reverse piped data or the text
  • #caps <text> : UPPERCASE piped text
  • #lower <text> : lowercase piped text
  • #rot13 <text> : Ceaser shift 13 piped text
  • #list : List the loaded plugins
  • #sed <sed pattern> <text> : Does a sed replace on text. Searches for a #match for the 1st operand of the regex in previous messages seen reverse #chronologically.
  • #help <command> for more in-depth help on a command
  • lots more

markov

Talks.

  • #talk to <nick> : Talk to someone
  • #talk about <topic> : Talk about a given topic

The bot will also respond if directly referenced in a message.

17:40 < graymalkin> PiperBot: hi
17:40 < PiperBot> graymalkin: on your tongue too

seval

A meta circular evaluator, or a Python interpreter written in Python. A little bit complicated!

seval may be invoked with #> or #seval.

Basic usage:

  • #> 1+1 : It will do some maths
  • #> [x+1 for x in [1,2,3]] : List comprehensions
  • #> a = 5; b = a + 2; : Local assignments
  • #> lambda x: x*2 : Lambdas

A selection of standard python functions are available. For full documentation see here.

piperbot's People

Contributors

dazzyg avatar egelmex avatar ellxc avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

piperbot's Issues

logs and logging

implement simple logging system, preferably one that is machine readable.

Error message when mongo is not installed/running is less helpful than it could be.

Traceback (most recent call last):
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/pymongo/mongo_client.py", line 374, in __init__
    self._ensure_connected(True)
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/pymongo/mongo_client.py", line 939, in _ensure_connected
    self.__ensure_member()
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/pymongo/mongo_client.py", line 813, in __ensure_member
    member, nodes = self.__find_node()
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/pymongo/mongo_client.py", line 904, in __find_node
    raise AutoReconnect(', '.join(errors))
pymongo.errors.AutoReconnect: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "piperbot.py", line 587, in <module>
    bot.load_plugin_from_module(plugin_)
  File "piperbot.py", line 146, in load_plugin_from_module
    self.load_plugin(Class)
  File "piperbot.py", line 169, in load_plugin
    func()
  File "/home/me92/Dropbox/projects/piperbot/plugins/general.py", line 194, in alaiasload
    con = pymongo.MongoClient()
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/pymongo/mongo_client.py", line 377, in __init__
    raise ConnectionFailure(str(e))
pymongo.errors.ConnectionFailure: [Errno 111] Connection refused

clean up current plugins.

some plugins have way too many things in (general.py, web.py) and others need a clean up in terms of code.

rework plugins to allow non strings to be passed through pipes?

Can easily be done via changing how the pipe function works in the main file, instead of converting to a string and trying to append it, can check if either previous string is empty or using string formating to use the value in its native form.
This will allow some interesting interactions especially with time objects.

rework admin system

allow identifying with a password or by having a white-listed user and domain. stop using authentication based on nick only.

Expand event handling system.

Allow plugins to register event handlers.
Add global event handlers.
Convert handle message into separate event handlers?

Bot does not recover from ping timeouts.

<< blitzed: 2015-04-06 15:15:45 PING :penguin.uk.eu.blitzed.org
>> blitzed: 2015-04-06 15:15:45 PONG :penguin.uk.eu.blitzed.org
<< blitzed: 2015-04-06 15:18:10 <Marvin([email protected])> QUIT :Ping timeout: 265 seconds
<< blitzed: 2015-04-06 15:18:10 ERROR :Closing Link: ba26-585.members.linode.com (Ping timeout: 265 seconds)

Excess Flood

10:52 < mattH> #> ( "penis " * 1000 ) * 1000
10:52 < tris> > "penis " * 10
10:52 < Marvin> 'penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis
penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis penis
10:52 -!- Marvin [~[email protected]] has quit [Excess Flood]

create user system

keep track of user's name changes for use in plugins such as karma, namespaces in seval etc
and allow storing of information from a plugin such as karma score.
keep information stored in mongo or a local file.

Feature: Config system

It would be nice if one could specify all the config details in a .json file.

Something like:

[
    {
        "IRCName" : "PiperBot",
        "IRCHost" : "irc.freenode.org",
        "IRCNick" : "PiperBot",
        "IRCUser" : "PiperBot",
        "IRCPassword" : "my_secret_password",
        "IRCPort" : 6697,
        "AutoJoin" : ["#KentCS"]
        "Admins" : ["Pengwin"]
    },
    // ...
]

I'll probably work on this over the next few evenings.

persistence for seval

thinking is to store the values in mongo where appropriate, and when the values can't be pickled to pickle the AST representation for expression, with the at the time values subbed in in place of the corresponding names. this would have to be done at time of definition,
as pickling and unpickling can be slow, might be worth having local versions in dicts, and writing to mongo as definitions are made, but only reading from mongo at startup.

better help system

at the moment the help system is in dire need of attention, very few commands have help and invoking the command without any arguments gives an error.
maybe it should link to here on GitHub for some of the docs?

Unhelpful error message when failing to connect.

Traceback (most recent call last):
  File "piperbot.py", line 600, in <module>
    bot.connect_to(server_name, network, port, nick, autojoin, admins, password, user, name, usessl)
  File "piperbot.py", line 103, in connect_to
    self.servers[servername].connect()
  File "/home/me92/Dropbox/projects/piperbot/serverconnection.py", line 38, in connect
    self.socket.connect((self.network, self.port))
socket.gaierror: [Errno -2] Name or service not known

Retrieving titles can result in mojibake

Presumably something somewhere isn't dealing with encoding properly.

I'd guess that a simple fix for this would be:

title = brokenhtml.xpath("//title/text()").encoding("utf-8")

cdn help could be more.... helpful

cdn: starts a new countdown numbers game for the current channel

Should probably list the other commands that are usefull, maybe a seealso tag for help?

Admin levels

It would be nice if there were a couple of levels of admin.

For example, having an administrator who may use #load #unload #join #leave etc, but not #eval.

My reasoning being you then have someone who can prevent the bot running a-muck; without giving them direct shell access to your machine via #eval

FINISH SEVAL

augment assignments, userspaces, string representations for builtin types, better errors

Is the mongo integration too deep?

Should Marvin be able to function without mongo? Currently the integration is very deep - perhaps it should be moved out to the plugin level a bit more cleanly.

On the same note maybe a plugin dependency system would be a good idea?

Documentation for `seval` plugin

seval is a powerful plugin which is quite complicated. It would be neat if there were a bit of documentation defining its features. It could be referenced in #help seval potentially.

Add Module specific configuration and more error checking into config file

#2 being fixed now means we can specify servers, and logins in a non-code file, which is nice. However it's a little fragile and doesn't have all the defaults it should.

It would also be nice if you could pass through configs to various plugins. E.g. mongo db settings to markov, again with sensible defaults.

Similarly it should be extensible. Potentially with a global list of API keys, accessible by other plugins to safely grab a key without needing to in-line it in code, or have a custom solution.

This could also be per-server, where instead of a list of auto-load plugin names, there's a list of plugin configs.

{
    /* other config lines ... */
    "Plugins": [
        {
            "Name" : "markov",
            "DBName" : "markov"
        },
        {
            "Name" : "seval",
            "timeout" : 3
        }
    ]
}

Issue Pickling.

  File "/usr/lib64/python3.4/pickle.py", line 479, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/dill/dill.py", line 949, in save_module
    state=_main_dict)
  File "/usr/lib64/python3.4/pickle.py", line 627, in save_reduce
    save(state)
  File "/usr/lib64/python3.4/pickle.py", line 479, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/dill/dill.py", line 658, in save_module_dict
    StockPickler.save_dict(pickler, obj)
  File "/usr/lib64/python3.4/pickle.py", line 814, in save_dict
    self._batch_setitems(obj.items())
  File "/usr/lib64/python3.4/pickle.py", line 840, in _batch_setitems
    save(v)
  File "/usr/lib64/python3.4/pickle.py", line 524, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib64/python3.4/pickle.py", line 627, in save_reduce
    save(state)
  File "/usr/lib64/python3.4/pickle.py", line 479, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/dill/dill.py", line 658, in save_module_dict
    StockPickler.save_dict(pickler, obj)
  File "/usr/lib64/python3.4/pickle.py", line 814, in save_dict
    self._batch_setitems(obj.items())
  File "/usr/lib64/python3.4/pickle.py", line 840, in _batch_setitems
    save(v)
  File "/usr/lib64/python3.4/pickle.py", line 524, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib64/python3.4/pickle.py", line 598, in save_reduce
    save(cls)
  File "/usr/lib64/python3.4/pickle.py", line 479, in save
    f(self, obj) # Call unbound method with explicit self
  File "/home/me92/.virtualenvs/piper/lib/python3.4/site-packages/dill/dill.py", line 993, in save_type
    StockPickler.save_global(pickler, obj)
  File "/usr/lib64/python3.4/pickle.py", line 915, in save_global
    (obj, module_name, name))

Document `lxml` installation on Windows

Windows people will need a compiler on their %PATH% to build lxml. This is somewhat involved, so it would be nice to have a full set of instructions on this.

It will probably involve installing Visual Studio Express, as the default pip installation complains with this message:

error: Unable to find vcvarsall.bat

vcvarsall.bat puts various MSVC settings in the environment - and it's the 1st part of a Visual Studio C build chain.

Bot does not close down cleanly when sent SIGTERM

^CTraceback (most recent call last):
  File "piperbot.py", line 111, in run
    message = self.in_queue.get(timeout=10)
  File "/usr/lib64/python3.4/queue.py", line 176, in get
    self.not_empty.wait(remaining)
  File "/usr/lib64/python3.4/threading.py", line 294, in wait
    gotit = waiter.acquire(True, timeout)
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "piperbot.py", line 605, in <module>
    bot.run()
  File "piperbot.py", line 117, in run
    self.shutdown()
  File "piperbot.py", line 125, in shutdown
    server.disconnect(message="shutting down")
  File "/home/me92/documents/projects/piperbot/serverconnection.py", line 96, in disconnect
    self.socket.send(('QUIT :' + message + '\r\n').encode())
BrokenPipeError: [Errno 32] Broken pipe


Should the bot create json files if not found?

Traceback (most recent call last):
  File "piperbot.py", line 586, in <module>
    bot.load_plugin_from_module(plugin_)
  File "piperbot.py", line 145, in load_plugin_from_module
    self.load_plugin(Class)
  File "piperbot.py", line 168, in load_plugin
    func()
  File "/home/me92/documents/projects/piperbot/plugins/karma.py", line 14, in onload
    with open('karma.json', 'r') as infile:
FileNotFoundError: [Errno 2] No such file or directory: 'karma.json'

seval is DOSable.

15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357
15:46 <@edd> #> 2**649854985749857439857389457894357

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.