mirror of
https://github.com/Mikaela/Limnoria.git
synced 2024-11-14 14:49:21 +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 urllib
|
||||
import urllib2
|
||||
import tarfile
|
||||
from cStringIO import StringIO
|
||||
|
||||
import git
|
||||
|
||||
import supybot.log as log
|
||||
import supybot.conf as conf
|
||||
import supybot.utils as utils
|
||||
from supybot.commands import *
|
||||
import supybot.plugins as plugins
|
||||
@ -56,8 +61,18 @@ class GithubRepository(GitRepository):
|
||||
def __init__(self, username, reponame, path='/'):
|
||||
self._username = username
|
||||
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'
|
||||
def _query(self, type_, uri_end, args={}):
|
||||
@ -74,7 +89,8 @@ class GithubRepository(GitRepository):
|
||||
self._reponame,
|
||||
)
|
||||
)['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:
|
||||
log.error((
|
||||
'Cannot get plugins list from repository %s/%s '
|
||||
@ -114,6 +130,41 @@ class GithubRepository(GitRepository):
|
||||
# Remember we pop(0)ed the path
|
||||
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 = {
|
||||
'ProgVal': GithubRepository('ProgVal', 'Supybot-plugins'),
|
||||
'quantumlemur': GithubRepository(
|
||||
@ -137,6 +188,11 @@ class PluginDownloader(callbacks.Plugin):
|
||||
global repositories
|
||||
if repository is None:
|
||||
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:
|
||||
plugins = repositories[repository].getPluginList()
|
||||
if plugins == []:
|
||||
@ -145,6 +201,28 @@ class PluginDownloader(callbacks.Plugin):
|
||||
irc.reply(_(', ').join([x for x in plugins]))
|
||||
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)
|
||||
Class = PluginDownloader
|
||||
|
@ -28,14 +28,50 @@
|
||||
|
||||
###
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from supybot.test import *
|
||||
|
||||
pluginsPath = '%s/test-plugins' % os.getcwd()
|
||||
|
||||
class PluginDownloaderTestCase(PluginTestCase):
|
||||
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):
|
||||
self.assertResponse('repolist', 'quantumlemur, ProgVal')
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user