# HG changeset patch # User Sylvain Thénault # Date 1320330510 -3600 # Node ID a48301a44b50e44011e8611f0f6fdf63a901fd2a # Parent bdd555df7a919bc99c37020da6a526659c695190# Parent 10a0f73d834d1c3148369fa1f4d619c6235efa72 backport stable diff -r bdd555df7a91 -r a48301a44b50 cwconfig.py --- a/cwconfig.py Thu Nov 03 11:18:37 2011 +0100 +++ b/cwconfig.py Thu Nov 03 15:28:30 2011 +0100 @@ -22,6 +22,9 @@ Resource mode ------------- +Standard resource mode +``````````````````````````` + A resource *mode* is a predefined set of settings for various resources directories, such as cubes, instances, etc. to ease development with the framework. There are two running modes with *CubicWeb*: @@ -30,7 +33,7 @@ usually requiring root access): - instances are stored in :file:`/etc/cubicweb.d` - - temporary files (such as pid file) in :file:`/var/run/cubicweb` + - temporary files (such as pid file) in :file:`/var/run/cubicweb` where `` is the detected installation prefix ('/usr/local' for instance). @@ -42,6 +45,25 @@ + +.. _CubicwebWithinVirtualEnv: + +Within virtual environment +``````````````````````````` + +If you are not administrator of you machine or if you need to play with some +specific version of |cubicweb| you can use `virtualenv`_ a tool to create +isolated Python environments. Since version 3.9 |cubicweb| is **`virtualenv` +friendly** and won't write any file outside the virtualenv directory. + +- instances are stored in :file:`/etc/cubicweb.d` +- temporary files (such as pid file) in :file:`/var/run/cubicweb` + +.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv + +Custom resource location +```````````````````````````````` + Notice that each resource path may be explicitly set using an environment variable if the default doesn't suit your needs. Here are the default resource directories that are affected according to mode: @@ -49,8 +71,8 @@ * **system**: :: CW_INSTANCES_DIR = /etc/cubicweb.d/ - CW_INSTANCES_DATA_DIR = /var/lib/cubicweb/instances/ - CW_RUNTIME_DIR = /var/run/cubicweb/ + CW_INSTANCES_DATA_DIR = /var/lib/cubicweb/instances/ + CW_RUNTIME_DIR = /var/run/cubicweb/ * **user**: :: @@ -60,10 +82,13 @@ Cubes search path is also affected, see the :ref:`Cube` section. -By default, the mode automatically set to `user` if a :file:`.hg` directory is found -in the cubicweb package, else it's set to `system`. You can force this by setting -the :envvar:`CW_MODE` environment variable to either `user` or `system` so you can -easily: +Setting Cubicweb Mode +````````````````````` + +By default, the mode is set to 'system' for standard installation. The mode is +set to 'user' if `cubicweb is used from a mercurial repository`_. You can force +this by setting the :envvar:`CW_MODE` environment variable to either 'user' or +'system' so you can easily: * use system wide installation but user specific instances and all, without root privileges on the system (`export CW_MODE=user`) @@ -74,7 +99,15 @@ If you've a doubt about the mode you're currently running, check the first line outputed by the :command:`cubicweb-ctl list` command. -Also, if cubicweb is a mercurial checkout located in ``: +.. _`cubicweb is used from a mercurial repository`: CubicwebDevelopmentMod_ + +.. _CubicwebDevelopmentMod: + +Development Mode +````````````````````` +If :file:`.hg` directory is found into the cubicweb package, there are specific resource rules. + +`` is the mercurial checkout of cubicweb: * main cubes directory is `/../cubes`. You can specify another one with :envvar:`CW_INSTANCES_DIR` environment variable or simply diff -r bdd555df7a91 -r a48301a44b50 rset.py --- a/rset.py Thu Nov 03 11:18:37 2011 +0100 +++ b/rset.py Thu Nov 03 15:28:30 2011 +0100 @@ -351,7 +351,8 @@ if offset <= entity.cw_row < stop: entity.cw_row = entity.cw_row - offset else: - self.req.drop_entity_cache(entity.eid) + entity.cw_rset = entity.as_rset() + entity.cw_row = entity.cw_col = 0 else: rset = self.copy(rows, descr) if not offset: diff -r bdd555df7a91 -r a48301a44b50 server/migractions.py --- a/server/migractions.py Thu Nov 03 11:18:37 2011 +0100 +++ b/server/migractions.py Thu Nov 03 15:28:30 2011 +0100 @@ -392,7 +392,7 @@ if cube is None: directory = osp.join(CW_SOFTWARE_ROOT, 'schemas') else: - directory = self.config.cube_dir(cube) + directory = osp.join(self.config.cube_dir(cube), 'schema') sql_scripts = glob(osp.join(directory, '*.%s.sql' % driver)) for fpath in sql_scripts: print '-> installing', fpath diff -r bdd555df7a91 -r a48301a44b50 test/unittest_rset.py --- a/test/unittest_rset.py Thu Nov 03 11:18:37 2011 +0100 +++ b/test/unittest_rset.py Thu Nov 03 15:28:30 2011 +0100 @@ -107,7 +107,7 @@ self.compare_urls(req.build_url('view', _restpath=''), baseurl) - def test_resultset_build(self): + def test_build(self): """test basic build of a ResultSet""" rs = ResultSet([1,2,3], 'CWGroup X', description=['CWGroup', 'CWGroup', 'CWGroup']) self.assertEqual(rs.rowcount, 3) @@ -115,7 +115,7 @@ self.assertEqual(rs.description, ['CWGroup', 'CWGroup', 'CWGroup']) - def test_resultset_limit(self): + def test_limit(self): rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']], 'Any U,L where U is CWUser, U login L', description=[['CWUser', 'String']] * 3) @@ -128,8 +128,30 @@ self.assertEqual(rs.limit(2, offset=2).rows, [[14000, 'nico']]) self.assertEqual(rs.limit(2, offset=3).rows, []) + def test_limit_2(self): + req = self.request() + # drop user from cache for the sake of this test + req.drop_entity_cache(req.user.eid) + rs = req.execute('Any E,U WHERE E is CWEType, E created_by U') + # get entity on row 9. This will fill its created_by relation cache, + # with cwuser on row 9 as well + e1 = rs.get_entity(9, 0) + # get entity on row 10. This will fill its created_by relation cache, + # with cwuser built on row 9 + e2 = rs.get_entity(10, 0) + # limit result set from row 10 + rs.limit(1, 10, inplace=True) + # get back eid + e = rs.get_entity(0, 0) + self.assertTrue(e2 is e) + # rs.limit has properly removed cwuser for request cache, but it's + # still referenced by e/e2 relation cache + u = e.created_by[0] + # now ensure this doesn't trigger IndexError because cwuser.cw_row is 9 + # while now rset has only one row + u.cw_rset[u.cw_row] - def test_resultset_filter(self): + def test_filter(self): rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']], 'Any U,L where U is CWUser, U login L', description=[['CWUser', 'String']] * 3) @@ -142,7 +164,7 @@ self.assertEqual(len(rs2), 2) self.assertEqual([login for _, login in rs2], ['adim', 'syt']) - def test_resultset_transform(self): + def test_transform(self): rs = ResultSet([[12, 'adim'], [13, 'syt'], [14, 'nico']], 'Any U,L where U is CWUser, U login L', description=[['CWUser', 'String']] * 3) @@ -154,7 +176,7 @@ self.assertEqual(len(rs2), 3) self.assertEqual(list(rs2), [['adim'],['syt'],['nico']]) - def test_resultset_sort(self): + def test_sort(self): rs = ResultSet([[12000, 'adim'], [13000, 'syt'], [14000, 'nico']], 'Any U,L where U is CWUser, U login L', description=[['CWUser', 'String']] * 3) @@ -179,7 +201,7 @@ # make sure rs is unchanged self.assertEqual([login for _, login in rs], ['adim', 'syt', 'nico']) - def test_resultset_split(self): + def test_split(self): rs = ResultSet([[12000, 'adim', u'Adim chez les pinguins'], [12000, 'adim', u'Jardiner facile'], [13000, 'syt', u'Le carrelage en 42 leçons'], diff -r bdd555df7a91 -r a48301a44b50 web/data/cubicweb.fckcwconfig-full.js --- a/web/data/cubicweb.fckcwconfig-full.js Thu Nov 03 11:18:37 2011 +0100 +++ b/web/data/cubicweb.fckcwconfig-full.js Thu Nov 03 15:28:30 2011 +0100 @@ -29,6 +29,9 @@ FCKConfig.ContextMenu = ['Generic','Link','Anchor','Image','BulletedList','NumberedList','Table'] ; FCKConfig.LinkUpload = false ; +FCKConfig.LinkBrowser = false ; FCKConfig.ImageUpload = false ; +FCKConfig.ImageBrowser = false ; FCKConfig.FlashUpload = false ; +FCKConfig.FlashBrowser = false ; diff -r bdd555df7a91 -r a48301a44b50 web/data/cubicweb.fckcwconfig.js --- a/web/data/cubicweb.fckcwconfig.js Thu Nov 03 11:18:37 2011 +0100 +++ b/web/data/cubicweb.fckcwconfig.js Thu Nov 03 15:28:30 2011 +0100 @@ -11,5 +11,8 @@ FCKConfig.ContextMenu = ['Generic','Link','Anchor','Image','BulletedList','NumberedList','Table'] ; FCKConfig.LinkUpload = false ; +FCKConfig.LinkBrowser = false ; FCKConfig.ImageUpload = false ; +FCKConfig.ImageBrowser = false ; FCKConfig.FlashUpload = false ; +FCKConfig.FlashBrowser = false ; diff -r bdd555df7a91 -r a48301a44b50 web/views/basecomponents.py --- a/web/views/basecomponents.py Thu Nov 03 11:18:37 2011 +0100 +++ b/web/views/basecomponents.py Thu Nov 03 15:28:30 2011 +0100 @@ -50,25 +50,22 @@ visible = False def call(self, view=None): + req = self._cw if hasattr(view, 'filter_box_context_info'): rset = view.filter_box_context_info()[0] else: rset = self.cw_rset # display multilines query as one line - rql = rset is not None and rset.printable_rql(encoded=False) or self._cw.form.get('rql', '') + rql = rset is not None and rset.printable_rql(encoded=False) or req.form.get('rql', '') rql = rql.replace(u"\n", u" ") - req = self._cw - self.w(u'''
-
-
+ self.w(u'''
-
''' % (not self.cw_propval('visible') and 'hidden' or '', - self._cw.build_url('view'), xml_escape(rql), req._('full text or RQL query'), req.next_tabindex())) - if self._cw.search_state[0] != 'normal': + req.build_url('view'), xml_escape(rql), req._('full text or RQL query'), req.next_tabindex())) + if req.search_state[0] != 'normal': self.w(u'' % ':'.join(req.search_state[1])) - self.w(u'
') + self.w(u'
')