--- a/.hgtags Wed Feb 11 14:46:26 2009 +0100
+++ b/.hgtags Wed Feb 11 14:46:46 2009 +0100
@@ -14,3 +14,5 @@
a736bae56d4a703a26933fb9875fb9caab216c6b cubicweb-debian-version-3_0_3-1
2e400b8dfc25ae30db602f64601e30e210b3fade cubicweb-version-3_0_4
fc222bc99929d395c1c2235c40d3bb6f247b4ba9 cubicweb-debian-version-3_0_4-1
+7ad527099393ef56f27af313392022bb8ed73082 cubicweb-version-3_0_9
+a8e9e53b245d53838a07aa8c76d1bed352692a9f cubicweb-debian-version-3_0_9-1
--- a/debian/changelog Wed Feb 11 14:46:26 2009 +0100
+++ b/debian/changelog Wed Feb 11 14:46:46 2009 +0100
@@ -1,3 +1,9 @@
+cubicweb (3.0.9-1) unstable; urgency=low
+
+ * new upstream (interim) release
+
+ -- Aurélien Campéas <aurelien.campeas@logilab.fr> Tue, 10 Feb 2009 14:05:12 +0100
+
cubicweb (3.0.4-1) unstable; urgency=low
* new upstream release
--- a/doc/book/en/C012-create-instance.en.txt Wed Feb 11 14:46:26 2009 +0100
+++ b/doc/book/en/C012-create-instance.en.txt Wed Feb 11 14:46:46 2009 +0100
@@ -24,11 +24,11 @@
A cube defines entities, their views, their schemas and workflows
in an independant directory located in ``/path/to/forest/cubicweb/cubes/``
-for a Mercurila installation or in ``/usr/share/cubicweb/cubes`` for
-a debian packages installation.
+for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for
+a debian package installation.
When an instance is created, you list one or more cubes that your instance
-will use. Use a cube means having the entities defined in your cube's schema
+will use. Using a cube means having the entities defined in your cube's schema
available in your instance as well as their views and workflows.
.. note::
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/Z010-beginners.en.txt Wed Feb 11 14:46:46 2009 +0100
@@ -0,0 +1,12 @@
+.. -*- coding: utf-8 -*-
+
+.. _QuickInstall:
+
+===========================================
+Quick Installation of a `CubicWeb` instance
+===========================================
+
+.. include:: C011-installation.en.txt
+.. include:: Z012-create-instance.en.txt
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/book/en/Z012-create-instance.en.txt Wed Feb 11 14:46:46 2009 +0100
@@ -0,0 +1,79 @@
+.. -*- coding: utf-8 -*-
+
+Creation of your first instance
+===============================
+
+What is an instance?
+--------------------
+
+A `CubicWeb` instance is a container that
+refers to cubes and configuration parameters for your web application.
+Each instance is stored as a directory in ``~/etc/cubicweb.d`` which enables
+us to run your application.
+
+What is a cube?
+---------------
+
+Cubes represent data and basic building bricks of your web applications :
+blogs, person, date, addressbook and a lot more.
+
+.. XXX They related to each other by a 'Schema' which is also the PostGres representation.
+
+Each cube defines entities, their views, their schemas and workflows
+in an independant directory located in ``/path/to/forest/cubicweb/cubes/``
+for a Mercurial installation or in ``/usr/share/cubicweb/cubes`` for
+a debian package installation. For example, the 'blog' cube defines the entities
+blogs and blogentries.
+
+When an `CubicWeb` instance is created, you list the cubes that you want to use.
+Using a cube means having the entities defined in your cube's schema
+available in your instance as well as their views and workflows.
+
+
+Creating a basic `CubicWeb` Instance
+------------------------------------
+
+We can create an instance to view our
+application in a web browser. ::
+
+ cubicweb-ctl create blog myblog
+
+.. XXX or ::
+
+.. XXX cubicweb-ctl create forge myforge
+
+
+.. note::
+ The commands used below are more detailled in the section dedicated to
+ :ref:`cubicweb-ctl`.
+
+A series of questions will be prompted to you, the default answer is usually
+sufficient. You can allways modify the parameters later by editing
+configuration files. When a user/psswd is requested to access the database
+please use the login you create at the time you configured the database
+(:ref:`ConfigurationPostgres`).
+
+It is important to distinguish here the user used to access the database and
+the user used to login to the cubicweb application. When a `CubicWeb` application
+starts, it uses the login/psswd for the database to get the schema and handle
+low level transaction. But, when ``cubicweb-ctl create`` asks for
+a manager login/psswd of `CubicWeb`, it refers to an application user
+to administrate your web application.
+The configuration files are stored in *~/etc/cubicweb.d/myblog/*.
+
+To launch the web application, you just type ::
+
+ cubicweb-ctl start myblog
+
+You can see how it looks by
+visiting the URL `http://localhost:8080`.
+To login, please use the cubicweb administrator login/psswd you
+defined when you created the instance.
+
+To shutdown the instance ::
+
+ cubicweb-ctl stop myinstance
+
+.. XXX something like `cubicweb-ctl live-server intra` would be nice
+
+
--- a/doc/book/en/index.txt Wed Feb 11 14:46:26 2009 +0100
+++ b/doc/book/en/index.txt Wed Feb 11 14:46:46 2009 +0100
@@ -29,7 +29,9 @@
The hacker will join development at the forge_.
-The impatient will move right away to :ref:`MiseEnPlaceEnv`.
+The impatient will go strait away to :ref:`QuickInstall`.
+
+The impatient developper will move right away to :ref:`MiseEnPlaceEnv`.
.. _Logilab: http://www.logilab.fr/
.. _forge: http://www.cubicweb.org/project/
--- a/goa/test/unittest_editcontroller.py Wed Feb 11 14:46:26 2009 +0100
+++ b/goa/test/unittest_editcontroller.py Wed Feb 11 14:46:46 2009 +0100
@@ -17,7 +17,7 @@
config.global_set_option('use-google-auth', False)
config.global_set_option('schema-type', 'yams')
config.global_set_option('included-cubes', ())
- config.global_set_option('included-yams-cubes', ('eblog',))
+ config.global_set_option('included-yams-cubes', ('blog',))
MODEL_CLASSES = ()
from cubicweb.web.views import editcontroller
--- a/rset.py Wed Feb 11 14:46:26 2009 +0100
+++ b/rset.py Wed Feb 11 14:46:46 2009 +0100
@@ -464,7 +464,8 @@
rqlst = self.syntax_tree()
etype = self.description[row][col]
if self.vreg.schema.eschema(etype).is_final():
- # final type, find a better (ambiguous) one
+ # final type, find a better one to locate the correct subquery
+ # (ambiguous if possible)
for i in xrange(len(rqlst.children[0].selection)):
if i == col:
continue
@@ -476,18 +477,17 @@
locate_query_col = i
if len(self.column_types(i)) > 1:
break
- # UNION query, find the subquery from which this entity has been
- # found
+ # UNION query, find the subquery from which this entity has been found
select = rqlst.locate_subquery(locate_query_col, etype, self.args)
try:
myvar = select.selection[col].variable
except AttributeError:
- # no .selection attribute is available
+ # not a variable
return None, None
rel = myvar.main_relation()
if rel is not None:
index = rel.children[0].variable.selected_index()
- if index is not None:
+ if index is not None and self.rows[row][index]:
return self.get_entity(row, index), rel.r_type
return None, None
--- a/test/unittest_rset.py Wed Feb 11 14:46:26 2009 +0100
+++ b/test/unittest_rset.py Wed Feb 11 14:46:46 2009 +0100
@@ -300,7 +300,13 @@
attr = etype == 'Bookmark' and 'title' or 'name'
self.assertEquals(entity[attr], n)
-
+ def test_related_entity_optional(self):
+ e = self.add_entity('Bookmark', title=u'aaaa', path=u'path')
+ rset = self.execute('Any B,U,L WHERE B bookmarked_by U?, U login L')
+ entity, rtype = rset.related_entity(0, 2)
+ self.assertEquals(entity, None)
+ self.assertEquals(rtype, None)
+
def test_related_entity_union_subquery(self):
e = self.add_entity('Bookmark', title=u'aaaa', path=u'path')
rset = self.execute('Any X,N ORDERBY N WITH X,N BEING '
--- a/web/test/test_views.py Wed Feb 11 14:46:26 2009 +0100
+++ b/web/test/test_views.py Wed Feb 11 14:46:46 2009 +0100
@@ -39,9 +39,9 @@
self.view('table', rset, template=None, displayfilter=True, displaycols=[0,2])
rset = self.execute('Any P,F,S LIMIT 1 WHERE P is EUser, P firstname F, P surname S')
rset.req.form['rtype'] = 'firstname'
- self.view('editrelation', rset, template=None, htmlcheck=False)
+ self.view('editrelation', rset, template=None)
rset.req.form['rtype'] = 'use_email'
- self.view('editrelation', rset, template=None, htmlcheck=False)
+ self.view('editrelation', rset, template=None)
def test_sortable_js_added(self):
--- a/web/views/baseforms.py Wed Feb 11 14:46:26 2009 +0100
+++ b/web/views/baseforms.py Wed Feb 11 14:46:46 2009 +0100
@@ -392,17 +392,22 @@
if rschema != 'eid']
def relations_form(self, entity, kwargs):
+ pendings = list(self.restore_pending_inserts(entity))
+ relations_table = list(self.relations_table(entity))
+ srels_by_cat = entity.srelations_by_category(('generic', 'metadata'), 'add')
+ if not pendings and not relations_table and not srels_by_cat:
+ return u''
req = self.req
_ = self.req._
label = u'%s :' % _('This %s' % entity.e_schema).capitalize()
eid = entity.eid
html = []
- pendings = list(self.restore_pending_inserts(entity))
w = html.append
w(u'<fieldset class="subentity">')
w(u'<legend class="iformTitle">%s</legend>' % label)
w(u'<table id="relatedEntities">')
- for row in self.relations_table(entity):
+ for row in relations_table:
+ # already linked entities
if row[2]:
w(u'<tr><th class="labelCol">%s</th>' % row[0].display_name(req, row[1]))
w(u'<td>')
@@ -419,6 +424,7 @@
w(u'<tr><th> </th><td> </td></tr>')
else:
for row in pendings:
+ # soon to be linked to entities
w(u'<tr id="tr%s">' % row[1])
w(u'<th>%s</th>' % row[3])
w(u'<td>')
@@ -434,7 +440,8 @@
w(u'<select id="relationSelector_%s" tabindex="%s" onchange="javascript:showMatchingSelect(this.options[this.selectedIndex].value,%s);">'
% (eid, req.next_tabindex(), html_escape(dumps(eid))))
w(u'<option value="">%s</option>' % _('select a relation'))
- for i18nrtype, rschema, target in entity.srelations_by_category(('generic', 'metadata'), 'add'):
+ for i18nrtype, rschema, target in srels_by_cat:
+ # more entities to link to
w(u'<option value="%s_%s">%s</option>' % (rschema, target, i18nrtype))
w(u'</select>')
w(u'</th>')
--- a/web/views/baseviews.py Wed Feb 11 14:46:26 2009 +0100
+++ b/web/views/baseviews.py Wed Feb 11 14:46:46 2009 +0100
@@ -57,14 +57,14 @@
"""
id = 'final'
- def cell_call(self, row, col, props=None, displaytime=False):
+ def cell_call(self, row, col, props=None, displaytime=False, format='text/html'):
etype = self.rset.description[row][col]
value = self.rset.rows[row][col]
if etype == 'String':
entity, rtype = self.rset.related_entity(row, col)
if entity is not None:
# yes !
- self.w(entity.printable_value(rtype, value))
+ self.w(entity.printable_value(rtype, value, format=format))
return
if etype in ('Time', 'Interval'):
_ = self.req._
@@ -639,7 +639,7 @@
row=rowindex, col=colindex)
else:
val = self.view('final', rset, displaytime=True,
- row=rowindex, col=colindex)
+ row=rowindex, col=colindex, format='text/plain')
w(simple_sgml_tag(tag, val, **attrs))
w(u' </row>\n')
w(u'</%s>\n' % self.xml_root)
@@ -747,7 +747,8 @@
content = self.view('textincontext', rset,
row=rowindex, col=colindex)
else:
- content = self.view('final', rset, displaytime=True,
+ content = self.view('final', rset,
+ displaytime=True, format='text/plain',
row=rowindex, col=colindex)
csvrow.append(content)
writer.writerow(csvrow)
@@ -862,13 +863,8 @@
assert rtype is not None, "rtype is mandatory for 'edirelation' view"
targettype = self.req.form.get('targettype', targettype)
role = self.req.form.get('role', role)
- mode = entity.rtags.get_mode(rtype, targettype, role)
- if mode == 'create':
- return
category = entity.rtags.get_category(rtype, targettype, role)
- if category in ('generated', 'metadata'):
- return
- elif category in ('primary', 'secondary'):
+ if category in ('primary', 'secondary') or self.schema.rschema(rtype).is_final():
if hasattr(entity, '%s_format' % rtype):
formatwdg = entity.get_widget('%s_format' % rtype, role)
self.w(formatwdg.edit_render(entity))
@@ -879,10 +875,8 @@
self.w(u'%s %s %s' %
(wdg.render_error(entity), wdg.edit_render(entity),
wdg.render_help(entity),))
- elif category == 'generic':
+ else:
self._render_generic_relation(entity, rtype, role)
- else:
- self.error("oops, wrong category %s", category)
def _render_generic_relation(self, entity, relname, role):
text = self.req.__('add %s %s %s' % (entity.e_schema, relname, role))
--- a/web/views/euser.py Wed Feb 11 14:46:26 2009 +0100
+++ b/web/views/euser.py Wed Feb 11 14:46:46 2009 +0100
@@ -72,10 +72,7 @@
% html_escape(entity.firstname))
emailaddr = entity.get_email()
if emailaddr:
- m = sha()
- m.update(html_escape(emailaddr))
- crypt_sha1 = m.hexdigest()
- self.w(u'<foaf:mbox_sha1sum>%s</foaf:mbox_sha1sum>\n' % crypt_sha1)
+ self.w(u'<foaf:mbox>%s</foaf:mbox>\n' % html_escape(unicode(emailaddr)))
self.w(u'</foaf:Person>\n')