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 tmp-tests
root-system root-system
root-tests root-tests
talTranslations.py

View File

@ -129,6 +129,7 @@ archive: dist-clean
clean: clean:
rm -rf tmp-system tmp-tests rm -rf tmp-system tmp-tests
rm -rf root-tests root-system rm -rf root-tests root-system
rm -f talTranslations.py
config: config.in config: config.in
cat $^ | sed -e "s/^glasnost = .*/glasnost = $(GLASNOST)/g" \ 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/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 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/ \ po: glasnost-web/ \
shared/common/ \ shared/common/ \
shared/proxy/ \ shared/proxy/ \
shared/server/ \ shared/server/ \
shared/web/ shared/web/ \
talTranslations.py
cp po/glasnost-web/de.po po/glasnost-web/de.pox cp po/glasnost-web/de.po po/glasnost-web/de.pox
cp po/glasnost-web/es.po po/glasnost-web/es.pox cp po/glasnost-web/es.po po/glasnost-web/es.pox

View File

@ -27,27 +27,21 @@ plane - Plane
- Quality: **** - Quality: ****
- Inspiration: default skin of Plane <http://www.plane.org> - 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 macfly - macfly
--------------- ---------------
- Colours: black on orange; red/brown for misc elements - Colours: black on orange; red/brown for misc elements
- Navigation: one level, vertical, right - Navigation: one level, vertical, right
- Quality: **** - 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 watercolor - Water Color
------------------------ ------------------------
- Colours: black on light blue; shades of blue - Colours: black on light blue; shades of blue
- Navigation: one level, vertical, top right - 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 - Inspiration: some watercolor metacity theme elements
@ -65,6 +59,7 @@ artus - artus (current version)
------------------------------- -------------------------------
- ARTUS (Code Lutin customer) - ARTUS (Code Lutin customer)
- Based on entrouvert2; should be removed
bxlug - BxLUG bxlug - BxLUG
------------- -------------
@ -72,10 +67,25 @@ bxlug - BxLUG
- Bruxelles Linux User Group - Bruxelles Linux User Group
- http://www.bxlug.be - 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 easter-eggs - Easter-eggs
------------------------- -------------------------
- Proposal for http://www.easter-eggs.org - Proposal for http://www.easter-eggs.org
- Lacks several styles to be really used
- Bad coding style in CSS files
entrouvert.be - entrouvert.be entrouvert.be - entrouvert.be
----------------------------- -----------------------------
@ -102,6 +112,7 @@ libre-entreprise - Libre-entreprise
----------------------------------- -----------------------------------
- http://www.libre-entreprise.org and http://www.libre-entreprise.com - http://www.libre-entreprise.org and http://www.libre-entreprise.com
- TODO: add login button
rap - R.A.P. Belgique rap - R.A.P. Belgique
--------------------- ---------------------
@ -110,28 +121,59 @@ rap - R.A.P. Belgique
- http://www.antipub.be - 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 Unsorted
-------- --------
- chambon.raviart - Chambon.Raviart - chambon.raviart - Chambon.Raviart
[REMOVE]
- codelutin - Code Lutin - codelutin - Code Lutin
- codelutin.org - Code Lutin.org [REMOVE]
- crans - CRANS
- cuisine - Cuisine (site pour les examples) - cuisine - Cuisine (site pour les examples)
[REMOVE] [or modify to remove hardcoded strings]
- cyborg - Cyborg - cyborg - Cyborg
- eclova - Eclova - eclova - Eclova
[REMOVE] [or modify to be generic]
- entrouvert - entr'ouvert (first version) - entrouvert - entr'ouvert (first version)
[REMOVE]
- entrouvert2 - entr'ouvert (current version) - entrouvert2 - entr'ouvert (current version)
[hardcodes some strings]
- fsfeurope - FSF (~europe) - fsfeurope - FSF (~europe)
[REMOVE]
- glasnost - Glasnost - glasnost - Glasnost
[REMOVE] [or modify to get in shape]
- glasnost2 - Glasnost 2 - glasnost2 - Glasnost 2
[default for now; should rename and remove background image]
- i3c - i3c - i3c - i3c
[nice one; should sort]
- in3activa - in3activa - in3activa - in3activa
[REMOVE]
- linuxdays - Luxembourg LinuxDays - linuxdays - Luxembourg LinuxDays
[REMOVE] [despite nice colour scheme]
- pel-infini - infini (assoc brest) - pel-infini - infini (assoc brest)
[REMOVE]
- theridion - Theridion (new) - theridion - Theridion (new)
[REMOVE]
- upthings - upthings - upthings - upthings
[REMOVE]
- vecam - Vecam - vecam - Vecam
- wretched - Wretched of the Earth [REMOVE] [template now in metis]

View File

@ -27,7 +27,6 @@ WebDirectoryPath = %(webdir)s
[Mail] [Mail]
# Email address to use when no admin has been defined in Glasnost # 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 to show in emails sent to new people
Website = http://localhost Website = http://localhost
# Host name and port of the SMTP server # 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: if (year, month, d) == today:
more = ' id="today"' more = ' id="today"'
date = '%s-%02d-%02d' % (year, month, cal[i][j]) 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]) (date, more, cal[i][j])
return cal return cal

View File

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

View File

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

View File

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

View File

@ -1,202 +1,100 @@
addEvent(window, "load", makeBalloonHelp); addEvent(window, "load", makeBalloonHelp);
var CURRENT_BALLOON_HELP; document.getElementsByClassName = function ( class_name ) {
var onLabels = 0; 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() { function makeBalloonHelp() {
if (!document.createElement) return; if (!document.createElement) return;
var tagsHelp = new Array('tr', 'div'); var tags = document.getElementsByClassName('tooltip');
for (var i=0; i<tagsHelp.length; i++) { for (var i=0; i<tags.length; i++) {
var tags = document.getElementsByTagName(tagsHelp[i]); tag = tags[i];
for (var tagi=0; tagi<tags.length; tagi++) { if (tag.id.substring(0, 3) != 'for' ) continue;
tag = tags[tagi]; tag.style.display = 'none';
if (tag.className.indexOf('row') > -1) { tag.style.visibility = 'visible';
processElemForm(tag); 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]
uls = document.getElementsByTagName("ul"); parentTag.balloonHelp = tag;
for (var uli=0; uli<uls.length; uli++) { addEvent(parentTag, "mouseover", showBalloonHelp);
ul = uls[uli]; addEvent(parentTag, "focus", showBalloonHelp);
if (ul.nodeName == "UL" && ul.className == "appointment-details") { addEvent(parentTag, "mouseout", hideBalloonHelp);
processAppointment(ul); 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) { function addEvent(obj, evType, fn) {
/* adds an eventListener for browsers which support it /* adds an eventListener for browsers which support it.
Written by Scott Andrew: nice one, Scott */ Derived from snippet by Scott Andrew */
if (obj.addEventListener) { if (obj.addEventListener) {
obj.addEventListener(evType, fn, true); obj.addEventListener(evType, fn, true);
return 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) { function showBalloonHelp(e) {
if (!document.getElementsByTagName) return;
if (window.event && window.event.srcElement) { if (window.event && window.event.srcElement) {
el = window.event.srcElement el = window.event.srcElement
} else if (e && e.target) { } else if (e && e.target) {
el = e.target el = e.target
} }
if (!el) return; if (!el) return;
if (el.nodeType == 3) {
// lnk is a textnode -- ascend parents until we hit an input while (! el.balloonHelp ) {
el = getParent(el, "INPUT"); el = el.parentNode;
} }
if (!el) return; tag = el.balloonHelp;
balloonHelp = el.getAttribute("balloon-help");
if (CURRENT_BALLOON_HELP) hideBalloonHelp(e); if (currentBalloon && tag != currentBalloon)
hideBalloonHelp();
var d = document.createElement("div");
d.className = "balloon-help"; if (tag == previousBalloon)
tnt = document.createTextNode(balloonHelp); return;
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';
mx = findPosX(el); tag.style.display = 'block';
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;
currentBalloon = tag;
clearTimeout(timeoutId);
timeoutId = setTimeout('hideBalloonHelp()', 3000);
} }
function hideBalloonHelp(e) { function hideBalloonHelp(e) {
if (!document.getElementsByTagName) return; if (!document.getElementsByTagName) return;
if (CURRENT_BALLOON_HELP) { if (currentBalloon) {
document.getElementsByTagName("body")[0].removeChild(CURRENT_BALLOON_HELP); currentBalloon.style.display = 'none';
CURRENT_BALLOON_HELP = null; previousBalloon = currentBalloon;
currentBalloon = null;
clearTimeout(timeoutIdPrevious);
timeoutIdPrevious = setTimeout('clearPrevious()', 5000);
} }
} }
// Add an eventListener to browsers that can do it somehow. function clearPrevious(e) {
// Originally by the amazing Scott Andrew. previousBalloon = null;
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;
} }

View File

@ -84,22 +84,26 @@ def index():
import re import re
for article in articles.values(): for article in articles.values():
if article.format == 'spip': 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: for l in links:
id = '%s/articles/%s' % (dispatcherId, l) id = '%s/articles/%s' % (dispatcherId, l)
d[id] = 1 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: for l in links:
if not pagenames.has_key(l): if not pagenames.has_key(l):
print 'Wrong pagename: %s' % l print 'Wrong pagename: %s' % l
continue continue
d[pagenames[l]] = 1 d[pagenames[l]] = 1
elif article.format == 'rst': 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: for l in links:
id = '%s/articles/%s' % (dispatcherId, l) id = '%s/articles/%s' % (dispatcherId, l)
d[id] = 1 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: for l in links:
if not pagenames.has_key(l): if not pagenames.has_key(l):
# print 'Wrong pagename: %s' % l # print 'Wrong pagename: %s' % l

View File

@ -9,7 +9,7 @@ then
fi fi
echo "Installing glasnost://system environment in root-system/" echo "Installing glasnost://system environment in root-system/"
make config-system install \ rm config && make config config-system install \
GLASNOST=glasnost-system PORT=8500 \ GLASNOST=glasnost-system PORT=8500 \
PREFIX=`pwd`/root-system/usr/local \ PREFIX=`pwd`/root-system/usr/local \
VARPREFIX=`pwd`/root-system/var/lib/ \ VARPREFIX=`pwd`/root-system/var/lib/ \
@ -18,7 +18,16 @@ make config-system install \
SERVER_USER=`id -u` SERVER_GROUP=`id -u` \ SERVER_USER=`id -u` SERVER_GROUP=`id -u` \
WEB_USER=`id -u` WEB_GROUP=`id -u` &> /dev/null 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 (cd tmp-system && ./generate-system.py) < /dev/null
$ROOT_SBIN/glasnost-system-ctl stop $ROOT_SBIN/glasnost-system-ctl stop

View File

@ -8,7 +8,7 @@ fi
echo "Installing test environment in root-tests/" echo "Installing test environment in root-tests/"
rm -rf root-tests && mkdir root-tests 2> /dev/null 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 \ GLASNOST=glasnost-tests PORT=8500 \
PREFIX=`pwd`/root-tests/usr/local \ PREFIX=`pwd`/root-tests/usr/local \
VARPREFIX=`pwd`/root-tests/var/lib/ \ VARPREFIX=`pwd`/root-tests/var/lib/ \
@ -17,7 +17,15 @@ make config-tests install \
SERVER_USER=`id -u` SERVER_GROUP=`id -u` \ SERVER_USER=`id -u` SERVER_GROUP=`id -u` \
WEB_USER=`id -u` WEB_GROUP=`id -u` &> /dev/null WEB_USER=`id -u` WEB_GROUP=`id -u` &> /dev/null
root-tests/usr/local/sbin/glasnost-tests-ctl start SERVERS="Dispatcher ArticlesServer AtomsServer AuthenticationServer \
(cd tmp-tests && ./launch.py $1) 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 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): def addObjectXmlRpc(self, objectImport):
objectId = ObjectsServer.addObjectXmlRpc(self, objectImport) objectId = ObjectsServer.addObjectXmlRpc(self, objectImport)
return objectId
# TODO: proper notification email
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
object = virtualServer.loadObjectCore(objectId) object = virtualServer.loadObjectCore(objectId)

View File

@ -74,7 +74,9 @@ class VcfParser(saxlib.XMLReader) :
if m : if m :
vobjname = m.group(1) vobjname = m.group(1)
if self._handle_namespaces: if self._handle_namespaces:
self._cont_handler.startElementNS((EMPTY_NAMESPACE,vobjname),vobjname,AttributesNSImpl({},{})) self._cont_handler.startElementNS(
(EMPTY_NAMESPACE, vobjname),
vobjname, AttributesNSImpl({}, {}))
else: else:
self._cont_handler.startElement(vobjname,AttributesImpl({})) self._cont_handler.startElement(vobjname,AttributesImpl({}))
@ -83,7 +85,8 @@ class VcfParser(saxlib.XMLReader) :
if m : if m :
vobjname = m.group(1) vobjname = m.group(1)
if self._handle_namespaces: if self._handle_namespaces:
self._cont_handler.endElementNS((EMPTY_NAMESPACE,vobjname),vobjname) self._cont_handler.endElementNS(
(EMPTY_NAMESPACE, vobjname), vobjname)
else: else:
self._cont_handler.endElement(vobjname) self._cont_handler.endElement(vobjname)
else : else :
@ -113,13 +116,15 @@ class VcfParser(saxlib.XMLReader) :
attrs[(EMPTY_NAMESPACE,'x-name')] = propname attrs[(EMPTY_NAMESPACE,'x-name')] = propname
propname = 'extension' propname = 'extension'
propvalue = unicode(to_xml_string(propvalue,'iso-8859-1'),'UTF-8') propvalue = unicode(propvalue, 'iso-8859-1')
# <=> to the above line, but doesn't work with python
# versions <2.0 self._cont_handler.startElementNS(
#propvalue = unicode(propvalue,'iso-8859-1') (EMPTY_NAMESPACE, propname),
self._cont_handler.startElementNS((EMPTY_NAMESPACE,propname),propname,AttributesNSImpl(attrs,qnames)) propname, AttributesNSImpl(attrs, qnames))
self._cont_handler.characters(propvalue) self._cont_handler.characters(propvalue)
self._cont_handler.endElementNS((EMPTY_NAMESPACE,propname),propname) self._cont_handler.endElementNS(
(EMPTY_NAMESPACE, propname),
propname)
data = nextLine data = nextLine
file.close() file.close()
@ -128,20 +133,23 @@ class VcfParser(saxlib.XMLReader) :
return self._handle_namespaces return self._handle_namespaces
elif name == saxlib.feature_namespace_prefixes: elif name == saxlib.feature_namespace_prefixes:
return 0 return 0
raise saxlib.SAXNotRecognizedException("Feature '%s' not recognized" % name) raise saxlib.SAXNotRecognizedException(
"Feature '%s' not recognized" % name)
def setFeature(self, name, value): def setFeature(self, name, value):
if name == saxlib.feature_namespaces: if name == saxlib.feature_namespaces:
self._handle_namespaces = value self._handle_namespaces = value
else: else:
raise saxlib.SAXNotRecognizedException("Feature '%s' not recognized" % name) raise saxlib.SAXNotRecognizedException(
"Feature '%s' not recognized" % name)
def getProperty(self, name): def getProperty(self, name):
if name == saxlib.property_lexical_handler: if name == saxlib.property_lexical_handler:
return self._lex_handler return self._lex_handler
elif name == saxlib.property_declaration_handler: elif name == saxlib.property_declaration_handler:
return self._decl_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): def setProperty(self, name, value):
if name == saxlib.property_lexical_handler: if name == saxlib.property_lexical_handler:
@ -149,73 +157,6 @@ class VcfParser(saxlib.XMLReader) :
elif name == saxlib.property_declaration_handler: elif name == saxlib.property_declaration_handler:
self._decl_handler = value self._decl_handler = value
else: 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 del self.authentications
self.markCoreAsDirty() self.markCoreAsDirty()
return return
raise faults.WrongLogin(partialAccount[0]) raise faults.WrongLogin(authenticationObject.login)
def emailAdminsForNewUser(self, object, authenticationObject): def emailAdminsForNewUser(self, object, authenticationObject):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
@ -209,12 +209,14 @@ For more information about this user, please see:
def emailPasswordToUser(self, object, authenticationObject): def emailPasswordToUser(self, object, authenticationObject):
emailAddress = getEmailForObject(object) emailAddress = getEmailForObject(object)
if not emailAddress: if not emailAddress:
print 'Not sending because no email address'
return return
if not self.getServer().getAdminCore().stockPasswordsInClearText: if not self.getServer().getAdminCore().stockPasswordsInClearText:
# TODO: mail user explaining we can generate a new password for # TODO: mail user explaining we can generate a new password for
# him and provide him with an url with a token (so that others # him and provide him with an url with a token (so that others
# can't force password changes) # can't force password changes)
print 'Not sending because passwords are not in plain text'
return return
toAddress = [emailAddress] toAddress = [emailAddress]
@ -290,14 +292,20 @@ The Glasnost administrator - %(fromAddress)s
result.append((userId, cleanedAuthObject.exportToXmlRpc())) result.append((userId, cleanedAuthObject.exportToXmlRpc()))
return result return result
def getAccountUserId(self, authenticationObject): def getAccountUserIdPrivate(self, authenticationObject):
if not self.getServer().isAdmin():
raise faults.UserAccessDenied()
if self.authentications is not None: if self.authentications is not None:
for userId, authObject in self.authentications.items(): for userId, authObject in self.authentications.items():
if authObject.login == authenticationObject.login: if authObject.login == authenticationObject.login:
return userId 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): def getAdminEmailAddresses(self, stopAsap = 0):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
@ -370,7 +378,7 @@ class AuthenticationLoginPasswordServer(
authenticationObject = commonTools.importThing(authenticationDict) authenticationObject = commonTools.importThing(authenticationDict)
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
userId = virtualServer.getAccountUserId(authenticationObject) userId = virtualServer.getAccountUserIdPrivate(authenticationObject)
userObject = getObject(userId) userObject = getObject(userId)
virtualServer.emailPasswordToUser(userObject, authenticationObject) virtualServer.emailPasswordToUser(userObject, authenticationObject)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -455,6 +455,19 @@ class aliasUrl(rootUrl):
action = '' action = ''
return '%s%s%s' % (path, self.alias, 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): class idUrl(rootUrl):
action = None action = None

View File

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

View File

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

View File

@ -90,15 +90,6 @@ class VirtualHostsProxy(VirtualHostsCommonMixin, ObjectsProxy):
'canModifyObject', 'canModifyObject',
[serverId, getApplicationToken(), userToken, objectId]) [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): def getObjectByHostName(self, hostName, serverId = None):
userToken = context.getVar('userToken', default = '') userToken = context.getVar('userToken', default = '')

View File

@ -108,6 +108,15 @@ class Appointment(ObjectWebMixin, Appointment):
return [] return []
group = groupsProxy.getObject(admin.categoriesGroupId) group = groupsProxy.getObject(admin.categoriesGroupId)
return group.membersSet 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): def getSlotNames(self, parentSlot = None):
slotNames = _Appointment.getSlotNames(self, parentSlot = parentSlot) slotNames = _Appointment.getSlotNames(self, parentSlot = parentSlot)
@ -148,12 +157,11 @@ DTEND:%sT235900""" % (date, date) )
s.append('END:VEVENT\n') s.append('END:VEVENT\n')
return '\n'.join(s) return '\n'.join(s)
register(Appointment) register(Appointment)
def weekNumberToDate(year, weekNumber): 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 secondsSinceJan4th = jan4thSecs + (weekNumber-1)*7*24*60*60
weekTuple = time.localtime(secondsSinceJan4th) weekTuple = time.localtime(secondsSinceJan4th)
daysToAdd = - weekTuple[6] daysToAdd = - weekTuple[6]
@ -163,14 +171,14 @@ def weekNumberToDate(year, weekNumber):
def dateToWeekNumber(year, month, day): 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) janFirstTuple = time.localtime(janFirstSecs)
if janFirstTuple[6] < 4: if janFirstTuple[6] < 4:
week0Secs = janFirstSecs - janFirstTuple[6]*24*60*60 week0Secs = janFirstSecs - janFirstTuple[6]*24*60*60
else: else:
week0Secs = janFirstSecs + (7-janFirstTuple[6])*24*60*60 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 diffSecs = secondsSinceEpoch - week0Secs
weekNumber, mod = divmod(diffSecs, 7*24*60*60) weekNumber, mod = divmod(diffSecs, 7*24*60*60)
weekNumber = int(weekNumber) + 1 weekNumber = int(weekNumber) + 1
@ -184,7 +192,42 @@ def dateToWeekNumber(year, month, day):
class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy): class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
def agenda(self): 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 agenda.isPublicForWeb = 1
def day(self, year, month, day): def day(self, year, month, day):
@ -246,7 +289,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
ul = X.ul() ul = X.ul()
hourAppointments.sort(lambda x,y: cmp(x.start, y.start)) hourAppointments.sort(lambda x,y: cmp(x.start, y.start))
for d in hourAppointments: 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 hourContent += ul
className = '' className = ''
if len(hourAppointments): if len(hourAppointments):
@ -471,10 +514,11 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
className += ' busy' className += ' busy'
app = dayAppointments[0] app = dayAppointments[0]
dayContent = X.a(href = X.idUrl(app.id), dayContent = X.a(href = X.idUrl(app.id),
title = app.getLabel())(dayLabel) title = app.getLabelTranslated(withHour = 1))(
dayLabel)
else: else:
className += ' busy' className += ' busy'
title = ', '.join([x.getLabel() for x in dayAppointments]) title = ', '.join([x.getLabelTranslated() for x in dayAppointments])
dayContent = X.a( dayContent = X.a(
href = '/%s/day/%d/%d/%d' % ( href = '/%s/day/%d/%d/%d' % (
self.serverRole, year, month, d), self.serverRole, year, month, d),
@ -578,7 +622,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
disp, role, id = splitObjectId(d.id) disp, role, id = splitObjectId(d.id)
idAttribute = 'appointment-%s-%s' % (disp, id) idAttribute = 'appointment-%s-%s' % (disp, id)
li += X.a(href = X.idUrl(d.id), id = idAttribute)( li += X.a(href = X.idUrl(d.id), id = idAttribute)(
d.getLabel()) d.getLabelTranslated(withHour = 1))
details = X.ul(_class = 'appointment-details tooltip', details = X.ul(_class = 'appointment-details tooltip',
id = 'for-' + idAttribute) id = 'for-' + idAttribute)
start = d.getBeginningHourAndMinute() start = d.getBeginningHourAndMinute()
@ -589,7 +633,9 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
if d.body: if d.body:
details += X.li(d.body) details += X.li(d.body)
hasDetails = 1 hasDetails = 1
if hasDetails: if hasDetails and \
context.getVar('virtualHost').showTooltips:
webTools.addContextualHeader('tooltips.js')
li += details li += details
ul += li ul += li
dayContent += ul dayContent += ul
@ -639,7 +685,7 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
ul += X.li(monthLink) ul += X.li(monthLink)
if not 'year' in exclude: if not 'year' in exclude:
ul += X.li(yearLink) ul += X.li(yearLink)
return ul return X.array(ul, self.getViewAllButtonsBarLayout())
def submitAddObject(self, object, **keywords): def submitAddObject(self, object, **keywords):
result = ObjectsWebMixin.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_widget_preview = 1
body_kind_widgetName = 'TextArea' body_kind_widgetName = 'TextArea'
editionTime_kind_defaultValue = 'now' editionTime_kind_stateInEditMode = 'hidden'
editionTime_kind_stateInEditMode = 'read-only'
editionTime_kind_widget_fieldLabel = N_('Edition Time') editionTime_kind_widget_fieldLabel = N_('Edition Time')
editionTime_kind_widgetName = 'InputText' editionTime_kind_widgetName = 'InputText'
@ -187,7 +186,8 @@ class Article(ObjectWebMixin, Article):
if 'body' in slotNames: if 'body' in slotNames:
slotNames.remove('body') slotNames.remove('body')
userToken = context.getVar('userToken', default = '') 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 ( for slotName in (
'authorsSet', 'creationTime', 'editionTime', 'format', 'authorsSet', 'creationTime', 'editionTime', 'format',
'lastEditorId', 'modificationTime', 'readersSet', 'title', 'lastEditorId', 'modificationTime', 'readersSet', 'title',

View File

@ -185,7 +185,8 @@ class AuthenticationLibertyAllianceWeb(WebMixin,
del keywords['tokenId'] del keywords['tokenId']
from Provider.ServiceProvider import ServiceProvider 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) authnResponse = sp.getAuthnResponseFromEmbeddedUrl(keywords)
authWeb = getWebForServerRole('authentication') authWeb = getWebForServerRole('authentication')
@ -207,7 +208,8 @@ class AuthenticationLibertyAllianceWeb(WebMixin,
keywords = {} keywords = {}
from Provider.ServiceProvider import ServiceProvider 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() authnRequest = sp.getNewAuthnRequest()
embeddedAuthnRequest = authnRequest.exportToEmbeddedUrl() embeddedAuthnRequest = authnRequest.exportToEmbeddedUrl()
response = idpUrl+'?'+embeddedAuthnRequest response = idpUrl+'?'+embeddedAuthnRequest

View File

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

View File

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

View File

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

View File

@ -275,7 +275,8 @@ class VoteMixin(ObjectWebMixin):
electionId_kind_hasToMakeFieldFromValue = 0 electionId_kind_hasToMakeFieldFromValue = 0
electionId_kind_hasToRepairField = 0 electionId_kind_hasToRepairField = 0
electionId_kind_hasToSubmitField = 0 electionId_kind_hasToSubmitField = 0
electionId_kind_stateInEditMode = 'read-only' electionId_kind_stateInEditMode = 'hidden'
electionId_kind_stateInViewMode = 'hidden'
electionId_kindName = 'Id' electionId_kindName = 'Id'
electionId_kind_serverRoles = ['elections'] electionId_kind_serverRoles = ['elections']
electionId_kind_widget_fieldLabel = N_('Election') electionId_kind_widget_fieldLabel = N_('Election')
@ -865,6 +866,8 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
if voterId and voterId == userId and electionsWeb.canVote(electionId): if voterId and voterId == userId and electionsWeb.canVote(electionId):
layout += X.buttonStandalone( layout += X.buttonStandalone(
'edit',X.idUrl(id, 'edit').add('electionId', electionId)) 'edit',X.idUrl(id, 'edit').add('electionId', electionId))
layout += X.buttonStandalone(
_('Go to election'), X.idUrl(electionId))
return writePageLayout( return writePageLayout(
layout, '%s - %s' % (_(self.objectNameCapitalized), label)) layout, '%s - %s' % (_(self.objectNameCapitalized), label))
view.isPublicForWeb = 1 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, endSlot) is None and
getattr(x, startSlot) >= timeStart ) or \ getattr(x, startSlot) >= timeStart ) or \
getattr(x, endSlot) >= timeStart)] 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): if len(dayObjects):
ul = X.ul() ul = X.ul()
for d in dayObjects: 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('webDirectoryPath'))
os.chdir( context.getVar('templatesDirectoryPath') ) os.chdir( context.getVar('templatesDirectoryPath') )
dict['contextualHeaders'] = '\n'.join(context.getVar('htmlHeaders'))
dict['body'] = layout.getAsXml() dict['body'] = layout.getAsXml()
fileName = context.getVar('templateFileName') fileName = context.getVar('templateFileName')
@ -987,10 +988,7 @@ def processTALFile(fileName, file = None, xtal = None, **keywords):
for k, v in dict.items(): for k, v in dict.items():
engine.locals[k] = v engine.locals[k] = v
t1 = context.getVar('t1')
interp = TALInterpreter(program, macros, engine, stream=req, wrap=80) interp = TALInterpreter(program, macros, engine, stream=req, wrap=80)
open('/tmp/webbench', 'a+').write(' %f (before interp())\n' % (
time.time() - t1))
try: try:
interp() interp()
except TALError: except TALError:
@ -1000,8 +998,6 @@ def processTALFile(fileName, file = None, xtal = None, **keywords):
exception = traceback.format_exception_only( exception = traceback.format_exception_only(
info[0], info[1])[0].strip() info[0], info[1])[0].strip()
writePageException(exception) writePageException(exception)
open('/tmp/webbench', 'a+').write(' %f (after interp())\n' % (
time.time() - t1))
if req.caching: if req.caching:
req.closeCachePage() req.closeCachePage()

View File

@ -55,6 +55,7 @@ except ImportError:
import glasnost.common.context as context import glasnost.common.context as context
import glasnost.common.tools_new as commonTools import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
def debugInfos(): def debugInfos():
@ -137,3 +138,15 @@ def getConfig(value, default = None, vars = None, raw = 0):
default = commonTools.getConfig('Misc', value, default, vars, raw), default = commonTools.getConfig('Misc', value, default, vars, raw),
vars = vars, raw = 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 # 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 # want a nice markup so we can't simply <div class="cell"> v </div> and
# go away with this. # go away with this.
if self.isInForm() and context.getVar('virtualHost').showTooltips:
webTools.addContextualHeader('tooltips.js')
return X.enclose(self.getHtmlValue(slot, fields, **keywords), return X.enclose(self.getHtmlValue(slot, fields, **keywords),
_class = 'cell') _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> <title metal:define-slot="title">Théridion - [title]</title>
<link rel="stylesheet" href="/css/april.css" tal:reroot="href" /> <link rel="stylesheet" href="/css/april.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" /> <link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head> </head>
<body id="entrouvert-april-org"> <body id="entrouvert-april-org">

View File

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

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" 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-default.css" tal:reroot="href" />
<link rel="stylesheet" type="text/css" href="/css/artus.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" /> <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 metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -12,8 +12,8 @@
<link rel="home" href="/" tal:reroot="href" /> <link rel="home" href="/" tal:reroot="href" />
<link rel="icon" href="/images/bxlug-favicon.ico" 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" /> <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 metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

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

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</metal:block> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" 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="stylesheet" href="/css/codelutin.org.css" tal:reroot="href" />
<link rel="home" href="/" tal:reroot="href" /> <link rel="home" href="/" tal:reroot="href" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script src="/javascript/tooltips.js" tal:reroot="src" type="text/javascript"></script>
</head> </head>
<body> <body>
@ -61,7 +62,7 @@ http://www.codelutin.com
<tr metal:use-macro="macro.tal/treemenu"/> <tr metal:use-macro="macro.tal/treemenu"/>
</div> </div>
<tr tal:condition="not user" <tr tal:condition="not user" tal:on-error="nothing"
tal:repeat="role [GlasnostServerRole('tasks'), GlasnostServerRole('appointments')]"> 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/arb0.png" width="10" height="22" /></td>
<td><img tal:reroot="src" src="/images/arbopics/arb-.png" width="15" 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; font-family: Verdana, Arial, Georgia, Geneva, sans-serif;
background-image: url(/images/lutin-background.png); background-image: url(/images/lutin-background.png);
background-repeat: no-repeat; background-repeat: no-repeat;
background-color : #FFFFFF; background-color : white;
color: black;
margin: 0; margin: 0;
padding:0; padding:0;
} }

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
<h3 tal:content="comment.title">titre</h3> <h3 tal:content="comment.title">titre</h3>
<span class="comment-author">By <span tal:replace="GlasnostObject(comment.authorId)" tal:on-error="'Anonymous'"/></span> <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)" /> <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 class="comment-block" tal:condition="comments" tal:repeat="c comments" tal:content="structure template('comment.tal', comment=c)" />
</div> </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" <span metal:define-macro="breadCrumb"
tal:define="objectPath getPathToObject(currentObject)" tal:define="objectPath getPathToObject(currentObject)"

View File

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

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" 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/demo04.css" media="all"/>
<link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/print.css" media="print" /> <link tal:reroot="href" rel="stylesheet" type="text/css" href="/css/print.css" media="print" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
</head> </head>
<body> <body>
@ -42,7 +44,7 @@
<li><a id="link-forum" href="/forums" tal:translate="">Forums</a></li> <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-vote" href="/elections" tal:translate="">Elections</a></li>
<li><a id="link-file" href="/uploadfiles" tal:translate="">Files</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> </ul>
</div> </div>

View File

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

View File

@ -40,3 +40,9 @@ ul.nav2 {
img { img {
border: 0; 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; } div.copyleft { text-align: center; font-size: 0.7em; margin-top: 4em; }
.center { text-align: center; } .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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,14 +10,14 @@
<title metal:define-slot="title">[title]</title> <title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/eclova.css" /> <link tal:reroot="href" rel="stylesheet" href="/css/eclova.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>
<div id="header"> <div id="header">
<h1>Eclova</h1> <h1 tal:content="str(virtualHost)">title</h1>
<h2>&nbsp;</h2> <!-- no motto yet --> <h2>&nbsp;</h2> <!-- no motto yet -->
</div> </div>

View File

@ -34,7 +34,7 @@ html, body {
#footer { #footer {
font-size: 70%; font-size: 70%;
text-align: right; 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> <title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/entrouvert.be.css" /> <link tal:reroot="href" rel="stylesheet" href="/css/entrouvert.be.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" 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="author" href="mailto:info@theridion.com" title="Auteur" />
<link tal:reroot="href" rel="icon" href="/theridion/favicon.png" type="image/png" />--> <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" /> <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 metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <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="stylesheet" type="text/css" href="/css/entrouvert1.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body bgcolor="white" text="black" topmargin="0" leftmargin="0" marginwidth="0" <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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" 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="stylesheet" type="text/css" media="print" href="/css/entrouvert2-print.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<link rel="shortcut icon" href="/images/entrouvert.com-favicon.ico" tal:reroot="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 metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

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

View File

@ -2,6 +2,7 @@
body { body {
background: white; background: white;
color: black;
margin: 0; margin: 0;
padding: 0; padding: 0;
font-family: sans-serif; 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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <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="stylesheet" type="text/css" href="/css/glasnost.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/balloonHelp.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

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

View File

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

View File

@ -10,6 +10,7 @@
<title metal:define-slot="title">[title]</title> <title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/i3c.css" /> <link tal:reroot="href" rel="stylesheet" href="/css/i3c.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script type="text/javascript"> <script type="text/javascript">
function goRubric(form) { function goRubric(form) {
@ -18,13 +19,12 @@ function goRubric(form) {
return false; return false;
} }
</script> </script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body id="glasnost-i3c"> <body id="glasnost-i3c">
<div id="header"> <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"> <p class="glasnost-cmd">
<span metal:use-macro="buttons.tal/preferences" /> <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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <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="stylesheet" type="text/css" href="/css/in3activa.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

@ -1,5 +1,5 @@
<metal:block define-macro="pre"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,6 +10,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <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="stylesheet" type="text/css" href="/css/calendar.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<style tal:condition="user" type="text/css" media="screen"> <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> <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="stylesheet" href="/css/libre-entreprise.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body id="libre-entreprise-com"> <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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title> <title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/lightbulb.css" /> <link tal:reroot="href" rel="stylesheet" href="/css/lightbulb.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

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

View File

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

View File

@ -145,15 +145,16 @@ hr {
height: 1px; height: 1px;
} }
span.error, div.error .label {
div.error { color: #800;
/* Class for error indication in forms */ }
span.error-message {
background: #ffce7b; background: #ffce7b;
border: 1px dashed red; border: 1px dashed red;
padding: 0.5em; padding: 0 1em;
margin: 0; margin-bottom: 2px;
width: 74%; }
}
.calendar-week-full, .calendar-week-full,
.calendar-month-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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <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="stylesheet" type="text/css" href="/css/pel-infini.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

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

View File

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

View File

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

View File

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

View File

@ -10,8 +10,8 @@
<title metal:define-slot="title">[title]</title> <title metal:define-slot="title">[title]</title>
<link tal:reroot="href" rel="stylesheet" href="/css/september.css" /> <link tal:reroot="href" rel="stylesheet" href="/css/september.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>
@ -35,7 +35,7 @@
</div> </div>
<hr /> <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 /> <hr />
<span metal:use-macro="buttons.tal/preferences" /> <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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,6 +9,7 @@
<title metal:define-slot="title">Website title</title> <title metal:define-slot="title">Website title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" title="Default" href="/css/skelblue.css" /> <link rel="stylesheet" title="Default" href="/css/skelblue.css" />
<meta metal:define-slot="contextualHeaders" />
</head> </head>
<body> <body>
<div id="header"> <div id="header">
@ -24,14 +25,8 @@
</ul> </ul>
<div id="commands" tal:condition="userToken"> <div id="commands" tal:condition="userToken">
<h2>Commandes</h2> <h2 tal:translate="">Navigation</h2>
<ul> <ul metal:use-macro="nav.tal/ulRoles" />
<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>
</div> </div>
</div> </div>
@ -54,6 +49,7 @@
<div id="footer"> <div id="footer">
<span metal:use-macro="buttons.tal/newAccount">new account</span> <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/login">login</span>
<span metal:use-macro="buttons.tal/logout">login</span>
<span metal:use-macro="buttons.tal/about">about</span> <span metal:use-macro="buttons.tal/about">about</span>
</div> </div>
</body> </body>

View File

@ -1,3 +1,5 @@
@import url("/css/calendar.css");
html, body { html, body {
margin: 0; margin: 0;
font-family: sans-serif; font-family: sans-serif;
@ -8,7 +10,7 @@ a:link {
} }
a:visited { a:visited {
color: #c00; color: #008;
} }
div#header h1 { div#header h1 {
@ -49,6 +51,7 @@ div#navigation li a:hover {
div#navigation h2 { div#navigation h2 {
margin: 1em 0.5em 0.1em -0.5em; margin: 1em 0.5em 0.1em -0.5em;
padding: 0 0.2em;
font-size: 100%; font-size: 100%;
border: 1px outset #ccf; border: 1px outset #ccf;
background: #00a; background: #00a;
@ -121,6 +124,7 @@ div.row .tooltip {
font-style: italic; font-style: italic;
font-size: smaller; font-size: smaller;
margin-left: 2em; margin-left: 2em;
display: none;
} }
div.row .cell { div.row .cell {
@ -257,3 +261,13 @@ hr {
height: 1px; 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 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="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" /> <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 metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
<!--<style <!--<style
tal:content="'#logoGnu { -moz-binding: url(%s);}' % roleUrl('xbl', 'glasnost#menu')"></style>--> tal:content="'#logoGnu { -moz-binding: url(%s);}' % roleUrl('xbl', 'glasnost#menu')"></style>-->
@ -77,7 +77,7 @@
</div> </div>
<div tal:condition="not fileName.startswith('index')"> <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>
</div> <!-- end of nav --> </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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -10,8 +10,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <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="stylesheet" type="text/css" href="/css/upthings.css" />
<link tal:reroot="href" rel="home" href="/" /> <link tal:reroot="href" rel="home" href="/" />
<meta metal:define-slot="contextualHeaders" />
<script metal:use-macro="forms.tal/formScript"></script> <script metal:use-macro="forms.tal/formScript"></script>
<script tal:reroot="src" src="/javascript/tooltips.js" type="text/javascript"></script>
</head> </head>
<body> <body>

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
@import url("/css/balloonHelp.css");
@import url("/css/calendar.css"); @import url("/css/calendar.css");
html, body { html, body {
@ -117,10 +118,6 @@ div#footer a.button {
margin: 0 0.5em; margin: 0 0.5em;
} }
.tooltip, .balloon-help {
display: none;
}
div#content ul { div#content ul {
list-style: circle; list-style: circle;
} }
@ -153,6 +150,7 @@ div.row ul {
div.buttons-bar { div.buttons-bar {
margin-top: 1em; margin-top: 1em;
clear: both;
} }
div.buttons-bar .button { div.buttons-bar .button {
@ -233,3 +231,9 @@ div.diff-error {
font-size: 80%; 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" <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> </metal:block>
<html xmlns="http://www.w3.org/1999/xhtml" <html xmlns="http://www.w3.org/1999/xhtml"
xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:tal="http://xml.zope.org/namespaces/tal"
@ -9,6 +9,7 @@
<title metal:define-slot="title">Website title</title> <title metal:define-slot="title">Website title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" /> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15" />
<link rel="stylesheet" title="Default" href="/css/wretched.css" /> <link rel="stylesheet" title="Default" href="/css/wretched.css" />
<script metal:use-macro="forms.tal/formScript"></script>
</head> </head>
<body> <body>
<div id="header"> <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