From 3ad685e892257db6368778cdc04ad6cdabcc76e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Wed, 20 Jul 2011 19:04:52 +0200 Subject: [PATCH] Add function to get object base URL --- etc/trytond.conf | 3 ++ trytond/config.py | 1 + trytond/model/model.py | 3 +- trytond/report/report.py | 3 +- trytond/test/__init__.py | 1 + trytond/test/model.py | 9 ++++++ trytond/test/wizard.py | 26 +++++++++++++++ trytond/tests/test_mixins.py | 62 ++++++++++++++++++++++++++++++++++++ trytond/tests/test_tools.py | 14 +++++++- trytond/tests/test_tryton.py | 2 ++ trytond/url.py | 39 +++++++++++++++++++++++ trytond/wizard/wizard.py | 3 +- 12 files changed, 162 insertions(+), 4 deletions(-) create mode 100644 trytond/test/wizard.py create mode 100644 trytond/tests/test_mixins.py create mode 100644 trytond/url.py diff --git a/etc/trytond.conf b/etc/trytond.conf index 894d201565..f99ac12a04 100644 --- a/etc/trytond.conf +++ b/etc/trytond.conf @@ -2,6 +2,9 @@ #this repository contains the full copyright notices and license terms. [options] +# This is the hostname used when generating tryton URI +#hostname = + # Configure the IP address for trytond # If empty, the server will listen on all available interfaces #interface = diff --git a/trytond/config.py b/trytond/config.py index 39e772c0ad..e4c5fe374c 100644 --- a/trytond/config.py +++ b/trytond/config.py @@ -6,6 +6,7 @@ import ConfigParser, os, sys class ConfigManager(object): def __init__(self, fname=None): self.options = { + 'hostname': None, 'interface': '', 'netrpc': True, 'netport': 8070, diff --git a/trytond/model/model.py b/trytond/model/model.py index d9415a832b..ce492fd402 100644 --- a/trytond/model/model.py +++ b/trytond/model/model.py @@ -8,9 +8,10 @@ from trytond.error import WarningErrorMixin from trytond.pool import Pool from trytond.pyson import PYSONEncoder from trytond.transaction import Transaction +from trytond.url import URLMixin -class Model(WarningErrorMixin): +class Model(WarningErrorMixin, URLMixin): """ Define a model in Tryton. """ diff --git a/trytond/report/report.py b/trytond/report/report.py index b3988d4c8c..5aeb02b1a5 100644 --- a/trytond/report/report.py +++ b/trytond/report/report.py @@ -31,6 +31,7 @@ from trytond.config import CONFIG from trytond.backend import DatabaseIntegrityError from trytond.pool import Pool from trytond.transaction import Transaction +from trytond.url import URLMixin PARENTS = { 'table-row': 1, @@ -77,7 +78,7 @@ class TranslateFactory: self.language = language -class Report(object): +class Report(URLMixin): _name = "" def __new__(cls): diff --git a/trytond/test/__init__.py b/trytond/test/__init__.py index 0325085a89..e457e73eb7 100644 --- a/trytond/test/__init__.py +++ b/trytond/test/__init__.py @@ -8,3 +8,4 @@ from import_data import * from export_data import * from trigger import * from access import * +from wizard import * diff --git a/trytond/test/model.py b/trytond/test/model.py index 1aa2a3e05b..24b56babd9 100644 --- a/trytond/test/model.py +++ b/trytond/test/model.py @@ -14,3 +14,12 @@ class Singleton(ModelSingleton, ModelSQL): return 'test' Singleton() + + +class URLObject(ModelSQL): + _name = 'test.urlobject' + + name = fields.Char('Name') + + +URLObject() diff --git a/trytond/test/wizard.py b/trytond/test/wizard.py new file mode 100644 index 0000000000..4c718f15e9 --- /dev/null +++ b/trytond/test/wizard.py @@ -0,0 +1,26 @@ +from trytond.model import ModelView, fields +from trytond.wizard import Wizard + + +class TestWizardInit(ModelView): + _name = 'test.test_wizard.init' + name = fields.Char('Test me') + +TestWizardInit() + + +class TestWizard(Wizard): + _name = 'test.test_wizard' + states = { + 'init': { + 'result': { + 'type': 'form', + 'object': 'test.test_wizard.init', + 'state': [ + ('end', 'Ok', 'tryton-ok', True), + ], + }, + }, + } + +TestWizard() diff --git a/trytond/tests/test_mixins.py b/trytond/tests/test_mixins.py new file mode 100644 index 0000000000..3146726758 --- /dev/null +++ b/trytond/tests/test_mixins.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +#This file is part of Tryton. The COPYRIGHT file at the top level of +#this repository contains the full copyright notices and license terms. + +import unittest +import socket +import urllib + +from trytond.config import CONFIG +from trytond.tests.test_tryton import (POOL, DB_NAME, USER, CONTEXT, + install_module) +from trytond.transaction import Transaction + + +class UrlTestCase(unittest.TestCase): + "Test URL generation" + + def setUp(self): + install_module('test') + self.urlmodel = POOL.get('test.urlobject') + self.urlwizard = POOL.get('test.test_wizard', type='wizard') + self.hostname = socket.getfqdn() + + def testModelURL(self): + "Test model URLs" + with Transaction().start(DB_NAME, USER, CONTEXT): + self.assertEqual(self.urlmodel.get_url(), + 'tryton://%s:%s/%s/model/test.urlobject' % (self.hostname, + CONFIG['netport'], urllib.quote(DB_NAME))) + + server_name = 'michaelscott.paper.test' + CONFIG['hostname'] = server_name + self.assertEqual(self.urlmodel.get_url(), + 'tryton://%s:%s/%s/model/test.urlobject' % (server_name, + CONFIG['netport'], urllib.quote(DB_NAME))) + + def testWizardURL(self): + "Test wizard URLs" + with Transaction().start(DB_NAME, USER, CONTEXT): + CONFIG['hostname'] = None + self.assertEqual(self.urlwizard.get_url(), + 'tryton://%s:%s/%s/wizard/test.test_wizard' % (self.hostname, + CONFIG['netport'], urllib.quote(DB_NAME))) + + server_name = 'michaelscott.paper.test' + CONFIG['hostname'] = server_name + self.assertEqual(self.urlwizard.get_url(), + 'tryton://%s:%s/%s/wizard/test.test_wizard' % (server_name, + CONFIG['netport'], urllib.quote(DB_NAME))) + + +def suite(): + func = unittest.TestLoader().loadTestsFromTestCase + suite = unittest.TestSuite() + for testcase in (UrlTestCase,): + suite.addTests(func(testcase)) + return suite + +if __name__ == '__main__': + suite = suite() + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/trytond/tests/test_tools.py b/trytond/tests/test_tools.py index c6bb78c8be..be748c0c1e 100644 --- a/trytond/tests/test_tools.py +++ b/trytond/tests/test_tools.py @@ -5,8 +5,15 @@ import unittest import datetime +import socket +import urllib + +from trytond.config import CONFIG from trytond.tools import reduce_ids, safe_eval, datetime_strftime, \ reduce_domain +from trytond.tests.test_tryton import (POOL, DB_NAME, USER, CONTEXT, + install_module) +from trytond.transaction import Transaction class ToolsTestCase(unittest.TestCase): @@ -125,8 +132,13 @@ class ToolsTestCase(unittest.TestCase): self.assertEqual(reduce_domain(i), j, '%s -> %s != %s' % (i, reduce_domain(i), j)) + def suite(): - return unittest.TestLoader().loadTestsFromTestCase(ToolsTestCase) + func = unittest.TestLoader().loadTestsFromTestCase + suite = unittest.TestSuite() + for testcase in (ToolsTestCase,): + suite.addTests(func(testcase)) + return suite if __name__ == '__main__': suite = suite() diff --git a/trytond/tests/test_tryton.py b/trytond/tests/test_tryton.py index e7c65a0366..4a4eca4ee7 100644 --- a/trytond/tests/test_tryton.py +++ b/trytond/tests/test_tryton.py @@ -188,6 +188,8 @@ def all_suite(): suite_.addTests(test_sequence.suite()) import trytond.tests.test_access as test_access suite_.addTests(test_access.suite()) + import trytond.tests.test_mixins as test_mixins + suite_.addTests(test_mixins.suite()) return suite_ def modules_suite(): diff --git a/trytond/url.py b/trytond/url.py new file mode 100644 index 0000000000..cd5a1177a8 --- /dev/null +++ b/trytond/url.py @@ -0,0 +1,39 @@ +#This file is part of Tryton. The COPYRIGHT file at the top level of +#this repository contains the full copyright notices and license terms. + +import encodings.idna +import urllib +import socket + +from trytond.config import CONFIG +from trytond.transaction import Transaction + + +class URLMixin(object): + + def get_url(self): + from trytond.model import Model + from trytond.wizard import Wizard + from trytond.report import Report + url_part = {} + + hostname = CONFIG['hostname'] or unicode(socket.getfqdn(), 'utf8') + url_part['hostname'] = '.'.join(encodings.idna.ToASCII(part) for part in + hostname.split('.')) + url_part['port'] = CONFIG['netport'] + + if isinstance(self, Model): + url_part['type'] = 'model' + elif isinstance(self, Wizard): + url_part['type'] = 'wizard' + elif isinstance(self, Report): + url_part['type'] = 'report' + else: + raise NotImplementedError + + url_part['name'] = self._name + url_part['database'] = Transaction().cursor.database_name + + host_part = '%(hostname)s:%(port)s' % url_part + local_part = urllib.quote('%(database)s/%(type)s/%(name)s' % url_part) + return 'tryton://%s/%s' % (host_part, local_part) diff --git a/trytond/wizard/wizard.py b/trytond/wizard/wizard.py index a02ab252e5..320571c638 100644 --- a/trytond/wizard/wizard.py +++ b/trytond/wizard/wizard.py @@ -7,9 +7,10 @@ from xmlrpclib import MAXINT from trytond.pool import Pool from trytond.transaction import Transaction from trytond.error import WarningErrorMixin +from trytond.url import URLMixin -class Wizard(WarningErrorMixin): +class Wizard(WarningErrorMixin, URLMixin): _name = "" states = {}