diff --git a/debian/rules b/debian/rules index 041ec5cec..e1cc80f0f 100755 --- a/debian/rules +++ b/debian/rules @@ -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 diff --git a/debian/wcs.init b/debian/wcs.init index 18a7a4e2f..3c6ba9811 100755 --- a/debian/wcs.init +++ b/debian/wcs.init @@ -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 diff --git a/setup.py b/setup.py index 146e7e953..00175cf96 100644 --- a/setup.py +++ b/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/') diff --git a/tests/test_ctl.py b/tests/test_ctl.py index 2cae2e073..8a75acf90 100644 --- a/tests/test_ctl.py +++ b/tests/test_ctl.py @@ -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 diff --git a/wcs/ctl/runscript.py b/wcs/ctl/runscript.py deleted file mode 100644 index b7977c3e3..000000000 --- a/wcs/ctl/runscript.py +++ /dev/null @@ -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 . - -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() diff --git a/wcs/ctl/shell.py b/wcs/ctl/shell.py deleted file mode 100644 index 4cd20d018..000000000 --- a/wcs/ctl/shell.py +++ /dev/null @@ -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 . - -# 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() diff --git a/wcs/qommon/ctl.py b/wcs/qommon/ctl.py deleted file mode 100644 index f3a879b84..000000000 --- a/wcs/qommon/ctl.py +++ /dev/null @@ -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 . - -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) diff --git a/wcsctl.py b/wcsctl.py deleted file mode 100755 index e5b47510f..000000000 --- a/wcsctl.py +++ /dev/null @@ -1,11 +0,0 @@ -#! /usr/bin/env python3 - -import os -import sys - -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'wcs.settings') - -import wcs.qommon.ctl - -ctl = wcs.qommon.ctl.Ctl(cmd_prefixes=['wcs.ctl']) -ctl.run(sys.argv[1:])