Packages: Remove plugin.
parent
0096931e15
commit
5f4817d40f
|
@ -1,39 +0,0 @@
|
||||||
This plugin is a packages downloadeder and installer.
|
|
||||||
It handles basic dependencies, based on tags.
|
|
||||||
|
|
||||||
Repositories must have a root JSON file, that uses the fellowing
|
|
||||||
format:
|
|
||||||
{
|
|
||||||
"repository": {
|
|
||||||
"maintainers": {
|
|
||||||
"ProgVal": "progval@gmail.com",
|
|
||||||
},
|
|
||||||
"repo-name": "Main packages repository",
|
|
||||||
"repo-url": "http://packages.supybot.fr.cr",
|
|
||||||
"project-name": "Supybot-fr",
|
|
||||||
"project-url": "http://supybot.fr.cr"
|
|
||||||
}
|
|
||||||
"packages": [
|
|
||||||
{
|
|
||||||
"name": "Trigger",
|
|
||||||
"version": "0.1",
|
|
||||||
"author": [
|
|
||||||
"Valentin Lorentz",
|
|
||||||
"ProgVal",
|
|
||||||
"progval@gmail.com"
|
|
||||||
],
|
|
||||||
"info-url": "http://supybot.fr.cr/Trigger",
|
|
||||||
"download-url": "./Trigger-0.1.tar",
|
|
||||||
"requires": {
|
|
||||||
"package-installer": "0.1"
|
|
||||||
},
|
|
||||||
"suggests": {
|
|
||||||
"i18n": "0.1",
|
|
||||||
"conditional": "0.1"
|
|
||||||
},
|
|
||||||
"provides": {
|
|
||||||
"trigger": "0.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,74 +0,0 @@
|
||||||
###
|
|
||||||
# Copyright (c) 2011, Valentin Lorentz
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of the author of this software nor the name of
|
|
||||||
# contributors to this software may be used to endorse or promote products
|
|
||||||
# derived from this software without specific prior written consent.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
"""
|
|
||||||
Packages is a packaging system for Supybot plugins.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import supybot
|
|
||||||
import supybot.world as world
|
|
||||||
|
|
||||||
# Use this for the version of this plugin. You may wish to put a CVS keyword
|
|
||||||
# in here if you're keeping the plugin in CVS or some similar system.
|
|
||||||
__version__ = "0.2.1"
|
|
||||||
|
|
||||||
# XXX Replace this with an appropriate author or supybot.Author instance.
|
|
||||||
if not hasattr(supybot.authors, 'progval'):
|
|
||||||
supybot.authors.progval = supybot.Author('Valentin Lorentz', 'ProgVal',
|
|
||||||
'progval@gmail.com')
|
|
||||||
__author__ = supybot.authors.progval
|
|
||||||
|
|
||||||
# This is a dictionary mapping supybot.Author instances to lists of
|
|
||||||
# contributions.
|
|
||||||
__contributors__ = {}
|
|
||||||
|
|
||||||
# This is a url where the most recent plugin package can be downloaded.
|
|
||||||
__url__ = '' # 'http://supybot.com/Members/yourname/Packages/download'
|
|
||||||
|
|
||||||
import config
|
|
||||||
import plugin
|
|
||||||
import packaging
|
|
||||||
reload(plugin) # In case we're being reloaded.
|
|
||||||
# Add more reloads here if you add third-party modules and want them to be
|
|
||||||
# reloaded when this plugin is reloaded. Don't forget to import them as well!
|
|
||||||
|
|
||||||
if world.testing:
|
|
||||||
import test
|
|
||||||
|
|
||||||
Class = plugin.Class
|
|
||||||
configure = config.configure
|
|
||||||
|
|
||||||
try:
|
|
||||||
world.features.update(provides)
|
|
||||||
except:
|
|
||||||
world.features = packaging.provides
|
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
|
@ -1,58 +0,0 @@
|
||||||
###
|
|
||||||
# Copyright (c) 2011, Valentin Lorentz
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of the author of this software nor the name of
|
|
||||||
# contributors to this software may be used to endorse or promote products
|
|
||||||
# derived from this software without specific prior written consent.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
import supybot.conf as conf
|
|
||||||
import supybot.registry as registry
|
|
||||||
try:
|
|
||||||
from supybot.i18n import PluginInternationalization
|
|
||||||
from supybot.i18n import internationalizeDocstring
|
|
||||||
_ = PluginInternationalization('Packages')
|
|
||||||
except:
|
|
||||||
# This are useless functions that's allow to run the plugin on a bot
|
|
||||||
# without the i18n plugin
|
|
||||||
_ = lambda x:x
|
|
||||||
internationalizeDocstring = lambda x:x
|
|
||||||
|
|
||||||
def configure(advanced):
|
|
||||||
# This will be called by supybot to configure this module. advanced is
|
|
||||||
# a bool that specifies whether the user identified himself as an advanced
|
|
||||||
# user or not. You should effect your configuration by manipulating the
|
|
||||||
# registry as appropriate.
|
|
||||||
from supybot.questions import expect, anything, something, yn
|
|
||||||
conf.registerPlugin('Packages', True)
|
|
||||||
|
|
||||||
|
|
||||||
Packages = conf.registerPlugin('Packages')
|
|
||||||
# This is where your configuration variables (if any) should go. For example:
|
|
||||||
# conf.registerGlobalValue(Packages, 'someConfigVariableName',
|
|
||||||
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
|
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
|
@ -1,148 +0,0 @@
|
||||||
#!/usr/bin/env python2.7
|
|
||||||
|
|
||||||
###
|
|
||||||
# Copyright (c) 2011, Valentin Lorentz
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of the author of this software nor the name of
|
|
||||||
# contributors to this software may be used to endorse or promote products
|
|
||||||
# derived from this software without specific prior written consent.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
###
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import atexit
|
|
||||||
import tarfile
|
|
||||||
import optparse
|
|
||||||
|
|
||||||
import supybot.world as world
|
|
||||||
unregister = [world.makeDriversDie, world.makeIrcsDie, world.startDying,
|
|
||||||
world.finished, world.upkeep]
|
|
||||||
|
|
||||||
import plugin # I mean the Supybot plugin, the one which should be distributed
|
|
||||||
# with this script and is runned by Supybot.
|
|
||||||
|
|
||||||
def main(filename):
|
|
||||||
with tarfile.open(name=filename, mode='r:*') as file_:
|
|
||||||
directory = plugin.getDirectory(file_)
|
|
||||||
if not directory:
|
|
||||||
print('%s is not a valid package.' % filename)
|
|
||||||
return
|
|
||||||
class packaging:
|
|
||||||
"""Namespace for runned code"""
|
|
||||||
exec(file_.extractfile('%s/packaging.py' % directory).read())
|
|
||||||
class init:
|
|
||||||
"""Namespace for runned code"""
|
|
||||||
exec(file_.extractfile('%s/__init__.py' % directory).read())
|
|
||||||
def getPrettyJsonFromDict(dict_):
|
|
||||||
output = ''
|
|
||||||
for key, value in dict_.items():
|
|
||||||
output += """
|
|
||||||
"%s": "%s",""" % (key, value)
|
|
||||||
if output != '':
|
|
||||||
output = output[0:-1] # Remove the ending comma
|
|
||||||
return output
|
|
||||||
doc = init.__doc__
|
|
||||||
if doc.startswith('\n'):
|
|
||||||
doc = doc[1:]
|
|
||||||
if doc.endswith('\n'):
|
|
||||||
doc = doc[0:-1]
|
|
||||||
doc = doc.replace('\n', ' ')
|
|
||||||
if doc.startswith('Add a description of the plugin'):
|
|
||||||
doc = ''
|
|
||||||
output = """
|
|
||||||
{
|
|
||||||
"name": "%(name)s",
|
|
||||||
"version": "%(version)s",
|
|
||||||
"author": [
|
|
||||||
"%(author_name)s",
|
|
||||||
"%(author_nick)s",
|
|
||||||
"%(author_email)s"
|
|
||||||
],
|
|
||||||
"info-url": "%(info_url)s",
|
|
||||||
"download-url": "./%(name)s-%(version)s.tar",
|
|
||||||
"description": "%(description)s",
|
|
||||||
"requires": {%(requires)s
|
|
||||||
},
|
|
||||||
"suggests": {%(suggests)s
|
|
||||||
},
|
|
||||||
"provides": {%(provides)s
|
|
||||||
}
|
|
||||||
}""" % {'name': directory,
|
|
||||||
'version': init.__version__,
|
|
||||||
'author_name': init.__author__.name,
|
|
||||||
'author_nick': init.__author__.nick,
|
|
||||||
'author_email': init.__author__.email,
|
|
||||||
'info_url': init.__url__,
|
|
||||||
'description': doc.replace('"', '\\"'),
|
|
||||||
'requires': getPrettyJsonFromDict(packaging.requires),
|
|
||||||
'suggests': getPrettyJsonFromDict(packaging.suggests),
|
|
||||||
'provides': getPrettyJsonFromDict(packaging.provides)}
|
|
||||||
return output
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = optparse.OptionParser(usage='Usage: %prog Package.tar',
|
|
||||||
version='Supybot Packager 0.1')
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
if len(args) > 0:
|
|
||||||
filename = args[0]
|
|
||||||
output = main(filename)
|
|
||||||
else:
|
|
||||||
output = """
|
|
||||||
{
|
|
||||||
"repository": {
|
|
||||||
"maintainers": {
|
|
||||||
"ProgVal": "progval@gmail.com"
|
|
||||||
},
|
|
||||||
"repo-name": "Main packages repository",
|
|
||||||
"repo-url": "http://packages.supybot.fr.cr",
|
|
||||||
"project-name": "Supybot-fr",
|
|
||||||
"project-url": "http://supybot.fr.cr"
|
|
||||||
},
|
|
||||||
"packages": ["""
|
|
||||||
addComma = False
|
|
||||||
for filename in os.listdir('.'):
|
|
||||||
if not filename.endswith('.tar'):
|
|
||||||
continue
|
|
||||||
if addComma:
|
|
||||||
output += ','
|
|
||||||
output += main(filename)
|
|
||||||
addComma = True
|
|
||||||
output += """
|
|
||||||
]
|
|
||||||
}"""
|
|
||||||
if sys.version_info > (3, 0, 0):
|
|
||||||
# clean
|
|
||||||
for function in unregister:
|
|
||||||
atexit.unregister(function)
|
|
||||||
else:
|
|
||||||
# less clean
|
|
||||||
for function in unregister:
|
|
||||||
atexit._exithandlers.remove((function, (), {}))
|
|
||||||
if output is not None:
|
|
||||||
print(output)
|
|
|
@ -1 +0,0 @@
|
||||||
# Stub so local is a module, used for third-party modules
|
|
|
@ -1,152 +0,0 @@
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: Supybot-fr\n"
|
|
||||||
"POT-Creation-Date: 2011-08-21 02:16+CEST\n"
|
|
||||||
"PO-Revision-Date: 2011-08-23 19:33+0200\n"
|
|
||||||
"Last-Translator: skizzhg <skizzhg@gmx.com>\n"
|
|
||||||
"Language-Team: Italian <skizzhg@gmx.com>\n"
|
|
||||||
"Language: it\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
|
|
||||||
|
|
||||||
#: plugin.py:62
|
|
||||||
#, docstring
|
|
||||||
msgid "Returns -1, 0, or 1, depending on the newest version."
|
|
||||||
msgstr "Restituisce -1, 0 o 1 a seconda della versione più recente."
|
|
||||||
|
|
||||||
#: plugin.py:80
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"Tries to find the directory where plugin files are. Returns None\n"
|
|
||||||
" if it is not found or if any file is missing."
|
|
||||||
msgstr ""
|
|
||||||
"Tenta di trovare la directory dove risiedono i file dei plugin. Restituisce\n"
|
|
||||||
" \"None\" se non trovata o se un file è mancante."
|
|
||||||
|
|
||||||
#: plugin.py:118
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"Add the help for \"@plugin help Packages\" here\n"
|
|
||||||
" This should describe *how* to use this plugin."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:124
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"<filename> [--force]\n"
|
|
||||||
"\n"
|
|
||||||
" Installs the package. If the package has been downloaded with Packages,\n"
|
|
||||||
" just give the package name; otherwise, give the full path (including\n"
|
|
||||||
" the extension).\n"
|
|
||||||
" If given, --force disables sanity checks (usage is deprecated)."
|
|
||||||
msgstr ""
|
|
||||||
"<nome_file> [--force]\n"
|
|
||||||
"\n"
|
|
||||||
" Installa un pacchetto. Se questo è stato scaricato con Packages è sufficiente\n"
|
|
||||||
" il nome del pacchetto, altrimenti è necessario fornire il percorso completo\n"
|
|
||||||
" (inclusa l'estensione). Se specificato, --force disabilita il controllo\n"
|
|
||||||
" dell'integrità dei dati (il suo uso è deprecato)."
|
|
||||||
|
|
||||||
#: plugin.py:137
|
|
||||||
msgid "Cannot open the package. Are you sure it is readable, it is a tarball and it is not corrupted?"
|
|
||||||
msgstr "Impossibile aprire il pacchetto; sei certo che sia un archivio tar leggibile e non danneggiato?"
|
|
||||||
|
|
||||||
#: plugin.py:143
|
|
||||||
msgid "The file is not a valid package."
|
|
||||||
msgstr "Il file non è un pacchetto valido."
|
|
||||||
|
|
||||||
#: plugin.py:146
|
|
||||||
#, docstring
|
|
||||||
msgid "Namespace for runned code"
|
|
||||||
msgstr "Namespace per il codice eseguito"
|
|
||||||
|
|
||||||
#: plugin.py:152
|
|
||||||
msgid "%s (missing)"
|
|
||||||
msgstr "%s (mancante)"
|
|
||||||
|
|
||||||
#: plugin.py:154
|
|
||||||
msgid "%s (>=%s needed, but %s available)"
|
|
||||||
msgstr "%s (>=%s necessaria ma %s disponibile)"
|
|
||||||
|
|
||||||
#: plugin.py:157
|
|
||||||
msgid "Missing dependency(ies): "
|
|
||||||
msgstr "Dipendenze mancanti:"
|
|
||||||
|
|
||||||
#: plugin.py:163
|
|
||||||
msgid "No writable plugin directory found."
|
|
||||||
msgstr "Non è stata trovata nessuna directory del plugin scrivibile."
|
|
||||||
|
|
||||||
#: plugin.py:174
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"<package> [--version <version>] [--repo <repository url>]\n"
|
|
||||||
"\n"
|
|
||||||
" Downloads the <package> at the <repository url>.\n"
|
|
||||||
" <version> defaults to the latest version available.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr/"
|
|
||||||
msgstr ""
|
|
||||||
"<pacchetto> [--version <versione>] [--repo <URL repository>]\n"
|
|
||||||
"\n"
|
|
||||||
" Scarica <pacchetto> da <URL repository>.\n"
|
|
||||||
" <versione> è in modo predefinito l'ultima disponibile, mentre\n"
|
|
||||||
" <URL repository> predefinito è http://packages.supybot.fr.cr/"
|
|
||||||
|
|
||||||
#: plugin.py:187
|
|
||||||
msgid "Bad formed url."
|
|
||||||
msgstr "Formato URL errato."
|
|
||||||
|
|
||||||
#: plugin.py:195 plugin.py:258 plugin.py:308 plugin.py:350
|
|
||||||
msgid "Server's JSON is bad formed."
|
|
||||||
msgstr "Il server JSON è errato."
|
|
||||||
|
|
||||||
#: plugin.py:212
|
|
||||||
msgid "No packages matches your query."
|
|
||||||
msgstr "Nessun pacchetto corrisponde alla richiesta."
|
|
||||||
|
|
||||||
#: plugin.py:247
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"[<repository url>]\n"
|
|
||||||
"\n"
|
|
||||||
" Checks for updates for loaded plugins at the <repository url>.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr/"
|
|
||||||
msgstr ""
|
|
||||||
"[<URL repository>]\n"
|
|
||||||
"\n"
|
|
||||||
" Cerca aggiornamenti per i plugin caricati su <URL repository>,\n"
|
|
||||||
" l'indirizzo predefinito è http://packages.supybot.fr.cr/"
|
|
||||||
|
|
||||||
#: plugin.py:276
|
|
||||||
msgid "All loaded plugins are up to date :)"
|
|
||||||
msgstr "Tutti i plugin caricati sono aggiornati :)"
|
|
||||||
|
|
||||||
#: plugin.py:283
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"[<repository url>] [--name <name>] [--version <version>] [--author <author>] [<description>]\n"
|
|
||||||
"\n"
|
|
||||||
" Searches the packages matching the query in the <repository url>.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr"
|
|
||||||
msgstr ""
|
|
||||||
"[<URL repository>] [--name <nome>] [--version <versione>] [--author <autore>] [<descrizione>]\n"
|
|
||||||
"\n"
|
|
||||||
" Cerca i pacchetti corrispondenti alla richiesta in <URL repository>,\n"
|
|
||||||
" l'indirizzo predefinito è http://packages.supybot.fr.cr"
|
|
||||||
|
|
||||||
#: plugin.py:334
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"[<repository url>] <package> [<version>] [--author-full]\n"
|
|
||||||
"\n"
|
|
||||||
" Displays informations about the <package>, at the given <version>.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr/ and\n"
|
|
||||||
" <version> defaults to the latest available."
|
|
||||||
msgstr ""
|
|
||||||
"[<URL repository>] <pacchetto> [<versione>] [--author-full]\n"
|
|
||||||
"\n"
|
|
||||||
" Mostra le informazioni di <pacchetto> alla data <versione>.\n"
|
|
||||||
" <URL repository> predefinito è http://packages.supybot.fr.cr/\n"
|
|
||||||
" mentre <versione> è in modo predefinito l'ultima disponibile."
|
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
#!/usr/bin/env python2.7
|
|
||||||
|
|
||||||
###
|
|
||||||
# Copyright (c) 2011, Valentin Lorentz
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of the author of this software nor the name of
|
|
||||||
# contributors to this software may be used to endorse or promote products
|
|
||||||
# derived from this software without specific prior written consent.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
###
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import atexit
|
|
||||||
import tarfile
|
|
||||||
import optparse
|
|
||||||
|
|
||||||
import supybot.world as world
|
|
||||||
unregister = [world.makeDriversDie, world.makeIrcsDie, world.startDying,
|
|
||||||
world.finished, world.upkeep]
|
|
||||||
if sys.version_info > (3, 0, 0):
|
|
||||||
# clean
|
|
||||||
for function in unregister:
|
|
||||||
atexit.unregister(function)
|
|
||||||
else:
|
|
||||||
# less clean
|
|
||||||
for function in unregister:
|
|
||||||
atexit._exithandlers.remove((function, (), {}))
|
|
||||||
|
|
||||||
def addToArchive(archive, path):
|
|
||||||
for item in os.listdir(path):
|
|
||||||
if item.startswith('.') or item.endswith('~') or \
|
|
||||||
item.endswith('.swp') or item.endswith('.swo') or \
|
|
||||||
item.endswith('.pyc') or item.endswith('.pyo'):
|
|
||||||
continue
|
|
||||||
itemPath = os.path.join(path, item)
|
|
||||||
archive.add(itemPath, recursive=False)
|
|
||||||
if os.path.isdir(itemPath):
|
|
||||||
addToArchive(archive, itemPath)
|
|
||||||
|
|
||||||
def main(dirname):
|
|
||||||
if dirname.endswith('/'):
|
|
||||||
dirname = dirname[0:-1]
|
|
||||||
class init:
|
|
||||||
"""Namespace for runned code"""
|
|
||||||
exec(open('%s/__init__.py' % dirname))
|
|
||||||
assert init.__version__ != '', 'Version is empty'
|
|
||||||
assert hasattr(init, '__url__'), 'Has no __url__'
|
|
||||||
path = '%s-%s.tar' % (dirname, init.__version__)
|
|
||||||
try:
|
|
||||||
os.unlink(path)
|
|
||||||
except OSError:
|
|
||||||
# Does not exist
|
|
||||||
pass
|
|
||||||
with tarfile.open(path, 'a') as archive:
|
|
||||||
addToArchive(archive, dirname)
|
|
||||||
names = archive.getnames()
|
|
||||||
for name in ('__init__', 'config', 'plugin', 'test', 'packaging'):
|
|
||||||
assert '%s/%s.py' % (dirname, name) in names, \
|
|
||||||
'%s.py is missing' % name
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
parser = optparse.OptionParser(usage='Usage: %prog Package.tar',
|
|
||||||
version='Supybot Packager 0.1')
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
assert len(args) > 0
|
|
||||||
dirname = args[0]
|
|
||||||
output = main(dirname)
|
|
|
@ -1,130 +0,0 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
|
||||||
# Copyright (C) YEAR ORGANIZATION
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
|
||||||
"POT-Creation-Date: 2011-08-21 02:16+CEST\n"
|
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=CHARSET\n"
|
|
||||||
"Content-Transfer-Encoding: ENCODING\n"
|
|
||||||
"Generated-By: pygettext.py 1.5\n"
|
|
||||||
|
|
||||||
|
|
||||||
#: plugin.py:62
|
|
||||||
#, docstring
|
|
||||||
msgid "Returns -1, 0, or 1, depending on the newest version."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:80
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"Tries to find the directory where plugin files are. Returns None\n"
|
|
||||||
" if it is not found or if any file is missing."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:118
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"Add the help for \"@plugin help Packages\" here\n"
|
|
||||||
" This should describe *how* to use this plugin."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:124
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"<filename> [--force]\n"
|
|
||||||
"\n"
|
|
||||||
" Installs the package. If the package has been downloaded with Package,\n"
|
|
||||||
" just give the package name; otherwise, give the full path (including\n"
|
|
||||||
" the extension).\n"
|
|
||||||
" If given, --force disables sanity checks (usage is deprecated)."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:137
|
|
||||||
msgid "Cannot open the package. Are you sure it is readable, it is a tarball and it is not corrupted?"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:143
|
|
||||||
msgid "The file is not a valid package."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:146
|
|
||||||
#, docstring
|
|
||||||
msgid "Namespace for runned code"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:152
|
|
||||||
msgid "%s (missing)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:154
|
|
||||||
msgid "%s (>=%s needed, but %s available)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:157
|
|
||||||
msgid "Missing dependency(ies) : "
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:163
|
|
||||||
msgid "No writable plugin directory found."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:174
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"<package> [--version <version>] [--repo <repository url>]\n"
|
|
||||||
"\n"
|
|
||||||
" Downloads the <package> at the <repository url>.\n"
|
|
||||||
" <version> defaults to the latest version available.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr/"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:187
|
|
||||||
msgid "Bad formed url."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:195 plugin.py:258 plugin.py:308 plugin.py:350
|
|
||||||
msgid "Server's JSON is bad formed."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:212
|
|
||||||
msgid "No packages matches your query."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:247
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"[<repository url>]\n"
|
|
||||||
"\n"
|
|
||||||
" Checks for updates for loaded plugins at the <repository url>.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr/"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:276
|
|
||||||
msgid "All loaded plugins are up to date :)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:283
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"[<repository url>] [--name <name>] [--version <version>] [--author <author>] [<description>]\n"
|
|
||||||
"\n"
|
|
||||||
" Searches the packages matching the query in the <repository url>.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: plugin.py:334
|
|
||||||
#, docstring
|
|
||||||
msgid ""
|
|
||||||
"[<repository url>] <package> [<version>] [--author-full]\n"
|
|
||||||
"\n"
|
|
||||||
" Displays informations about the <package>, at the given <version>.\n"
|
|
||||||
" <repository url> defaults to http://packages.supybot.fr.cr/ and\n"
|
|
||||||
" <version> defaults to the latest available."
|
|
||||||
msgstr ""
|
|
||||||
|
|
|
@ -1,392 +0,0 @@
|
||||||
###
|
|
||||||
# Copyright (c) 2011, Valentin Lorentz
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of the author of this software nor the name of
|
|
||||||
# contributors to this software may be used to endorse or promote products
|
|
||||||
# derived from this software without specific prior written consent.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import json
|
|
||||||
import tarfile
|
|
||||||
import supybot.conf as conf
|
|
||||||
import supybot.utils as utils
|
|
||||||
import supybot.world as world
|
|
||||||
from supybot.commands import *
|
|
||||||
import supybot.plugins as plugins
|
|
||||||
import supybot.ircutils as ircutils
|
|
||||||
import supybot.callbacks as callbacks
|
|
||||||
try:
|
|
||||||
from supybot.i18n import PluginInternationalization
|
|
||||||
from supybot.i18n import internationalizeDocstring
|
|
||||||
_ = PluginInternationalization('Packages')
|
|
||||||
except:
|
|
||||||
# This are useless functions that's allow to run the plugin on a bot
|
|
||||||
# without the i18n plugin
|
|
||||||
_ = lambda x:x
|
|
||||||
internationalizeDocstring = lambda x:x
|
|
||||||
|
|
||||||
if not hasattr(world, 'features'):
|
|
||||||
world.features = {}
|
|
||||||
world.features.update({'package-installer': '0.2'})
|
|
||||||
|
|
||||||
BIGGER = 1
|
|
||||||
EQUAL = 0
|
|
||||||
LOWER = -1
|
|
||||||
|
|
||||||
def compareVersions(v1, v2):
|
|
||||||
"""Returns -1, 0, or 1, depending on the newest version."""
|
|
||||||
def split(version):
|
|
||||||
splitted = version.split('+')
|
|
||||||
patches = splitted[1:]
|
|
||||||
numbers = splitted[0].split('.')
|
|
||||||
return numbers.extend(patches)
|
|
||||||
for index in range(0, min(len(v1), len(v2))):
|
|
||||||
if v1[index] < v2[index]:
|
|
||||||
return LOWER
|
|
||||||
elif v1[index] > v2[index]:
|
|
||||||
return BIGGER
|
|
||||||
if len(v1) < len(v2):
|
|
||||||
return LOWER
|
|
||||||
if len(v1) > len(v2):
|
|
||||||
return BIGGER
|
|
||||||
return EQUAL
|
|
||||||
|
|
||||||
def getDirectory(file_):
|
|
||||||
"""Tries to find the directory where plugin files are. Returns None
|
|
||||||
if it is not found or if any file is missing."""
|
|
||||||
directory = None
|
|
||||||
names = []
|
|
||||||
for name in file_.getnames():
|
|
||||||
assert not name.startswith('/')
|
|
||||||
assert not name.startswith('../')
|
|
||||||
assert ':' not in name # Prevents Windows drives and bad formed names
|
|
||||||
if directory is not None and not name.startswith(directory + '/'):
|
|
||||||
# No more than one directory at root
|
|
||||||
return False
|
|
||||||
elif directory is None:
|
|
||||||
directory = name.split('/')[0]
|
|
||||||
if '/' in name:
|
|
||||||
assert name.startswith(directory + '/')
|
|
||||||
else:
|
|
||||||
assert name == directory
|
|
||||||
names.append(name[len(directory)+1:])
|
|
||||||
if directory is None:
|
|
||||||
return None
|
|
||||||
if not all([x in names for x in ('__init__.py', 'config.py',
|
|
||||||
'plugin.py', 'packaging.py',
|
|
||||||
'test.py')]):
|
|
||||||
# I know, test.py is not necessary. But people who don't write
|
|
||||||
# test case suck. More over, supybot-plugin-create automatically
|
|
||||||
# creates this file for a long time, so it should be there.
|
|
||||||
return None
|
|
||||||
return directory
|
|
||||||
|
|
||||||
def getWritableDirectoryFromList(directories):
|
|
||||||
for directory in directories:
|
|
||||||
if os.access(directory, os.W_OK):
|
|
||||||
return directory
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
@internationalizeDocstring
|
|
||||||
class Packages(callbacks.Plugin):
|
|
||||||
"""Add the help for "@plugin help Packages" here
|
|
||||||
This should describe *how* to use this plugin."""
|
|
||||||
threaded = True
|
|
||||||
|
|
||||||
@internationalizeDocstring
|
|
||||||
def install(self, irc, msg, args, filename, optlist):
|
|
||||||
"""<filename> [--force]
|
|
||||||
|
|
||||||
Installs the package. If the package has been downloaded with Packages,
|
|
||||||
just give the package name; otherwise, give the full path (including
|
|
||||||
the extension).
|
|
||||||
If given, --force disables sanity checks (usage is deprecated)."""
|
|
||||||
filename = os.path.expanduser(filename)
|
|
||||||
if os.path.sep not in filename:
|
|
||||||
filename = os.path.join(conf.supybot.directories.data(), filename)
|
|
||||||
filename += '.tar'
|
|
||||||
try:
|
|
||||||
file_ = tarfile.open(name=filename, mode='r:*')
|
|
||||||
except:
|
|
||||||
irc.error(_('Cannot open the package. Are you sure it is '
|
|
||||||
'readable, it is a tarball and it is not '
|
|
||||||
'corrupted?'))
|
|
||||||
return
|
|
||||||
directory = getDirectory(file_)
|
|
||||||
if not directory:
|
|
||||||
irc.error(_('The file is not a valid package.'))
|
|
||||||
return
|
|
||||||
class packaging:
|
|
||||||
"""Namespace for runned code"""
|
|
||||||
exec(file_.extractfile('%s/packaging.py' % directory).read())
|
|
||||||
if not ('force', True) in optlist:
|
|
||||||
failures = []
|
|
||||||
for feature, version in packaging.requires.items():
|
|
||||||
if feature not in world.features:
|
|
||||||
failures.append(_('%s (missing)') % feature)
|
|
||||||
elif compareVersions(world.features[feature], version) == LOWER:
|
|
||||||
failures.append(_('%s (>=%s needed, but %s available)') %
|
|
||||||
(feature, version, world.features[feature]))
|
|
||||||
if failures != []:
|
|
||||||
irc.error(_('Missing dependency(ies): ') +
|
|
||||||
', '.join(failures))
|
|
||||||
return
|
|
||||||
directories = conf.supybot.directories.plugins()
|
|
||||||
directory = getWritableDirectoryFromList(directories)
|
|
||||||
if directory is None:
|
|
||||||
irc.error(_('No writable plugin directory found.'))
|
|
||||||
return
|
|
||||||
file_.extractall(directory)
|
|
||||||
irc.replySuccess()
|
|
||||||
if hasattr(packaging, 'additionalReply'):
|
|
||||||
irc.reply('The plugin provides this additional information: %s' %
|
|
||||||
packaging.additionalReply)
|
|
||||||
install = wrap(install, ['owner', 'filename', getopts({'force': ''})])
|
|
||||||
|
|
||||||
@internationalizeDocstring
|
|
||||||
def download(self, irc, msg, args, name, optlist):
|
|
||||||
"""<package> [--version <version>] [--repo <repository url>]
|
|
||||||
|
|
||||||
Downloads the <package> at the <repository url>.
|
|
||||||
<version> defaults to the latest version available.
|
|
||||||
<repository url> defaults to http://packages.supybot.fr.cr/"""
|
|
||||||
# Parse and check parameters
|
|
||||||
version = None
|
|
||||||
repo = 'http://packages.supybot.fr.cr/'
|
|
||||||
for key, value in optlist:
|
|
||||||
if key == 'version': version = value
|
|
||||||
elif key == 'repo': repo = value
|
|
||||||
if __builtins__['any']([x in repo for x in ('?', '&')]):
|
|
||||||
# Supybot rewrites any() in commands.py
|
|
||||||
irc.error(_('Bad formed url.'))
|
|
||||||
return
|
|
||||||
selectedPackage = None
|
|
||||||
|
|
||||||
# Get server's index
|
|
||||||
try:
|
|
||||||
index = json.load(utils.web.getUrlFd(repo))
|
|
||||||
except ValueError:
|
|
||||||
irc.error(_('Server\'s JSON is bad formed.'))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Crawl the available packages list
|
|
||||||
for package in index['packages']:
|
|
||||||
if not package['name'] == name:
|
|
||||||
continue
|
|
||||||
if version is None and (
|
|
||||||
selectedPackage == None or
|
|
||||||
compareVersions(selectedPackage['version'],
|
|
||||||
package['version']) == LOWER):
|
|
||||||
# If not version given, and [no selected package
|
|
||||||
# or selected package is older than this one]
|
|
||||||
selectedPackage = package
|
|
||||||
elif package['version'] == version:
|
|
||||||
selectedPackage = package
|
|
||||||
if selectedPackage is None:
|
|
||||||
irc.error(_('No packages matches your query.'))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Determines the package's real URL
|
|
||||||
# TODO: handle relative URL starting with /
|
|
||||||
# FIXME: URL ending with /foobar.txt
|
|
||||||
packageUrl = selectedPackage['download-url']
|
|
||||||
if packageUrl.startswith('./'):
|
|
||||||
packageUrl = repo
|
|
||||||
if not packageUrl.endswith('/'):
|
|
||||||
packageUrl += '/'
|
|
||||||
packageUrl += selectedPackage['download-url']
|
|
||||||
|
|
||||||
# Write the package to the disk
|
|
||||||
directory = conf.supybot.directories.data()
|
|
||||||
assert os.access(directory, os.W_OK)
|
|
||||||
path = os.path.join(directory, '%s.tar' % name)
|
|
||||||
try:
|
|
||||||
os.unlink(path)
|
|
||||||
except OSError:
|
|
||||||
# Does not exist
|
|
||||||
pass
|
|
||||||
with open(path, 'ab') as file_:
|
|
||||||
try:
|
|
||||||
file_.write(utils.web.getUrlFd(packageUrl).read())
|
|
||||||
except utils.web.Error as e:
|
|
||||||
irc.reply(e.args[0])
|
|
||||||
return
|
|
||||||
irc.replySuccess()
|
|
||||||
download = wrap(download, ['owner', 'something',
|
|
||||||
getopts({'version': 'something',
|
|
||||||
'repo': 'httpUrl'})])
|
|
||||||
|
|
||||||
@internationalizeDocstring
|
|
||||||
def checkupdates(self, irc, msg, args, repo):
|
|
||||||
"""[<repository url>]
|
|
||||||
|
|
||||||
Checks for updates for loaded plugins at the <repository url>.
|
|
||||||
<repository url> defaults to http://packages.supybot.fr.cr/"""
|
|
||||||
if repo is None:
|
|
||||||
repo = 'http://packages.supybot.fr.cr/'
|
|
||||||
|
|
||||||
# Get server's index
|
|
||||||
try:
|
|
||||||
index = json.load(utils.web.getUrlFd(repo))
|
|
||||||
except ValueError:
|
|
||||||
irc.error(_('Server\'s JSON is bad formed.'))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Crawl the index
|
|
||||||
needUpdate = {}
|
|
||||||
for package in index['packages']:
|
|
||||||
if package['name'] in sys.modules and (
|
|
||||||
not hasattr(sys.modules[package['name']], '__version__') or
|
|
||||||
compareVersions(sys.modules[package['name']].__version__,
|
|
||||||
package['version']) == LOWER):
|
|
||||||
if package['name'] in needUpdate:
|
|
||||||
if compareVersions(needUpdate[package['name']].__version__,
|
|
||||||
package['version']) != LOWER:
|
|
||||||
continue
|
|
||||||
needUpdate.update({package['name']: package})
|
|
||||||
|
|
||||||
# Display results
|
|
||||||
if needUpdate == {}:
|
|
||||||
irc.reply(_('All loaded plugins are up to date :)'))
|
|
||||||
else:
|
|
||||||
irc.reply(', '.join(['%s (%s)' % (y['name'],y['version'])
|
|
||||||
for x,y in needUpdate.items()]))
|
|
||||||
checkupdates = wrap(checkupdates, ['owner', optional('httpUrl')])
|
|
||||||
|
|
||||||
def search(self, irc, msg, args, repo, optlist, description):
|
|
||||||
"""[<repository url>] [--name <name>] [--version <version>]\
|
|
||||||
[--author <author>] [<description>]
|
|
||||||
|
|
||||||
Searches the packages matching the query in the <repository url>.
|
|
||||||
<repository url> defaults to http://packages.supybot.fr.cr"""
|
|
||||||
# Parse the arguments
|
|
||||||
if repo is None:
|
|
||||||
repo = 'http://packages.supybot.fr.cr/'
|
|
||||||
if description is None:
|
|
||||||
description = ''
|
|
||||||
if not __builtins__['any'](x in description for x in '*?'):
|
|
||||||
description = '*%s*' % description
|
|
||||||
optlist.append(('description', description))
|
|
||||||
def glob2matcher(glob):
|
|
||||||
glob = utils.python.glob2re(glob)
|
|
||||||
return re.compile(glob).match
|
|
||||||
matchers = {}
|
|
||||||
for key, value in optlist:
|
|
||||||
if value != None:
|
|
||||||
matchers.update({key: glob2matcher(value)})
|
|
||||||
|
|
||||||
# Get server's index
|
|
||||||
try:
|
|
||||||
index = json.load(utils.web.getUrlFd(repo))
|
|
||||||
except ValueError:
|
|
||||||
irc.error(_('Server\'s JSON is bad formed.'))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Crawl packages index
|
|
||||||
results = []
|
|
||||||
for package in index['packages']:
|
|
||||||
ok = True
|
|
||||||
for key, matcher in matchers.items():
|
|
||||||
if key in package and not matcher(str(package[key])):
|
|
||||||
# If the packages index doesn't have this key, we consider
|
|
||||||
# the key matched.
|
|
||||||
ok = False
|
|
||||||
break
|
|
||||||
if ok:
|
|
||||||
results.append(package)
|
|
||||||
|
|
||||||
# Display results
|
|
||||||
reply = ['%s (%s)' % (x['name'],x['version']) for x in results]
|
|
||||||
reply.sort()
|
|
||||||
irc.reply(', '.join(reply))
|
|
||||||
options = ['name', 'version', 'author']
|
|
||||||
search = wrap(search, [optional('httpUrl'),
|
|
||||||
getopts(dict([(x,'anything') for x in options])),
|
|
||||||
optional('text')])
|
|
||||||
|
|
||||||
def info(self, irc, msg, args, repo, name, version, optlist):
|
|
||||||
"""[<repository url>] <package> [<version>] [--author-full]
|
|
||||||
|
|
||||||
Displays informations about the <package>, at the given <version>.
|
|
||||||
<repository url> defaults to http://packages.supybot.fr.cr/ and
|
|
||||||
<version> defaults to the latest available."""
|
|
||||||
# Parse the arguments
|
|
||||||
if repo is None:
|
|
||||||
repo = 'http://packages.supybot.fr.cr/'
|
|
||||||
if version == '--author-full': # Bug in wrap()
|
|
||||||
version = None
|
|
||||||
optlist.append(('--author-full', True))
|
|
||||||
|
|
||||||
# Get server's index
|
|
||||||
try:
|
|
||||||
index = json.load(utils.web.getUrlFd(repo))
|
|
||||||
except ValueError:
|
|
||||||
irc.error(_('Server\'s JSON is bad formed.'))
|
|
||||||
return
|
|
||||||
|
|
||||||
# Crawl the index
|
|
||||||
selectedPackage = None
|
|
||||||
for package in index['packages']:
|
|
||||||
if package['name'] == name:
|
|
||||||
if version is not None and package['version'] != version:
|
|
||||||
continue
|
|
||||||
if version is None and selectedPackage is not None and \
|
|
||||||
compareVersions(selectedPackage['version'],
|
|
||||||
package['version']) != LOWER:
|
|
||||||
continue
|
|
||||||
selectedPackage = package
|
|
||||||
|
|
||||||
# Display result
|
|
||||||
if selectedPackage is None:
|
|
||||||
irc.error('No such package/version.')
|
|
||||||
return
|
|
||||||
selectedPackage['author-name'] = selectedPackage['author'][0]
|
|
||||||
selectedPackage['author-nick'] = selectedPackage['author'][1]
|
|
||||||
selectedPackage['author-email'] = selectedPackage['author'][2]
|
|
||||||
if ('author-full', True) in optlist:
|
|
||||||
selectedPackage['author-string'] = '%s "%s" <%s>' % \
|
|
||||||
tuple(selectedPackage['author'])
|
|
||||||
else:
|
|
||||||
selectedPackage['author-string'] = selectedPackage['author-name']
|
|
||||||
for key in ('requires', 'suggests', 'provides'):
|
|
||||||
selectedPackage[key] = ', '.join('%s (%s)' % x for x in
|
|
||||||
selectedPackage[key].items())
|
|
||||||
irc.reply(('%(name)s (version %(version)s) has been written by '
|
|
||||||
'%(author-string)s and requires the fellowing flags: '
|
|
||||||
'%(requires)s') % selectedPackage)
|
|
||||||
info = wrap(info, [optional('httpUrl'), 'something',
|
|
||||||
optional('something'), getopts({'author-full': ''})])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Class = Packages
|
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
|
|
|
@ -1,37 +0,0 @@
|
||||||
###
|
|
||||||
# Copyright (c) 2011, Valentin Lorentz
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions are met:
|
|
||||||
#
|
|
||||||
# * Redistributions of source code must retain the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer.
|
|
||||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
# this list of conditions, and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
# * Neither the name of the author of this software nor the name of
|
|
||||||
# contributors to this software may be used to endorse or promote products
|
|
||||||
# derived from this software without specific prior written consent.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
###
|
|
||||||
|
|
||||||
from supybot.test import *
|
|
||||||
|
|
||||||
class PackagesTestCase(PluginTestCase):
|
|
||||||
plugins = ('Packages',)
|
|
||||||
|
|
||||||
|
|
||||||
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:
|
|
Loading…
Reference in New Issue