From 3b90db2c2f5e2c1b8ee43c1e108c0a20d63c4d2c Mon Sep 17 00:00:00 2001
From: andrei <b1naryth1ef@gmail.com>
Date: Fri, 27 Oct 2017 18:19:04 -0700
Subject: [PATCH] Remove builtin support for storage

---
 disco/bot/bot.py         | 11 -----
 disco/bot/plugin.py      |  1 -
 disco/bot/storage.py     | 89 ----------------------------------------
 examples/basic_plugin.py | 21 ++++------
 examples/storage.py      | 33 ---------------
 tests/imports.py         |  1 -
 6 files changed, 7 insertions(+), 149 deletions(-)
 delete mode 100644 disco/bot/storage.py
 delete mode 100644 examples/storage.py

diff --git a/disco/bot/bot.py b/disco/bot/bot.py
index 5419c4d..a359815 100644
--- a/disco/bot/bot.py
+++ b/disco/bot/bot.py
@@ -12,7 +12,6 @@ from gevent.wsgi import WSGIServer
 from disco.types.guild import GuildMember
 from disco.bot.plugin import Plugin
 from disco.bot.command import CommandEvent, CommandLevels
-from disco.bot.storage import Storage
 from disco.util.config import Config
 from disco.util.logging import LoggingClass
 from disco.util.serializer import Serializer
@@ -94,11 +93,6 @@ class BotConfig(Config):
     plugin_config_format = 'json'
     plugin_config_dir = 'config'
 
-    storage_enabled = True
-    storage_fsync = True
-    storage_serializer = 'json'
-    storage_path = 'storage.json'
-
     http_enabled = False
     http_host = '0.0.0.0'
     http_port = 7575
@@ -136,11 +130,6 @@ class Bot(LoggingClass):
         # The context carries information about events in a threadlocal storage
         self.ctx = ThreadLocal()
 
-        # The storage object acts as a dynamic contextual aware store
-        self.storage = None
-        if self.config.storage_enabled:
-            self.storage = Storage(self.ctx, self.config.from_prefix('storage'))
-
         # If the manhole is enabled, add this bot as a local
         if self.client.config.manhole_enable:
             self.client.manhole_locals['bot'] = self
diff --git a/disco/bot/plugin.py b/disco/bot/plugin.py
index 8422cb7..bd341b2 100644
--- a/disco/bot/plugin.py
+++ b/disco/bot/plugin.py
@@ -179,7 +179,6 @@ class Plugin(LoggingClass, PluginDeco):
         self.client = bot.client
         self.state = bot.client.state
         self.ctx = bot.ctx
-        self.storage = bot.storage
         self.config = config
 
         # General declartions
diff --git a/disco/bot/storage.py b/disco/bot/storage.py
deleted file mode 100644
index c02df4a..0000000
--- a/disco/bot/storage.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import os
-
-from six.moves import UserDict
-
-from disco.util.hashmap import HashMap
-from disco.util.serializer import Serializer
-
-
-class StorageHashMap(HashMap):
-    def __init__(self, data):
-        self.data = data
-
-
-class ContextAwareProxy(UserDict):
-    def __init__(self, ctx):
-        self.ctx = ctx
-
-    @property
-    def data(self):
-        return self.ctx()
-
-
-class StorageDict(UserDict):
-    def __init__(self, parent, data):
-        self._parent = parent
-        self.data = data
-
-    def update(self, other):
-        self.data.update(other)
-        self._parent._update()
-
-    def __setitem__(self, key, value):
-        self.data[key] = value
-        self._parent._update()
-
-    def __delitem__(self, key):
-        del self.data[key]
-        self._parent._update()
-
-
-class Storage(object):
-    def __init__(self, ctx, config):
-        self._ctx = ctx
-        self._path = config.path
-        self._serializer = config.serializer
-        self._fsync = config.fsync
-        self._data = {}
-
-        if os.path.exists(self._path):
-            with open(self._path, 'r') as f:
-                self._data = Serializer.loads(self._serializer, f.read())
-                if not self._data:
-                    self._data = {}
-
-    def __getitem__(self, key):
-        if key not in self._data:
-            self._data[key] = {}
-        return StorageHashMap(StorageDict(self, self._data[key]))
-
-    def _update(self):
-        if self._fsync:
-            self.save()
-
-    def save(self):
-        if not self._path:
-            return
-
-        with open(self._path, 'w') as f:
-            f.write(Serializer.dumps(self._serializer, self._data))
-
-    def guild(self, key):
-        return ContextAwareProxy(
-            lambda: self['_g{}:{}'.format(self._ctx['guild'].id, key)],
-        )
-
-    def channel(self, key):
-        return ContextAwareProxy(
-            lambda: self['_c{}:{}'.format(self._ctx['channel'].id, key)],
-        )
-
-    def plugin(self, key):
-        return ContextAwareProxy(
-            lambda: self['_p{}:{}'.format(self._ctx['plugin'].name, key)],
-        )
-
-    def user(self, key):
-        return ContextAwareProxy(
-            lambda: self['_u{}:{}'.format(self._ctx['user'].id, key)],
-        )
diff --git a/examples/basic_plugin.py b/examples/basic_plugin.py
index 71c864b..3557f18 100644
--- a/examples/basic_plugin.py
+++ b/examples/basic_plugin.py
@@ -32,6 +32,13 @@ class BasicPlugin(Plugin):
             requests.rate_limited_duration(),
         ))
 
+    @Plugin.command('safe', '<user_input:str...>')
+    def on_safe(self, event, user_input):
+        # Disco exposes a function that can sanitize user input
+        event.msg.reply(u'No at-everyones here! {}'.format(
+            S(user_input),
+        ))
+
     @Plugin.command('ban', '<user:snowflake> <reason:str...>')
     def on_ban(self, event, user, reason):
         event.guild.create_ban(user, reason=reason + u'\U0001F4BF')
@@ -64,20 +71,6 @@ class BasicPlugin(Plugin):
     def on_math_sub_command(self, event, a, b):
         event.msg.reply('{}'.format(a - b))
 
-    @Plugin.command('tag', '<name:str> [value:str...]')
-    def on_tag(self, event, name, value=None):
-        # Plugins can easily store data locally using Disco's built in storage
-        tags = self.storage.guild.ensure('tags')
-
-        if value:
-            tags[name] = value
-            event.msg.reply(u':ok_hand: created tag `{}`'.format(S(name)))
-        else:
-            if name in tags:
-                return event.msg.reply(tags[name])
-            else:
-                return event.msg.reply(u'Unknown tag: `{}`'.format(S(name)))
-
     @Plugin.command('test', parser=True)
     @Plugin.parser.add_argument('-a', '--asdf', help='wow')
     @Plugin.parser.add_argument('--help', action='store_true')
diff --git a/examples/storage.py b/examples/storage.py
deleted file mode 100644
index c8e5ce3..0000000
--- a/examples/storage.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from disco.bot import Plugin
-
-
-class BasicPlugin(Plugin):
-    def load(self, ctx):
-        super(BasicPlugin, self).load(ctx)
-        self.tags = self.storage.guild('tags')
-
-    @Plugin.command('add', '<name:str> <value:str...>', group='tags')
-    def on_tags_add(self, event, name, value):
-        if name in self.tags:
-            return event.msg.reply('That tag already exists!')
-
-        self.tags[name] = value
-        return event.msg.reply(u':ok_hand: created the tag {}'.format(name), sanitize=True)
-
-    @Plugin.command('get', '<name:str>', group='tags')
-    def on_tags_get(self, event, name):
-        if name not in self.tags:
-            return event.msg.reply('That tag does not exist!')
-
-        return event.msg.reply(self.tags[name], sanitize=True)
-
-    @Plugin.command('delete', '<name:str>', group='tags', aliases=['del', 'rmv', 'remove'])
-    def on_tags_delete(self, event, name):
-        if name not in self.tags:
-            return event.msg.reply('That tag does not exist!')
-
-        del self.tags[name]
-
-        return event.msg.reply(u':ok_hand: I deleted the {} tag for you'.format(
-            name
-        ), sanitize=True)
diff --git a/tests/imports.py b/tests/imports.py
index 8257c0a..384717d 100644
--- a/tests/imports.py
+++ b/tests/imports.py
@@ -9,7 +9,6 @@ from disco.bot.bot import *
 from disco.bot.command import *
 from disco.bot.parser import *
 from disco.bot.plugin import *
-from disco.bot.storage import *
 from disco.gateway.client import *
 from disco.gateway.events import *
 from disco.gateway.ipc import *