--- a/etwist/server.py Sun Sep 27 14:37:55 2009 +0200
+++ b/etwist/server.py Mon Sep 28 11:09:50 2009 +0200
@@ -10,10 +10,10 @@
import sys
import os
import select
+import hotshot
from time import mktime
from datetime import date, timedelta
from urlparse import urlsplit, urlunsplit
-import hotshot
from twisted.application import strports
from twisted.internet import reactor, task, threads
@@ -55,20 +55,9 @@
def start_task(interval, func):
lc = task.LoopingCall(func)
- lc.start(interval)
-
-def start_looping_tasks(repo):
- for interval, func, args in repo._looping_tasks:
- repo.info('starting twisted task %s with interval %.2fs',
- func.__name__, interval)
- def catch_error_func(repo=repo, func=func, args=args):
- try:
- func(*args)
- except:
- repo.exception('error in looping task')
- start_task(interval, catch_error_func)
- # ensure no tasks will be further added
- repo._looping_tasks = ()
+ # wait until interval has expired to actually start the task, else we have
+ # to wait all task to be finished for the server to be actually started
+ lc.start(interval, now=False)
def host_prefixed_baseurl(baseurl, host):
scheme, netloc, url, query, fragment = urlsplit(baseurl)
@@ -122,14 +111,14 @@
reactor.addSystemEventTrigger('before', 'shutdown',
self.shutdown_event)
# monkey patch start_looping_task to get proper reactor integration
- self.appli.repo.__class__.start_looping_tasks = start_looping_tasks
+ #self.appli.repo.__class__.start_looping_tasks = start_looping_tasks
if config.pyro_enabled():
# if pyro is enabled, we have to register to the pyro name
# server, create a pyro daemon, and create a task to handle pyro
# requests
self.pyro_daemon = self.appli.repo.pyro_register()
self.pyro_listen_timeout = 0.02
- start_task(1, self.pyro_loop_event)
+ self.repo.looping_task(1, self.pyro_loop_event)
self.appli.repo.start_looping_tasks()
self.set_url_rewriter()
CW_EVENT_MANAGER.bind('after-registry-reload', self.set_url_rewriter)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/migration/3.5.3_Any.py Mon Sep 28 11:09:50 2009 +0200
@@ -0,0 +1,2 @@
+sync_schema_props_perms('state_of')
+sync_schema_props_perms('transition_of')
--- a/schemas/workflow.py Sun Sep 27 14:37:55 2009 +0200
+++ b/schemas/workflow.py Mon Sep 28 11:09:50 2009 +0200
@@ -57,7 +57,7 @@
allowed_transition = SubjectRelation('BaseTransition', cardinality='**',
constraints=[RQLConstraint('S state_of WF, O transition_of WF')],
description=_('allowed transitions from this state'))
- state_of = SubjectRelation('Workflow', cardinality='1*',
+ state_of = SubjectRelation('Workflow', cardinality='1*', composite='object',
description=_('workflow to which this state belongs'),
constraints=[RQLUniqueConstraint('S name N, Y state_of O, Y name N')])
@@ -80,7 +80,7 @@
require_group = SubjectRelation('CWGroup', cardinality='**',
description=_('group in which a user should be to be '
'allowed to pass this transition'))
- transition_of = SubjectRelation('Workflow', cardinality='1*',
+ transition_of = SubjectRelation('Workflow', cardinality='1*', composite='object',
description=_('workflow to which this transition belongs'),
constraints=[RQLUniqueConstraint('S name N, Y transition_of O, Y name N')])
--- a/server/sources/native.py Sun Sep 27 14:37:55 2009 +0200
+++ b/server/sources/native.py Mon Sep 28 11:09:50 2009 +0200
@@ -554,7 +554,7 @@
"""
try:
self.indexer.cursor_unindex_object(eid, session.pool['system'])
- except:
+ except Exception: # let KeyboardInterrupt / SystemExit propagate
if self.indexer is not None:
self.exception('error while unindexing %s', eid)
@@ -565,7 +565,7 @@
try:
self.indexer.cursor_reindex_object(entity.eid, entity,
session.pool['system'])
- except:
+ except Exception: # let KeyboardInterrupt / SystemExit propagate
if self.indexer is not None:
self.exception('error while reindexing %s', entity)
# update entities.mtime
--- a/skeleton/__pkginfo__.py.tmpl Sun Sep 27 14:37:55 2009 +0200
+++ b/skeleton/__pkginfo__.py.tmpl Mon Sep 28 11:09:50 2009 +0200
@@ -43,8 +43,8 @@
# Note: here, you'll need to add subdirectories if you want
# them to be included in the debian package
-
-cube_eid = None # <=== FIXME if you need direct bug-subscription
+__depends_cubes__ = {}
+__depends__ = {'cubicweb': '>= 3.5.0'}
__use__ = (%(dependancies)s)
__recommend__ = ()
--- a/skeleton/migration/precreate.py Sun Sep 27 14:37:55 2009 +0200
+++ b/skeleton/migration/precreate.py Mon Sep 28 11:09:50 2009 +0200
@@ -7,4 +7,4 @@
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
"""
# You could create your own groups here, like in :
-# add_entity('CWGroup', name=u'mygroup')
+# create_entity('CWGroup', name=u'mygroup')
--- a/web/data/cubicweb.css Sun Sep 27 14:37:55 2009 +0200
+++ b/web/data/cubicweb.css Mon Sep 28 11:09:50 2009 +0200
@@ -482,22 +482,6 @@
padding-right: 1em;
}
-div.boxPref {
- margin: 10px 0px 0px;
-}
-
-div.boxPrefTitle {
- font-weight: bold;
- background: #cfceb7;
- margin-bottom: 6px;
- padding-bottom: 0.2em;
- overflow: hidden;
-}
-
-div.boxPrefTitle span{
- padding:0px 5px;
-}
-
input.rqlsubmit{
background: #fffff8 url("go.png") 50% 50% no-repeat;
width: 20px;
--- a/web/data/cubicweb.htmlhelpers.js Sun Sep 27 14:37:55 2009 +0200
+++ b/web/data/cubicweb.htmlhelpers.js Mon Sep 28 11:09:50 2009 +0200
@@ -154,7 +154,7 @@
CubicWeb.rounded = [
['div.sideBoxBody', 'bottom 6px'],
- ['div.boxTitle, div.boxPrefTitle, div.sideBoxTitle, th.month', 'top 6px']
+ ['div.boxTitle, div.sideBoxTitle, th.month', 'top 6px']
];
function roundedCorners(node) {
--- a/web/formfields.py Sun Sep 27 14:37:55 2009 +0200
+++ b/web/formfields.py Mon Sep 28 11:09:50 2009 +0200
@@ -320,10 +320,12 @@
widget = FileInput
needs_multipart = True
- def __init__(self, format_field=None, encoding_field=None, **kwargs):
+ def __init__(self, format_field=None, encoding_field=None, name_field=None,
+ **kwargs):
super(FileField, self).__init__(**kwargs)
self.format_field = format_field
self.encoding_field = encoding_field
+ self.name_field = name_field
def actual_fields(self, form):
yield self
@@ -331,6 +333,8 @@
yield self.format_field
if self.encoding_field:
yield self.encoding_field
+ if self.name_field:
+ yield self.name_field
def render(self, form, renderer):
wdgs = [self.get_widget(form).render(form, self, renderer)]
@@ -342,6 +346,8 @@
xml_escape(form.req.build_url('data/puce_down.png')),
form.req._('show advanced fields')))
wdgs.append(u'<div id="%s" class="hidden">' % divid)
+ if self.name_field:
+ wdgs.append(self.render_subfield(form, self.name_field, renderer))
if self.format_field:
wdgs.append(self.render_subfield(form, self.format_field, renderer))
if self.encoding_field:
@@ -563,7 +569,7 @@
kwargs['max_length'] = cstr.max
return StringField(**kwargs)
if fieldclass is FileField:
- for metadata in ('format', 'encoding'):
+ for metadata in ('format', 'encoding', 'name'):
metaschema = eschema.has_metadata(rschema, metadata)
if metaschema is not None:
kwargs['%s_field' % metadata] = guess_field(eschema, metaschema,
--- a/web/uicfg.py Sun Sep 27 14:37:55 2009 +0200
+++ b/web/uicfg.py Mon Sep 28 11:09:50 2009 +0200
@@ -157,7 +157,11 @@
'CWGroup': 'system',
'CWPermission': 'system',
'CWCache': 'system',
+ 'Workflow': 'system',
+ 'State': 'hidden',
'BaseTransition': 'hidden',
+ 'Transition': 'hidden',
+ 'WorkflowTransition': 'hidden',
}
--- a/web/views/actions.py Sun Sep 27 14:37:55 2009 +0200
+++ b/web/views/actions.py Mon Sep 28 11:09:50 2009 +0200
@@ -9,7 +9,7 @@
_ = unicode
from cubicweb.appobject import objectify_selector
-from cubicweb.selectors import (EntitySelector,
+from cubicweb.selectors import (EntitySelector, yes,
one_line_rset, two_lines_rset, one_etype_rset, relation_possible,
nonempty_rset, non_final_entity,
authenticated_user, match_user_groups, match_search_state,
@@ -359,6 +359,18 @@
__select__ = match_user_groups('users','managers')
+class PoweredByAction(Action):
+ id = 'poweredby'
+ __select__ = yes()
+
+ category = 'footer'
+ order = 3
+ title = _('powered by CubicWeb')
+
+ def url(self):
+ return 'http://www.cubicweb.org'
+
+
from logilab.common.deprecation import class_moved
from cubicweb.web.views.bookmark import FollowAction
FollowAction = class_moved(FollowAction)
--- a/web/views/basetemplates.py Sun Sep 27 14:37:55 2009 +0200
+++ b/web/views/basetemplates.py Mon Sep 28 11:09:50 2009 +0200
@@ -425,14 +425,13 @@
def call(self, **kwargs):
req = self.req
self.w(u'<div class="footer">')
- # XXX Take object from the registry if in there? would be
- # better anyway
- from cubicweb.web.views.wdoc import ChangeLogView
- self.w(u'<a href="%s">%s</a> | ' % (req.build_url('changelog'),
- req._(ChangeLogView.title).lower()))
- self.w(u'<a href="%s">%s</a> | ' % (req.build_url('doc/about'),
- req._('about this site')))
- self.w(u'<a href="http://www.cubicweb.org">%s</a>' % req._('powered by CubicWeb'))
+ actions = self.vreg['actions'].possible_actions(self.req, rset=self.rset)
+ footeractions = actions.get('footer', ())
+ for i, action in enumerate(footeractions):
+ self.w(u'<a href="%s">%s</a>' % (action.url(),
+ self.req._(action.title)))
+ if i < (len(footeractions) - 1):
+ self.w(u' | ')
self.w(u'</div>')
@@ -529,8 +528,3 @@
if config.get('https-url'):
return req.url().replace(req.base_url(), config['https-url'])
return req.url()
-
-
-## vregistry registration callback ############################################
-def registration_callback(vreg):
- vreg.register_all(globals().values(), __name__)
--- a/web/views/startup.py Sun Sep 27 14:37:55 2009 +0200
+++ b/web/views/startup.py Mon Sep 28 11:09:50 2009 +0200
@@ -21,6 +21,7 @@
id = 'manage'
title = _('manage')
http_cache_manager = httpcache.EtagHTTPCacheManager
+ add_etype_links = ()
@classmethod
def vreg_initialization_completed(cls):
@@ -78,6 +79,16 @@
self.w(u'<h4>%s</h4>\n' % self.req._('Browse by category'))
self.vreg['views'].select('tree', self.req).render(w=self.w)
+ def create_links(self):
+ self.w(u'<ul class="createLink">')
+ for etype in self.add_etype_links:
+ eschema = self.schema.eschema(etype)
+ if eschema.has_perm(self.req, 'add'):
+ self.w(u'<li><a href="%s">%s</a></li>' % (
+ self.req.build_url('add/%s' % eschema),
+ self.req.__('add a %s' % eschema).capitalize()))
+ self.w(u'</ul>')
+
def startup_views(self):
self.w(u'<h4>%s</h4>\n' % self.req._('Startup views'))
self.startupviews_table()
--- a/web/views/wdoc.py Sun Sep 27 14:37:55 2009 +0200
+++ b/web/views/wdoc.py Mon Sep 28 11:09:50 2009 +0200
@@ -15,12 +15,11 @@
from logilab.common.changelog import ChangeLog
from logilab.mtconverter import CHARSET_DECL_RGX
-from cubicweb.selectors import match_form_params
+from cubicweb.selectors import match_form_params, yes
from cubicweb.view import StartupView
from cubicweb.utils import strptime, todate
from cubicweb.common.uilib import rest_publish
-from cubicweb.web import NotFound
-
+from cubicweb.web import NotFound, action
_ = unicode
# table of content management #################################################
@@ -235,3 +234,28 @@
break
w('') # blank line
self.w(rest_publish(self, '\n'.join(restdata)))
+
+
+class ChangeLogAction(action.Action):
+ id = 'changelog'
+ __select__ = yes()
+
+ category = 'footer'
+ order = 1
+ title = ChangeLogView.title
+
+ def url(self):
+ return self.req.build_url('changelog')
+
+
+class AboutAction(action.Action):
+ id = 'about'
+ __select__ = yes()
+
+ category = 'footer'
+ order = 2
+ title = _('about this site')
+
+ def url(self):
+ return self.req.build_url('doc/about')
+