diff --git a/pokemongo_bot/plugin_loader.py b/pokemongo_bot/plugin_loader.py index 9362197bc8..8666b53254 100644 --- a/pokemongo_bot/plugin_loader.py +++ b/pokemongo_bot/plugin_loader.py @@ -1,6 +1,8 @@ import os import sys import importlib +import re +import requests class PluginLoader(object): folder_cache = [] @@ -15,8 +17,8 @@ def _get_correct_path(self, path): return correct_path - def load_plugin(self, path): - correct_path = self._get_correct_path(path) + def load_plugin(self, plugin): + correct_path = self._get_correct_path(plugin) if correct_path not in self.folder_cache: self.folder_cache.append(correct_path) @@ -31,3 +33,54 @@ def get_class(self, namespace_class): my_module = importlib.import_module(namespace) return getattr(my_module, class_name) +class GithubPlugin(object): + def __init__(self, plugin_name): + self.plugin_name = plugin_name + self.plugin_parts = self.get_github_parts() + + def is_valid_plugin(self): + return self.plugin_parts is not None + + def get_github_parts(self): + groups = re.match('(.*)\/(.*)#(.*)', self.plugin_name) + + if groups is None: + return None + + parts = {} + parts['user'] = groups.group(1) + parts['repo'] = groups.group(2) + parts['sha'] = groups.group(3) + + return parts + + def get_local_destination(self): + parts = self.plugin_parts + if parts is None: + raise Exception('Not a valid github plugin') + + file_name = '{}_{}_{}.zip'.format(parts['user'], parts['repo'], parts['sha']) + full_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'plugins', file_name) + return full_path + + def get_github_download_url(self): + parts = self.plugin_parts + if parts is None: + raise Exception('Not a valid github plugin') + + github_url = 'https://github.com/{}/{}/archive/{}.zip'.format(parts['user'], parts['repo'], parts['sha']) + return github_url + + def download(self): + url = self.get_github_download_url() + dest = self.get_local_destination() + + r = requests.get(url, stream=True) + r.raise_for_status() + + with open(dest, 'wb') as f: + for chunk in r.iter_content(chunk_size=1024): + if chunk: + f.write(chunk) + r.close() + return dest diff --git a/pokemongo_bot/plugins/.keep b/pokemongo_bot/plugins/.keep new file mode 100644 index 0000000000..5d848b8301 --- /dev/null +++ b/pokemongo_bot/plugins/.keep @@ -0,0 +1 @@ +keep this so we can install plugins into this folder diff --git a/pokemongo_bot/test/plugin_loader_test.py b/pokemongo_bot/test/plugin_loader_test.py index 38a566b35c..ecf50888e6 100644 --- a/pokemongo_bot/test/plugin_loader_test.py +++ b/pokemongo_bot/test/plugin_loader_test.py @@ -6,7 +6,7 @@ import os from datetime import timedelta, datetime from mock import patch, MagicMock -from pokemongo_bot.plugin_loader import PluginLoader +from pokemongo_bot.plugin_loader import PluginLoader, GithubPlugin from pokemongo_bot.test.resources.plugin_fixture import FakeTask class PluginLoaderTest(unittest.TestCase): @@ -26,3 +26,27 @@ def test_load_zip(self): loaded_class = self.plugin_loader.get_class('plugin_fixture_test.FakeTask') self.assertEqual(loaded_class({}, {}).work(), 'FakeTask') self.plugin_loader.remove_path(package_path) + + def test_get_github_parts_for_valid_github(self): + github_plugin = GithubPlugin('org/repo#sha') + self.assertTrue(github_plugin.is_valid_plugin()) + self.assertEqual(github_plugin.plugin_parts['user'], 'org') + self.assertEqual(github_plugin.plugin_parts['repo'], 'repo') + self.assertEqual(github_plugin.plugin_parts['sha'], 'sha') + + def test_get_github_parts_for_invalid_github(self): + self.assertFalse(GithubPlugin('org/repo').is_valid_plugin()) + self.assertFalse(GithubPlugin('foo').is_valid_plugin()) + self.assertFalse(GithubPlugin('/Users/foo/bar.zip').is_valid_plugin()) + + def test_get_local_destination(self): + github_plugin = GithubPlugin('org/repo#sha') + path = github_plugin.get_local_destination() + expected = os.path.realpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'plugins', 'org_repo_sha.zip')) + self.assertEqual(path, expected) + + def test_get_github_download_url(self): + github_plugin = GithubPlugin('org/repo#sha') + url = github_plugin.get_github_download_url() + expected = 'https://github.com/org/repo/archive/sha.zip' + self.assertEqual(url, expected)