add support for installation of single file plugins

This commit is contained in:
Kevin Dangoor 2010-03-09 21:22:59 -05:00
Родитель f0eb148924
Коммит 29fc14a8ac
3 изменённых файлов: 91 добавлений и 6 удалений

Просмотреть файл

@ -452,11 +452,12 @@ def validate_url(url):
raise BadRequest("Invalid url: " + url)
return url
@expose(r'^/project/fromurl/(?P<project_name>[^/]+)', "POST")
def import_from_url(request, response):
project_name = request.kwargs['project_name']
url = validate_url(request.body)
def _download_data(url, request):
"""downloads the data to a temporary file, raising BadRequest
if there are issues, doing a HEAD request first to ensure that
the URL is good and also ensuring that the user has enough
space available."""
url = validate_url(url)
try:
resp = httplib2.Http().request(url, method="HEAD")
except httplib2.HttpLib2Error, e:
@ -478,6 +479,14 @@ def import_from_url(request, response):
tempdatafile.write(datafile.read())
datafile.close()
tempdatafile.seek(0)
return tempdatafile
@expose(r'^/project/fromurl/(?P<project_name>[^/]+)', "POST")
def import_from_url(request, response):
project_name = request.kwargs['project_name']
tempdatafile = _download_data(request.body, request)
url_parts = urlparse(url)
filename = os.path.basename(url_parts[2])
_perform_import(request.user, project_name, filename, tempdatafile)
@ -1164,6 +1173,35 @@ def _wrap_script(plugin_name, script_path, script_text):
;}); tiki.script('%s:%s');""" % (plugin_name, module_name,
script_text, plugin_name, script_path)
urlmatch = re.compile(r'^(http|https)://')
@expose(r'^/plugin/install/', 'POST')
def install_plugin(request, response):
"""Installs a plugin into the user's BespinSettings/plugins directory."""
user = request.user
url = request.POST.get('url')
plugin_name = request.POST.get('pluginName')
if not url or not urlmatch.search(url):
raise BadRequest("URL not provided")
if not plugin_name or "/" in plugin_name or ".." in plugin_name:
raise BadRequest("Invalid plugin name. / and .. are not permitted")
tempdatafile = _download_data(url, request)
settings_project = get_project(user, user, "BespinSettings")
destination = settings_project.location / "plugins"
path_entry = dict(name="user", chop=len(user.get_location()))
plugin = plugins.install_plugin(tempdatafile, url, destination,
path_entry, plugin_name)
tempdatafile.close()
plugin_collection = dict()
plugin_collection[plugin.name] = plugin.metadata
response.body = simplejson.dumps(plugin_collection)
response.content_type = "application/json"
return response()
def db_middleware(app):
def wrapped(environ, start_response):

Просмотреть файл

@ -34,6 +34,8 @@
#
# ***** END LICENSE BLOCK *****
#
import os
from urlparse import urlparse
from dryice.plugins import (Plugin as BasePlugin,
find_plugins as base_find_plugins,
@ -105,3 +107,22 @@ def lookup_plugin(name, search_path=None):
search_path = config.c.plugin_path
return base_lookup_plugin(name, search_path, cls=Plugin)
def install_plugin(f, url, destination, path_entry, plugin_name=None):
if not destination.exists():
destination.mkdir()
if plugin_name is None:
url_parts = urlparse(url)
filename = os.path.basename(url_parts[2])
plugin_name = os.path.splitext(filename)[0]
# check for single file plugin
if url.endswith(".js"):
destination = destination / (plugin_name + ".js")
destination.write_bytes(f.read())
plugin = Plugin(plugin_name, destination, path_entry)
return plugin

Просмотреть файл

@ -41,6 +41,7 @@ from simplejson import loads
from bespin import config, plugins, controllers
from bespin.database import User, Base
from bespin.filesystem import get_project
from __init__ import BespinTestApp
@ -77,6 +78,32 @@ def _init_data():
macgyver = User.find_user("MacGyver")
def test_install_single_file_plugin():
_init_data()
settings_project = get_project(macgyver, macgyver, "BespinSettings")
destination = settings_project.location / "plugins"
path_entry = dict(chop=len(macgyver.get_location()), name="user")
sfp = plugindir / "SingleFilePlugin1.js"
plugin = plugins.install_plugin(open(sfp), "http://somewhere/file.js",
destination, path_entry, "APlugin")
destfile = destination / "APlugin.js"
assert destfile.exists()
desttext = destfile.text()
assert "someFunction" in desttext
assert plugin.name == "APlugin"
assert plugin.location == destfile
assert plugin.relative_location == "BespinSettings/plugins/APlugin.js"
metadata = plugin.metadata
type = metadata['type']
assert type == "user"
plugin = plugins.install_plugin(open(sfp), "http://somewhere/Flibber.js",
destination, path_entry)
destfile = destination / "Flibber.js"
assert destfile.exists()
assert plugin.name == "Flibber"
# Web tests
def test_default_plugin_registration():
@ -171,4 +198,3 @@ def test_plugin_reload():
assert '"plugin2": {' in response.body
# just need the plugin, not its dependents
assert '"depends": ["plugin2"]' not in response.body