mirror of
https://github.com/Mikaela/Limnoria.git
synced 2025-02-04 08:34:11 +01:00
PluginDownloader: add the @install command.
This commit is contained in:
parent
187ed38ecc
commit
f18429fdf7
@ -28,12 +28,17 @@
|
|||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
import os
|
||||||
import json
|
import json
|
||||||
import urllib
|
import urllib
|
||||||
|
import urllib2
|
||||||
|
import tarfile
|
||||||
|
from cStringIO import StringIO
|
||||||
|
|
||||||
import git
|
import git
|
||||||
|
|
||||||
import supybot.log as log
|
import supybot.log as log
|
||||||
|
import supybot.conf as conf
|
||||||
import supybot.utils as utils
|
import supybot.utils as utils
|
||||||
from supybot.commands import *
|
from supybot.commands import *
|
||||||
import supybot.plugins as plugins
|
import supybot.plugins as plugins
|
||||||
@ -56,7 +61,17 @@ class GithubRepository(GitRepository):
|
|||||||
def __init__(self, username, reponame, path='/'):
|
def __init__(self, username, reponame, path='/'):
|
||||||
self._username = username
|
self._username = username
|
||||||
self._reponame = reponame
|
self._reponame = reponame
|
||||||
self._path = [x for x in path.split('/') if x != '']
|
if not path.startswith('/'):
|
||||||
|
path = '/' + path
|
||||||
|
if not path.endswith('/'):
|
||||||
|
path += '/'
|
||||||
|
self._path = path
|
||||||
|
|
||||||
|
self._downloadUrl = 'https://github.com/%s/%s/tarball/master' % \
|
||||||
|
(
|
||||||
|
self._username,
|
||||||
|
self._reponame,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
_apiUrl = 'http://github.com/api/v2/json'
|
_apiUrl = 'http://github.com/api/v2/json'
|
||||||
@ -74,7 +89,8 @@ class GithubRepository(GitRepository):
|
|||||||
self._reponame,
|
self._reponame,
|
||||||
)
|
)
|
||||||
)['branches']['master']
|
)['branches']['master']
|
||||||
treeHash = self._navigate(latestCommit, self._path)
|
path = [x for x in self._path.split('/') if x != '']
|
||||||
|
treeHash = self._navigate(latestCommit, path)
|
||||||
if treeHash is None:
|
if treeHash is None:
|
||||||
log.error((
|
log.error((
|
||||||
'Cannot get plugins list from repository %s/%s '
|
'Cannot get plugins list from repository %s/%s '
|
||||||
@ -114,6 +130,41 @@ class GithubRepository(GitRepository):
|
|||||||
# Remember we pop(0)ed the path
|
# Remember we pop(0)ed the path
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def install(self, plugin):
|
||||||
|
directories = conf.supybot.directories.plugins()
|
||||||
|
directory = self._getWritableDirectoryFromList(directories)
|
||||||
|
assert directory is not None
|
||||||
|
dirname = ''.join((self._path, plugin))
|
||||||
|
|
||||||
|
fileObject = urllib2.urlopen(self._downloadUrl)
|
||||||
|
fileObject2 = StringIO()
|
||||||
|
fileObject2.write(fileObject.read())
|
||||||
|
fileObject.close()
|
||||||
|
fileObject2.seek(0)
|
||||||
|
archive = tarfile.open(fileobj=fileObject2, mode='r:gz')
|
||||||
|
prefix = archive.getnames()[0]
|
||||||
|
try:
|
||||||
|
assert archive.getmember(prefix + dirname).isdir()
|
||||||
|
|
||||||
|
for file in archive.getmembers():
|
||||||
|
if file.name.startswith(prefix + dirname):
|
||||||
|
extractedFile = archive.extractfile(file)
|
||||||
|
newFileName = os.path.join(*file.name.split('/')[1:])
|
||||||
|
newFileName = os.path.join(directory, newFileName)
|
||||||
|
if extractedFile is None:
|
||||||
|
os.mkdir(newFileName)
|
||||||
|
else:
|
||||||
|
open(newFileName, 'a').write(extractedFile.read())
|
||||||
|
finally:
|
||||||
|
archive.close()
|
||||||
|
|
||||||
|
def _getWritableDirectoryFromList(self, directories):
|
||||||
|
for directory in directories:
|
||||||
|
if os.access(directory, os.W_OK):
|
||||||
|
return directory
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
repositories = {
|
repositories = {
|
||||||
'ProgVal': GithubRepository('ProgVal', 'Supybot-plugins'),
|
'ProgVal': GithubRepository('ProgVal', 'Supybot-plugins'),
|
||||||
'quantumlemur': GithubRepository(
|
'quantumlemur': GithubRepository(
|
||||||
@ -137,6 +188,11 @@ class PluginDownloader(callbacks.Plugin):
|
|||||||
global repositories
|
global repositories
|
||||||
if repository is None:
|
if repository is None:
|
||||||
irc.reply(_(', ').join([x for x in repositories]))
|
irc.reply(_(', ').join([x for x in repositories]))
|
||||||
|
elif repository not in repositories:
|
||||||
|
irc.error(_(
|
||||||
|
'This repository does not exist or is not known by '
|
||||||
|
'this bot.'
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
plugins = repositories[repository].getPluginList()
|
plugins = repositories[repository].getPluginList()
|
||||||
if plugins == []:
|
if plugins == []:
|
||||||
@ -145,6 +201,28 @@ class PluginDownloader(callbacks.Plugin):
|
|||||||
irc.reply(_(', ').join([x for x in plugins]))
|
irc.reply(_(', ').join([x for x in plugins]))
|
||||||
repolist = wrap(repolist, [optional('something')])
|
repolist = wrap(repolist, [optional('something')])
|
||||||
|
|
||||||
|
@internationalizeDocstring
|
||||||
|
def install(self, irc, msg, args, repository, plugin):
|
||||||
|
"""<repository> <plugin>
|
||||||
|
|
||||||
|
Downloads and installs the <plugin> from the <repository>."""
|
||||||
|
global repositories
|
||||||
|
if repository not in repositories:
|
||||||
|
irc.error(_(
|
||||||
|
'This repository does not exist or is not known by '
|
||||||
|
'this bot.'
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
repositories[repository].install(plugin)
|
||||||
|
irc.replySuccess()
|
||||||
|
except Exception as e:
|
||||||
|
#FIXME: more detailed error message
|
||||||
|
log.error(str(e))
|
||||||
|
irc.error('The plugin could not be installed.')
|
||||||
|
|
||||||
|
install = wrap(install, ['owner', 'something', 'something'])
|
||||||
|
|
||||||
|
|
||||||
PluginDownloader = internationalizeDocstring(PluginDownloader)
|
PluginDownloader = internationalizeDocstring(PluginDownloader)
|
||||||
Class = PluginDownloader
|
Class = PluginDownloader
|
||||||
|
@ -28,14 +28,50 @@
|
|||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
from supybot.test import *
|
from supybot.test import *
|
||||||
|
|
||||||
|
pluginsPath = '%s/test-plugins' % os.getcwd()
|
||||||
|
|
||||||
class PluginDownloaderTestCase(PluginTestCase):
|
class PluginDownloaderTestCase(PluginTestCase):
|
||||||
plugins = ('PluginDownloader',)
|
plugins = ('PluginDownloader',)
|
||||||
|
config = {'supybot.directories.plugins': [pluginsPath]}
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
PluginTestCase.setUp(self)
|
||||||
|
try:
|
||||||
|
shutil.rmtree(pluginsPath)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
os.mkdir(pluginsPath)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
try:
|
||||||
|
shutil.rmtree(pluginsPath)
|
||||||
|
finally:
|
||||||
|
PluginTestCase.tearDown(self)
|
||||||
|
|
||||||
def testRepolist(self):
|
def testRepolist(self):
|
||||||
self.assertResponse('repolist', 'quantumlemur, ProgVal')
|
self.assertResponse('repolist', 'quantumlemur, ProgVal')
|
||||||
self.assertRegexp('repolist ProgVal', '(.*, )?AttackProtector(, .*)?')
|
self.assertRegexp('repolist ProgVal', '(.*, )?AttackProtector(, .*)?')
|
||||||
|
|
||||||
|
def testInstallProgVal(self):
|
||||||
|
self.assertError('plugindownloader install ProgVal Listener')
|
||||||
|
self.assertNotError('plugindownloader install ProgVal AttackProtector')
|
||||||
|
self.assertError('plugindownloader install ProgVal Listener')
|
||||||
|
assert os.path.isdir(pluginsPath + '/AttackProtector/')
|
||||||
|
assert os.path.isfile(pluginsPath + '/AttackProtector/plugin.py')
|
||||||
|
assert os.path.isfile(pluginsPath + '/AttackProtector/config.py')
|
||||||
|
|
||||||
|
def testInstallQuantumlemur(self):
|
||||||
|
self.assertError('plugindownloader install quantumlemur AttackProtector')
|
||||||
|
self.assertNotError('plugindownloader install quantumlemur Listener')
|
||||||
|
self.assertError('plugindownloader install quantumlemur AttackProtector')
|
||||||
|
assert os.path.isdir(pluginsPath + '/Listener/')
|
||||||
|
assert os.path.isfile(pluginsPath + '/Listener/plugin.py')
|
||||||
|
assert os.path.isfile(pluginsPath + '/Listener/config.py')
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
||||||
|
Loading…
Reference in New Issue
Block a user