Git Product home page Git Product logo

cardinal's Issues

complex URL plugin rules

I would like to add support for, for example, grabbing the amount of time, title, and uploader of YouTube videos, the time and track artist on SoundCloud links, etc.

add info bot plugin

I have to ideas for syntax... either:

Cardinal: Android is a mobile operating system developed by Google.
Cardinal: what is android?
whoami: Android is a mobile operating system developed by Google.

Alternatively...

.dadd android a mobile operating system developed by Google
.define android
whoami: a mobile operating system developed by Google

With the second syntax, it may be beneficial to also make lookups easier with alternative syntax of:

.android
whoami: a mobile operating system developed by Google

If a command exists by the definition name, it would default to the command rather than the definition (with .define serving as the only way to read the definition.)

add more bot meta info

e.g. Number of times reloaded, bot uptime, connected time, latest git commit (for version).

Move plugin interface outside of CardinalBot

The goal is to move the interface that plugins are provided (e.g. through the cardinal param) outside of the CardinalBot class. Separating this out from the protocol-specific logic will make the ability to write different protocol drivers simpler.

Users module (track users nick changes, aliases, etc.)

Ideally, I would like to see the following features implemented:

  • User profiles with aliases created under them through watching of nick changes
  • Ability to change which alias is the primary alias
  • Ability to merge two user profiles
  • Ability to separate an alias from a user profile
  • Tracking of vhosts to determine whether a user is a likely alias of another nick
  • Tie into other plugins to provide a better method of tracking user data (for example Last.fm username data would be accessible from any alias)

per-channel plugin enable/disable

This is useful for things like disabling the URL plugin in channels where another bot has already taken care of the service. Things to take into account:

  1. Plugin's events could trigger other plugins that aren't disabled
  2. Config syntax? Or only available on-the-fly?
  3. If there'll be a way to do it in config, it should be implemented with the new-style config that accompanies the multi-server change (TODO: Create issue on Github)

Plugin system needs a way to remove events / callbacks

Currently, if a plugin that defined an event is reloaded, it won't be able to re-define its event, since the EventManager will believe it still exists. Similarly, if an event that has registered a callback is reloaded, when EventManager tries to call it, Python will cry.

This blocks milestone Crimson (version 2.0).

irc_MODE can complain about regex matching

Happened on first connect. Probably because a MODE gets sent to the client with the user being the name of the network (e.g. irc.darchoods.net), which can't be split with *!*@*.

Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 202, in irc_MODE
    (user.group(1), user.group(2), user.group(3), channel, mode)
exceptions.AttributeError: 'NoneType' object has no attribute 'group'

issues after reconnection

Looks like the Plugin Manager didn't get instantiated correctly, as well as the irc.invite method never got de-registered when Cardinal disconnected. (Basic guess, would have to look deeper in the code to verify.)

2015-03-06 02:25:51,214 - cardinal.bot - INFO - Could not connect ([Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionRefusedError'>: Connection was refused by
 other side: 111: Connection refused.
]), retrying in 300 seconds
2015-03-06 02:30:52,594 - cardinal.bot - INFO - Signed on as Cardinal
2015-03-06 02:30:52,595 - cardinal.bot - INFO - Attempting to identify with NickServ
Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 1846, in irc_RPL_WELCOME
    self.signedOn()
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 85, in signedOn
    self.event_manager.register("irc.invite", 2)
  File "/home/john/files/Cardinal-DH/cardinal/plugins.py", line 674, in register
    raise EventAlreadyExistsError("Event already exists: %s" % name)
cardinal.exceptions.EventAlreadyExistsError: Event already exists: irc.invite
2015-03-06 02:30:52,608 - cardinal.plugins - INFO - Calling callbacks for event: irc.mode
2015-03-06 02:30:52,680 - cardinal.plugins - INFO - Calling callbacks for event: irc.notice
2015-03-06 02:30:52,774 - cardinal.plugins - INFO - Calling callbacks for event: irc.notice
2015-03-06 02:30:52,851 - cardinal.plugins - INFO - Calling callbacks for event: irc.privmsg
Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 139, in irc_PRIVMSG
    self.plugin_manager.call_command(user, channel, message)
exceptions.AttributeError: 'NoneType' object has no attribute 'call_command'
2015-03-07 15:06:26,477 - cardinal.plugins - INFO - Calling callbacks for event: irc.notice
2015-03-12 20:13:51,596 - cardinal.bot - INFO - Connection lost ([Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
]), reconnecting in 10 seconds.
2015-03-12 20:14:08,986 - cardinal.bot - INFO - Signed on as Cardinal
2015-03-12 20:14:08,986 - cardinal.bot - INFO - Attempting to identify with NickServ
Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 1846, in irc_RPL_WELCOME
    self.signedOn()
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 85, in signedOn
    self.event_manager.register("irc.invite", 2)
  File "/home/john/files/Cardinal-DH/cardinal/plugins.py", line 674, in register
    raise EventAlreadyExistsError("Event already exists: %s" % name)
    cardinal.exceptions.EventAlreadyExistsError: Event already exists: irc.invite
2015-03-12 20:14:08,992 - cardinal.plugins - INFO - Calling callbacks for event: irc.mode
2015-03-12 20:14:46,450 - cardinal.plugins - INFO - Calling callbacks for event: irc.notice

No module named words.protocol

I executed $python cardinal.py
Its giving me

from twisted.words.protocols import irc
ImportError: No module named words.protocols

Time plugin (timezones)

The point of the module would be to allow the user to check what's the current time in some timezone. For example, if one would enter the following:

.time +1

it would return the current time of the GMT+1 timezone.

.time

without any arguments defaults to GMT +/- 0

.time -5

would return the time of GMT-5.

Anti-spam plugin

May involve adding to the core of the bot for ignoring commands by users, but the functionality should be in the plugin so as to allow easy editing, whitelists, etc.

Unhandled error for ".note <nonexistent note>"

2015-04-27 00:26:25,770 - cardinal.plugins - INFO - Calling callbacks for event: irc.privmsg
Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 144, in irc_PRIVMSG
    self.plugin_manager.call_command(user, channel, message)
  File "/home/john/files/Cardinal-DH/cardinal/plugins.py", line 630, in call_command
    command(self.cardinal, user, channel, message)
  File "/home/john/files/Cardinal-DH/plugins/notes/plugin.py", line 118, in get_note
    content = self._get_note_from_db(title)
  File "/home/john/files/Cardinal-DH/plugins/notes/plugin.py", line 134, in _get_note_from_db
    if not result[0]:
exceptions.TypeError: 'NoneType' object has no attribute '__getitem__'

Help plugin fails when trying to get help for a command

Happened when attempting .help setlastfm

Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 139, in irc_PRIVMSG
    self.plugin_manager.call_command(user, channel, message)
  File "/home/john/files/Cardinal-DH/cardinal/plugins.py", line 613, in call_command
    command(self.cardinal, user, channel, message)
  File "/home/john/files/Cardinal-DH/plugins/help/plugin.py", line 89, in help
    help = self._get_command_help(cardinal, command)
  File "/home/john/files/Cardinal-DH/plugins/help/plugin.py", line 39, in _get_command_help
    for name, module in cardinal.loaded_plugins.items():
exceptions.AttributeError: CardinalBot instance has no attribute 'loaded_plugins'

update plugin system to add new functionality

Here's how I'd like the plugin system to work:

Each plugin is loaded up and its constructor is called. The constructor will register commands based on what type of action is called (for example an ACTION, PRIVMSG, NICK, etc.), a regex or a command (with the command symbol prior to it) and a callback. On each action received by the bot, it will go through the list of callbacks, and hit any that are associated.

Plugins will have three possible components: plugin, which is necessary, api, which exposes some features to other plugins through a cardinal.api.<plugin_name> object, and a config which is where configuration data goes. All other plugins will have access to the APIs of currently enabled plugins and can even depend on other plugins in order to work.

Plugins will be also able to register with the bot hooks for certain functionality. For example, the urls plugin, which looks up URLs and returns the title of the page would allow other plugins to hook in, and override the default functionality.

For example, in the constructor, the urls plugin would call something like cardinal.register_hook('urls'). This would let Cardinal know that there is a hook other plugins can register to named urls. From the constructors of other plugins, you could call cardinal.register_hook_callback('urls', '/http:\/\/youtube.com\/watch?v=(.+)/', self.urls_callback). When the urls plugin calls cardinal.handle_callbacks('urls', url), Cardinal will check if any of the callbacks have regexes matching the url variable and if so will return true, letting the urls plugin know that some other functionality was called (allowing urls to no-op). If none were found matching, it will return false.

Lastly, there should be a plugin providing configuration support. This would allow plugins to have some on-the-fly configuration (such as set urls.detection off to turn detection of URLs off.)

Bot seems to hang on disconnect

Not sure if this happens 100% of times, but if the connection to the IRC network is killed, Cardinal seems to hang, rather than reconnecting in 15 seconds as it should. C-c also will not kill it, and it has to be killed with a "kill -9" command.

Fix possible memory leaks in EventManager with weak references

It's also worth taking a look at the PluginManager and seeing whether weak references may be useful there as well. In the case of the EventManager, callbacks to events should be registered as weak references, so that if the plugin that registered the callback doesn't remove its callback for some reason, it doesn't prevent the garbage collector from handling the plugin (and this would help to prevent accidental duplicate callbacks for reloaded plugins.)

Snapchat plugin

It would be cool to make a plugin that can accept snaps and send them to a configured IRC channel upon receiving them.

Don't spam URL titles

I think, at least initially, this will be pretty simple, logic similar to:

if link_to_parse == last_link_parsed and last_link_parsed_time < 5 minutes ago:
    return

This would make talking about sites like goo.gl and Last.fm a lot less annoying.

split CardinalBot.py into classes

CardinalBot.py contains all the main bot logic.

It would be much easier and nicer to read if it was split into pieces. I would like to start using proper logging, with the Python logging library, and a separate class for plugin logic at the very least.

This would also be a good time to start making things PEP-8 compatible.

  • Use Python's logging for console output
  • Create a config system for Cardinal in JSON
  • Implement config in plugins
  • Re-implement events

Allow UTF-8 characters in URL titles

Probably the same fix as 8141a89.

2015-02-27 15:00:47,614 - cardinal.plugins - INFO - Calling callbacks for event: irc.privmsg
Unhandled Error
Traceback (most recent call last):
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/policies.py", line 120, in dataReceived
    self.wrappedProtocol.dataReceived(data)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2430, in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/protocols/basic.py", line 571, in dataReceived
    why = self.lineReceived(line)
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2438, in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "/home/john/files/Cardinal-DH/local/lib/python2.7/site-packages/twisted/words/protocols/irc.py", line 2482, in handleCommand
    method(prefix, params)
  File "/home/john/files/Cardinal-DH/cardinal/bot.py", line 139, in irc_PRIVMSG
    self.plugin_manager.call_command(user, channel, message)
  File "/home/john/files/Cardinal-DH/cardinal/plugins.py", line 611, in call_command
    command(self.cardinal, user, channel, message)
  File "/home/john/files/Cardinal-DH/plugins/urls/plugin.py", line 91, in get_title
    title = str(h.unescape(title))
exceptions.UnicodeEncodeError: 'ascii' codec can't encode character u'\xb7' in position 12: ordinal not in range(128)

Urban Dictionary plugin

.ud what's up should return the first definition and a permalink to the definitions page.

Move Twisted hooks outside of CardinalBot

Instead, CardinalBot will trigger a new instance of TwistedIRCProtocol, which will hook into CardinalBot. The instance of TwistedIRCProtocol will handle connection to the protocol as well as interfacing with it.

Re-evaluate class / instance members

Lots of class members should probably be defined as instance members instead (this really bit me in the butt with #44).

Learning a language by writing an IRC bot means falling prone to the typical gotchas. :(

switch to a new source for calculator support

iGoogle was recently shutdown, taking the unofficial Google Calculator API with it. Might switch to Wolfram Alpha. Alternatively I could use a library to add calculator support. Need to look into it.

When Cardinal reconnects, her uptime loses anything over 24 hours.

11:22:40      whoami | .info
11:22:41   +Cardinal | I am a Python-based Cardinal IRC bot. My owners are: whoami. You can find out more about me on my Github page: http://johnmaguire.github.io/Cardinal (Try
                     | .help for commands.)
11:22:41   +Cardinal | I have been online without downtime for 3 days 00:42:18, and was initially brought online 3 days 00:35:04 ago. I've been reloaded (or partially reloaded)
                     | 0 times since then.
11:24:43         <-- | Cardinal ([email protected]) has quit (Killed (NickServ (GHOST command used by [email protected])))
11:24:55         --> | Cardinal ([email protected]) has joined #darchoods
11:24:55          -- | Mode #darchoods [+v Cardinal] by ChanServ
11:24:57      whoami | .info   
11:24:59   +Cardinal | I am a Python-based Cardinal IRC bot. My owners are: whoami. You can find out more about me on my Github page: http://johnmaguire.github.io/Cardinal (Try
                     | .help for commands.)
11:25:00   +Cardinal | I have been online without downtime for 00:00:02, and was initially brought online 00:37:20 ago. I've been reloaded (or partially reloaded) 0 times since
                     | then.

Add URL detection event to URLs plugin

URLs plugin should fire an event when it detects a URL so other plug-ins can hook in and provide additional info.

Some ideas for handlers:
imgur
reddit
YouTube
Wikipedia
Urban Dictionary

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.