Giter Club home page Giter Club logo

skybot's Introduction

Skybot

Goals

  • simplicity
    • little boilerplate
    • minimal magic
  • power
    • multithreading
    • automatic reloading
    • extensibility

Features

  • Multithreaded dispatch and the ability to connect to multiple networks at a time.
  • Easy plugin development with automatic reloading and a simple hooking API.

Requirements

To install dependencies, run:

pip install -r requirements.txt

Skybot runs on Python 2.7 and Python 3.7.

License

Skybot is public domain. If you find a way to make money using it, I'll be very impressed.

See LICENSE for precise terms.

skybot's People

Contributors

andyeff avatar avidal avatar bwreilly avatar craisins avatar crisisking avatar darkone23 avatar dstufft avatar ell avatar epalm avatar factormystic avatar imhitchens avatar imnotjames avatar jmgao avatar jstultz avatar kanetw avatar lahwran avatar lightquake avatar lindseyb avatar mezmor avatar nightchaos avatar olslash avatar parkrrr avatar pmrowla avatar rmmh avatar robdennis avatar sklnd avatar spathi-wa avatar stoneleaf avatar tomjakubowski avatar twiedenbein avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

skybot's Issues

CTCP VERSION throws exception on Windows with GitHub for Windows

I'm using the new GitHub for Windows client and if you run the bot it'll throw exceptions when trying to respond to VERSION requests. The problem is that it can't find Git.

Unhandled exception in thread started by <function run at 0x00000000024ED7B8>
Traceback (most recent call last):
  File "core\main.py", line 66, in run
    out = func(input.inp, **kw)
  File "plugins\misc.py", line 61, in onjoin
    ident, rev = get_version()
  File "plugins\misc.py", line 12, in get_version
    p = subprocess.Popen(['git', 'log', '--oneline'], stdout=subprocess.PIPE)
  File "C:\Python27\lib\subprocess.py", line 679, in __init__
    errread, errwrite)
  File "C:\Python27\lib\subprocess.py", line 893, in _execute_child
    startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

Add CTCP VERSION/TIME/PING plugin and parse the reply

Hello, I would like to ask if you could make something like letting the bot VERSION, TIME, PING etc other people, such thing as:

conn.cmd('PRIVMSG',[inp,'\x01VERSION\x01'])

parse the reply

say(parsed.reply())

where of course inp is the nick that's VERSION, PING, TIME you would like to get. I was looking for something similar, but couldn't find. What will help you doing it is https://github.com/PiPeep/python-ircutils/blob/master/ircutils/ctcp.py.

Regards.

Add botnet support

Add support for multiple bots sharing the same brain, like eggdrop has

bot.py broken after wrapping it in main()(

$ python2 bot.py
Loading plugins
Traceback (most recent call last):
File "bot.py", line 58, in
main()
File "bot.py", line 29, in main
reload(init=True)
TypeError: reload() takes no keyword arguments

.youtube throws exception

The latest change throws an unhandled exception when the plugin is called:

Unhandled exception in thread started by <function run at 0x8c4eb1c>
Traceback (most recent call last):
  File "core/main.py", line 68, in run
    out = func(input.inp)
  File "plugins/youtube.py", line 62, in youtube_url
    return get_video_description(match.group(1))
  File "plugins/youtube.py", line 48, in get_video_description
    j['viewCount'], 1).decode(locale.getlocale()[1])
TypeError: decode() argument 1 must be string, not None

Not unescaping for bible module

When I type .du luka 3, it gave me:
Ich t&ouml;te deine eltern.
It should be Ich töte deine eltern., right?

Hint: There is a function HTMLParser.HTMLParser().unescape() that can unescape it.

RFC: Pull in plugins from External Modules

I'm opening this to go over a feature I'm working on that requires a bit of a change on the internals of skybot, so I thought it'd be best to open an RFC issue before I go and start throwing the pull requests out there.

I have been wanting to pull in plugins from external modules. Why? Because there are plugins that I have that I'd like to share - plugins which are useful (or useless but funny) but which I don't think fit in with the main skybot repository. They might require external modules (like a few reddit plugins I've made or the amazon plugin) or are just less useful for other folks (a plugin for an in-joke with the IRC channels the bot runs on).

I'm also be interested in pulling skybot as a dependency of a separate application so we can extend on top of it without having to copy all the files and adding in custom plugins with a simple install (eg teampeggle/ppp-helpdesk). Right now it's painful because I have to manually sync all the changes.

It is possible to do this! I've been experimenting with a few things to do this, which mostly entails cleaning up the codebase:

  • Make skybot run as a package rather than as a bunch of scripts #183
  • Clean up skybot's imports / reloader so they stop abusing globals WIP
  • Clean up the hook API on functions (stop over-polluting the function properties)
  • Update the reloader to pull in plugins via module name rather than filename
  • Add a configuration value to specify plugins to pull in via module

Ideally, the configuration for specifying plugins would default to all plugins under skybot.plugins.* (backwards compatibility), and if specified would then start pulling in plugins to use, setting up the reloader, etc.

After these are complete, any module within the python path can be used as a plugin! EG, if you were to pip install skybot-plugin-awesome, you could pull it in as a fantastic new plugin without copying it to the plugins directory!

Thoughts, concerns, etc?

Add support for middleware (ie, input/output hooks)

The idea is being able to write plugins that process the input before they are parsed into commands or run through the sieves, as well as being able to modify the output before it's sent to the server.

I've written some code that provides basic (although working) support for input/output hooks. Before I go any further, I wanted some feedback as to the utility of it.

You can look at the compare view here: avidal/skybot@master...middleware

One example for an input hook would be moving the acl and bot ignoring stuff from main.py into an input hook. You could also add rate limiting by nick as an input hook easily, as well as write a plugin for flood protection as an output hook.

about socket.timeout: timed out

hello ,
when i run skybot ,a error occured.it says "socket.timeout: timed out
"

and the all command:
Loading plugins
plugin listing:
command:
plugins/bf.py:bf:14 bf
plugins/bigassmessage.py:bam:4 bam
plugins/bitcoin.py:bitcoin:4 bitcoin
plugins/choose.py:choose:7 choose
plugins/dice.py:dice:35 dice, roll
plugins/dictionary.py:define:27 dictionary, define
plugins/dictionary.py:etymology:87 etymology, e
plugins/dictionary.py:urban:6 urban, u
plugins/dotnetpad.py:cs:53 cs
plugins/dotnetpad.py:fs:46 fs
plugins/down.py:down:6 down
plugins/drama.py:drama:10 drama, ed
plugins/explain.py:explain:5 explain
plugins/gcalc.py:calc:4 calc
plugins/google.py:gis:12 gis
plugins/google.py:google:26 google, g
plugins/hash.py:hash:16 hash
plugins/hash.py:md5:6 md5
plugins/hash.py:sha1:11 sha1
plugins/help.py:help:6 help
plugins/imdb.py:imdb:6 imdb
plugins/lastfm.py:lastfm:10 lastfm
plugins/mem.py:mem:7 mem
plugins/metacritic.py:metacritic:9 mc
plugins/mtg.py:mtg:6 mtg
plugins/oblique.py:oblique:31 oblique, o
plugins/pre.py:predb:6 predb
plugins/profile.py:profile:6 profile
plugins/pyexec.py:python:9 python
plugins/quote.py:quote:38 quote, q
plugins/religion.py:bible:4 bible, god
plugins/religion.py:koran:26 allah, koran
plugins/remember.py:forget:64 forget, f
plugins/remember.py:remember:23 remember, r
plugins/rottentomatoes.py:rottentomatoes:8 rottentomatoes, rt
plugins/seen.py:seen:25 seen
plugins/snopes.py:snopes:9 snopes
plugins/stock.py:stock:6 stock
plugins/suggest.py:suggest:8 suggest
plugins/tag.py:munge:8 munge
plugins/tag.py:tag:79 tag
plugins/tell.py:showtells:50 showtells
plugins/tell.py:tell:72 tell
plugins/tf.py:tf:9 hats, tf
plugins/translate.py:babel:108 babel
plugins/translate.py:babelext:121 babelext
plugins/translate.py:translate:66 translate
plugins/tvdb.py:tv_last:131 tv_last, tv_prev
plugins/tvdb.py:tv_next:85 tv_next, tv
plugins/twitter.py:twitter:28 twitter
plugins/validate.py:validate:10 validate
plugins/weather.py:weather:6 weather
plugins/wikipedia.py:wiki:15 wiki, w
plugins/wolframalpha.py:wolframalpha:6 wolframalpha, wa
plugins/yahooanswers.py:answer:4 answer
plugins/youtube.py:youtube:65 youtube, y
event:
plugins/misc.py:rejoin:27 KICK
plugins/misc.py:onjoin:40 004
plugins/misc.py:invite:35 INVITE
plugins/log.py:log:84 *
plugins/tell.py:tellinput:25 PRIVMSG
plugins/seen.py:seeninput:15 PRIVMSG
regex:
plugins/misc.py:version:64 ^\x01VERSION\x01$
plugins/youtube.py:youtube_url:60 (?:youtube.?(?:v=|/v/)|youtu.be/|yooouuutuuube.?id=)([-_a-z0-9]+)
plugins/somethingawful.py:forum_link:22 (?i)forums.somethingawful.com/\S+threadid=(\d+)
plugins/vimeo.py:vimeo_url:4 vimeo.com/([0-9]+)
plugins/tinyurl.py:tinyurl:4 (?i)http://(?:www.)?tinyurl.com/([A-Za-z0-9-]+)
plugins/remember.py:question:84 ^? ?(.+)
plugins/urlhistory.py:urlinput:66 ([a-zA-Z]+://|www.)[^ ]+
sieve:
plugins/sieve.py:sieve_suite:6

Connecting to IRC
Running main loop
^F
^F
Unhandled exception in thread started by <bound method crlf_tcp.run of <main.crlf_tcp object at 0x196fd50>>
Traceback (most recent call last):
File "core/irc.py", line 45, in run
self.socket.connect((self.host, self.port))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.timeout: timed out

what should i do?
thanks!

Vanilla install, No module named cdecl from pycparser from pip

Steps to Reproduce

  1. Create new virtualenv (in ex. dir /opt) "skybot"
    cd /opt virtualenv skybot
  2. Put skybot source code in /opt/skybot/skybot directory
  3. Activate the skybot virtualenv
    source /opt/skybot/bin/activate
  4. Install the necessary python packages via pip.
    pip install -r /opt/skybot/skybot/requirements.txt
  5. Run skybot.
    python /opt/skybot/skybot/bot.py

Every time I run this and the explain.py plugin is in the plugins directory, I get this error before loading the plugins:


Traceback (most recent call last):
  File "core/reload.py", line 89, in reload
    eval(code, namespace)
  File "plugins/explain.py", line 2, in <module>
    from pycparser.cdecl import explain_c_declaration
ImportError: No module named cdecl

Does anyone else get this error? I looked at my site-packages folder in /opt/skybot/lib/python2.7/site-packages/pycparser and there is no examples directory or cdecl.py file. If this is the case for current pip installs, perhaps explain.py should be removed or refactored to not use this example code?

possible LAN data leak.

if any of you has made a plugin/factoid that allows users to input a http:// link or an IP/DNS hostname make sure you check what addresses they're actually sending packets to if you're sending packets directly from the bot and not an external service (eg. google).
if you are not it is possible for an attacker to port scan your LAN via the bot using the plugin/factoid.

eg.

  • connection refused will mean i know a host is at that IP and has the port closed.
  • connection timed will mean i know there isnt a host at that internal IP.
  • a page title of None will mean i found a service on that port.

i recommend that a censor for the /plugins/util/http.py plugin to disallow these netmasked addresses:

192.168.0.0/16
172.16.0.0/16 to 172.31.0.0/16
10.0.0.0/8
127.0.0.0/8
169.254.0.0/16

as any of these IP addresses are LAN addresses and dont map to the internet, they shouldnt be queried at all as they can leak LAN information on to the internet.

this will not affect you if you dont have a LAN connection on the running host of the bot. (eg. a VPS or similar that only has a direct internet connection and cannot in anyway contact these addresses).

Pretty logs

I recently got interested in IRC bots. I see them as a
powerful tool, good for startups that heavily rely on
remote workers: Async communication, SCM and CI, integration,
automated processes, etc.

Not missing anything is also important to me, I would
like to improve logs readability, and ultimately come up
with something like these logs: https://botbot.me/
HTML generation, a flask app?
Does it sound like something useful?, any advice?

log should include bot responses

might require some sort of way to register hooks on output (like sieve on input?)

would be helpful for identifying auto-kline phrases that knock bots offline

Google API issues.

When using a browser/website API key, I get error 403 forbidden.

When using a server API key, I get error 403 forbidden.

Unhandled exception in thread started by <function run at 0x6f8699a9baa0>
Traceback (most recent call last):
  File "core/main.py", line 78, in run
    out = func(input.inp, **kw)
  File "plugins/youtube.py", line 76, in youtube
    j = http.get_json(search_api_url, **params)
  File "plugins/util/http.py", line 42, in get_json
    return json.loads(get(*args, **kwargs))
  File "plugins/util/http.py", line 30, in get
    return open(*args, **kwargs).read()
  File "plugins/util/http.py", line 84, in open
    return opener.open(request)
  File "/usr/lib/python2.7/urllib2.py", line 410, in open
    response = meth(req, response)
  File "/usr/lib/python2.7/urllib2.py", line 523, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python2.7/urllib2.py", line 448, in error
    return self._call_chain(*args)
  File "/usr/lib/python2.7/urllib2.py", line 382, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 531, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden

How exactly do you set up the google plugin?
I'm getting my api keys from here:
https://console.developers.google.com/apis/credentials

Thanks :)

SomethingAwful Thread Title Format Change

With the new dev, we have new code in the front end, which isn't parsed correctly. Actually I already fixed it but didn't really want to fork/pull request over a one liner. Diff follows:

diff --git a/plugins/somethingawful.py b/plugins/somethingawful.py
index 84bda1f..13dd000 100644
--- a/plugins/somethingawful.py
+++ b/plugins/somethingawful.py
@@ -30,7 +30,7 @@ def forum_link(inp, bot=None):
thread = http.get_html(showthread, threadid=inp.group(1), perpage='1',
cookies=True)

  • breadcrumbs = thread.xpath('//div[@Class="breadcrumbs"]//a/text()')
  • breadcrumbs = thread.xpath('//div[@Class="breadcrumbs"]//span[@Class="mainbodytextlarge"]//a/text()')

if not breadcrumbs:
return

Store full user input into database rather than stripped out loc

Hi Scaevolus, I had an issue with the way the weather plugin wrote back to the database, in that it looked to be only writing back 'loc' - this looked to cause an issue at least doing weather lookups for UK / Europe in that without having the 'state' information included caused wunderground to always query which 'loc' you were looking for.

I've tested by writing back 'inp' instead of 'loc' to the database and so far doesn't appear to have broken anything but Python is fairly new to me and I dunno if this would cause issues that I don't know about.

So for example I changed

    if inp and not dontsave:
        db.execute("insert or replace into weather(nick, loc) values (?,?)",
                     (nick.lower(), loc))
        db.commit()

to

    if inp and not dontsave:
        db.execute("insert or replace into weather(nick, loc) values (?,?)",
                     (nick.lower(), inp))
        db.commit()

Example of the problem before fixing:

.we oxford, uk
Oxford, United Kingdom: Clear, 12.9C, Humidity: 87%, Wind: From the ENE at 0.0mph / 0.0km/h

.we
Could not find weather for . Possible matches include: Oxford AL USA, Oxford AR USA, Oxford CT USA, Oxford FL USA, Oxford GA USA, Oxford ID USA
(It's only stored 'oxford' in the db rather than 'oxford, uk'

Sorry if this looks like ass, I also don't know markdown very well either.

Any way to send a message to a channel unprompted?

I'd like to make a plugin that scrapes an RSS feed every 15-30 minutes and stores any new news items in a database. I'd like any new news items to be sent to the channel, but I can't seem to find any way to send a message without being prompted (by a command). I tried poking around with the say() and message() methods in the Input class, but couldn't get anywhere with those. Does anyone have any ideas?

Channels should be joined when config is updated

Skybot doesn't refresh channel states when the configuration when has changed. If a channel or server is added to the list, SkyBot must be completely restarted to finalize the changes. This should be automatic at runtime.

No License declaration

I like the skybot framework a lot. I'm not sure how the author feels about forks & derivatives though. Is there any chance at getting a license of sort mentioned?

use `requests` library?

Instead of using open, and the util.http module for handling HTTP requests, would there be interest in converting this over to using the requests library? It means a more generalized library with more control over the workflow.

If so, we could utilize requests-mock to create mocks more easily for tests for the plugins.

A branch using requests in the util.http can be found here https://github.com/imnotjames/skybot/tree/feature/use-requests-for-http but I think there's a benefit in handling everything with requests directly.

Thoughts, concerns, etc?

Upgrade to Python 3?

I wanted to open an issue to discuss what concerns there are - if any - on upgrading to Python 3 from 2.7. At the very least, I'd be interested in trying to get python 3 compatible code up with future but there are no Python2-only dependencies, so I'm using Python 3 live.

I've already done a quick pass for the fork of skybot that I keep up, but it's always nice to push things back upstream. ( imnotjames@960e8b6 )

I hit a few problems:

  • There are no tests. This makes it very difficult to know if something's broken or not. Since most of the bot relies on outside APIs, and there's no culture to enforce tests, I'm not sure the best way to handle that.
  • Without tests, I can't set up tox to check both 2 and 3 compatibility. I'm manually running two bots right now with both 2 and 3.
  • Instead of standard strings, we end up with binary strings in many cases. These have to be correctly encoded / decoded to be valid. I think I got them, but see the point about tests for cases where there might be problems..

Would there be interest in merging these changes upstream?

Bot not joining channel when Config is changed

For some reason when i execute the start command the bot connects to the IRC network, but does not join 2channels i added on Config.

Note that i can use commands via PM to Bot, but i want the bot on my channel.

Regards, Saloun.

Format for Twitter API Keys?

I have had no luck finding the proper format for the key-value pairs in config that Skybot is expecting to run twitter.py. Could you give us a clue? I do have the four keys needed according to twitter. Perhaps a config file in the future with some of these keys present but no values?

Seen plugin stops updating the seen table

The seen table in the database stops updating after a few months, seemingly spontaneously. I've had 3 long term skybots (first two were not mine, the current one is) where the .seen command will stop working after somewhere around a year. I looked at the seen table in my current database and it stopped updating 2 months ago.

Everything else using that database seems to be working as usual.

better plugin distribution

There should be a way to add/remove plugins without forking skybot. Most people don't need to modify the core, but do want to customize the commands.

Git submodules + host them in gists?

Weather plugin not happy with unicode

I'm having problems figuring out how best to address the issue of Wunderground returning data that triggers a UnicodeDecodeError. The swedish town of 'umea' seems to be a good test case.

".we umea" triggers the following traceback:

Unhandled exception in thread started by <function run at 0x7f56a5a21b90>
Traceback (most recent call last):
  File "core/main.py", line 78, in run
    out = func(input.inp, **kw)
  File "plugins/weather.py", line 71, in weather
    parsed_json = http.get_json(url)
  File "plugins/util/http.py", line 42, in get_json
    return json.loads(get(*args, **kwargs))
  File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe5 in position 3: unexpected end of data

Unicode still confuses me and makes me question my purpose in the universe, so I don't know whether this is an issue with the JSON that wunderground returns, or whether the get_json function just doesn't like dealing with non-ASCII. I wouldn't mind trying to fix it myself and putting in a pull request, but I'm really unsure about how to edit rmmh's existing url-parsing functions without breaking everything. Anyone got a suggestion where I should start?

Lack of Plugin-writer documentation

I'm attempting to write plugins and finding the documentation extremely lacking and the internal code that actually runs the plugins somewhat confusing. at the moment I'm specifically trying to find a list of available named arguments to each of the hooks.

Hooks for Task Scheduling / Periodic Events

I know that Skybot has a hook for 'events', but what would about periodic scheduling or task scheduling?

Say you wanted something to run every x amount of hours or at a specified time - are there any solutions implemented to do this already or would a new hook have to be added with this functionality?

.twitter truncates long retweets

.twitter somebody is a retweet and the original tweet is long, the text printed is "RT @whomever blah blah blah blah blah blah bl ..."
It should just print the entire tweet.

Impossible to hook into ACTION events

At present ACTION, as a subset of PRIVMSG, is not possible to hook into without post-event regex to determine whether or not a /me actually occurred.

Documentation: plugin hooks - Shared arguments

In the documentation it says:

channel -- string, the channel the message was sent on. Equal to nick if it's a private message.

But, from what I've found, the shared argument is actually "chan" to return the channel name.

This is with the regex hook, but I'm not sure if it's system wide?

gcalc chokes on &nbsp;

If you do a request that results in a number that is separated with a space skybot will choke. For example, request 1*10000 which will return 10 000:

16:02:35 #ijustam <ijustam> .calc 1*10000
Unhandled exception in thread started by <function run at 0x02C17C30>
Traceback (most recent call last):
  File "core\main.py", line 80, in run
    out = func(input.inp)
  File "plugins\gcalc.py", line 10, in calc
    m = h.xpath('//h2[@class="r"]/text()')
  File "src/lxml/lxml.etree.pyx", line 1587, in lxml.etree._Element.xpath (src\lxml\lxml.etree.c:61854)
  File "src/lxml/xpath.pxi", line 307, in lxml.etree.XPathElementEvaluator.__call__ (src\lxml\lxml.etree.c:178516)
  File "src/lxml/xpath.pxi", line 230, in lxml.etree._XPathEvaluatorBase._handle_result (src\lxml\lxml.etree.c:177452)
  File "src/lxml/extensions.pxi", line 623, in lxml.etree._unwrapXPathObject (src\lxml\lxml.etree.c:171189)
  File "src/lxml/extensions.pxi", line 657, in lxml.etree._createNodeSetResult (src\lxml\lxml.etree.c:171659)
  File "src/lxml/extensions.pxi", line 678, in lxml.etree._unpackNodeSetEntry (src\lxml\lxml.etree.c:171886)
  File "src/lxml/extensions.pxi", line 804, in lxml.etree._buildElementStringResult (src\lxml\lxml.etree.c:173487)
  File "src/lxml/apihelpers.pxi", line 1417, in lxml.etree.funicode (src\lxml\lxml.etree.c:32150)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa0 in position 6: invalid start byte

The HTML result:
<h2 class="r" style="display:inline;font-size:138%">1 * 10&nbsp;000 = 10&nbsp;000</h2>

Improve ACLs

There should be support for per-channel/per-server whitelisting. Currently ACLs are only allow-except/deny-except for specifically named functions, which isn't so useful.

`.python` is vulnerable

You can do this

.python __import__('sys').setrecursionlimit(1)

which results in a semi-permanent disable of scybot's python environment.

This is somewhat useful when people start botspamming with .python, but should still be fixed.

Custom bot prefixes issue

Commit 4c970f6 broke custom bot prefixes because it just does a literal match of the config string in prefixes instead of the old behaviour introduced in 2b44d0a where bots can have a list of possible custom prefixes because some people like one over the other. So instead of a config prefix string of "!." allowing users to choose !command or .command, it forces users to use !.command instead.

Am I the only one who thinks this is an issue?

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.