diff options
| author | Antony Lesuisse <lesuisse@gmail.com> | 2014-05-29 18:33:04 +0200 |
|---|---|---|
| committer | Antony Lesuisse <lesuisse@gmail.com> | 2014-05-29 18:33:04 +0200 |
| commit | d4624fa826a5e9542782f2c53c8ba2c766d093bc (patch) | |
| tree | be214779eb6d1f17157aa48e72fbcbf95405e38b /openerpcommand | |
| parent | 045ecc603e67911a5390c812cb6b5b123d9c190e (diff) | |
[IMP] repository cleanup
- move packaging stuff to setup
- remove historical stuff
- remove oe, odoo-cmd-fme will be merged with the convered commands
- add an odoo.py script to run odo and boostrap it
- simplify README
- prepare to move documentation to the github wiki
Diffstat (limited to 'openerpcommand')
28 files changed, 0 insertions, 1578 deletions
diff --git a/openerpcommand/__init__.py b/openerpcommand/__init__.py deleted file mode 100644 index b7131913e1e..00000000000 --- a/openerpcommand/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -import argparse -import textwrap - -from .call import Call -from .client import Open, Show, ConsumeNothing, ConsumeMemory, LeakMemory, ConsumeCPU -from .benchmarks import Bench, BenchRead, BenchFieldsViewGet, BenchDummy, BenchLogin -from .bench_sale_mrp import BenchSaleMrp -from . import common - -from . import conf # Not really server-side (in the `for` below). -from . import cron -from . import drop -from . import initialize -from . import model -from . import module -from . import read -from . import scaffold -from . import uninstall -from . import update -from . import web -from . import grunt_tests - -command_list_server = (conf, cron, drop, initialize, model, module, read, - scaffold, uninstall, update, web, grunt_tests, ) - -command_list_client = (Call, Open, Show, ConsumeNothing, ConsumeMemory, - LeakMemory, ConsumeCPU, Bench, BenchRead, - BenchFieldsViewGet, BenchDummy, BenchLogin, - BenchSaleMrp, ) - -def main_parser(): - parser = argparse.ArgumentParser( - usage=argparse.SUPPRESS, - description=textwrap.fill(textwrap.dedent("""\ - OpenERP Command provides a set of command-line tools around - the OpenERP framework: openobject-server. All the tools are - sub-commands of a single oe executable.""")), - epilog="""Use <command> --help to get information about the command.""", - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - description = [] - for x in command_list_server: - description.append(x.__name__[len(__package__)+1:]) - if x.__doc__: - description.extend([ - ":\n", - textwrap.fill(str(x.__doc__).strip(), - subsequent_indent=' ', - initial_indent=' '), - ]) - description.append("\n\n") - subparsers = parser.add_subparsers( - title="Available commands", - help=argparse.SUPPRESS, - description="".join(description[:-1]), - ) - # Server-side commands. - for x in command_list_server: - x.add_parser(subparsers) - # Client-side commands. TODO one per .py file. - for x in command_list_client: - x(subparsers) - return parser diff --git a/openerpcommand/addons/bench_sale_mrp/__init__.py b/openerpcommand/addons/bench_sale_mrp/__init__.py deleted file mode 100644 index 99ae05ee3a1..00000000000 --- a/openerpcommand/addons/bench_sale_mrp/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -# Nothing here, the module provides only data. -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerpcommand/addons/bench_sale_mrp/__openerp__.py b/openerpcommand/addons/bench_sale_mrp/__openerp__.py deleted file mode 100644 index 3d8781905cc..00000000000 --- a/openerpcommand/addons/bench_sale_mrp/__openerp__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -{ - 'name': 'bench_sale_mrp', - 'version': '0.1', - 'category': 'Benchmarks', - 'description': """Prepare some data to run a benchmark.""", - 'author': 'OpenERP SA', - 'maintainer': 'OpenERP SA', - 'website': 'http://www.openerp.com', - 'depends': ['base', 'sale_mrp'], - 'data': ['data.yml'], - 'installable': True, - 'auto_install': False, -} -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerpcommand/addons/bench_sale_mrp/data.yml b/openerpcommand/addons/bench_sale_mrp/data.yml deleted file mode 100644 index 419492e60e1..00000000000 --- a/openerpcommand/addons/bench_sale_mrp/data.yml +++ /dev/null @@ -1,41 +0,0 @@ -- - This is a subset of `sale_mrp/test/sale_mrp.yml`. -- - I define a product category `Mobile Products Sellable`. -- - !record {model: product.category, id: my_product_category_0}: - name: Mobile Products Sellable -- - I define a product `Slider Mobile` -- - !record {model: product.product, id: my_slider_mobile_0}: - categ_id: my_product_category_0 - cost_method: standard - list_price: 200.0 - mes_type: fixed - name: Slider Mobile - procure_method: make_to_order - seller_delay: '1' - seller_ids: - - delay: 1 - name: base.res_partner_agrolait - min_qty: 2.0 - qty: 5.0 - standard_price: 189.0 - supply_method: produce - type: product - uom_id: product.product_uom_unit - uom_po_id: product.product_uom_unit -- - I create a Bill of Material for the `Slider Mobile` product. -- - !record {model: mrp.bom, id: mrp_bom_slidermobile0}: - company_id: base.main_company - name: Slider Mobile - product_efficiency: 1.0 - product_id: my_slider_mobile_0 - product_qty: 1.0 - product_uom: product.product_uom_unit - product_uos_qty: 0.0 - sequence: 0.0 - type: normal diff --git a/openerpcommand/bench_sale_mrp.py b/openerpcommand/bench_sale_mrp.py deleted file mode 100644 index 60e53037855..00000000000 --- a/openerpcommand/bench_sale_mrp.py +++ /dev/null @@ -1,68 +0,0 @@ -""" -Benchmark based on the `sale_mrp` addons (in `sale_mrp/test/sale_mrp.yml`). -""" - -import time - -from .benchmarks import Bench - -class BenchSaleMrp(Bench): - """\ - Similar to `sale_mrp/test/sale_mrp.yml`. - - This benchmarks the OpenERP server `sale_mrp` module by creating and - confirming a sale order. As it creates data in the server, it is necessary - to ensure unique names for the newly created data. You can use the --seed - argument to give a lower bound to those names. (The number of generated - names is --jobs * --samples.) - """ - - command_name = 'bench-sale-mrp' - bench_name = '`sale_mrp/test/sale_mrp.yml`' - - def measure_once(self, i): - if self.worker >= 0: - i = int(self.args.seed) + i + (self.worker * int(self.args.samples)) - else: - i = int(self.args.seed) + i - - # Resolve a few external-ids (this has little impact on the running - # time of the whole method). - product_uom_unit = self.execute('ir.model.data', 'get_object_reference', 'product', 'product_uom_unit')[1] - my_slider_mobile_0 = self.execute('ir.model.data', 'get_object_reference', 'bench_sale_mrp', 'my_slider_mobile_0')[1] - res_partner_4 = self.execute('ir.model.data', 'get_object_reference', 'base', 'res_partner_4')[1] - res_partner_address_7 = self.execute('ir.model.data', 'get_object_reference', 'base', 'res_partner_address_7')[1] - list0 = self.execute('ir.model.data', 'get_object_reference', 'product', 'list0')[1] - shop = self.execute('ir.model.data', 'get_object_reference', 'sale', 'shop')[1] - - # Create a sale order for the product `Slider Mobile`. - data = { - 'client_order_ref': 'ref_xxx_' + str(i).rjust(6, '0'), - 'date_order': time.strftime('%Y-%m-%d'), - 'invoice_quantity': 'order', - 'name': 'sale_order_ref_xxx_' + str(i).rjust(6, '0'), - 'order_line': [(0, 0, { - 'name': 'Slider Mobile', - 'price_unit': 2, - 'product_uom': product_uom_unit, - 'product_uom_qty': 5.0, - 'state': 'draft', - 'delay': 7.0, - 'product_id': my_slider_mobile_0, - 'product_uos_qty': 5, - 'type': 'make_to_order', - })], - 'order_policy': 'manual', - 'partner_id': res_partner_4, - 'partner_invoice_id': res_partner_address_7, - 'partner_order_id': res_partner_address_7, - 'partner_shipping_id': res_partner_address_7, - 'picking_policy': 'direct', - 'pricelist_id': list0, - 'shop_id': shop, - } - sale_order_id = self.execute('sale.order', 'create', data, {}) - - # Confirm the sale order. - self.object_proxy.exec_workflow(self.database, self.uid, self.password, 'sale.order', 'order_confirm', sale_order_id, {}) - diff --git a/openerpcommand/benchmarks.py b/openerpcommand/benchmarks.py deleted file mode 100644 index 401ce077b77..00000000000 --- a/openerpcommand/benchmarks.py +++ /dev/null @@ -1,166 +0,0 @@ -""" -Define a base class for client-side benchmarking. -""" -import hashlib -import multiprocessing -import sys -import time - -from .client import Client - -class Bench(Client): - """ - Base class for concurrent benchmarks. The measure_once() method must be - overriden. - - Each sub-benchmark will be run in its own process then a report is done - with all the results (shared with the main process using a - `multiprocessing.Array`). - """ - - def __init__(self, subparsers=None): - super(Bench, self).__init__(subparsers) - self.parser.add_argument('-n', '--samples', metavar='INT', - default=100, help='number of measurements to take') - # TODO if -n <int>s is given (instead of -n <int>), run the - # benchmark for <int> seconds and return the number of iterations. - self.parser.add_argument('-o', '--output', metavar='PATH', - required=True, help='path to save the generated report') - self.parser.add_argument('--append', action='store_true', - default=False, help='append the report to an existing file') - self.parser.add_argument('-j', '--jobs', metavar='JOBS', - default=1, help='number of concurrent workers') - self.parser.add_argument('--seed', metavar='SEED', - default=0, help='a value to ensure different runs can create unique data') - self.worker = -1 - - def work(self, iarr=None): - if iarr: - # If an array is given, it means we are a worker process... - self.work_slave(iarr) - else: - # ... else we are the main process and we will spawn workers, - # passing them an array. - self.work_master() - - def work_master(self): - N = int(self.args.samples) - self.arrs = [(i, multiprocessing.Array('f', range(N))) - for i in xrange(int(self.args.jobs))] - ps = [multiprocessing.Process(target=self.run, args=(arr,)) - for arr in self.arrs] - [p.start() for p in ps] - [p.join() for p in ps] - - self.report_html() - - def work_slave(self, iarr): - j, arr = iarr - self.worker = j - N = int(self.args.samples) - total_t0 = time.time() - for i in xrange(N): - t0 = time.time() - self.measure_once(i) - t1 = time.time() - arr[i] = t1 - t0 - print >> sys.stdout, '\r%s' % ('|' * (i * 60 / N)), - print >> sys.stdout, '%s %s%%' % \ - (' ' * (60 - (i * 60 / N)), int(float(i+1)/N*100)), - sys.stdout.flush() - total_t1 = time.time() - print '\nDone in %ss.' % (total_t1 - total_t0) - - def report_html(self): - series = [] - for arr in self.arrs: - serie = """{ - data: %s, - points: { show: true } - }""" % ([[x, i] for i, x in enumerate(arr)],) - series.append(serie) - chart_id = hashlib.md5(" ".join(sys.argv)).hexdigest() - HEADER = """<!doctype html> -<title>Benchmarks</title> -<meta charset=utf-8> -<script type="text/javascript" src="js/jquery.min.js"></script> -<script type="text/javascript" src="js/jquery.flot.js"></script> -""" - - CONTENT = """<h1>%s</h1> -%s -<div id='chart_%s' style='width:400px;height:300px;'>...</div> -<script type="text/javascript"> -$.plot($("#chart_%s"), [%s], - {yaxis: { ticks: false }}); -</script>""" % (self.bench_name, ' '.join(sys.argv), chart_id, chart_id, - ','.join(series)) - if self.args.append: - with open(self.args.output, 'a') as f: - f.write(CONTENT,) - else: - with open(self.args.output, 'w') as f: - f.write(HEADER + CONTENT,) - - def measure_once(self, i): - """ - The `measure_once` method is called --jobs times. A `i` argument is - supplied to allow to create unique values for each execution (e.g. to - supply fresh identifiers to a `create` method. - """ - pass - -class BenchRead(Bench): - """Read a record repeatedly.""" - - command_name = 'bench-read' - bench_name = 'res.users.read(1)' - - def __init__(self, subparsers=None): - super(BenchRead, self).__init__(subparsers) - self.parser.add_argument('-m', '--model', metavar='MODEL', - required=True, help='the model') - self.parser.add_argument('-i', '--id', metavar='RECORDID', - required=True, help='the record id') - - def measure_once(self, i): - self.execute(self.args.model, 'read', [self.args.id], []) - -class BenchFieldsViewGet(Bench): - """Read a record's fields and view architecture repeatedly.""" - - command_name = 'bench-view' - bench_name = 'res.users.fields_view_get(1)' - - def __init__(self, subparsers=None): - super(BenchFieldsViewGet, self).__init__(subparsers) - self.parser.add_argument('-m', '--model', metavar='MODEL', - required=True, help='the model') - self.parser.add_argument('-i', '--id', metavar='RECORDID', - required=True, help='the record id') - - def measure_once(self, i): - self.execute(self.args.model, 'fields_view_get', self.args.id) - -class BenchDummy(Bench): - """Dummy (call test.limits.model.consume_nothing()).""" - - command_name = 'bench-dummy' - bench_name = 'test.limits.model.consume_nothing()' - - def __init__(self, subparsers=None): - super(BenchDummy, self).__init__(subparsers) - self.parser.add_argument('-a', '--args', metavar='ARGS', - default='', help='some arguments to serialize') - - def measure_once(self, i): - self.execute('test.limits.model', 'consume_nothing') - -class BenchLogin(Bench): - """Login (update res_users.date).""" - - command_name = 'bench-login' - bench_name = 'res.users.login(1)' - - def measure_once(self, i): - self.common_proxy.login(self.database, self.user, self.password) diff --git a/openerpcommand/call.py b/openerpcommand/call.py deleted file mode 100644 index b4f9e95075a..00000000000 --- a/openerpcommand/call.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -Call an arbitrary model's method. -""" -import ast -import os -import pprint -import sys -import time -import xmlrpclib - -import client - -class Call(client.Client): - """\ - Call an arbitrary model's method. - - Example: - > oe call res.users.read '[1, 3]' '[]' -u 1 -p admin - """ - # TODO The above docstring is completely borked in the - # --help message. - - command_name = 'call' - - def __init__(self, subparsers=None): - super(Call, self).__init__(subparsers) - self.parser.add_argument('call', metavar='MODEL.METHOD', - help='the model and the method to call, using the ' - '<model>.<method> format.') - self.parser.add_argument('args', metavar='ARGUMENT', - nargs='+', - help='the argument for the method call, must be ' - '`ast.literal_eval` compatible. Can be repeated.') - - def work(self): - try: - model, method = self.args.call.rsplit('.', 1) - except: - print "Invalid syntax `%s` must have the form <model>.<method>." - sys.exit(1) - args = tuple(map(ast.literal_eval, self.args.args)) if self.args.args else () - x = self.execute(model, method, *args) - pprint.pprint(x, indent=4) - diff --git a/openerpcommand/client.py b/openerpcommand/client.py deleted file mode 100644 index 87586b68ddf..00000000000 --- a/openerpcommand/client.py +++ /dev/null @@ -1,137 +0,0 @@ -""" -Define a few common arguments for client-side command-line tools. -""" -import os -import sys -import time -import xmlrpclib - -import common - -class Client(common.Command): - """ - Base class for XML-RPC command-line clients. It must be inherited and the - work() method overriden. - """ - - def __init__(self, subparsers=None): - super(Client, self).__init__(subparsers) - required_or_default = common.required_or_default - self.parser.add_argument('-H', '--host', metavar='HOST', - **required_or_default('HOST', 'the server host')) - self.parser.add_argument('-P', '--port', metavar='PORT', - **required_or_default('PORT', 'the server port')) - - def execute(self, *args): - return self.object_proxy.execute(self.database, self.uid, self.password, *args) - - def initialize(self): - self.host = self.args.host - self.port = int(self.args.port) - self.database = self.args.database - self.user = self.args.user - self.password = self.args.password - - self.url = 'http://%s:%d/xmlrpc/' % (self.host, self.port) - self.common_proxy = xmlrpclib.ServerProxy(self.url + 'common') - self.object_proxy = xmlrpclib.ServerProxy(self.url + 'object') - - try: - self.uid = int(self.user) - except ValueError, e: - self.uid = self.common_proxy.login(self.database, self.user, self.password) - - def run(self, *args): - self.initialize() - self.work(*args) - - def work(self, *args): - pass - -class Open(Client): - """Get the web client's URL to view a specific model.""" - - command_name = 'open' - - def __init__(self, subparsers=None): - super(Open, self).__init__(subparsers) - self.parser.add_argument('-m', '--model', metavar='MODEL', - required=True, help='the view type') - self.parser.add_argument('-v', '--view-mode', metavar='VIEWMODE', - default='tree', help='the view mode') - - def work(self): - ids = self.execute('ir.actions.act_window', 'search', [ - ('res_model', '=', self.args.model), - ('view_mode', 'like', self.args.view_mode), - ]) - xs = self.execute('ir.actions.act_window', 'read', ids, []) - for x in xs: - print x['id'], x['name'] - d = {} - d['host'] = self.host - d['port'] = self.port - d['action_id'] = x['id'] - print " http://%(host)s:%(port)s/web/webclient/home#action_id=%(action_id)s" % d - -class Show(Client): - """Display a record.""" - - command_name = 'show' - - def __init__(self, subparsers=None): - super(Show, self).__init__(subparsers) - self.parser.add_argument('-m', '--model', metavar='MODEL', - required=True, help='the model') - self.parser.add_argument('-i', '--id', metavar='RECORDID', - required=True, help='the record id') - - def work(self): - xs = self.execute(self.args.model, 'read', [self.args.id], []) - if xs: - x = xs[0] - print x['name'] - else: - print "Record not found." - -class ConsumeNothing(Client): - """Call test.limits.model.consume_nothing().""" - - command_name = 'consume-nothing' - - def work(self): - xs = self.execute('test.limits.model', 'consume_nothing') - -class ConsumeMemory(Client): - """Call test.limits.model.consume_memory().""" - - command_name = 'consume-memory' - - def __init__(self, subparsers=None): - super(ConsumeMemory, self).__init__(subparsers) - self.parser.add_argument('--size', metavar='SIZE', - required=True, help='size of the list to allocate') - - def work(self): - xs = self.execute('test.limits.model', 'consume_memory', int(self.args.size)) - -class LeakMemory(ConsumeMemory): - """Call test.limits.model.leak_memory().""" - - command_name = 'leak-memory' - - def work(self): - xs = self.execute('test.limits.model', 'leak_memory', int(self.args.size)) - -class ConsumeCPU(Client): - """Call test.limits.model.consume_cpu_time().""" - - command_name = 'consume-cpu' - - def __init__(self, subparsers=None): - super(ConsumeCPU, self).__init__(subparsers) - self.parser.add_argument('--seconds', metavar='INT', - required=True, help='how much CPU time to consume') - - def work(self): - xs = self.execute('test.limits.model', 'consume_cpu_time', int(self.args.seconds)) diff --git a/openerpcommand/common.py b/openerpcommand/common.py deleted file mode 100644 index 7572bb4efa6..00000000000 --- a/openerpcommand/common.py +++ /dev/null @@ -1,108 +0,0 @@ -""" -Define a few common arguments for server-side command-line tools. -""" -import argparse -import os -try: - from setproctitle import setproctitle -except ImportError: - setproctitle = lambda x: None -import sys - -def add_addons_argument(parser): - """ - Add a common --addons argument to a parser. - """ - parser.add_argument('--addons', metavar='ADDONS', - **required_or_default('ADDONS', - 'colon-separated list of paths to addons')) -def set_addons(args): - """ - Turn args.addons into a list instead of a column-separated strings. - Set openerp.toools.config accordingly. - """ - import openerp.tools.config - config = openerp.tools.config - - assert hasattr(args, 'addons') - if args.addons: - args.addons = args.addons.split(':') - else: - args.addons = [] - - config['addons_path'] = ','.join(args.addons) - -def get_addons_from_paths(paths, exclude): - """ - Build a list of available modules from a list of addons paths. - """ - exclude = exclude or [] - module_names = [] - for p in paths: - if os.path.exists(p): - names = [n for n in os.listdir(p) if os.path.isfile(os.path.join(p, n, '__openerp__.py')) and not n.startswith('.') and n not in exclude] - names = filter(lambda a: os.path.isdir(os.path.join(p, a)), names) - names = filter(lambda a: os.path.exists(os.path.join(p, a, '__openerp__.py')), names) - module_names.extend(names) - else: - print "The addons path `%s` doesn't exist." % p - sys.exit(1) - return module_names - -def required_or_default(name, h): - """ - Helper to define `argparse` arguments. If the name is the environment, - the argument is optional and draw its value from the environment if not - supplied on the command-line. If it is not in the environment, make it - a mandatory argument. - """ - if os.environ.get('OPENERP_' + name.upper()): - d = {'default': os.environ['OPENERP_' + name.upper()]} - else: - d = {'required': True} - d['help'] = h + '. The environment variable OPENERP_' + \ - name.upper() + ' can be used instead.' - return d - -class Command(object): - """ - Base class to create command-line tools. It must be inherited and the - run() method overriden. - """ - - command_name = 'stand-alone' - - def __init__(self, subparsers=None): - if subparsers: - self.parser = parser = subparsers.add_parser(self.command_name, - description=self.__class__.__doc__) - else: - self.parser = parser = argparse.ArgumentParser( - description=self.__class__.__doc__) - - parser.add_argument('-d', '--database', metavar='DATABASE', - **required_or_default('DATABASE', 'the database to connect to')) - parser.add_argument('-u', '--user', metavar='USER', - **required_or_default('USER', 'the user login or ID. When using ' - 'RPC, providing an ID avoid the login() step')) - parser.add_argument('-p', '--password', metavar='PASSWORD', - **required_or_default('PASSWORD', 'the user password')) # TODO read it from the command line or from file. - - parser.set_defaults(run=self.run_with_args) - - def run_with_args(self, args): - self.args = args - self.run() - - def run(self): - print 'Stub Command.run().' - - @classmethod - def stand_alone(cls): - """ - A single Command object is a complete command-line program. See - `openerp-command/stand-alone` for an example. - """ - command = cls() - args = command.parser.parse_args() - args.run(args) diff --git a/openerpcommand/conf.py b/openerpcommand/conf.py deleted file mode 100644 index 98237ea5ad8..00000000000 --- a/openerpcommand/conf.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -Display the currently used configuration. The configuration for any -sub-command is normally given by options. But some options can be specified -using environment variables. This sub-command shows those variables. -A `set` sub-command should be provided when the configuration is in a real -configuration file instead of environment variables. -""" -import os -import sys -import textwrap - -def run(args): - for x in ('database', 'addons', 'host', 'port'): - x_ = ('openerp_' + x).upper() - if x_ in os.environ: - print '%s: %s' % (x, os.environ[x_]) - else: - print '%s: <not set>' % (x, ) - os.environ['OPENERP_DATABASE'] = 'yeah' - -def add_parser(subparsers): - parser = subparsers.add_parser('conf', - description='Display the currently used configuration.') - - parser.set_defaults(run=run) diff --git a/openerpcommand/cron.py b/openerpcommand/cron.py deleted file mode 100644 index abfe1272b17..00000000000 --- a/openerpcommand/cron.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -Run an OpenERP cron process. -""" - -import os - -import common - -def run(args): - import openerp - import openerp.cli.server - import openerp.tools.config - import openerp.service.cron - config = openerp.tools.config - - os.environ["TZ"] = "UTC" - common.set_addons(args) - args.database = args.database or [] - - config['log_handler'] = [':WARNING', 'openerp.addons.base.ir.ir_cron:DEBUG'] - - openerp.multi_process = True - common.setproctitle('openerp-cron [%s]' % ', '.join(args.database)) - - openerp.cli.server.check_root_user() - openerp.netsvc.init_logger() - #openerp.cli.server.report_configuration() - openerp.cli.server.setup_signal_handlers(openerp.cli.server.signal_handler) - import openerp.addons.base - if args.database: - for db in args.database: - openerp.cli.server.preload_registry(db) - openerp.service.cron.start_service() - openerp.cli.server.quit_on_signals() - else: - print "No database given." - - -def add_parser(subparsers): - parser = subparsers.add_parser('cron', - description='Run an OpenERP cron process.') - common.add_addons_argument(parser) - parser.add_argument('--database', action='append', - help='Database for which cron jobs are processed (can be repeated)') - - parser.set_defaults(run=run) diff --git a/openerpcommand/drop.py b/openerpcommand/drop.py deleted file mode 100644 index b64442716de..00000000000 --- a/openerpcommand/drop.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -Drop a database. -""" - -import common - -# TODO turn template1 in a parameter -# This should be exposed from openerp (currently in -# openerp/service/web_services.py). -def drop_database(database_name): - import openerp - openerp.netsvc.init_logger() - db = openerp.sql_db.db_connect('template1') - cr = db.cursor() - cr.autocommit(True) # avoid transaction block - try: - # TODO option for doing this. - # Try to terminate all other connections that might prevent - # dropping the database - - # PostgreSQL 9.2 renamed pg_stat_activity.procpid to pid: - # http://www.postgresql.org/docs/9.2/static/release-9-2.html#AEN110389 - pid_col = 'pid' if cr._cnx.server_version >= 90200 else 'procpid' - try: - cr.execute("""SELECT pg_terminate_backend(%(pid_col)s) - FROM pg_stat_activity - WHERE datname = %%s AND - %(pid_col)s != pg_backend_pid()""" % {'pid_col': pid_col}, - (database_name,)) - except Exception: - pass - - try: - cr.execute('DROP DATABASE "%s"' % database_name, log_exceptions=False) - except Exception, e: - print "Can't drop %s" % (database_name,) - finally: - cr.close() - -def run(args): - assert args.database - drop_database(args.database) - -def add_parser(subparsers): - parser = subparsers.add_parser('drop', - description='Drop a database.') - parser.add_argument('-d', '--database', metavar='DATABASE', - **common.required_or_default('DATABASE', 'the database to create')) - - parser.set_defaults(run=run) diff --git a/openerpcommand/grunt_tests.py b/openerpcommand/grunt_tests.py deleted file mode 100644 index db2513f2bc0..00000000000 --- a/openerpcommand/grunt_tests.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -Search for Gruntfile.js files in all the addons and launch them using the 'grunt test' command. -""" - -import common -import fnmatch -import os -import re -import sys -import subprocess - -def grunt_tester(directories, log = sys.stdout): - result = 0 - - matches = [] - for direc in directories: - for root, dirnames, filenames in os.walk(direc): - for filename in fnmatch.filter(filenames, 'Gruntfile.js'): - full = os.path.join(root, filename) - if re.match(r"(^.*?/node_modules/.*$)|(^.*?/lib/.*$)", full): - continue - matches.append(full) - - for file_ in matches: - folder = os.path.dirname(file_) - p = subprocess.Popen(['npm', 'install'], cwd=folder) - if p.wait() != 0: - raise Exception("Failed to install dependencies for Gruntfile located in folder %s" % folder) - - p = subprocess.Popen(['grunt', 'test', '--no-color'], cwd=folder, stdout=log, stderr=log) - if p.wait() != 0: - result = 1 - - return result - -def run(args): - if args.addons: - args.addons = args.addons.split(':') - else: - args.addons = [] - result = grunt_tester(args.addons) - if result != 0: - sys.exit(result) - -def add_parser(subparsers): - parser = subparsers.add_parser('grunt-tests', - description='Run the tests contained in Gruntfile.js files.') - common.add_addons_argument(parser) - - parser.set_defaults(run=run) diff --git a/openerpcommand/initialize.py b/openerpcommand/initialize.py deleted file mode 100644 index cf4e54bfb82..00000000000 --- a/openerpcommand/initialize.py +++ /dev/null @@ -1,121 +0,0 @@ -""" -Install OpenERP on a new (by default) database. -""" -import contextlib -import errno -import os -import sys -import time - -import common - -# From http://code.activestate.com/recipes/576572/ -@contextlib.contextmanager -def lock_file(path, wait_delay=.1, max_try=600): - attempt = 0 - while True: - attempt += 1 - if attempt > max_try: - raise IOError("Could not lock file %s." % path) - try: - fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR) - except OSError, e: - if e.errno != errno.EEXIST: - raise - time.sleep(wait_delay) - continue - else: - break - try: - yield fd - finally: - os.close(fd) - os.unlink(path) - -def run(args): - assert args.database - assert not (args.module and args.all_modules) - - import openerp - - config = openerp.tools.config - config['db_name'] = args.database - - if args.tests: - config['log_handler'] = [':INFO'] - config['test_enable'] = True - config['without_demo'] = False - if args.port: - config['xmlrpc_port'] = int(args.port) - else: - config['log_handler'] = [':CRITICAL'] - config['test_enable'] = False - config['without_demo'] = True - - if args.addons: - args.addons = args.addons.split(':') - else: - args.addons = [] - config['addons_path'] = ','.join(args.addons) - - if args.all_modules: - module_names = common.get_addons_from_paths(args.addons, args.exclude) - elif args.module: - module_names = args.module - else: - module_names = ['base'] - config['init'] = dict.fromkeys(module_names, 1) - - if args.coverage: - import coverage - # Without the `include` kwarg, coverage generates 'memory:0xXXXXX' - # filenames (which do not exist) and cause it to crash. No idea why. - cov = coverage.coverage(branch=True, include='*.py') - cov.start() - openerp.netsvc.init_logger() - - if not args.no_create: - with lock_file('/tmp/global_openerp_create_database.lock'): - openerp.service.db._create_empty_database(args.database) - - config['workers'] = False - - rc = openerp.service.server.start(preload=[args.database], stop=True) - - if args.coverage: - cov.stop() - cov.html_report(directory='coverage') - # If we wanted the report on stdout: - # cov.report() - - sys.exit(rc) - -def add_parser(subparsers): - parser = subparsers.add_parser('initialize', - description='Create and initialize a new OpenERP database.') - parser.add_argument('-d', '--database', metavar='DATABASE', - **common.required_or_default('DATABASE', 'the database to create')) - common.add_addons_argument(parser) - parser.add_argument('-P', '--port', metavar='PORT', - **common.required_or_default('PORT', 'the server port')) - parser.add_argument('--module', metavar='MODULE', action='append', - help='specify a module to install' - ' (this option can be repeated)') - parser.add_argument('--all-modules', action='store_true', - help='install all visible modules (not compatible with --module)') - parser.add_argument('--no-create', action='store_true', - help='do not create the database, only initialize it') - parser.add_argument('--exclude', metavar='MODULE', action='append', - help='exclude a module from installation' - ' (this option can be repeated)') - parser.add_argument('--tests', action='store_true', - help='run the tests as modules are installed' - ' (use the `run-tests` command to choose specific' - ' tests to run against an existing database).' - ' Demo data are installed.') - parser.add_argument('--coverage', action='store_true', - help='report code coverage (particularly useful with --tests).' - ' The report is generated in a coverage directory and you can' - ' then point your browser to coverage/index.html.') - - parser.set_defaults(run=run) diff --git a/openerpcommand/main.py b/openerpcommand/main.py deleted file mode 100644 index f5a1b03f774..00000000000 --- a/openerpcommand/main.py +++ /dev/null @@ -1,7 +0,0 @@ -import openerpcommand - -def run(): - """ Main entry point for the openerp-command tool.""" - parser = openerpcommand.main_parser() - args = parser.parse_args() - args.run(args) diff --git a/openerpcommand/model.py b/openerpcommand/model.py deleted file mode 100644 index ccd3ae78718..00000000000 --- a/openerpcommand/model.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -Display information about a given model. -""" -import os -import sys -import textwrap - -def run(args): - assert args.database - assert args.model - import openerp - openerp.tools.config['log_level'] = 100 - openerp.netsvc.init_logger() - registry = openerp.modules.registry.RegistryManager.get( - args.database, update_module=False) - model = registry[args.model] - longest_k = 1 - longest_string = 1 - columns = model._columns - - if args.field and args.field not in columns: - print "No such field." - sys.exit(1) - - if args.field: - columns = { args.field: columns[args.field] } - else: - print "Fields (model `%s`, database `%s`):" % (args.model, args.database) - - for k, v in columns.items(): - longest_k = len(k) if longest_k < len(k) else longest_k - longest_string = len(v.string) \ - if longest_string < len(v.string) else longest_string - for k, v in sorted(columns.items()): - attr = [] - if v.required: - attr.append("Required") - if v.readonly: - attr.append("Read-only") - attr = '/'.join(attr) - attr = '(' + attr + ')' if attr else attr - if args.verbose: - print v.string, '-- ' + k + ', ' + v._type, attr - else: - print k.ljust(longest_k + 2), v._type, attr - if args.verbose and v.help: - print textwrap.fill(v.help, initial_indent=' ', subsequent_indent=' ') - -def add_parser(subparsers): - parser = subparsers.add_parser('model', - description='Display information about a given model for an existing database.') - parser.add_argument('-d', '--database', metavar='DATABASE', required=True, - help='the database to connect to') - parser.add_argument('-m', '--model', metavar='MODEL', required=True, - help='the model for which information should be displayed') - parser.add_argument('-v', '--verbose', action='store_true', - help='display more information') - parser.add_argument('-f', '--field', metavar='FIELD', - help='display information only for this particular field') - - parser.set_defaults(run=run) diff --git a/openerpcommand/module.py b/openerpcommand/module.py deleted file mode 100644 index 284c0186785..00000000000 --- a/openerpcommand/module.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -Show module information for a given database or from the file-system. -""" -import os -import sys -import textwrap - -from . import common - -# TODO provide a --rpc flag to use XML-RPC (with a specific username) instead -# of server-side library. -def run(args): - assert args.database - import openerp - - config = openerp.tools.config - config['log_handler'] = [':CRITICAL'] - if args.addons: - args.addons = args.addons.split(':') - else: - args.addons = [] - config['addons_path'] = ','.join(args.addons) - openerp.netsvc.init_logger() - - if args.filesystem: - module_names = common.get_addons_from_paths(args.addons, []) - print "Modules (addons path %s):" % (', '.join(args.addons),) - for x in sorted(module_names): - print x - else: - registry = openerp.modules.registry.RegistryManager.get( - args.database, update_module=False) - - xs = [] - ir_module_module = registry.get('ir.module.module') - with registry.cursor() as cr: - ids = ir_module_module.search(cr, openerp.SUPERUSER_ID, [], {}) - xs = ir_module_module.read(cr, openerp.SUPERUSER_ID, ids, [], {}) - - if xs: - print "Modules (database `%s`):" % (args.database,) - for x in xs: - if args.short: - print '%3d %s' % (x['id'], x['name']) - else: - print '%3d %s %s' % (x['id'], x['name'], {'installed': '(installed)'}.get(x['state'], '')) - else: - print "No module found (database `%s`)." % (args.database,) - -def add_parser(subparsers): - parser = subparsers.add_parser('module', - description='Display modules known from a given database or on file-system.') - parser.add_argument('-d', '--database', metavar='DATABASE', - **common.required_or_default('DATABASE', 'the database to modify')) - common.add_addons_argument(parser) - parser.add_argument('-m', '--module', metavar='MODULE', required=False, - help='the module for which information should be shown') - parser.add_argument('-v', '--verbose', action='store_true', - help='display more information') - parser.add_argument('--short', action='store_true', - help='display less information') - parser.add_argument('-f', '--filesystem', action='store_true', - help='display module in the addons path, not in db') - - parser.set_defaults(run=run) diff --git a/openerpcommand/oe-bash-completion b/openerpcommand/oe-bash-completion deleted file mode 100644 index 57a4391d803..00000000000 --- a/openerpcommand/oe-bash-completion +++ /dev/null @@ -1,89 +0,0 @@ -_oe() -{ - local cur prev opts - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - - cmd="${COMP_WORDS[0]}" - subcmd="" - if [[ ${COMP_CWORD} > 0 ]] ; then - subcmd="${COMP_WORDS[1]}" - fi - - # oe - - opts="initialize model read run-tests scaffold update \ - call open show consume-nothing consume-memory leak-memory \ - consume-cpu bench-read bench-fields-view-get bench-dummy bench-login \ - bench-sale-mrp --help" - - if [[ ${prev} == oe && ${cur} != -* ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # oe call - - opts="--database --user --password --host --port --help" - - if [[ ${subcmd} == call ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # oe initialize - - opts="--database --addons --all-modules --exclude --no-create --help" - - if [[ ${subcmd} == initialize ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # oe model - - opts="--database --model --field --verbose --help" - - if [[ ${subcmd} == model ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # oe read - - opts="--database --model --id --field --verbose --short --help" - - if [[ ${subcmd} == read ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # oe run-tests - - opts="--database --addons --module --dry-run --help" - - if [[ ${subcmd} == run-tests ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # oe scaffold - - opts="--help" - - if [[ ${subcmd} == scaffold ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi - - # fallback for unimplemented completion - - opts="--help" - - if [[ true ]] ; then - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - fi -} -complete -F _oe oe diff --git a/openerpcommand/read.py b/openerpcommand/read.py deleted file mode 100644 index 61c05117875..00000000000 --- a/openerpcommand/read.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -Read a record. -""" -import os -import sys -import textwrap - -import common - -# TODO provide a --rpc flag to use XML-RPC (with a specific username) instead -# of server-side library. -def run(args): - assert args.database - assert args.model - import openerp - config = openerp.tools.config - config['log_handler'] = [':CRITICAL'] - common.set_addons(args) - openerp.netsvc.init_logger() - registry = openerp.modules.registry.RegistryManager.get( - args.database, update_module=False) - model = registry[args.model] - field_names = [args.field] if args.field else [] - if args.short: - # ignore --field - field_names = ['name'] - with registry.cursor() as cr: - xs = model.read(cr, 1, args.id, field_names, {}) - - if xs: - print "Records (model `%s`, database `%s`):" % (args.model, args.database) - x = xs[0] - if args.short: - print str(x['id']) + '.', x['name'] - else: - longest_k = 1 - for k, v in x.items(): - longest_k = len(k) if longest_k < len(k) else longest_k - for k, v in sorted(x.items()): - print (k + ':').ljust(longest_k + 2), v - else: - print "Record not found." - -def add_parser(subparsers): - parser = subparsers.add_parser('read', - description='Display a record.') - parser.add_argument('-d', '--database', metavar='DATABASE', - **common.required_or_default('DATABASE', 'the database to connect to')) - common.add_addons_argument(parser) - parser.add_argument('-m', '--model', metavar='MODEL', required=True, - help='the model for which a record should be read') - parser.add_argument('-i', '--id', metavar='RECORDID', required=True, - help='the record id') - parser.add_argument('-v', '--verbose', action='store_true', - help='display more information') - parser.add_argument('--short', action='store_true', - help='display less information') - parser.add_argument('-f', '--field', metavar='FIELD', - help='display information only for this particular field') - - parser.set_defaults(run=run) diff --git a/openerpcommand/scaffold.py b/openerpcommand/scaffold.py deleted file mode 100644 index 4713f739306..00000000000 --- a/openerpcommand/scaffold.py +++ /dev/null @@ -1,131 +0,0 @@ -""" -Generate an OpenERP module skeleton. -""" - -import functools -import keyword -import os -import re -import sys - -import jinja2 - -# FIXME: add logging -def run(args): - env = jinja2.Environment(loader=jinja2.PackageLoader( - 'openerpcommand', 'templates')) - env.filters['snake'] = snake - args.dependency = 'web' if args.controller else 'base' - - module_name = snake(args.module) - module = functools.partial( - os.path.join, args.modules_dir, module_name) - - if args.controller is True: - args.controller = module_name - - if args.model is True: - args.model = module_name - - if os.path.exists(module()): - message = "The path `%s` already exists." % module() - die(message) - - dump(env, '__openerp__.jinja2', module('__openerp__.py'), config=args) - dump(env, '__init__.jinja2', module('__init__.py'), modules=[ - args.controller and 'controllers', - args.model and 'models' - ]) - dump(env, 'ir.model.access.jinja2', module('security', 'ir.model.access.csv'), config=args) - - if args.controller: - controller_module = snake(args.controller) - dump(env, '__init__.jinja2', module('controllers', '__init__.py'), modules=[controller_module]) - dump(env, 'controllers.jinja2', - module('controllers', '%s.py' % controller_module), - config=args) - - if args.model: - model_module = snake(args.model) - dump(env, '__init__.jinja2', module('models', '__init__.py'), modules=[model_module]) - dump(env, 'models.jinja2', module('models', '%s.py' % model_module), config=args) - -def add_parser(subparsers): - parser = subparsers.add_parser('scaffold', - description='Generate an OpenERP module skeleton.') - parser.add_argument('module', metavar='MODULE', - help='the name of the generated module') - parser.add_argument('modules_dir', metavar='DIRECTORY', type=directory, - help="Modules directory in which the new module should be generated") - - controller = parser.add_mutually_exclusive_group() - controller.add_argument('--controller', type=identifier, - help="The name of the controller to generate") - controller.add_argument('--no-controller', dest='controller', - action='store_const', const=None, help="Do not generate a controller") - - model = parser.add_mutually_exclusive_group() - model.add_argument('--model', type=identifier, - help="The name of the model to generate") - model.add_argument('--no-model', dest='model', - action='store_const', const=None, help="Do not generate a model") - - mod = parser.add_argument_group("Module information", - "these are added to the module metadata and displayed on e.g. " - "apps.openerp.com. For company-backed modules, the company " - "information should be used") - mod.add_argument('--name', dest='author_name', default="", - help="Name of the module author") - mod.add_argument('--website', dest='author_website', default="", - help="Website of the module author") - mod.add_argument('--category', default="Uncategorized", - help="Broad categories to which the module belongs, used for " - "filtering within OpenERP and on apps.openerp.com." - "Defaults to %(default)s") - mod.add_argument('--summary', default="", - help="Short (1 phrase/line) summary of the module's purpose, used as " - "subtitle on modules listing or apps.openerp.com") - - parser.set_defaults(run=run, controller=True, model=True) - -def snake(s): - """ snake cases ``s`` - - :param str s: - :return: str - """ - # insert a space before each uppercase character preceded by a - # non-uppercase letter - s = re.sub(r'(?<=[^A-Z])\B([A-Z])', r' \1', s) - # lowercase everything, split on whitespace and join - return '_'.join(s.lower().split()) - -def dump(env, template, dest, **kwargs): - outdir = os.path.dirname(dest) - if not os.path.exists(outdir): - os.makedirs(outdir) - env.get_template(template).stream(**kwargs).dump(dest) - # add trailing newline which jinja removes - with open(dest, 'a') as f: - f.write('\n') - -def identifier(s): - if keyword.iskeyword(s): - die("%s is a Python keyword and can not be used as a name" % s) - if not re.match('[A-Za-z_][A-Za-z0-9_]*', s): - die("%s is not a valid Python identifier" % s) - return s - -def directory(p): - expanded = os.path.abspath( - os.path.expanduser( - os.path.expandvars(p))) - if not os.path.exists(expanded): - os.makedirs(expanded) - if not os.path.isdir(expanded): - die("%s exists but is not a directory" % p) - return expanded - -def die(message, code=1): - print >>sys.stderr, message - sys.exit(code) diff --git a/openerpcommand/templates/__init__.jinja2 b/openerpcommand/templates/__init__.jinja2 deleted file mode 100644 index 0124cdd2d93..00000000000 --- a/openerpcommand/templates/__init__.jinja2 +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -{% for module in modules if module -%} -import {{ module }} -{% endfor %} diff --git a/openerpcommand/templates/__openerp__.jinja2 b/openerpcommand/templates/__openerp__.jinja2 deleted file mode 100644 index d37a6f33334..00000000000 --- a/openerpcommand/templates/__openerp__.jinja2 +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -{ - 'name': "{{ config.module }}", - # short description, used as subtitles on modules listings - 'summary': "{{ config.summary }}", - # long description of module purpose - 'description': """ -""", - # Who you are - 'author': "{{ config.author_name }}", - 'website': "{{ config.author_website }}", - - # categories can be used to filter modules in modules listing - 'category': '{{ config.category }}', - 'version': '0.1', - - # any module necessary for this one to work correctly - 'depends': ['{{ config.dependency }}'], - 'data': [ - {{- "'security/ir.model.access.csv'" if config.model -}} - ], - 'tests': [ - ], -} diff --git a/openerpcommand/templates/controllers.jinja2 b/openerpcommand/templates/controllers.jinja2 deleted file mode 100644 index 3cc47365d40..00000000000 --- a/openerpcommand/templates/controllers.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- - -from openerp import http -from openerp.addons.web.controllers import main - -class {{ config.controller }}(main.Home): - @http.route('/', auth='none') - def index(self): - return "Hello, world!" diff --git a/openerpcommand/templates/ir.model.access.jinja2 b/openerpcommand/templates/ir.model.access.jinja2 deleted file mode 100644 index e5e2fb35fe7..00000000000 --- a/openerpcommand/templates/ir.model.access.jinja2 +++ /dev/null @@ -1,6 +0,0 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -{% if config.model -%} -access_{{ config.module|snake }}_{{ config.model|snake }},{{- '' -}} -access_{{ config.module|snake }}_{{ config.model|snake }},{{- '' -}} -model_{{ config.module|snake }}_{{ config.model|snake }},,1,0,0,0 -{%- endif %} diff --git a/openerpcommand/templates/models.jinja2 b/openerpcommand/templates/models.jinja2 deleted file mode 100644 index 878bf9be4f6..00000000000 --- a/openerpcommand/templates/models.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ -# -*- coding: utf-8 -*- -from openerp.osv import orm, fields - -class {{ config.model }}(orm.Model): - _name = "{{ config.module|snake }}.{{ config.model|snake }}" - - _columns = { - 'name': fields.char(), - } diff --git a/openerpcommand/uninstall.py b/openerpcommand/uninstall.py deleted file mode 100644 index 244b0575e53..00000000000 --- a/openerpcommand/uninstall.py +++ /dev/null @@ -1,63 +0,0 @@ -""" -Install OpenERP on a new (by default) database. -""" -import os -import sys - -import common - -# TODO turn template1 in a parameter -# This should be exposed from openerp (currently in -# openerp/service/web_services.py). -def create_database(database_name): - import openerp - db = openerp.sql_db.db_connect('template1') - cr = db.cursor() # TODO `with db as cr:` - try: - cr.autocommit(True) - cr.execute("""CREATE DATABASE "%s" - ENCODING 'unicode' TEMPLATE "template1" """ \ - % (database_name,)) - finally: - cr.close() - -def run(args): - assert args.database - assert args.module - - import openerp - - config = openerp.tools.config - config['log_handler'] = [':CRITICAL'] - if args.addons: - args.addons = args.addons.split(':') - else: - args.addons = [] - config['addons_path'] = ','.join(args.addons) - openerp.netsvc.init_logger() - - # Install the import hook, to import openerp.addons.<module>. - openerp.modules.module.initialize_sys_path() - - registry = openerp.modules.registry.RegistryManager.get( - args.database, update_module=False) - - ir_module_module = registry.get('ir.module.module') - with registry.cursor() as cr: - ids = ir_module_module.search(cr, openerp.SUPERUSER_ID, [('name', 'in', args.module), ('state', '=', 'installed')], {}) - if len(ids) == len(args.module): - ir_module_module.button_immediate_uninstall(cr, openerp.SUPERUSER_ID, ids, {}) - else: - print "At least one module not found (database `%s`)." % (args.database,) - -def add_parser(subparsers): - parser = subparsers.add_parser('uninstall', - description='Uninstall some modules from an OpenERP database.') - parser.add_argument('-d', '--database', metavar='DATABASE', - **common.required_or_default('DATABASE', 'the database to modify')) - common.add_addons_argument(parser) - parser.add_argument('--module', metavar='MODULE', action='append', - help='specify a module to uninstall' - ' (this option can be repeated)') - - parser.set_defaults(run=run) diff --git a/openerpcommand/update.py b/openerpcommand/update.py deleted file mode 100644 index 66a47dc5692..00000000000 --- a/openerpcommand/update.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -Update an existing OpenERP database. -""" - -def run(args): - assert args.database - import openerp - config = openerp.tools.config - config['update']['all'] = 1 - openerp.modules.registry.RegistryManager.get( - args.database, update_module=True) - -def add_parser(subparsers): - parser = subparsers.add_parser('update', - description='Update an existing OpenERP database.') - parser.add_argument('-d', '--database', metavar='DATABASE', required=True, - help='the database to update') - - parser.set_defaults(run=run) diff --git a/openerpcommand/web.py b/openerpcommand/web.py deleted file mode 100644 index 5d9d429244b..00000000000 --- a/openerpcommand/web.py +++ /dev/null @@ -1,93 +0,0 @@ -""" -Run a normal OpenERP HTTP process. -""" - -import logging -import os -import signal - -import common - -_logger = logging.getLogger(__name__) - -def mk_signal_handler(server): - def signal_handler(sig, frame): - """ - Specialized signal handler for the evented process. - """ - print "\n\n\nStopping gevent HTTP server...\n\n\n" - server.stop() - return signal_handler - -def setup_signal_handlers(signal_handler): - SIGNALS = (signal.SIGINT, signal.SIGTERM) - map(lambda sig: signal.signal(sig, signal_handler), SIGNALS) - -def run(args): - # Note that gevent monkey patching must be done before importing the - # `threading` module, see http://stackoverflow.com/questions/8774958/. - if args.gevent: - import gevent - import gevent.monkey - import gevent.wsgi - import psycogreen.gevent - gevent.monkey.patch_all() - psycogreen.gevent.patch_psycopg() - import threading - import openerp - import openerp.cli.server - import openerp.service.wsgi_server - import openerp.tools.config - config = openerp.tools.config - - os.environ["TZ"] = "UTC" - common.set_addons(args) - - openerp.multi_process = True - common.setproctitle('openerp-web') - - openerp.cli.server.check_root_user() - openerp.netsvc.init_logger() - #openerp.cli.server.report_configuration() - - target = openerp.service.wsgi_server.serve - if not args.gevent: - openerp.evented = False - openerp.cli.server.setup_signal_handlers(openerp.cli.server.signal_handler) - # TODO openerp.multi_process with a multi-threaded process probably - # doesn't work very well (e.g. waiting for all threads to complete - # before killing the process is not implemented). - arg = (args.interface, int(args.port), args.threaded) - threading.Thread(target=target, args=arg).start() - openerp.cli.server.quit_on_signals() - else: - openerp.evented = True - - app = openerp.service.wsgi_server.application - server = gevent.wsgi.WSGIServer((args.interface, int(args.port)), app) - setup_signal_handlers(mk_signal_handler(server)) - try: - server.serve_forever() - except KeyboardInterrupt: - try: - server.stop() - gevent.shutdown() - except KeyboardInterrupt: - sys.stderr.write("Forced shutdown.\n") - gevent.shutdown() - -def add_parser(subparsers): - parser = subparsers.add_parser('web', - description='Run a normal OpenERP HTTP process. By default a ' - 'singly-threaded Werkzeug server is used.') - common.add_addons_argument(parser) - parser.add_argument('--interface', default='0.0.0.0', - help='HTTP interface to listen on (default is %(default)s)') - parser.add_argument('--port', metavar='INT', default=8069, - help='HTTP port to listen on (default is %(default)s)') - parser.add_argument('--threaded', action='store_true', - help='Use a multithreaded Werkzeug server (incompatible with --gevent)') - parser.add_argument('--gevent', action='store_true', - help="Use gevent's WSGI server (incompatible with --threaded)") - - parser.set_defaults(run=run) |
