Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: extend redis backend #63

Closed
cabrinha opened this issue Jun 24, 2018 · 2 comments
Closed

feature request: extend redis backend #63

cabrinha opened this issue Jun 24, 2018 · 2 comments

Comments

@cabrinha
Copy link

cabrinha commented Jun 24, 2018

Let's extend the redis backend to support more actions like:

This would be in order to scan or get all keys for a given plugin and iterate over them.

I'm trying to create a "Karma" plugin and I'd like to show the top Karma scores:

from machine.plugins.base import MachineBasePlugin
from machine.plugins.decorators import listen_to, respond_to
import re


class Karma(MachineBasePlugin):
    @respond_to(r'(?P<user>.*) \+\+')
    def up(self, msg, user):
        if self.storage.has(user):
            karma = self.storage.get(user)
            karma += 1
            self.storage.set(user, karma)
            msg.say('{}\'s karma is now: {}'.format(user, karma))
        else:
            self.storage.set(user, 1)
            msg.say('No karma found for: {}, setting to 1'.format(user))

    @respond_to(r'(?P<user>.*) \-\-')
    def down(self, msg, user):
        if self.storage.has(user):
            karma = self.storage.get(user)
            karma -= 1
            self.storage.set(user, karma)
            msg.say('{}\'s karma is now: {}'.format(user, karma))
        else:
            self.storage.set(user, -1)
            msg.say('No karma found for: {}, setting to -1'.format(user))

    @respond_to(r'.*(top karma).*')
    def top(self, msg):
        for i in self.storage.keys(pattern='*'):
            print(i)

in machine/storage/backends/redis.py:

...
    def get(self, key):
        return self._redis.get(self._prefix(key))

    def keys(self, pattern):
        return self._redis.keys(pattern='*')
...

Something like this...

But, I get: AttributeError: 'PluginStorage' object has no attribute 'keys'

@DonDebonair
Copy link
Owner

DonDebonair commented Jun 24, 2018

Great idea! I'll have to think a bit on it, but I'll get back to you on this!

edit: the implementation you suggest cannot be used as-is, because what SlackMachine does by default, is prefixing keys in Redis with a unique identifier for each plugin. This should be taken into account when scanning. The pattern provided through the keys(...) method could be prefixed with the unique idea for example.

@cabrinha
Copy link
Author

cabrinha commented Jun 25, 2018

That's fine. I assume that you mean something along the lines of this:

    def keys(self, key):
        return self._redis.scan_iter(pattern='{}:*'.format(self._prefix(key)))
...

I'm adding the following right underneath http://slack-machine.readthedocs.io/en/latest/_modules/machine/storage/backends/base.html#MachineBaseStorage.get:

    def keys(self, key, shared=False):
        """Retrieve data by key

        :param key: key for the data to retrieve
        :param shared: ``True/False`` wether to retrieve data from the shared (global) namespace.
        :return: the data, or ``None`` if the key cannot be found/has expired
        """
        namespaced_key = self._namespace_key(key, shared)
        # value = Storage.get_instance().get(namespaced_key)
        value = Storage.get_instance().keys(namespaced_key)
        if value:
            return dill.loads(value)
        else:
            return None

But, I'm still getting the error:

AttributeError: 'PluginStorage' object has no attribute 'keys'

Is there something else I'm missing? It's fine if this method could be renamed to "get_all_keys", or something of the sort. I'd like to extend the functionality of the storage backend to support more (or all) redis-py functions, if possible.

After modifying these files, do I just run python3 setup.py install again?

@cabrinha cabrinha closed this as completed Feb 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants