une semaine déconnectée; un meilleur glasnost

This commit is contained in:
fpeters 2003-10-05 10:30:42 +00:00
parent 8469dd56a5
commit 347a8fdf1a
114 changed files with 4818 additions and 4512 deletions

View File

@ -13,3 +13,4 @@ tmp-system
tmp-tests
root-system
root-tests
talTranslations.py

View File

@ -129,6 +129,7 @@ archive: dist-clean
clean:
rm -rf tmp-system tmp-tests
rm -rf root-tests root-system
rm -f talTranslations.py
config: config.in
cat $^ | sed -e "s/^glasnost = .*/glasnost = $(GLASNOST)/g" \
@ -347,11 +348,15 @@ mo: po/glasnost-web/de.po \
msgfmt --statistics -c -v -o locale/fr/LC_MESSAGES/glasnost-web.mo po/glasnost-web/fr.po
msgfmt --statistics -c -v -o locale/sv/LC_MESSAGES/glasnost-web.mo po/glasnost-web/sv.po
talTranslations.py: templates/
./talGettext.py templates/ > talTranslations.py
po: glasnost-web/ \
shared/common/ \
shared/proxy/ \
shared/server/ \
shared/web/
shared/web/ \
talTranslations.py
cp po/glasnost-web/de.po po/glasnost-web/de.pox
cp po/glasnost-web/es.po po/glasnost-web/es.pox

View File

@ -27,27 +27,21 @@ plane - Plane
- Quality: ****
- Inspiration: default skin of Plane <http://www.plane.org>
lightbulb - Lightbulb
---------------------
- Colours: black on light blue; blues for decoration
- Navigation: one level, vertical, bottom-left
- Quality: ** (original but not for production use)
macfly - macfly
---------------
- Colours: black on orange; red/brown for misc elements
- Navigation: one level, vertical, right
- Quality: ****
- Inspiration: colour scheme from an example of CSS use (lost url)
- Inspiration: design idea and colour scheme from an example of CSS use
<http://www.projectseven.com/grafitti/jan2003/macfly/index.htm>
watercolor - Water Color
------------------------
- Colours: black on light blue; shades of blue
- Navigation: one level, vertical, top right
- Quality: ** (nice but lots of styles needed by Glasnost are not yet done)
- Quality: ****
- Inspiration: some watercolor metacity theme elements
@ -65,6 +59,7 @@ artus - artus (current version)
-------------------------------
- ARTUS (Code Lutin customer)
- Based on entrouvert2; should be removed
bxlug - BxLUG
-------------
@ -72,10 +67,25 @@ bxlug - BxLUG
- Bruxelles Linux User Group
- http://www.bxlug.be
codelutin.org - Code Lutin.org
------------------------------
- Code Lutin
- http://www.codelutin.org
crans - CRANS
-------------
- Cachan / Réseau @ Normale Sup'
- http://assoce.crans.org
- FIXME: /images/crans_banner.png missing
easter-eggs - Easter-eggs
-------------------------
- Proposal for http://www.easter-eggs.org
- Lacks several styles to be really used
- Bad coding style in CSS files
entrouvert.be - entrouvert.be
-----------------------------
@ -102,6 +112,7 @@ libre-entreprise - Libre-entreprise
-----------------------------------
- http://www.libre-entreprise.org and http://www.libre-entreprise.com
- TODO: add login button
rap - R.A.P. Belgique
---------------------
@ -110,28 +121,59 @@ rap - R.A.P. Belgique
- http://www.antipub.be
------
Others
------
lightbulb - Lightbulb
---------------------
- Colours: black on light blue; blues for decoration
- Navigation: one level, vertical, bottom-left
- hardcodes to many things
wretched - Wretched of the Earth
--------------------------------
- Colours: black on red
- lacks many styles
--------
Unsorted
--------
- chambon.raviart - Chambon.Raviart
[REMOVE]
- codelutin - Code Lutin
- codelutin.org - Code Lutin.org
- crans - CRANS
[REMOVE]
- cuisine - Cuisine (site pour les examples)
[REMOVE] [or modify to remove hardcoded strings]
- cyborg - Cyborg
- eclova - Eclova
[REMOVE] [or modify to be generic]
- entrouvert - entr'ouvert (first version)
[REMOVE]
- entrouvert2 - entr'ouvert (current version)
[hardcodes some strings]
- fsfeurope - FSF (~europe)
[REMOVE]
- glasnost - Glasnost
[REMOVE] [or modify to get in shape]
- glasnost2 - Glasnost 2
[default for now; should rename and remove background image]
- i3c - i3c
[nice one; should sort]
- in3activa - in3activa
[REMOVE]
- linuxdays - Luxembourg LinuxDays
[REMOVE] [despite nice colour scheme]
- pel-infini - infini (assoc brest)
[REMOVE]
- theridion - Theridion (new)
[REMOVE]
- upthings - upthings
[REMOVE]
- vecam - Vecam
- wretched - Wretched of the Earth
[REMOVE] [template now in metis]

View File

@ -27,7 +27,6 @@ WebDirectoryPath = %(webdir)s
[Mail]
# Email address to use when no admin has been defined in Glasnost
Admin = root@localhost
# website to show in emails sent to new people
Website = http://localhost
# Host name and port of the SMTP server

View File

@ -66,7 +66,7 @@ def monthTupleJS(year = 0, month = 0):
if (year, month, d) == today:
more = ' id="today"'
date = '%s-%02d-%02d' % (year, month, cal[i][j])
cal[i][j] = """<a href="#" onclick="selectDay('%s')"%s>%s</a>""" % \
cal[i][j] = '<a href="#" onclick="selectDay(\'%s\')"%s>%s</a>' % \
(date, more, cal[i][j])
return cal

View File

@ -160,7 +160,7 @@ class Application(applications.Application):
if session is not None:
getProxyForServerRole('sessions').setSession(session,
context.getVar('virtualHost').defaultDispatcherId)
except faults.MissingItem:
except (faults.MissingItem, faults.UnknownServerId):
if context.getVar('debug'):
raise
if req.caching:
@ -184,14 +184,9 @@ class Application(applications.Application):
req.cancel()
raise
t1 = context.getVar('t1')
open('/tmp/webbench', 'a+').write('%f %s\n' % (
time.time() - t1, req.unparsed_uri))
return result
def handler(self, req):
t1 = time.time()
# Use direct access to _req for speed.
try:
_req = req._req
@ -227,6 +222,7 @@ class Application(applications.Application):
dispatcherId = None,
fallbackTemplatesDirectoryPath = None,
function = None,
htmlHeaders = [],
httpHostName = None,
httpLocalPath = None,
# The HTTP path, without the httpScriptDirectoryPath prefix.
@ -249,7 +245,6 @@ class Application(applications.Application):
session = None,
sessionToken = None,
sessionTokenInCookie = 0, # Was the sessionToken stored in the url?
t1 = t1,
talEngine = None,
templateDirectoryName = None,
templatesDirectoryPath = None,
@ -353,12 +348,9 @@ class Application(applications.Application):
try:
virtualHost = virtualHostsWeb.getObjectByHostName(httpHostName)
except faults.MissingItem:
try:
virtualHost = virtualHostsWeb.getDefaultVirtualHost()
except faults.MissingItem:
if context.getVar('debug'):
raise
return HTTP_NOT_FOUND
if context.getVar('debug'):
raise
return HTTP_NOT_FOUND
except (faults.UnknownDispatcherInId, faults.UnknownServerId):
if context.getVar('debug'):
raise
@ -757,8 +749,6 @@ class Application(applications.Application):
data = zbuf.getvalue()
req.headers_out['Content-Encoding'] = 'gzip'
t1 = context.getVar('t1')
if not t1:
t1 = time.time()
if lastModTime:
req.headers_out['Last-Modified'] = time.strftime(
'%a, %d %b %Y %H:%M:%S GMT', lastModTime)
@ -770,9 +760,6 @@ class Application(applications.Application):
t = time.strptime(req.headers_in['If-Modified-Since'][:25],
'%a, %d %b %Y %H:%M:%S')
if lastModTime <= t:
open('/tmp/webbench', 'a+').write(
'%f %s (static, not mod)\n' % (
time.time() - t1, req.unparsed_uri))
return HTTP_NOT_MODIFIED
except KeyError:
pass
@ -785,8 +772,6 @@ class Application(applications.Application):
except IOError:
# the user probably cancelled the request
return OK
open('/tmp/webbench', 'a+').write('%f %s (static)\n' % (
time.time() - t1, req.unparsed_uri))
return OK
def parseHttpPath(self, remaining):
@ -857,12 +842,15 @@ class Application(applications.Application):
return None
if not 'pagenames' in context.getVar('knownRoles'):
return None
objectId = getWebForServerRole('pagenames').getIdByName(
remaining[0])
try:
objectId = getWebForServerRole('pagenames').getIdByName(
remaining[0])
except faults.UnknownServerId:
return None
if not objectId:
return None
context.setVar('dispatcherId',
commonTools.extractDispatcherId(objectId))
commonTools.extractDispatcherId(objectId))
context.setVar('serverRole', commonTools.extractRole(objectId))
context.setVar('objectId', objectId)
remaining = remaining[1:]
@ -1113,15 +1101,13 @@ class RequestCache:
context.getVar('varDirectoryPath'), 'webcache')
self.cacheFilePath = os.path.join(
self.cacheDirectoryPath,
self.getCacheFileName(self.unparsed_uri, language))
self.getCacheFileName(language))
self.cacheFilePathDepends = os.path.join(
self.cacheDirectoryPath,
self.getCacheFileName(self.unparsed_uri, language)
+ '.depends')
self.getCacheFileName(language) + '.depends')
self.cacheFilePathMimeType = os.path.join(
self.cacheDirectoryPath,
self.getCacheFileName(self.unparsed_uri, language)
+ '.mimetype')
self.getCacheFileName(language) + '.mimetype')
self.depends = []
def cancel(self):
@ -1189,8 +1175,13 @@ class RequestCache:
mimeType = 'text/html'
return cachePage, mimeType
def getCacheFileName(self, uri, language):
return binascii.hexlify(md5.new(uri + language).digest())
def getCacheFileName(self, language):
if self.headers_in.has_key('Host'):
hostName = self.headers_in['Host']
else:
hostName = ''
uri = self.unparsed_uri
return binascii.hexlify(md5.new(hostName + uri + language).digest())
def getExpires(self):
try:
@ -1240,13 +1231,14 @@ def handler(req):
# those are legitimate and should be raised to modpython handler
raise
except Exception, e:
if not commonTools.getConfig('Misc', 'SendTalkBackTo'):
raise
import traceback
import smtplib
f = cStringIO.StringIO()
traceback.print_exc(file = f)
message = """Subject: [%(host)s] Glasnost Talkback
f = f.getvalue()
if commonTools.getConfig('Misc', 'SendTalkBackTo'):
import smtplib
message = """Subject: [%(host)s] Glasnost Talkback
Version: %(version)s
Time: %(time)s
@ -1257,14 +1249,18 @@ Url: %(url)s
%(traceback)s
""" % { 'time': time.ctime(),
'host': socket.getfqdn(),
'traceback': f.getvalue(),
'traceback': f,
'version': glasnost.versionNumber,
'url': req.unparsed_uri}
server = smtplib.SMTP('localhost')
server.sendmail(
commonTools.getConfig('Misc', 'AdminEmailAddress'),
commonTools.getConfig('Misc', 'SendTalkBackTo'),
message)
server = smtplib.SMTP('localhost')
try:
server.sendmail(
commonTools.getConfig('Misc', 'AdminEmailAddress',
default = 'root@localhost'),
commonTools.getConfig('Misc', 'SendTalkBackTo'),
message)
except:
pass
raise
return result
@ -1279,6 +1275,7 @@ if webTools.getConfig('Profiling', 'false') == 'true':
globals(), locals())
except SystemExit:
pass
prof.dump_stats('/tmp/glasnost-web-%s.prof'%os.path.split(req.filename)[1])
prof.dump_stats('/tmp/glasnost-web-%s.prof' % \
os.path.split(req.filename)[1])
return result

View File

@ -9,6 +9,7 @@
font-weight: bold;
background-color: #ffffd1;
z-index: 1000;
margin: 2.5em 0 0 2em;
}
ul.tooltip {

View File

@ -141,14 +141,6 @@ table.spip th {
text-align: center;
}
.odd {
background-color: transparent;
}
.even {
background-color: #fafafa; /* very light grey */
}
table.rst td,
table.objects-table td,
table.spip td {
@ -252,7 +244,6 @@ p#powered-by-glasnost a {
}
.error-message {
text-align: center;
color: red;
display: block;
}

View File

@ -1,202 +1,100 @@
addEvent(window, "load", makeBalloonHelp);
var CURRENT_BALLOON_HELP;
var onLabels = 0;
document.getElementsByClassName = function ( class_name ) {
var all_obj, ret_obj = new Array(), j = 0, strict = 0;
if ( document.getElementsByClassName.arguments.length > 1 )
strict = ( document.getElementsByClassName.arguments[1] ? 1 : 0 );
if ( document.all )
all_obj = document.all;
else if ( document.getElementsByTagName && !document.all )
all_obj = document.getElementsByTagName ( "*" );
for ( i = 0; i < all_obj.length; i++ ) {
if ( ( ' ' + all_obj[i].getAttribute("class") + ' ').toLowerCase().match(
new RegExp ( ( strict ? '^ ' + class_name + ' $' :
'^.* ' + class_name + ' .*$' ).toLowerCase(),'g' ) ) ) {
ret_obj[j++] = all_obj[i];
}
}
return ret_obj;
}
var previousBalloon;
var currentBalloon;
var timeoutId;
var timeoutIdPrevious;
function makeBalloonHelp() {
if (!document.createElement) return;
var tagsHelp = new Array('tr', 'div');
for (var i=0; i<tagsHelp.length; i++) {
var tags = document.getElementsByTagName(tagsHelp[i]);
for (var tagi=0; tagi<tags.length; tagi++) {
tag = tags[tagi];
if (tag.className.indexOf('row') > -1) {
processElemForm(tag);
}
}
}
uls = document.getElementsByTagName("ul");
for (var uli=0; uli<uls.length; uli++) {
ul = uls[uli];
if (ul.nodeName == "UL" && ul.className == "appointment-details") {
processAppointment(ul);
}
var tags = document.getElementsByClassName('tooltip');
for (var i=0; i<tags.length; i++) {
tag = tags[i];
if (tag.id.substring(0, 3) != 'for' ) continue;
tag.style.display = 'none';
tag.style.visibility = 'visible';
parentTag = document.getElementById(tag.id.substring(4, tag.id.length));
if (! parentTag) continue;
if (parentTag.childNodes.length == 1 &&
parentTag.childNodes[0].nodeType != 3)
parentTag = parentTag.childNodes[0]
parentTag.balloonHelp = tag;
addEvent(parentTag, "mouseover", showBalloonHelp);
addEvent(parentTag, "focus", showBalloonHelp);
addEvent(parentTag, "mouseout", hideBalloonHelp);
addEvent(parentTag, "blur", hideBalloonHelp);
addEvent(parentTag, "keydown", hideBalloonHelp);
}
}
function prepareTag(elem, text) {
addEvent(elem, "mouseover", showBalloonHelp);
addEvent(elem, "mouseout", hideBalloonHelp);
addEvent(elem, "focus", showBalloonHelp);
addEvent(elem, "blur", hideBalloonHelp);
addEvent(elem, "keydown", hideBalloonHelp);
elem.setAttribute("balloon-help", text);
}
function processElemForm(elem) {
if (!elem.childNodes || elem.childNodes.length == 0) return;
var s = "";
for (var itemi=0;itemi<elem.childNodes.length;itemi++) {
var item = elem.childNodes[itemi];
if (item.nodeType == 3) continue;
if (item.className.indexOf("field-description") > -1) {
s = item.innerHTML;
if (onLabels == 1) {
t = 0;
while (elem.childNodes[t].nodeType == 3) t++;
item = elem.childNodes[t];
if (item.childNodes[0].nodeType != 3) {
item = item.childNodes[0];
}
prepareTag(item, s);
break;
}
continue;
}
if (item.className.indexOf("field-value") > -1 ||
item.className.indexOf("cell") > -1) {
if (s == "") continue;
var tagsArray = new Array('select', 'textarea', 'input');
for (var i=0; i<tagsArray.length; i++) {
tags = item.getElementsByTagName(tagsArray[i]);
for (var tagi=0; tagi<tags.length; tagi++) {
tag = tags[tagi];
prepareTag(tag, s);
}
if ( tags.length > 0 ) break;
}
}
}
}
function processAppointment(elem) {
if (!elem.childNodes || elem.childNodes.length == 0) return;
/* TODO */
}
/* Utility functions */
function addEvent(obj, evType, fn) {
/* adds an eventListener for browsers which support it
Written by Scott Andrew: nice one, Scott */
/* adds an eventListener for browsers which support it.
Derived from snippet by Scott Andrew */
if (obj.addEventListener) {
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent) {
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
if (obj.attachEvent)
return obj.attachEvent("on"+evType, fn);
return false;
}
function showBalloonHelp(e) {
if (!document.getElementsByTagName) return;
if (window.event && window.event.srcElement) {
el = window.event.srcElement
} else if (e && e.target) {
el = e.target
}
if (!el) return;
if (el.nodeType == 3) {
// lnk is a textnode -- ascend parents until we hit an input
el = getParent(el, "INPUT");
while (! el.balloonHelp ) {
el = el.parentNode;
}
if (!el) return;
balloonHelp = el.getAttribute("balloon-help");
tag = el.balloonHelp;
if (CURRENT_BALLOON_HELP) hideBalloonHelp(e);
var d = document.createElement("div");
d.className = "balloon-help";
tnt = document.createTextNode(balloonHelp);
pat = document.createElement("p");
pat.appendChild(tnt);
d.appendChild(pat);
STD_WIDTH = 300;
w = balloonHelp.length * 10;
if (w > STD_WIDTH) {
w = STD_WIDTH;
}
d.style.width = w + 'px';
if (currentBalloon && tag != currentBalloon)
hideBalloonHelp();
if (tag == previousBalloon)
return;
mx = findPosX(el);
my = findPosY(el);
d.style.left = (mx+15) + 'px';
d.style.top = (my+25) + 'px';
if (document.body && document.body.offsetWidth && ((mx+w) > document.body.offsetWidth)) {
d.style.left = (document.body.offsetWidth - w - 20) + "px";
}
document.getElementsByTagName("body")[0].appendChild(d);
CURRENT_BALLOON_HELP = d;
tag.style.display = 'block';
currentBalloon = tag;
clearTimeout(timeoutId);
timeoutId = setTimeout('hideBalloonHelp()', 3000);
}
function hideBalloonHelp(e) {
if (!document.getElementsByTagName) return;
if (CURRENT_BALLOON_HELP) {
document.getElementsByTagName("body")[0].removeChild(CURRENT_BALLOON_HELP);
CURRENT_BALLOON_HELP = null;
if (currentBalloon) {
currentBalloon.style.display = 'none';
previousBalloon = currentBalloon;
currentBalloon = null;
clearTimeout(timeoutIdPrevious);
timeoutIdPrevious = setTimeout('clearPrevious()', 5000);
}
}
// Add an eventListener to browsers that can do it somehow.
// Originally by the amazing Scott Andrew.
function addEvent(obj, evType, fn) {
if (obj.addEventListener) {
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent) {
var r = obj.attachEvent("on"+evType, fn);
return r;
} else {
return false;
}
}
function getParent(el, pTagName) {
if (el == null) return null;
if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())
// Gecko bug, supposed to be uppercase
return el;
return getParent(el.parentNode, pTagName);
}
function findPosX(obj)
{
var curleft = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
}
else if (obj.x)
curleft += obj.x;
return curleft;
}
function findPosY(obj)
{
var curtop = 0;
if (obj.offsetParent) {
while (obj.offsetParent) {
curtop += obj.offsetTop
obj = obj.offsetParent;
}
}
else if (obj.y)
curtop += obj.y;
return curtop;
function clearPrevious(e) {
previousBalloon = null;
}

View File

@ -84,22 +84,26 @@ def index():
import re
for article in articles.values():
if article.format == 'spip':
links = [x[10:].strip() for x in re.findall(r'->article +\d+', article.body)]
links = [x[10:].strip() for x in re.findall(r'->article +\d+',
article.body)]
for l in links:
id = '%s/articles/%s' % (dispatcherId, l)
d[id] = 1
links = [x[8:].strip() for x in re.findall(r'->alias +[\w\-_]+', article.body)]
links = [x[8:].strip() for x in re.findall(r'->alias +[\w\-_]+',
article.body)]
for l in links:
if not pagenames.has_key(l):
print 'Wrong pagename: %s' % l
continue
d[pagenames[l]] = 1
elif article.format == 'rst':
links = [x[10:].strip() for x in re.findall(r'<article +\d+', article.body)]
links = [x[10:].strip() for x in re.findall(r'<article +\d+',
article.body)]
for l in links:
id = '%s/articles/%s' % (dispatcherId, l)
d[id] = 1
links = [x[8:].strip() for x in re.findall(r'<alias +[\w\-_]+', article.body)]
links = [x[8:].strip() for x in re.findall(r'<alias +[\w\-_]+',
article.body)]
for l in links:
if not pagenames.has_key(l):
# print 'Wrong pagename: %s' % l

View File

@ -9,7 +9,7 @@ then
fi
echo "Installing glasnost://system environment in root-system/"
make config-system install \
rm config && make config config-system install \
GLASNOST=glasnost-system PORT=8500 \
PREFIX=`pwd`/root-system/usr/local \
VARPREFIX=`pwd`/root-system/var/lib/ \
@ -18,7 +18,16 @@ make config-system install \
SERVER_USER=`id -u` SERVER_GROUP=`id -u` \
WEB_USER=`id -u` WEB_GROUP=`id -u` &> /dev/null
$ROOT_SBIN/glasnost-system-ctl start
SERVERS="Dispatcher ArticlesServer AuthenticationServer \
AuthenticationLoginPasswordServer CardsServer DataflowsServer \
GroupsServer PeopleServer VirtualHostsServer UploadFilesServer \
PageNamesServer TranslationsServer"
echo "Starting Glasnost servers..."
for SERVER in $SERVERS
do
$ROOT_SBIN/glasnost-system-ctl start-one $SERVER
done
(cd tmp-system && ./generate-system.py) < /dev/null
$ROOT_SBIN/glasnost-system-ctl stop

View File

@ -8,7 +8,7 @@ fi
echo "Installing test environment in root-tests/"
rm -rf root-tests && mkdir root-tests 2> /dev/null
make config-tests install \
rm config && make config config-tests install \
GLASNOST=glasnost-tests PORT=8500 \
PREFIX=`pwd`/root-tests/usr/local \
VARPREFIX=`pwd`/root-tests/var/lib/ \
@ -17,7 +17,15 @@ make config-tests install \
SERVER_USER=`id -u` SERVER_GROUP=`id -u` \
WEB_USER=`id -u` WEB_GROUP=`id -u` &> /dev/null
root-tests/usr/local/sbin/glasnost-tests-ctl start
(cd tmp-tests && ./launch.py $1)
SERVERS="Dispatcher ArticlesServer AtomsServer AuthenticationServer \
AuthenticationLoginPasswordServer CardsServer DataflowsServer \
GroupsServer PeopleServer VirtualHostsServer"
echo "Starting Glasnost servers..."
for SERVER in $SERVERS
do
root-tests/usr/local/sbin/glasnost-tests-ctl start-one $SERVER
done
(cd tmp-tests && python ./tests.py)
root-tests/usr/local/sbin/glasnost-tests-ctl stop

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -174,6 +174,9 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
def addObjectXmlRpc(self, objectImport):
objectId = ObjectsServer.addObjectXmlRpc(self, objectImport)
return objectId
# TODO: proper notification email
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(objectId)

View File

@ -74,7 +74,9 @@ class VcfParser(saxlib.XMLReader) :
if m :
vobjname = m.group(1)
if self._handle_namespaces:
self._cont_handler.startElementNS((EMPTY_NAMESPACE,vobjname),vobjname,AttributesNSImpl({},{}))
self._cont_handler.startElementNS(
(EMPTY_NAMESPACE, vobjname),
vobjname, AttributesNSImpl({}, {}))
else:
self._cont_handler.startElement(vobjname,AttributesImpl({}))
@ -83,7 +85,8 @@ class VcfParser(saxlib.XMLReader) :
if m :
vobjname = m.group(1)
if self._handle_namespaces:
self._cont_handler.endElementNS((EMPTY_NAMESPACE,vobjname),vobjname)
self._cont_handler.endElementNS(
(EMPTY_NAMESPACE, vobjname), vobjname)
else:
self._cont_handler.endElement(vobjname)
else :
@ -113,13 +116,15 @@ class VcfParser(saxlib.XMLReader) :
attrs[(EMPTY_NAMESPACE,'x-name')] = propname
propname = 'extension'
propvalue = unicode(to_xml_string(propvalue,'iso-8859-1'),'UTF-8')
# <=> to the above line, but doesn't work with python
# versions <2.0
#propvalue = unicode(propvalue,'iso-8859-1')
self._cont_handler.startElementNS((EMPTY_NAMESPACE,propname),propname,AttributesNSImpl(attrs,qnames))
propvalue = unicode(propvalue, 'iso-8859-1')
self._cont_handler.startElementNS(
(EMPTY_NAMESPACE, propname),
propname, AttributesNSImpl(attrs, qnames))
self._cont_handler.characters(propvalue)
self._cont_handler.endElementNS((EMPTY_NAMESPACE,propname),propname)
self._cont_handler.endElementNS(
(EMPTY_NAMESPACE, propname),
propname)
data = nextLine
file.close()
@ -128,20 +133,23 @@ class VcfParser(saxlib.XMLReader) :
return self._handle_namespaces
elif name == saxlib.feature_namespace_prefixes:
return 0
raise saxlib.SAXNotRecognizedException("Feature '%s' not recognized" % name)
raise saxlib.SAXNotRecognizedException(
"Feature '%s' not recognized" % name)
def setFeature(self, name, value):
if name == saxlib.feature_namespaces:
self._handle_namespaces = value
else:
raise saxlib.SAXNotRecognizedException("Feature '%s' not recognized" % name)
raise saxlib.SAXNotRecognizedException(
"Feature '%s' not recognized" % name)
def getProperty(self, name):
if name == saxlib.property_lexical_handler:
return self._lex_handler
elif name == saxlib.property_declaration_handler:
return self._decl_handler
raise saxlib.SAXNotRecognizedException("Property '%s' not recognized" % name)
raise saxlib.SAXNotRecognizedException(
"Property '%s' not recognized" % name)
def setProperty(self, name, value):
if name == saxlib.property_lexical_handler:
@ -149,73 +157,6 @@ class VcfParser(saxlib.XMLReader) :
elif name == saxlib.property_declaration_handler:
self._decl_handler = value
else:
raise saxlib.SAXNotRecognizedException("Property '%s' not recognized" % name)
raise saxlib.SAXNotRecognizedException(
"Property '%s' not recognized" % name)
xslt = '''<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" encoding="ISO-8859-1"/>
<xsl:strip-space elements='*'/>
<xsl:template match='/VCALENDAR'>BEGIN:VCALENDAR
<xsl:apply-templates/>END:VCALENDAR
</xsl:template>
<xsl:template match='VEVENT'>BEGIN:VEVENT
<xsl:apply-templates/>END:VEVENT
</xsl:template>
<xsl:template match='VTODO'>BEGIN:VTODO
<xsl:apply-templates/>END:VTODO
</xsl:template>
<xsl:template match='*[text()]'>
<xsl:choose>
<xsl:when test='name()="extension"'>
<xsl:value-of select='@x-name'/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select='name()'/>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select='@*[name()!="x-name"]'/>:<xsl:value-of select='text()'/><xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match='@*'>;<xsl:value-of select='name()'/>=<xsl:value-of select='.'/></xsl:template>
</xsl:transform>'''
#---------------------------------------------------------------------
# VCalendar file to DOM
def load_vcal_to_dom(uri) :
parser=VcfParser()
reader = Sax2.Reader(0, 0, None, Sax2.XmlDomGenerator, parser)
return reader.fromUri(uri)
# DOM to VCalendar file
def write_dom_to_vcal(doc, uri):
new_api = 0
try:
from Ft.Xml.Xslt.Processor import Processor
try:
from Ft.Xml.InputSource import InputSourceFactory,InputSource
except:
new_api = 1
except:
from xml.xslt.Processor import Processor
processor = Processor()
if not new_api:
processor.appendStylesheetString(xslt)
result = processor.runNode(doc,1,{},None)
else:
self.inputsourcefactory = InputSourceFactory()
self.processor.appendStylesheet(self.inputsourcefactory.fromString(
xslt, 'dummy'))
dom = self.processor.execute(doc,InputSource(None,"dummy"), 1, {},
None)
file = open(uri, 'w')
file.write(result)
file.close()

View File

@ -163,7 +163,7 @@ class AuthenticationLoginPasswordVirtualServer(AdministrableVirtualServer):
del self.authentications
self.markCoreAsDirty()
return
raise faults.WrongLogin(partialAccount[0])
raise faults.WrongLogin(authenticationObject.login)
def emailAdminsForNewUser(self, object, authenticationObject):
virtualServerId = context.getVar('applicationId')
@ -209,12 +209,14 @@ For more information about this user, please see:
def emailPasswordToUser(self, object, authenticationObject):
emailAddress = getEmailForObject(object)
if not emailAddress:
print 'Not sending because no email address'
return
if not self.getServer().getAdminCore().stockPasswordsInClearText:
# TODO: mail user explaining we can generate a new password for
# him and provide him with an url with a token (so that others
# can't force password changes)
print 'Not sending because passwords are not in plain text'
return
toAddress = [emailAddress]
@ -290,14 +292,20 @@ The Glasnost administrator - %(fromAddress)s
result.append((userId, cleanedAuthObject.exportToXmlRpc()))
return result
def getAccountUserId(self, authenticationObject):
if not self.getServer().isAdmin():
raise faults.UserAccessDenied()
def getAccountUserIdPrivate(self, authenticationObject):
if self.authentications is not None:
for userId, authObject in self.authentications.items():
if authObject.login == authenticationObject.login:
return userId
raise faults.WrongLogin(authenticationObject.login)
return ''
def getAccountUserId(self, authenticationObject):
if not self.getServer().isAdmin():
raise faults.UserAccessDenied()
userId = self.getAccountUserIdPrivate(authenticationObject)
if not userId:
raise faults.WrongLogin(authenticationObject.login)
return userId
def getAdminEmailAddresses(self, stopAsap = 0):
virtualServerId = context.getVar('applicationId')
@ -370,7 +378,7 @@ class AuthenticationLoginPasswordServer(
authenticationObject = commonTools.importThing(authenticationDict)
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
userId = virtualServer.getAccountUserId(authenticationObject)
userId = virtualServer.getAccountUserIdPrivate(authenticationObject)
userObject = getObject(userId)
virtualServer.emailPasswordToUser(userObject, authenticationObject)

View File

@ -395,3 +395,4 @@ dispatcher = Dispatcher()
if __name__ == "__main__":
dispatcher.launch(applicationName, applicationRole)

View File

@ -115,8 +115,7 @@ class VirtualHost(ObjectServerMixin, VirtualHostCommon):
def modify(self, changes, givenSlotNames = None):
objectsByHostName = self.getServer().virtualServer.objectsByHostName
hostName = self.hostName
ObjectServerMixin.modify(
self, changes, givenSlotNames = givenSlotNames)
ObjectServerMixin.modify(self, changes, givenSlotNames = givenSlotNames)
if self.hostName != hostName:
if hostName is not None:
del objectsByHostName[hostName]
@ -229,13 +228,6 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
def exportVirtualServer(self, virtualServerId, exportDirectoryPath):
return None
def getDefaultVirtualHost(self):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
if not virtualServer.admin.defaultVirtualHostId:
raise faults.MissingItem('default virtual host')
return self.getObjectXmlRpc(self.admin.defaultVirtualHostId)
def getHostNameXmlRpc(self):
"""Return the url of the virtual server."""
@ -250,27 +242,37 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
raise faults.MissingItem(dispatcherId)
def getObjectByHostName(self, hostName):
"""Return the first virtual host with the given host name."""
"""Return the virtual host with the given host name."""
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
askedHostName = hostName
if not virtualServer.objectsByHostName:
# The is no virtual host defined. Create one with the requested
# There is no virtual host defined. Create one with the requested
# host name.
object = commonTools.newThing(
'object', 'virtualhosts.VirtualHost')
object = commonTools.newThing('object', 'virtualhosts.VirtualHost')
object.title = 'Glasnost'
object.hostName = hostName
object.defaultDispatcherId = 'glasnost://%s' % hostName
object.language = 'en'
self.addObjectXmlRpc(object.exportToXmlRpc())
if not virtualServer.objectsByHostName.has_key(hostName):
for k in virtualServer.objectsByHostName.keys():
if fnmatch(hostName, k):
# hostNames, without eventual www.
hostNames = virtualServer.objectsByHostName.keys()
hostNames.sort(lambda x,y: -cmp(len(x), len(y)))
for k in hostNames:
if fnmatch(hostName, '*.'+k):
hostName = k
break
else:
raise faults.MissingItem(hostName)
if not virtualServer.admin.defaultVirtualHostId:
raise faults.MissingItem(hostName)
try:
object = virtualServer.objects[
virtualServer.admin.defaultVirtualHostId]
except KeyError:
raise faults.MissingItem(hostName)
return object
object = virtualServer.objectsByHostName[hostName]
return object
@ -292,14 +294,18 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
return 0
def hasHostNameXmlRpc(self, hostName):
# note that this method may return false while getObjectByHostName
# returns something
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
hostName = iso8859_15(hostName)
if virtualServer.objectsByHostName.has_key(hostName):
return 1
for k in virtualServer.objectsByHostName.keys():
if fnmatch(hostName, k):
return 1
#hostNames = virtualServer.objectsByHostName.keys()
#hostNames.sort(lambda x,y: -cmp(len(x), len(y)))
#for k in hostNames:
# if fnmatch(hostName, '*.'+k):
# return 1
return 0
def importVirtualServer(self, virtualServerId, importDirectoryPath):
@ -317,8 +323,6 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
def registerPublicMethods(self):
ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('getHostName', self.getHostNameXmlRpc)
self.registerPublicMethod('getDefaultVirtualHost',
self.getDefaultVirtualHost)
self.registerPublicMethod('getObjectByHostName',
self.getObjectByHostNameXmlRpc)
self.registerPublicMethod('getObjectIdByHostName',
@ -375,7 +379,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
def updateApacheVHost(self, object):
"""Update the apache virtual host configuration.
Get the apache config template from the vistual host server data
Get the apache config template from the virtual host server data
directory.
Create the apache vhost files and fill them to add the given object as
a new virtual host.
@ -395,7 +399,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
created.
*IOError*:
The vhost file cannot be writen, or the templace config file cannot
The vhost file cannot be written, or the template config file cannot
be read.
"""

View File

@ -77,6 +77,7 @@ class AppointmentCommon(ObjectCommon):
creationTime_kindName = 'CreationTime'
end = None
end_kind_stateInViewMode = 'read-only/hidden-if-empty'
end_kindName = 'Time'
participantsSet = None
@ -112,34 +113,42 @@ class AppointmentCommon(ObjectCommon):
result = ''
return result
def getLabel(self):
def getLabel(self, withDate = 0, withHour = 0):
title = self.getTitle()
if title is None:
return ''
hourTime = self.getBeginningHourAndMinute()
if hourTime:
when = '%s %s' % (
time.strftime('%d/%m/%Y', time.localtime(self.start)),
hourTime)
else:
when = time.strftime('%d/%m/%Y', time.localtime(self.start))
dateTime = self.getDateTime(withDate, withHour)
if dateTime:
return '%s - %s' % (dateTime, title)
return title
return '%s - %s' % (when, title)
def getDateTime(self, withDate = 0, withHour = 0):
hourTime = ''
if withHour:
hourTime = self.getBeginningHourAndMinute()
date = ''
if withDate:
date = time.strftime('%d/%m/%Y', time.localtime(self.start))
if not date and not hourTime:
return ''
return ' '.join([date, hourTime])
def getTitle(self):
return self.title
def getBeginningHourAndMinute(self):
"""Returns a string with the start time of the appointment (or None
if no time set)"""
"""Returns a string with the start time of the appointment (or an empty
string if no time set)"""
hour = '%02d:%02d' % time.localtime(self.start)[3:5]
if hour == '00:00' and not self.end:
return None
return ''
if self.end:
hourEnd = '%02d:%02d' % time.localtime(self.end)[3:5]
if hour == '00:00' and self.end - self.start < 86400 and \
hourEnd == '23:59':
return None
return ''
return hour
def getEndHourAndMinute(self):

View File

@ -98,6 +98,7 @@ class VirtualHostCommon(ObjectCommon):
hostName_kind_isTranslatable = 0
hostName_kind_label = N_('Web Host Name')
hostName_kind_widget_size = 40
hostName_kind_widgetName = 'Url'
hostName_kindName = 'String'
modificationTime = None
@ -109,6 +110,9 @@ class VirtualHostCommon(ObjectCommon):
serverRole = 'virtualhosts'
# TODO: everything so that it is editable by user
showTooltips = 0 # FIXME: default should be true
templateDirectoryName = 'glasnost2'
templateDirectoryName_kind_balloonHelp = N_(
'Select the template (skin) to use for this host.')

View File

@ -138,6 +138,7 @@ class BaseThing:
thingCategory = 'other'
thingCategory_kind_importExport = 'private'
thingCategory_kind_isRequiredInEditMode = 1
thingCategory_kind_isTranslatable = 0
thingCategory_kind_label = N_('Internal Category')
thingCategory_kind_stateInEditMode = 'hidden'
thingCategory_kind_stateInViewMode = 'hidden'
@ -146,6 +147,7 @@ class BaseThing:
thingName = None
thingName_kind_importExport = 'private'
thingName_kind_isRequiredInEditMode = 1
thingName_kind_isTranslatable = 0
thingName_kind_label = N_('Internal Name')
thingName_kind_stateInEditMode = 'hidden'
thingName_kind_stateInViewMode = 'hidden'

View File

@ -455,6 +455,19 @@ class aliasUrl(rootUrl):
action = ''
return '%s%s%s' % (path, self.alias, action)
class fileUrl(rootUrl):
filename = None
def __init__(self, filename):
rootUrl.__init__(self)
self.filename = filename
def getPath(self, **keywords):
path = rootUrl.getPath(self, **keywords)
if path[-1] == '/' and self.filename[0] == '/':
path = path[:-1]
return path + self.filename
class idUrl(rootUrl):
action = None

View File

@ -400,13 +400,21 @@ def _callServer(serverAccessor, functionName, arguments):
serverProxy = serverAccessor['serverProxy']
try:
result = apply(getattr(serverProxy, functionName), arguments)
except socket.gaierror, exception:
if exception[0] == -3: # Temporary failure in name resolution
raise faults.UnknownDispatcherInId(serverAccessor['serverId'])
raise
except socket.error, exception:
if exception[0] == 'host not found':
if exception[0] == 'host not found': # FIXME: looks dubious
raise faults.UnknownDispatcherInId(serverAccessor['serverId'])
if exception[0] == 111:
# Connection refused.
# Connection refused
raise faults.UnknownDispatcherInId(serverAccessor['serverId'])
raise
except socket.gaierror, exception:
if exception[0] == -3:
raise
raise
except xmlrpclib.ProtocolError, exception:
if exception.errcode == 406:
# Protocol Error: 406 Not Acceptable.

View File

@ -1160,8 +1160,7 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
multiCall = multiCall)
def getObjectLabelsTranslated(
self, objectIds, destinationLanguages,
serverId = None):
self, objectIds, destinationLanguages, serverId = None):
"""Get the objects labels in the specified languages.
Keyword Arguments:
@ -1193,8 +1192,10 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
multiCall = MultiCall()
for objectId in objectIds:
self.getObjectLabelAndLanguage(
objectId, multiCall = multiCall)
try:
self.getObjectLabelAndLanguage(objectId, multiCall = multiCall)
except faults.UnknownDispatcherInId:
objectIds.remove(objectId)
lazyLabelsAndLanguages = multiCall.call()
labelsAndLanguages = {}
for i in range(len(objectIds)):
@ -1230,7 +1231,7 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
return labels
def getObjectLabelTranslated(
self, objectId, destinationLanguages):
self, objectId, destinationLanguages):
"""Get the object label in the specified languages.
Keyword Arguments:

View File

@ -90,15 +90,6 @@ class VirtualHostsProxy(VirtualHostsCommonMixin, ObjectsProxy):
'canModifyObject',
[serverId, getApplicationToken(), userToken, objectId])
def getDefaultVirtualHost(self, serverId = None):
userToken = context.getVar('userToken', default = '')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getDefaultVirtualHost',
[serverId, getApplicationToken(), userToken],
resultHandler = self.getObject_handleResult)
def getObjectByHostName(self, hostName, serverId = None):
userToken = context.getVar('userToken', default = '')

View File

@ -108,6 +108,15 @@ class Appointment(ObjectWebMixin, Appointment):
return []
group = groupsProxy.getObject(admin.categoriesGroupId)
return group.membersSet
def getLabelTranslated(self, destinationLanguages = None, multiCall = None,
withDate = 0, withHour = 0):
label = ObjectWebMixin.getLabelTranslated(self, destinationLanguages,
multiCall)
dateTime = self.getDateTime(withDate, withHour)
if dateTime:
return '%s - %s' % (dateTime, label)
return label
def getSlotNames(self, parentSlot = None):
slotNames = _Appointment.getSlotNames(self, parentSlot = parentSlot)
@ -148,12 +157,11 @@ DTEND:%sT235900""" % (date, date) )
s.append('END:VEVENT\n')
return '\n'.join(s)
register(Appointment)
def weekNumberToDate(year, weekNumber):
jan4thSecs = time.mktime((year, 1, 4, 0, 0, 0, 0, 0, time.localtime()[-1]))
jan4thSecs = time.mktime((year, 1, 4, 0, 0, 0, 0, 0, 0))
secondsSinceJan4th = jan4thSecs + (weekNumber-1)*7*24*60*60
weekTuple = time.localtime(secondsSinceJan4th)
daysToAdd = - weekTuple[6]
@ -163,14 +171,14 @@ def weekNumberToDate(year, weekNumber):
def dateToWeekNumber(year, month, day):
janFirstSecs = time.mktime((year, 1, 1, 0, 0, 0, 0, 0, time.localtime()[-1]))
janFirstSecs = time.mktime((year, 1, 1, 0, 0, 0, 0, 0, 0))
janFirstTuple = time.localtime(janFirstSecs)
if janFirstTuple[6] < 4:
week0Secs = janFirstSecs - janFirstTuple[6]*24*60*60
else:
week0Secs = janFirstSecs + (7-janFirstTuple[6])*24*60*60
secondsSinceEpoch = time.mktime((year, month, day, 0, 0, 0, 0, 0, time.localtime()[-1]))
secondsSinceEpoch = time.mktime((year, month, day, 0, 0, 0, 0, 0, 0))
diffSecs = secondsSinceEpoch - week0Secs
weekNumber, mod = divmod(diffSecs, 7*24*60*60)
weekNumber = int(weekNumber) + 1
@ -184,7 +192,42 @@ def dateToWeekNumber(year, month, day):
class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
def agenda(self):
return ObjectsWebMixin.viewAll(self)
now = time.time()
objects = self.getObjects().values()
pastObjects = [x for x in objects if x.start < now]
pastObjects.sort(lambda x,y: -cmp(x.start, y.start))
futureObjects = [x for x in objects if x.start > now]
futureObjects.sort(lambda x,y: cmp(x.start, y.start))
layout = X.array()
if futureObjects:
table = X.table(_class = 'objects-table')
table += X.tr(
X.th(_('Date')),
X.th(_('Label')))
for object in futureObjects:
table += X.tr(
X.td(object.getDateTime(withDate = 1, withHour = 1)),
X.td(X.objectHypertextLabel(object.id)))
layout += X.h2(_('Future events'))
layout += table
if pastObjects:
table = X.table(_class = 'objects-table')
table += X.tr(
X.th(_('Date')),
X.th(_('Label')))
for object in pastObjects:
table += X.tr(
X.td(object.getDateTime(withDate = 1, withHour = 1)),
X.td(X.objectHypertextLabel(object.id)))
layout += X.h2(_('Past events'))
layout += table
return writePageLayout(layout, _('Agenda'))
agenda.isPublicForWeb = 1
def day(self, year, month, day):
@ -246,7 +289,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
ul = X.ul()
hourAppointments.sort(lambda x,y: cmp(x.start, y.start))
for d in hourAppointments:
ul += X.li(X.a(href = X.idUrl(d.id))(d.getLabel()))
ul += X.li(X.a(href = X.idUrl(d.id))(d.getLabelTranslated()))
hourContent += ul
className = ''
if len(hourAppointments):
@ -471,10 +514,11 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
className += ' busy'
app = dayAppointments[0]
dayContent = X.a(href = X.idUrl(app.id),
title = app.getLabel())(dayLabel)
title = app.getLabelTranslated(withHour = 1))(
dayLabel)
else:
className += ' busy'
title = ', '.join([x.getLabel() for x in dayAppointments])
title = ', '.join([x.getLabelTranslated() for x in dayAppointments])
dayContent = X.a(
href = '/%s/day/%d/%d/%d' % (
self.serverRole, year, month, d),
@ -578,7 +622,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
disp, role, id = splitObjectId(d.id)
idAttribute = 'appointment-%s-%s' % (disp, id)
li += X.a(href = X.idUrl(d.id), id = idAttribute)(
d.getLabel())
d.getLabelTranslated(withHour = 1))
details = X.ul(_class = 'appointment-details tooltip',
id = 'for-' + idAttribute)
start = d.getBeginningHourAndMinute()
@ -589,7 +633,9 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
if d.body:
details += X.li(d.body)
hasDetails = 1
if hasDetails:
if hasDetails and \
context.getVar('virtualHost').showTooltips:
webTools.addContextualHeader('tooltips.js')
li += details
ul += li
dayContent += ul
@ -639,7 +685,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
ul += X.li(monthLink)
if not 'year' in exclude:
ul += X.li(yearLink)
return ul
return X.array(ul, self.getViewAllButtonsBarLayout())
def submitAddObject(self, object, **keywords):
result = ObjectsWebMixin.submitAddObject(self, object, **keywords)

View File

@ -69,8 +69,7 @@ class Article(ObjectWebMixin, Article):
body_kind_widget_preview = 1
body_kind_widgetName = 'TextArea'
editionTime_kind_defaultValue = 'now'
editionTime_kind_stateInEditMode = 'read-only'
editionTime_kind_stateInEditMode = 'hidden'
editionTime_kind_widget_fieldLabel = N_('Edition Time')
editionTime_kind_widgetName = 'InputText'
@ -187,7 +186,8 @@ class Article(ObjectWebMixin, Article):
if 'body' in slotNames:
slotNames.remove('body')
userToken = context.getVar('userToken', default = '')
if not userToken or context.getVar('useCompactLayout', default = 0):
if context.getVar('useCompactLayout', default = 0) or \
not self.getWeb().canModifyObject(self.id):
for slotName in (
'authorsSet', 'creationTime', 'editionTime', 'format',
'lastEditorId', 'modificationTime', 'readersSet', 'title',

View File

@ -185,7 +185,8 @@ class AuthenticationLibertyAllianceWeb(WebMixin,
del keywords['tokenId']
from Provider.ServiceProvider import ServiceProvider
sp = ServiceProvider('localhost', 8089, 8090, SOAPEndpoint = 'http://localhost/soapEndPoint.html')
sp = ServiceProvider('localhost', 8089, 8090,
SOAPEndpoint = 'http://localhost/soapEndPoint.html')
authnResponse = sp.getAuthnResponseFromEmbeddedUrl(keywords)
authWeb = getWebForServerRole('authentication')
@ -207,7 +208,8 @@ class AuthenticationLibertyAllianceWeb(WebMixin,
keywords = {}
from Provider.ServiceProvider import ServiceProvider
sp = ServiceProvider('localhost', 8089, 8090, SOAPEndpoint = 'http://localhost/soapEndPoint.html')
sp = ServiceProvider('localhost', 8089, 8090,
SOAPEndpoint = 'http://localhost/soapEndPoint.html')
authnRequest = sp.getNewAuthnRequest()
embeddedAuthnRequest = authnRequest.exportToEmbeddedUrl()
response = idpUrl+'?'+embeddedAuthnRequest

View File

@ -77,11 +77,14 @@ class AccountLoginPassword(BaseObjectWebMixin, AccountLoginPassword):
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = BaseObjectWebMixin.getEditLayoutSlotNames(self,
fields, parentSlot = parentSlot)
if context.getVar('authMode') != 'login':
slotNames.remove('password')
slotNames.remove('password')
return slotNames
register(AccountLoginPassword)
class LoginAccountLoginPassword(BaseObjectWebMixin, AccountLoginPassword):
login_kind_balloonHelp = N_('Enter the username you use on this site.')
password_kind_balloonHelp = N_('Enter your password.')
register(LoginAccountLoginPassword)
class ChangingPassword(BaseObjectWebMixin, ObjectCommon):
id_kindName = None
@ -123,6 +126,7 @@ class ChangingPassword(BaseObjectWebMixin, ObjectCommon):
return slotNames
class ChangingUserPassword(BaseObjectWebMixin, ObjectCommon):
id_kindName = None
language_kindName = None
@ -284,6 +288,8 @@ class AuthenticationLoginPasswordWeb(WebMixin,
changePassword.isPublicForWeb = 1
def changePasswordSubmit(self, **keywords):
if not context.getVar('userToken'):
return accessForbidden()
admin = self.getAdmin()
if not admin.userCanChoosePassword:
return accessForbidden(dontAskForLogin = 1)
@ -321,8 +327,8 @@ class AuthenticationLoginPasswordWeb(WebMixin,
self.modifyAccount(context.getVar('userId'), authObject)
return success(
_('The password has been modified successfully.'),
X.url('/'))
_('The password has been modified successfully.'),
X.rootUrl())
changePasswordSubmit.isPublicForWeb = 1
@ -468,12 +474,11 @@ class AuthenticationLoginPasswordWeb(WebMixin,
req.headers_out['Pragma'] = 'no-cache'
if keywords is None:
keywords = {}
authObject = self.newAuthenticationObject()
authObject = LoginAccountLoginPassword()
if not again:
authObject.initFields(keywords)
authObject.repairFields(keywords)
context.push(_level = 'index', layoutMode = 'edit',
authMode = 'login')
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
if access == 'forbidden':
@ -575,8 +580,7 @@ class AuthenticationLoginPasswordWeb(WebMixin,
authObject.repairFields(keywords)
context.push(_level = 'index', layoutMode = 'edit',
authMode = 'newAccount')
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
@ -584,17 +588,6 @@ class AuthenticationLoginPasswordWeb(WebMixin,
method = 'post')
layout += form
#context.push(_level = 'edit', layoutMode = 'edit')
#widget = slot.getWidget()
#form += widget.getModelPageBodyLayout(userCardSlot, keywords)
#slot = slots.Root(authObject)
#widget = slot.getWidget()
#form += widget.getModelPageBodyLayout(slot, keywords)
#context.pull()
form += userCardObject.getEditLayout(
keywords, parentSlot = userCardSlot)
form += authObject.getEditLayout(keywords)

View File

@ -269,7 +269,8 @@ class ForumsWeb(ObjectsWebMixin, ForumsProxy):
comment.title))
tr += X.td(align = "center")(comment.nbReplies)
if comment.authorId:
tr += X.td(align = "center")(X.objectHypertextLabel(comment.authorId))
tr += X.td(align = "center")(
X.objectHypertextLabel(comment.authorId))
elif comment.name:
tr += X.td(align = "center")(comment.name)
else:

View File

@ -89,13 +89,18 @@ class BaseObjectWebMixin(things.ThingMixin):
self.repairFields(fields)
return self.getCompactViewLayout(fields, parentSlot = None)
def getLabelTranslated(self, destinationLanguages, multiCall = None):
def getLabelTranslated(self, destinationLanguages = None, multiCall = None):
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
return translationsProxy.getTranslation(
if not destinationLanguages:
destinationLanguages = context.getVar('destinationLanguages')
try:
return translationsProxy.getTranslation(
self.getLabel(), self.getId(), 'self.getLabel()',
self.getLabelLanguage(), destinationLanguages,
multiCall = multiCall)
except faults.UnknownStringDigest:
return self.getLabel()
else:
return self.getLabel()
@ -106,7 +111,9 @@ class BaseObjectWebMixin(things.ThingMixin):
slotNames = things.ThingMixin.getViewLayoutSlotNames(
self, fields, parentSlot = parentSlot)
userToken = context.getVar('userToken', default = '')
if not userToken or context.getVar('useCompactLayout', default = 0):
if context.getVar('useCompactLayout', default = 0) or (
self.id and not self.getWeb().canModifyObject(self.id)):
slotNames = slotNames[:]
for slotName in ('language',):
if slotName in slotNames:
@ -466,7 +473,10 @@ class ObjectsWebMixin(WebMixin):
lazyLabels = objectIds # fastest way to get a list of same len
for objectId, lazyLabel in zip(objectIds, lazyLabels):
if translationsProxy:
label = lazyLabel()
try:
label = lazyLabel()
except faults.UnknownStringDigest:
label = partialObjects[objectId].getLabel()
else:
label = partialObjects[objectId].getLabel()
partialObject = partialObjects[objectId]
@ -588,7 +598,10 @@ class ObjectsWebMixin(WebMixin):
object.getLabelTranslated(
readLanguages, multiCall = labelsMultiCall)
for id, lazyLabel in zip(ids, labelsMultiCall.call()):
labels[id] = lazyLabel()
try:
labels[id] = lazyLabel()
except faults.UnknownStringDigest:
labels[id] = objects[id].getLabel()
ids.sort(lambda id1, id2, labels = labels:
locale.strcoll(labels[id1], labels[id2]))
return ids
@ -664,6 +677,17 @@ class ObjectsWebMixin(WebMixin):
def getViewOtherActionButtonsBarLayout(self, object, fields):
return None
def id(self, id):
if not self.hasObject(id):
return pageNotFound()
if not self.canGetObject(id):
return accessForbidden()
object = self.getObject(id)
return writePageLayout(
X.p(id),
_('Id for "%s"') % object.getLabel())
id.isPublicForWeb = 1
image = download
image.isPublicForWeb = 1

View File

@ -275,7 +275,8 @@ class VoteMixin(ObjectWebMixin):
electionId_kind_hasToMakeFieldFromValue = 0
electionId_kind_hasToRepairField = 0
electionId_kind_hasToSubmitField = 0
electionId_kind_stateInEditMode = 'read-only'
electionId_kind_stateInEditMode = 'hidden'
electionId_kind_stateInViewMode = 'hidden'
electionId_kindName = 'Id'
electionId_kind_serverRoles = ['elections']
electionId_kind_widget_fieldLabel = N_('Election')
@ -865,6 +866,8 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
if voterId and voterId == userId and electionsWeb.canVote(electionId):
layout += X.buttonStandalone(
'edit',X.idUrl(id, 'edit').add('electionId', electionId))
layout += X.buttonStandalone(
_('Go to election'), X.idUrl(electionId))
return writePageLayout(
layout, '%s - %s' % (_(self.objectNameCapitalized), label))
view.isPublicForWeb = 1

View File

@ -133,7 +133,8 @@ def getMonthLayout(year, month, baseUrl, objects, startSlot, endSlot = None):
((getattr(x, endSlot) is None and
getattr(x, startSlot) >= timeStart ) or \
getattr(x, endSlot) >= timeStart)]
dayObjects.sort(lambda x,y: cmp(getattr(x, startSlot), getattr(y, startSlot)))
dayObjects.sort(lambda x,y: cmp(getattr(x, startSlot),
getattr(y, startSlot)))
if len(dayObjects):
ul = X.ul()
for d in dayObjects:

View File

@ -688,6 +688,7 @@ def writePageLayout(layout, title, canCache = 1):
#os.chdir(context.getVar('webDirectoryPath'))
os.chdir( context.getVar('templatesDirectoryPath') )
dict['contextualHeaders'] = '\n'.join(context.getVar('htmlHeaders'))
dict['body'] = layout.getAsXml()
fileName = context.getVar('templateFileName')
@ -987,10 +988,7 @@ def processTALFile(fileName, file = None, xtal = None, **keywords):
for k, v in dict.items():
engine.locals[k] = v
t1 = context.getVar('t1')
interp = TALInterpreter(program, macros, engine, stream=req, wrap=80)
open('/tmp/webbench', 'a+').write(' %f (before interp())\n' % (
time.time() - t1))
try:
interp()
except TALError:
@ -1000,8 +998,6 @@ def processTALFile(fileName, file = None, xtal = None, **keywords):
exception = traceback.format_exception_only(
info[0], info[1])[0].strip()
writePageException(exception)
open('/tmp/webbench', 'a+').write(' %f (after interp())\n' % (
time.time() - t1))
if req.caching:
req.closeCachePage()

View File

@ -55,6 +55,7 @@ except ImportError:
import glasnost.common.context as context
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
def debugInfos():
@ -137,3 +138,15 @@ def getConfig(value, default = None, vars = None, raw = 0):
default = commonTools.getConfig('Misc', value, default, vars, raw),
vars = vars, raw = raw)
def addContextualHeader(htmlLine):
knownLines = {
'tooltips.js':
'<script src="%s" type="text/javascript"></script>' % \
X.fileUrl('/javascript/tooltips.js'),
}
if htmlLine in knownLines.keys():
htmlLine = knownLines[htmlLine]
contextualHeaders = context.getVar('htmlHeaders')
if not htmlLine in contextualHeaders:
contextualHeaders.append(htmlLine)

View File

@ -142,6 +142,9 @@ class WidgetMixin(things.ThingMixin):
# We have to enclose the field value in a tag with class 'cell' but we
# want a nice markup so we can't simply <div class="cell"> v </div> and
# go away with this.
if self.isInForm() and context.getVar('virtualHost').showTooltips:
webTools.addContextualHeader('tooltips.js')
return X.enclose(self.getHtmlValue(slot, fields, **keywords),
_class = 'cell')

43
talGettext.py Executable file
View File

@ -0,0 +1,43 @@
#! /usr/bin/env python
# TODO: support attr-translate
import os
import sgmllib
import sys
directory = sys.argv[1]
translations = {}
class ParserForTranslations(sgmllib.SGMLParser):
def __init__(self, body):
sgmllib.SGMLParser.__init__(self)
self.translation = 0
self.feed(body)
def handle_data(self, data):
if not self.translation:
return
self.translation = 0
translations[data.strip()] = None
def unknown_starttag(self, tag, attrs):
attrs = [x for x in attrs if x[0] == 'tal:translate' and not x[1]]
if not attrs:
return
self.translation = 1
for root, dir, files in os.walk(directory):
for file in files:
if not file.endswith('.tal') and not file.endswith('.html'):
continue
file = os.path.join(root, file)
ParserForTranslations(open(file).read())
for t in translations.keys():
print '_("""%s""")' % t

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">Théridion - [title]</title>
<link rel="stylesheet" href="/css/april.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body id="entrouvert-april-org">

View File

@ -6,6 +6,8 @@ body {
margin-left: auto;
margin-right: auto;
font-family: sans-serif;
color: black;
background: white;
}
div#header {

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -12,8 +12,8 @@
<link rel="stylesheet" type="text/css" href="/css/artus-default.css" tal:reroot="href" />
<link rel="stylesheet" type="text/css" href="/css/artus.css" tal:reroot="href" />
<link rel="stylesheet" type="text/css" media="print" href="/css/artus-print.css" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -12,8 +12,8 @@
<link rel="home" href="/" tal:reroot="href" />
<link rel="icon" href="/images/bxlug-favicon.ico" tal:reroot="href" />
<link rel="shortcut icon" href="/images/bxlug-favicon.ico" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -13,8 +13,8 @@
<link rel="stylesheet" type="text/css" href="/entrouvert/entrouvert2.css" tal:reroot="href" />
<link rel="stylesheet" type="text/css" media="print" href="/entrouvert/entrouvert2-print.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -21,8 +21,9 @@ http://www.codelutin.com
<link rel="stylesheet" href="/css/codelutin.org.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body>
@ -61,7 +62,7 @@ http://www.codelutin.com
<tr metal:use-macro="macro.tal/treemenu"/>
</div>
<tr tal:condition="not user"
<tr tal:condition="not user" tal:on-error="nothing"
tal:repeat="role [GlasnostServerRole('tasks'), GlasnostServerRole('appointments')]">
<td><img tal:reroot="src" src="/images/arbopics/arb0.png" width="10" height="22" /></td>
<td><img tal:reroot="src" src="/images/arbopics/arb-.png" width="15" height="22" /></td>

View File

@ -4,7 +4,8 @@ body {
font-family: Verdana, Arial, Georgia, Geneva, sans-serif;
background-image: url(/images/lutin-background.png);
background-repeat: no-repeat;
background-color : #FFFFFF;
background-color : white;
color: black;
margin: 0;
padding:0;
}

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -26,8 +26,9 @@ http://www.codelutin.com
<link rel="stylesheet" href="/css/codelutin/global.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body>
@ -46,7 +47,7 @@ http://www.codelutin.com
<tr metal:use-macro="macro.tal/treemenu"/>
</div>
<tr tal:condition="not user"
<tr tal:condition="not user" tal:on-error="nothing"
tal:repeat="role [GlasnostServerRole('tasks'), GlasnostServerRole('appointments')]">
<td class="menuitemdebut"></td>
<td class="menuitemmilieu">

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" type="text/css" href="/css/crans.css" tal:reroot="href"/>
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body bgcolor="white" text="black" topmargin="0" leftmargin="0" marginwidth="0" marginheight="0">

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" type="text/css" href="/css/cuisine.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head>
<body>

View File

@ -1,18 +1,18 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
metal:define-macro="master">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<title metal:define-slot="title">[title]</title>
<link rel="stylesheet" href="/css/cyborg.css" tal:reroot="href" />
<link rel="author" href="mailto:fpeters@entrouvert.be" title="Auteur" />
<link rel="home" href="/" tal:reroot="href" />
<script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<title metal:define-slot="title">[title]</title>
<link rel="stylesheet" href="/css/cyborg.css" tal:reroot="href" />
<link rel="author" href="mailto:fpeters@entrouvert.be" title="Auteur" />
<link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
</head>
<body>

View File

@ -2,7 +2,7 @@
<h3 tal:content="comment.title">titre</h3>
<span class="comment-author">By <span tal:replace="GlasnostObject(comment.authorId)" tal:on-error="'Anonymous'"/></span>
<div class="comment" tal:content="structure parseSpip(comment.body)" />
<a tal:attributes="href roleUrl('post', sourceId=comment.id, nextUri=currentURI)" tal:translate="fr">Répondre</a>
<a tal:attributes="href roleUrl('post', sourceId=comment.id, nextUri=currentURI)" tal:translate="">Reply</a>
<div class="comment-block" tal:condition="comments" tal:repeat="c comments" tal:content="structure template('comment.tal', comment=c)" />
</div>

View File

@ -1,4 +1,4 @@
<p metal:define-macro="poweredBy" id="powered-by-glasnost"><a tal:attributes="href aboutUrl">Powered by Glasnost</a></p>
<p metal:define-macro="poweredBy" id="powered-by-glasnost"><a tal:attributes="href aboutUrl">Glasnost</a></p>
<span metal:define-macro="breadCrumb"
tal:define="objectPath getPathToObject(currentObject)"

View File

@ -4,13 +4,13 @@
metal:use-macro="StandardLookAndFeel.html/master">
<head>
<title metal:fill-slot="title" tal:content="str(virtualHost) + ' - ' + title">title</title>
<meta metal:fill-slot="contextualHeaders" tal:replace="structure contextualHeaders" />
</head>
<body>
<div metal:fill-slot="main" tal:omit-tag="">
<h1 tal:condition="title" tal:content="title">the title goes here</h1>
<span tal:replace="structure body" />
</div>
</body>
</html>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -11,6 +11,8 @@
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/demo04.css" media="all"/>
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/print.css" media="print" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
</head>
<body>
@ -42,7 +44,7 @@
<li><a id="link-forum" href="/forums" tal:translate="">Forums</a></li>
<li><a id="link-vote" href="/elections" tal:translate="">Elections</a></li>
<li><a id="link-file" href="/uploadfiles" tal:translate="">Files</a></li>
<li><a id="link-calendar" href="/appointments" tal:translate="fr">Calendrier</a></li>
<li><a id="link-calendar" href="/appointments" tal:translate="">Calendar</a></li>
</ul>
</div>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,10 +9,11 @@
<title metal:define-slot="title">Website title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="home" href="/" />
<link rel="stylesheet" type="text/css" href="/css/eeorg/basicstyle.css" />
<link rel="stylesheet" type="text/css" href="/css/basicstyle.css" />
<meta metal:define-slot="contextualHeaders" />
<style type="text/css" media="screen">
<!--
@import url("/css/eeorg/style.css");
@import url("/css/style.css");
-->
</style>
</head>

View File

@ -40,3 +40,9 @@ ul.nav2 {
img {
border: 0;
}
.tooltip {
display: none;
}
.error-message {
color: red;
}

View File

@ -94,3 +94,6 @@ li.c { margin-top: 1.5em; padding-top: 0.3em; list-style-type: none; border-top:
div.copyleft { text-align: center; font-size: 0.7em; margin-top: 4em; }
.center { text-align: center; }
div.preview { border: 1px dotted #036; margin-left: 2em; padding: 0;}

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,14 +10,14 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/eclova.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>
<div id="header">
<h1>Eclova</h1>
<h1 tal:content="str(virtualHost)">title</h1>
<h2>&nbsp;</h2> <!-- no motto yet -->
</div>

View File

@ -34,7 +34,7 @@ html, body {
#footer {
font-size: 70%;
text-align: right;
padding: 2px 10px 0 0;
padding: 2px 10px 10px 0;
}

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/entrouvert.be.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -15,8 +15,8 @@
<!--<link tal:reroot="href" rel="author" href="mailto:info@theridion.com" title="Auteur" />
<link tal:reroot="href" rel="icon" href="/theridion/favicon.png" type="image/png" />-->
<link rel="shortcut icon" href="/images/entrouvert.com-favicon.ico" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/entrouvert1.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body bgcolor="white" text="black" topmargin="0" leftmargin="0" marginwidth="0"

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -14,8 +14,8 @@
<link tal:reroot="href" rel="stylesheet" type="text/css" media="print" href="/css/entrouvert2-print.css" />
<link tal:reroot="href" rel="home" href="/" />
<link rel="shortcut icon" href="/images/entrouvert.com-favicon.ico" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/fsfeurope.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -2,6 +2,7 @@
body {
background: white;
color: black;
margin: 0;
padding: 0;
font-family: sans-serif;

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/glasnost.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/balloonHelp.js" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -11,8 +11,8 @@
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/entrouvert1.css" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/glasnost1.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -11,8 +11,8 @@
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/glasnost2.css" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/calendar.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/balloonHelp.js" type="text/javascript"></script>
</head>
<body>

View File

@ -10,6 +10,7 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/i3c.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script type="text/javascript">
function goRubric(form) {
@ -18,13 +19,12 @@ function goRubric(form) {
return false;
}
</script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body id="glasnost-i3c">
<div id="header">
<h1><a href="/" tal:reroot="href">I3C - Internet Créatif, Coopératif, Citoyen</a></h1>
<h1><a tal:attributes="href rootUrl()" tal:content="str(virtualHost)">title</a></h1>
<p class="glasnost-cmd">
<span metal:use-macro="buttons.tal/preferences" />

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/in3activa.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,6 +10,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/calendar.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<style tal:condition="user" type="text/css" media="screen">
<!--

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">Page title will be here</title>
<link tal:reroot="href" rel="stylesheet" href="/css/libre-entreprise.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body id="libre-entreprise-com">

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/lightbulb.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/linuxdays.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,8 +9,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" href="/css/macfly.css" rel="stylesheet" type="text/css">
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/balloonHelp.js" type="text/javascript"></script>
</head>
<body>
@ -32,11 +32,13 @@
<span metal:use-macro="buttons.tal/gotoObjects" />
<span metal:use-macro="buttons.tal/newObject" />
<!--
<ul tal:define="languages getPossibleLanguagesLabelAndUrl(notSelf = 1)"
tal:condition="languages">
<li tal:repeat="l languages"><a
tal:attributes="href l[2]" tal:content="l[1]">language</a></li>
</ul>
-->
</div>
<!-- Main Content -->

View File

@ -145,15 +145,16 @@ hr {
height: 1px;
}
span.error,
div.error {
/* Class for error indication in forms */
div.error .label {
color: #800;
}
span.error-message {
background: #ffce7b;
border: 1px dashed red;
padding: 0.5em;
margin: 0;
width: 74%;
}
padding: 0 1em;
margin-bottom: 2px;
}
.calendar-week-full,
.calendar-month-full {

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/pel-infini.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -10,31 +10,34 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/plane.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
<!--
<script tal:reroot="src" src="/javascript/htmlarea/htmlarea.js" type="text/javascript"></script>
<script tal:reroot="src" src="/javascript/htmlarea/htmlarea-lang-en.js" type="text/javascript"></script>
<script tal:reroot="src" src="/javascript/htmlarea/dialog.js" type="text/javascript"></script>
-->
</head>
<body>
<div class="top">
<div class="searchBox">
<div id="top">
<div id="searchBox">
<form id="searchForm" tal:attributes="action roleUrl('search', 'go')">
<input id="search" name="terms" size="20"/>
<input tal:attr-translate="value" type="submit" class="button" value="Search"/>
</form>
</div>
<a href="/" tal:reroot="href"><img tal:reroot="src" src="/images/glasnost-plane.png" alt="Glasnost" class="logo"/></a>
<h1 tal:content="str(virtualHost)">website title</h1>
<!-- <a href="/" tal:reroot="href"><img tal:reroot="src" src="/images/glasnost-plane.png" alt="Glasnost" class="logo"/></a>-->
</div>
<div class="tabs">
<div id="tabs">
<a href="/" tal:reroot="href" tal:translate="">Home</a>
<div metal:use-macro="nav.tal/aBlockOneLevelAllObjects" />
</div>
<div class="personalBar">
<div id="personalBar">
<a class="button user" tal:condition="user" tal:attributes="href user.getUrl()" tal:content="user">userName</a>
<span tal:condition="not user" tal:translate="">You are not logged in</span>
<span metal:use-macro="buttons.tal/login" />
@ -44,7 +47,7 @@
<span metal:use-macro="buttons.tal/about" />
</div>
<div class="pathBar" tal:condition="fileName.startswith('index') or currentObject"
<div id="pathBar" tal:condition="fileName.startswith('index') or currentObject"
tal:define="breadCrumbPrefix 'Vous êtes ici: '">
<span metal:use-macro="misc.tal/breadCrumb" />
</div>
@ -64,7 +67,7 @@
</div> <!-- end of main-content -->
<div class="footer">
<div id="footer">
<a href="http://glasnost.entrouvert.org">Glasnost</a>
</div> <!-- end of footer -->

View File

@ -41,7 +41,6 @@ hr {
color: #8cacbb;
}
h1, h2, h3, h4, h5, h6 {
color: black;
clear: left;
@ -51,6 +50,15 @@ h1, h2, h3, h4, h5, h6 {
border-bottom: 1px solid #8cacbb;
}
div#top h1 {
border: 0;
font-size: 300%;
letter-spacing: 0.1em;
color: #8cacbb;
padding: 0.5em;
font-weight: bold;
}
h1 {
font-size: 160%;
}
@ -186,7 +194,8 @@ pre {
color: black;
background-color: #dee7ec;
}
div.top {
div#top {
/* Top section */
margin: 0;
padding: 0;
@ -199,7 +208,7 @@ div.top {
}
div.searchBox {
div#searchBox {
/*searchbox style and positioning */
color: black;
float: right;
@ -215,7 +224,7 @@ input.searchButton {
margin-bottom: 1px ! important;
}
div.tabs {
div#tabs {
/* Navigational tabs */
border-collapse: collapse;
border-bottom-color: #8cacbb;
@ -225,7 +234,7 @@ div.tabs {
white-space: nowrap;
}
div.tabs a {
div#tabs a {
/* The normal, unselected tabs. They are all links */
border-color: #8cacbb;
border-width: 1px;
@ -238,7 +247,7 @@ div.tabs a {
text-decoration: none;
}
div.tabs a.selected {
div#tabs a.selected {
/* The selected tab. There's only one of this */
background: #dee7ec;
border: 1px solid #8cacbb;
@ -247,14 +256,14 @@ div.tabs a.selected {
font-weight: normal;
}
div.tabs a:hover {
div#tabs a:hover {
background: #dee7ec;
border-color: #8cacbb;
border-bottom-color: #dee7ec;
color: #436976;
}
div.personalBar {
div#personalBar {
/* Bar with personalized menu (user preferences, favorites etc) */
background: #dee7ec;
border-bottom-color: #8cacbb;
@ -266,23 +275,23 @@ div.personalBar {
text-transform: lowercase;
}
div.personalBar a.button {
div#personalBar a.button {
border: 0;
padding: 0;
}
div.personalBar a {
div#personalBar a {
text-decoration: none;
color: #436976;
font-weight: normal;
margin-left: 1em;
}
div.personalBar img {
div#personalBar img {
vertical-align: top;
}
div.pathBar {
div#pathBar {
/* The path bar, including breadcrumbs and add to favorites */
border-bottom-color: #8cacbb;
border-bottom-style: solid;
@ -292,17 +301,17 @@ div.pathBar {
text-transform: lowercase;
}
div.pathBar a {
div#pathBar a {
text-decoration: none;
}
div.top, div.tabs, div.personalBar, div.pathBar {
div#top, div#tabs, div#personalBar, div#pathBar {
font-size: 60%;
}
.footer {
#footer {
background: #dee7ec;
border-top: 1px solid #8cacbb;
border-bottom: 1px solid #8cacbb;
@ -451,7 +460,7 @@ span.error-message {
font: bold smaller sans-serif;
}
div.personalBar a.button, a.button {
div#personalBar a.button, a.button {
padding-left: 18px;
background: url("/images/item.png") 8px 40% no-repeat;
}
@ -461,7 +470,7 @@ input[type="submit"] {
background: white url("/images/submit.png") 5px 40% no-repeat;
}
div.personalBar a.user {
div#personalBar a.user {
padding-left: 12px;
background: url("/images/user.png") left top no-repeat;
}

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/rap.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/glasnostTooltips.js" type="text/javascript"></script>
</head>
<body id="antipub-be">

View File

@ -5,6 +5,7 @@ html, body {
margin: 0;
font-family: sans-serif;
background: white url('/images/fingerprint.png') fixed 80% 65% no-repeat;
color: black;
}
div#header {
@ -212,18 +213,11 @@ div.error-message {
background-color: #ffce7b;
}
fieldset {
border: 0;
margin: 0.5em 0em;
padding: 0.5em 0em;
}
fieldset select {
margin-bottom: 0.5em;
}
fieldset input {
margin-left: 1em;
span.error-message {
display: block;
color: red;
font-size: 80%;
font-weight: bold;
}
form {

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/september.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>
@ -35,7 +35,7 @@
</div>
<hr />
<a href="/" tal:reroot="href" tal:translate="fr">Retour au sommaire</a>
<a href="/" tal:reroot="href" tal:translate="">Back to home</a>
<hr />
<span metal:use-macro="buttons.tal/preferences" />

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,6 +9,7 @@
<title metal:define-slot="title">Website title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" title="Default" href="/css/skelblue.css" />
<meta metal:define-slot="contextualHeaders" />
</head>
<body>
<div id="header">
@ -24,14 +25,8 @@
</ul>
<div id="commands" tal:condition="userToken">
<h2>Commandes</h2>
<ul>
<li class="role" tal:repeat="role [x for x in getServerRoles() if canGetObjects(x)]">
<span tal:content="role.label">type</span> :
<a tal:attributes="href role.url" tal:translate="">Go</a>
<a tal:condition="canAddObject(role)" tal:attributes="href role.urlNew" tal:translate="">Add</a></li>
<li><a href="/login/logout" tal:translate="">Exit</a></li>
</ul>
<h2 tal:translate="">Navigation</h2>
<ul metal:use-macro="nav.tal/ulRoles" />
</div>
</div>
@ -54,6 +49,7 @@
<div id="footer">
<span metal:use-macro="buttons.tal/newAccount">new account</span>
<span metal:use-macro="buttons.tal/login">login</span>
<span metal:use-macro="buttons.tal/logout">login</span>
<span metal:use-macro="buttons.tal/about">about</span>
</div>
</body>

View File

@ -1,3 +1,5 @@
@import url("/css/calendar.css");
html, body {
margin: 0;
font-family: sans-serif;
@ -8,7 +10,7 @@ a:link {
}
a:visited {
color: #c00;
color: #008;
}
div#header h1 {
@ -49,6 +51,7 @@ div#navigation li a:hover {
div#navigation h2 {
margin: 1em 0.5em 0.1em -0.5em;
padding: 0 0.2em;
font-size: 100%;
border: 1px outset #ccf;
background: #00a;
@ -121,6 +124,7 @@ div.row .tooltip {
font-style: italic;
font-size: smaller;
margin-left: 2em;
display: none;
}
div.row .cell {
@ -257,3 +261,13 @@ hr {
height: 1px;
}
div.balloon-help {
display: none;
}
pre {
border: 1px solid #ccf;
background: #ddf;
padding: 0.5em;
}

View File

@ -16,8 +16,8 @@
<link rel="author" href="mailto:info@theridion.com" title="Auteur" />
<link tal:reroot="href" rel="icon" href="/images/favicon.png" type="image/png" />
<link tal:reroot="href" rel="alternate" type="application/rss+xml" title="RSS" href="http://www.theridion.com/rubrics/2/rss" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
<!--<style
tal:content="'#logoGnu { -moz-binding: url(%s);}' % roleUrl('xbl', 'glasnost#menu')"></style>-->
@ -77,7 +77,7 @@
</div>
<div tal:condition="not fileName.startswith('index')">
<h2 id="homeLink"><a accesskey="1" href="/" tal:reroot="href" tal:translate="fr">Retour au sommaire</a></h2>
<h2 id="homeLink"><a accesskey="1" href="/" tal:reroot="href" tal:translate="">Back to home</a></h2>
</div>
</div> <!-- end of nav -->

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/upthings.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head>
<body>

View File

@ -2,6 +2,7 @@
body {
background: white url(/images/upthings.jpeg) fixed top left no-repeat;
color: black;
font-family: sans-serif;
padding: 0;
margin: 0;

View File

@ -10,6 +10,7 @@
<title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/vecam.css" />
<link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
<script type="text/javascript">
function goRubric(form) {
@ -18,7 +19,6 @@ function goRubric(form) {
return false;
}
</script>
<script tal:reroot="src" src="/javascript/balloonHelp.js" type="text/javascript"></script>
</head>
<body id="glasnost-vecam">

View File

@ -2,6 +2,7 @@
html, body {
background: #10743d;
color: black;
padding-bottom: 15px;
font-family: verdana, sans-serif;
font-size: 12px;

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,6 +9,8 @@
<title metal:define-slot="title">Website title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" title="Default" href="/css/watercolor.css" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script>
</head>
<body>
<h1 id="header" tal:content="str(virtualHost)">website title</h1>
@ -37,7 +39,7 @@
<span metal:use-macro="buttons.tal/login">login</span>
<span metal:use-macro="buttons.tal/logout" />
<span metal:use-macro="buttons.tal/preferences" />
<a href="http://glasnost.entrouvert.org">Glasnost</a>
<a href="/about">Glasnost</a>
</div>
</body>
</html>

View File

@ -1,3 +1,4 @@
@import url("/css/balloonHelp.css");
@import url("/css/calendar.css");
html, body {
@ -117,10 +118,6 @@ div#footer a.button {
margin: 0 0.5em;
}
.tooltip, .balloon-help {
display: none;
}
div#content ul {
list-style: circle;
}
@ -153,6 +150,7 @@ div.row ul {
div.buttons-bar {
margin-top: 1em;
clear: both;
}
div.buttons-bar .button {
@ -233,3 +231,9 @@ div.diff-error {
font-size: 80%;
}
.preview {
border: 1px solid #44618f;
padding: 0.5em;
margin: 0.5em 0 0 2em;
}

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,6 +9,7 @@
<title metal:define-slot="title">Website title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" title="Default" href="/css/wretched.css" />
<script metal:use-macro="forms.tal/formScript"></script>
</head>
<body>
<div id="header">

View File

@ -0,0 +1,69 @@
# -*- coding: iso-8859-15 -*-
import sys
import unittest
glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)
from GlasnostTestCase import MinimalTestCase
from glasnost.web.AppointmentsWeb import weekNumberToDate, dateToWeekNumber
class WeekNumberKnownValuesTestCase(MinimalTestCase):
knownValues = ( ( (1995, 1), (1995, 1, 2) ),
( (1996, 1), (1996, 1, 1) ),
( (1997, 1), (1996, 12, 30) ),
( (1998, 1), (1997, 12, 29) ),
( (1999, 1), (1999, 1, 4) ),
( (2000, 1), (2000, 1, 3) ),
( (2001, 1), (2001, 1, 1) ),
( (2002, 1), (2001, 12, 31) ),
( (2003, 1), (2002, 12, 30) ),
( (2003, 2), (2003, 1, 6) ),
( (2003, 25), (2003, 6, 16) ),
( (2003, 52), (2003, 12, 22) ),
( (2004, 1), (2003, 12, 29) ),
( (1979, 24), (1979, 6, 11) ),
)
knownFromDateValues = ( ( (2003, 3, 16), (2003, 11) ),
( (2003, 3, 17), (2003, 12) ),
( (2003, 3, 18), (2003, 12) ),
( (2003, 3, 19), (2003, 12) ),
( (2003, 3, 20), (2003, 12) ),
( (2003, 3, 21), (2003, 12) ),
( (2003, 3, 22), (2003, 12) ),
( (2003, 3, 23), (2003, 12) ),
( (2003, 3, 24), (2003, 13) ),
( (1999, 12, 31), (1999, 52) ),
( (2000, 1, 1), (1999, 52) ),
( (2000, 1, 2), (1999, 52) ),
( (2000, 1, 3), (2000, 1) ),
)
def test01_ToDateKnownValues(self):
"""Convert week numbers to dates"""
for ywTuple, ymdTuple in self.knownValues:
date = weekNumberToDate(ywTuple[0], ywTuple[1])
self.assertEqual(date[:3], ymdTuple)
def test02_FromDateKnownValues(self):
"""Convert dates to week numbers"""
for ywTuple, ymdTuple in self.knownValues:
week = dateToWeekNumber(ymdTuple[0], ymdTuple[1], ymdTuple[2])
self.assertEqual(week, ywTuple)
def testFromDateMoreKnownValues(self):
"""Convert more dates to week numbers"""
for ymdTuple, ywTuple in self.knownFromDateValues:
week = dateToWeekNumber(ymdTuple[0], ymdTuple[1], ymdTuple[2])
self.assertEqual(week, ywTuple)
suite1 = unittest.makeSuite(WeekNumberKnownValuesTestCase, 'test')
allTests = unittest.TestSuite((suite1,))
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(allTests)

65
tests/ArticlesTests.py Normal file
View File

@ -0,0 +1,65 @@
# -*- coding: iso-8859-15 -*-
import sys
import unittest
glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)
from GlasnostTestCase import MinimalTestCase, OneUserTestCase
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.system as system
import glasnost.common.tools_new as commonTools
from glasnost.proxy.tools import getProxyForServerRole
articlesProxy = getProxyForServerRole('articles')
class AddingTestCase(OneUserTestCase):
def test01_noneObject(self):
'''Add a None article'''
try:
articlesProxy.addObject(None)
self.fail('Server accepted None')
except AttributeError:
pass
def test02_nonArticleObject(self):
"""Add a non article object"""
badObject = 'This is it!'
try:
articlesProxy.addObject(badObject)
self.fail('Server accepted a random string')
except AttributeError:
pass
def test03_viciousObject(self):
"""Add a vicious article"""
class ViciousObject:
def exportToXmlRpc(self):
return {
'__thingCategory__' : 'object',
'__thingName__' : 'articles.Article',
}
viciousObject = ViciousObject()
try:
articlesProxy.addObject(viciousObject)
self.fail('Server accepted the vicious object')
except faults.MissingSlotValue:
pass
suite1 = unittest.makeSuite(AddingTestCase, 'test')
allTests = unittest.TestSuite((suite1, ))
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(allTests)

View File

@ -1,76 +0,0 @@
# -*- coding: iso-8859-15 -*-
# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
# Romain Chantereau <rchantereau@entrouvert.com>
# Nicolas Clapiès <nclapies@easter-eggs.org>
# Pierre-Antoine Dejace <padejace@entrouvert.be>
# Thierry Dulieu <tdulieu@easter-eggs.com>
# Florent Monnier <monnier@codelutin.com>
# Cédric Musso <cmusso@easter-eggs.org>
# Frédéric Péters <fpeters@entrouvert.be>
# Benjamin Poussin <poussin@codelutin.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
# Sébastien Régnier <regnier@codelutin.com>
# Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
# Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
# Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Glasnost AuthenticationProxy Unit Tests."""
__version__ = '$Revision$'[11:-2]
import base64
import sys
import unittest
glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.tools_new as commonTools
from glasnost.proxy.tools import getProxyForServerRole
import getemailpassword
import TestCase
authenticationProxy = getProxyForServerRole('authentication')
peopleProxy = getProxyForServerRole('people')
class TestCase01_getUserToken(TestCase.PeopleTestCase):
"""Test the AuthenticationProxy.getUserToken method."""
pass
suite_testAuthentication = unittest.defaultTestLoader.loadTestsFromModule(
sys.modules[__name__])

292
tests/CardsTests.py Normal file
View File

@ -0,0 +1,292 @@
# -*- coding: iso-8859-15 -*-
import sys
import unittest
glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)
from GlasnostTestCase import MinimalTestCase
import glasnost.common.faults as faults
import glasnost.proxy.CardsProxy as CardsProxy
import glasnost.proxy.kinds as kinds
import glasnost.proxy.properties as properties
from glasnost.proxy.tools import getProxyForServerRole
cardsProxy = getProxyForServerRole('cards')
class CardsTestCase(MinimalTestCase):
cardsCount = None
def setUp(self):
MinimalTestCase.setUp(self)
self.cardsCount = cardsProxy.getObjectsCount()
def tearDown(self):
try:
if self.cardsCount is not None:
self.failUnlessEqual(cardsProxy.getObjectsCount(),
self.cardsCount)
finally:
MinimalTestCase.tearDown(self)
class BasicCardsTestCase(CardsTestCase):
def test01_cardCreationAndDeletion(self):
"""Test card creation and deletion"""
card = CardsProxy.Card()
cardId = cardsProxy.addObject(card)
card = cardsProxy.getObject(cardId)
cardsProxy.deleteObject(cardId)
def test02_cardWithOneProperty(self):
"""Test card with one property"""
card = CardsProxy.Card()
card.properties = []
property = properties.Property()
property.name = 'firstName'
kind = kinds.String()
kind.isTranslatable = 0
property.kind = kind
card.properties.append(property)
cardId = cardsProxy.addObject(card)
card = cardsProxy.getObject(cardId)
propertyNames = card.getPropertyNames()
self.failUnlessEqual(propertyNames, ['firstName'])
self.failUnlessEqual(
card.getSlot('firstName').getKind().getThingName(), 'String')
self.failIf(card.getSlot('firstName').getKind().isTranslatable)
cardsProxy.deleteObject(cardId)
def test03_newCardWithOnePropertyAndValue(self):
"""Test creating a card with one property and its value"""
card = CardsProxy.Card()
card.properties = []
property = properties.Property()
property.name = 'greetings'
kind = kinds.String()
property.kind = kind
card.properties.append(property)
card.getSlot('greetings').setValue('Hello World')
self.failUnlessEqual(card.getSlot('greetings').getValue(),
'Hello World')
cardId = cardsProxy.addObject(card)
card = cardsProxy.getObject(cardId)
propertyNames = card.getPropertyNames()
self.failUnlessEqual(propertyNames, ['greetings'])
self.failUnlessEqual(
card.getSlot('greetings').getKind().getThingName(), 'String')
self.failUnlessEqual(card.getSlot('greetings').getValue(),
'Hello World')
cardsProxy.deleteObject(cardId)
def test04_settingPropertyValue(self):
"""Test setting a property value"""
card = CardsProxy.Card()
card.properties = []
property = properties.Property()
property.name = 'greetings'
kind = kinds.String()
property.kind = kind
card.properties.append(property)
cardId = cardsProxy.addObject(card)
card = cardsProxy.getObject(cardId)
propertyNames = card.getPropertyNames()
self.failUnlessEqual(propertyNames, ['greetings'])
self.failUnlessEqual(
card.getSlot('greetings').getKind().getThingName(), 'String')
self.failUnlessEqual(card.getSlot('greetings').getValue(), None)
card.getSlot('greetings').setValue('Hello World')
self.failUnlessEqual(card.getSlot('greetings').getValue(),
'Hello World')
cardsProxy.modifyObject(card)
card = cardsProxy.getObject(cardId)
propertyNames = card.getPropertyNames()
self.failUnlessEqual(propertyNames, ['greetings'])
self.failUnlessEqual(
card.getSlot('greetings').getKind().getThingName(), 'String')
self.failUnlessEqual(card.getSlot('greetings').getValue(),
'Hello World')
cardsProxy.deleteObject(cardId)
def test06_settingPropertyValueRemotely(self):
"""Test setting a property value using remote function"""
card = CardsProxy.Card()
card.properties = []
property = properties.Property()
property.name = 'greetings'
kind = kinds.String()
property.kind = kind
card.properties.append(property)
cardId = cardsProxy.addObject(card)
valueHolder = cardsProxy.getObjectSlotValueHolder(
cardId, 'self.greetings')
self.failUnlessEqual(valueHolder.value, None)
valueHolder.value = 'Hello World!'
cardsProxy.setObjectSlotValueHolder(
cardId, 'self.greetings', valueHolder)
valueHolder = cardsProxy.getObjectSlotValueHolder(
cardId, 'self.greetings')
self.failUnlessEqual(valueHolder.value, 'Hello World!')
cardsProxy.deleteObject(cardId)
class ComplexCardsTestCase(CardsTestCase):
cardId = None
def checkCard(self, card):
propertyNames = card.getPropertyNames()
self.failUnlessEqual(
propertyNames,
['greetings', 'firstName', 'lastName', 'login', 'email'])
self.failUnlessEqual(
card.getSlot('greetings').getKind().getThingName(), 'String')
self.failUnless(card.getSlot('greetings').getKind().hideLabel)
self.failUnlessEqual(
card.getSlot('greetings').getKind().stateInEditMode,
'read-only')
self.failUnlessEqual(card.getSlot('greetings').getValue(),
'Hello World')
self.failUnlessEqual(
card.getSlot('firstName').getKind().getThingName(), 'String')
self.failIf(card.getSlot('firstName').getKind().isTranslatable)
self.failUnlessEqual(card.getSlot('lastName').getKind().getThingName(),
'String')
self.failIf(card.getSlot('lastName').getKind().isTranslatable)
self.failUnlessEqual(card.getSlot('login').getKind().getThingName(),
'String')
self.failIf(card.getSlot('login').getKind().isTranslatable)
self.failUnlessEqual(card.getSlot('email').getKind().getThingName(),
'Email')
def setUp(self):
CardsTestCase.setUp(self)
card = CardsProxy.Card()
card.properties = []
property = properties.Property()
property.name = 'greetings'
kind = kinds.String()
kind.hideLabel = 1
kind.stateInEditMode = 'read-only'
property.kind = kind
card.properties.append(property)
card.getSlot('greetings').setValue('Hello World')
property = properties.Property()
property.name = 'firstName'
kind = kinds.String()
kind.isTranslatable = 0
property.kind = kind
card.properties.append(property)
property = properties.Property()
property.name = 'lastName'
kind = kinds.String()
kind.isTranslatable = 0
property.kind = kind
card.properties.append(property)
property = properties.Property()
property.name = 'login'
kind = kinds.String()
kind.isTranslatable = 0
property.kind = kind
card.properties.append(property)
property = properties.Property()
property.name = 'email'
kind = kinds.Email()
property.kind = kind
card.properties.append(property)
self.cardId = cardsProxy.addObject(card)
def tearDown(self):
if self.cardsCount is not None:
cardsProxy.deleteObject(self.cardId)
CardsTestCase.tearDown(self)
def test01_card(self):
"""Test card with several properties"""
card = cardsProxy.getObject(self.cardId)
self.checkCard(card)
def test02_cardImplementation(self):
"""Test implementation of card with several properties"""
card = CardsProxy.Card()
card.prototypeIds = [self.cardId]
cardId = cardsProxy.addObject(card)
card = cardsProxy.getObject(cardId)
self.checkCard(card)
cardsProxy.deleteObject(cardId)
def test03_cardDepth2Implementation(self):
"""Test depth 2 implementation of card with several properties"""
cardImplementationIds = []
prototypeId = self.cardId
for i in range(2):
cardI = CardsProxy.Card()
cardI.prototypeIds = [prototypeId]
cardIId = cardsProxy.addObject(cardI)
cardImplementationIds.append(cardIId)
prototypeId = cardIId
cardId = cardImplementationIds[-1]
card = cardsProxy.getObject(cardId)
self.checkCard(card)
cardImplementationIds.reverse()
for cardImplemetationId in cardImplementationIds:
cardsProxy.deleteObject(cardImplemetationId)
## def test04_cardDepth10ImplementationPerformance(self):
## """Test depth 10 implementation performance of card with
## several properties"""
## import time
## startTime = time.time()
## self.test03_cardDepth10Implementation()
## duration = time.time() - startTime
## self.failIf(
## duration < 2.5,
## 'Card prototyping is faster than before (= %s s)' % duration)
## self.failIf(
## duration > 4.0,
## 'Card prototyping is slower than before (= %s s)' % duration)
suite1 = unittest.makeSuite(BasicCardsTestCase, 'test')
suite2 = unittest.makeSuite(ComplexCardsTestCase, 'test')
allTests = unittest.TestSuite((suite1, suite2))
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(allTests)

Some files were not shown because too many files have changed in this diff Show More