This commit is contained in:
parent
8ee2a8cee6
commit
5faf53489b
|
@ -8,8 +8,6 @@ export PYBUILD_NAME=wcs
|
|||
|
||||
override_dh_install:
|
||||
dh_install
|
||||
mv $(CURDIR)/debian/wcs/usr/bin/wcsctl.py \
|
||||
$(CURDIR)/debian/wcs/usr/bin/wcsctl
|
||||
mv $(CURDIR)/debian/wcs/usr/bin/manage.py \
|
||||
$(CURDIR)/debian/wcs/usr/lib/wcs/
|
||||
install -d $(CURDIR)/debian/wcs/etc/wcs
|
||||
|
|
|
@ -17,7 +17,6 @@ set -e
|
|||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DESC="Web Forms Manager"
|
||||
NAME=wcs
|
||||
WCSCTL=/usr/bin/wcsctl
|
||||
DAEMON=/usr/bin/uwsgi
|
||||
RUN_DIR=/run/$NAME
|
||||
PIDFILE=$RUN_DIR/$NAME.pid
|
||||
|
|
2
setup.py
2
setup.py
|
@ -208,7 +208,7 @@ setup(
|
|||
package_dir={'wcs': 'wcs'},
|
||||
packages=find_packages(),
|
||||
cmdclass=cmdclass,
|
||||
scripts=['wcsctl.py', 'manage.py'],
|
||||
scripts=['manage.py'],
|
||||
include_package_data=True,
|
||||
data_files=data_tree('share/wcs/web/', 'data/web/')
|
||||
+ data_tree('share/wcs/themes/', 'data/themes/')
|
||||
|
|
|
@ -3,7 +3,6 @@ import json
|
|||
import os
|
||||
import pickle
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import zipfile
|
||||
from unittest import mock
|
||||
|
@ -14,7 +13,6 @@ import pytest
|
|||
import responses
|
||||
from django.core.management import CommandError, call_command
|
||||
|
||||
import wcs.qommon.ctl
|
||||
from wcs.blocks import BlockDef
|
||||
from wcs.carddef import CardDef
|
||||
from wcs.ctl.management.commands.trigger_jumps import select_and_jump_formdata
|
||||
|
@ -54,16 +52,6 @@ def alt_tempdir():
|
|||
shutil.rmtree(alt_tempdir)
|
||||
|
||||
|
||||
def test_loading():
|
||||
ctl = wcs.qommon.ctl.Ctl(cmd_prefixes=['wcs.ctl'])
|
||||
ctl.load_all_commands(ignore_errors=False)
|
||||
# noqa pylint: disable=consider-iterating-dictionary
|
||||
assert 'shell' in ctl.get_commands().keys()
|
||||
# call all __init__() methods
|
||||
for cmd in ctl.get_commands().values():
|
||||
cmd()
|
||||
|
||||
|
||||
def test_collectstatic(pub, tmp_path):
|
||||
CmdCollectStatic.collectstatic(pub)
|
||||
assert os.path.exists(os.path.join(pub.app_dir, 'collectstatic', 'css', 'required.png'))
|
||||
|
@ -517,26 +505,6 @@ def test_runjob(pub):
|
|||
call_command('runjob', '--domain=example.net', '--job-id=%s' % job.id, '--force-replay', '--raise')
|
||||
|
||||
|
||||
def test_ctl_print_help(capsys):
|
||||
ctl = wcs.qommon.ctl.Ctl(cmd_prefixes=['wcs.ctl'])
|
||||
with pytest.raises(SystemExit):
|
||||
ctl.print_help()
|
||||
captured = capsys.readouterr()
|
||||
assert 'runscript' in captured.out
|
||||
|
||||
|
||||
def test_ctl_no_command(capsys):
|
||||
ctl = wcs.qommon.ctl.Ctl(cmd_prefixes=['wcs.ctl'])
|
||||
old_argv, sys.argv = sys.argv, ['wcsctl']
|
||||
try:
|
||||
with pytest.raises(SystemExit):
|
||||
ctl.run(None)
|
||||
captured = capsys.readouterr()
|
||||
assert 'error: You must use a command' in captured.err
|
||||
finally:
|
||||
sys.argv = old_argv
|
||||
|
||||
|
||||
def test_dbshell(pub):
|
||||
with pytest.raises(CommandError):
|
||||
call_command('dbshell') # missing tenant name
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
# w.c.s. - web application for online forms
|
||||
# Copyright (C) 2005-2013 Entr'ouvert
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os.path
|
||||
import runpy
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from ..qommon.ctl import Command, make_option
|
||||
|
||||
|
||||
class CmdRunScript(Command):
|
||||
'''Run a script within a given host publisher context'''
|
||||
|
||||
name = 'runscript'
|
||||
|
||||
def __init__(self):
|
||||
Command.__init__(
|
||||
self,
|
||||
[
|
||||
make_option('--vhost', metavar='VHOST', action='store', dest='vhost'),
|
||||
],
|
||||
)
|
||||
|
||||
def execute(self, base_options, sub_options, args):
|
||||
warnings.warn('Deprecated command, use management command', DeprecationWarning)
|
||||
from .. import publisher
|
||||
|
||||
self.config.remove_option('main', 'error_log')
|
||||
publisher.WcsPublisher.configure(self.config)
|
||||
publisher = publisher.WcsPublisher.create_publisher(register_tld_names=False)
|
||||
publisher.set_tenant_by_hostname(sub_options.vhost)
|
||||
fullpath = os.path.dirname(os.path.abspath(args[0]))
|
||||
sys.path.insert(0, fullpath)
|
||||
module_name = os.path.splitext(os.path.basename(args[0]))[0]
|
||||
sys.argv = args
|
||||
runpy.run_module(module_name)
|
||||
|
||||
|
||||
CmdRunScript.register()
|
|
@ -1,36 +0,0 @@
|
|||
# w.c.s. - web application for online forms
|
||||
# Copyright (C) 2005-2010 Entr'ouvert
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Most of this code is copied from the shell command [1] of the project Django
|
||||
# release 1.4. Many thanks to them.
|
||||
#
|
||||
# [1]: file django/core/management/commands/shell.py
|
||||
|
||||
import sys
|
||||
|
||||
from ..qommon.ctl import Command
|
||||
|
||||
|
||||
class CmdShell(Command):
|
||||
'''(obsolete) Launch a shell and initialize a publisher on a given host'''
|
||||
|
||||
name = 'shell'
|
||||
|
||||
def execute(self, base_options, sub_options, args):
|
||||
print('Error: use wcs-manage shell command', file=sys.stderr)
|
||||
|
||||
|
||||
CmdShell.register()
|
|
@ -1,161 +0,0 @@
|
|||
# w.c.s. - web application for online forms
|
||||
# Copyright (C) 2005-2010 Entr'ouvert
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import configparser
|
||||
import optparse # noqa pylint: disable=deprecated-module
|
||||
import os
|
||||
import sys
|
||||
from optparse import make_option # noqa pylint: disable=deprecated-module
|
||||
|
||||
__all__ = [
|
||||
'Command',
|
||||
]
|
||||
|
||||
from wcs import qommon
|
||||
|
||||
from . import _
|
||||
|
||||
qommon._commands = {}
|
||||
|
||||
|
||||
class Command:
|
||||
doc = ''
|
||||
name = None
|
||||
usage_args = '[ options ... ]'
|
||||
|
||||
def __init__(self, options=None):
|
||||
options = options or []
|
||||
self.config = configparser.ConfigParser()
|
||||
self.options = options + [
|
||||
make_option('--app-dir', metavar='DIR', action='store', dest='app_dir', default=None),
|
||||
make_option('--data-dir', metavar='DIR', action='store', dest='data_dir', default=None),
|
||||
]
|
||||
|
||||
def run(self, args, base_options):
|
||||
if base_options.configfile:
|
||||
if not os.path.exists(base_options.configfile):
|
||||
print('Missing configuration file %s' % base_options.configfile, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
try:
|
||||
self.config.read(base_options.configfile)
|
||||
except configparser.ParsingError as e:
|
||||
print('Invalid configuration file %s' % base_options.configfile, file=sys.stderr)
|
||||
print(e, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if not self.config.has_section('main'):
|
||||
self.config.add_section('main')
|
||||
sub_options, args = self.parse_args(args)
|
||||
if sub_options.app_dir:
|
||||
self.config.set('main', 'app_dir', sub_options.app_dir)
|
||||
if sub_options.data_dir:
|
||||
self.config.set('main', 'data_dir', sub_options.data_dir)
|
||||
return self.execute(base_options, sub_options, args)
|
||||
|
||||
def parse_args(self, args):
|
||||
self.parser = optparse.OptionParser(
|
||||
usage='%%prog %s %s' % (self.name, _(self.usage_args)), description=self.doc
|
||||
)
|
||||
self.parser.add_options(self.options)
|
||||
return self.parser.parse_args(args)
|
||||
|
||||
def execute(self, base_options, sub_options, args):
|
||||
"""The body of the command"""
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
qommon._commands[cls.name] = cls
|
||||
|
||||
|
||||
class Ctl:
|
||||
def __init__(self, cmd_prefixes=None):
|
||||
self.cmd_prefixes = cmd_prefixes or []
|
||||
self.parser = optparse.OptionParser(
|
||||
usage='%prog [ -f config ] command [ options ... ]', add_help_option=False
|
||||
)
|
||||
self.parser.disable_interspersed_args()
|
||||
self.parser.add_option(
|
||||
'-f',
|
||||
'--file',
|
||||
action='store',
|
||||
metavar='CONFIG',
|
||||
type='string',
|
||||
dest='configfile',
|
||||
help=_('use a non default configuration file'),
|
||||
)
|
||||
self.parser.add_option(
|
||||
'--help', action='callback', callback=self.print_help, help=_('Display this help and exit')
|
||||
)
|
||||
|
||||
def load_all_commands(self, ignore_errors=True):
|
||||
for cmd_prefix in self.cmd_prefixes:
|
||||
if not cmd_prefix in sys.modules:
|
||||
__import__(cmd_prefix)
|
||||
mod = sys.modules.get(cmd_prefix)
|
||||
if not mod:
|
||||
continue
|
||||
if os.path.isdir(mod.__file__):
|
||||
cmddir = os.path.abspath(mod.__file__)
|
||||
else:
|
||||
cmddir = os.path.abspath(os.path.dirname(mod.__file__))
|
||||
for fname in os.listdir(os.path.join(cmddir)):
|
||||
name, ext = os.path.splitext(fname)
|
||||
if not ext == '.py':
|
||||
continue
|
||||
if name.startswith('_'):
|
||||
continue
|
||||
try:
|
||||
__import__('%s.%s' % (cmd_prefix, name))
|
||||
except ImportError as e:
|
||||
if not ignore_errors:
|
||||
raise e
|
||||
|
||||
def get_commands(self):
|
||||
return qommon._commands
|
||||
|
||||
def print_help(self, *args):
|
||||
self.parser.print_help()
|
||||
self.load_all_commands()
|
||||
print()
|
||||
|
||||
commands = sorted((x.name, x.doc) for x in self.get_commands().values())
|
||||
print('Available commands:')
|
||||
for name, description in commands:
|
||||
print(' %-15s %s' % (name, description))
|
||||
sys.exit(0)
|
||||
|
||||
def run(self, args):
|
||||
options, args = self.parser.parse_args(args)
|
||||
if not args:
|
||||
self.parser.error('You must use a command')
|
||||
command, args = args[0], args[1:]
|
||||
|
||||
if command not in self.get_commands():
|
||||
# load a module named like the command, this is the common case
|
||||
for cmd_prefix in self.cmd_prefixes:
|
||||
try:
|
||||
__import__('%s.%s' % (cmd_prefix, command))
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if command not in self.get_commands():
|
||||
# if the command could not be loaded from a same-name module,
|
||||
# go over all modules
|
||||
self.load_all_commands()
|
||||
|
||||
command_class = self.get_commands()[command]
|
||||
cmd = command_class()
|
||||
return cmd.run(args, options)
|
Loading…
Reference in New Issue