2007-06-23 14:53:39 +00:00
|
|
|
|
//
|
|
|
|
|
|
// The Antville Project
|
|
|
|
|
|
// http://code.google.com/p/antville
|
|
|
|
|
|
//
|
|
|
|
|
|
// Copyright 2001-2007 by The Antville People
|
|
|
|
|
|
//
|
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the ``License'');
|
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
|
//
|
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
//
|
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
|
// distributed under the License is distributed on an ``AS IS'' BASIS,
|
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
//
|
|
|
|
|
|
// $Revision$
|
|
|
|
|
|
// $LastChangedBy$
|
|
|
|
|
|
// $LastChangedDate$
|
|
|
|
|
|
// $URL$
|
|
|
|
|
|
//
|
|
|
|
|
|
|
2007-10-12 10:20:46 +00:00
|
|
|
|
app.addRepository(app.dir + "/../lib/rome-0.9.jar");
|
|
|
|
|
|
app.addRepository(app.dir + "/../lib/jdom.jar");
|
|
|
|
|
|
app.addRepository(app.dir + "/../lib/itunes-0.4.jar");
|
|
|
|
|
|
|
2007-10-08 23:55:29 +00:00
|
|
|
|
app.addRepository("modules/core/Global.js");
|
2007-07-29 10:16:10 +00:00
|
|
|
|
app.addRepository("modules/core/HopObject.js");
|
2007-09-14 23:25:23 +00:00
|
|
|
|
app.addRepository("modules/core/Number.js");
|
2007-09-21 13:54:30 +00:00
|
|
|
|
app.addRepository("modules/core/Filters.js");
|
2007-09-14 23:25:23 +00:00
|
|
|
|
|
2007-09-22 21:48:33 +00:00
|
|
|
|
app.addRepository("modules/helma/Image.js");
|
2007-09-08 17:20:59 +00:00
|
|
|
|
app.addRepository("modules/helma/Html.js");
|
2007-10-11 23:03:17 +00:00
|
|
|
|
app.addRepository("modules/helma/Http.js");
|
2007-08-23 17:17:40 +00:00
|
|
|
|
app.addRepository("modules/helma/Mail.js");
|
2007-07-29 10:16:10 +00:00
|
|
|
|
app.addRepository("modules/helma/Search.js");
|
2007-09-26 22:22:37 +00:00
|
|
|
|
app.addRepository("modules/helma/Zip.js");
|
2007-07-29 10:16:10 +00:00
|
|
|
|
|
2007-10-06 10:26:30 +00:00
|
|
|
|
app.addRepository("modules/jala/code/Date.js");
|
2007-09-08 17:20:59 +00:00
|
|
|
|
app.addRepository("modules/jala/code/HopObject.js");
|
2007-08-23 17:17:40 +00:00
|
|
|
|
app.addRepository("modules/jala/code/I18n.js");
|
2008-01-04 17:30:07 +00:00
|
|
|
|
app.addRepository("modules/jala/code/ListRenderer.js");
|
2007-07-29 10:16:10 +00:00
|
|
|
|
app.addRepository("modules/jala/code/Utilities.js");
|
|
|
|
|
|
|
2007-10-12 19:05:33 +00:00
|
|
|
|
app.data.mails || (app.data.mails = []);
|
|
|
|
|
|
app.data.stories || (app.data.stories = {});
|
|
|
|
|
|
|
2007-11-03 22:02:30 +00:00
|
|
|
|
var rome = new JavaImporter(
|
|
|
|
|
|
Packages.com.sun.syndication.feed.synd,
|
|
|
|
|
|
Packages.com.sun.syndication.io.SyndFeedOutput,
|
|
|
|
|
|
Packages.com.sun.syndication.feed.module.itunes,
|
|
|
|
|
|
Packages.com.sun.syndication.feed.module.itunes.types
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
var html = new helma.Html();
|
|
|
|
|
|
|
2008-03-27 15:10:31 +00:00
|
|
|
|
var idle = new Function;
|
|
|
|
|
|
|
2007-11-03 22:02:30 +00:00
|
|
|
|
SHORTDATEFORMAT = "yyyy-MM-dd HH:mm";
|
|
|
|
|
|
LONGDATEFORMAT = "EEEE, d. MMMM yyyy, HH:mm";
|
|
|
|
|
|
|
2007-09-27 17:39:02 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* Extend the Mail prototype with a method that simply adds a mail object
|
|
|
|
|
|
* to an application-wide array (mail queue).
|
|
|
|
|
|
*/
|
|
|
|
|
|
helma.Mail.prototype.queue = function() {
|
2007-10-11 23:03:17 +00:00
|
|
|
|
return app.data.mails.push(this);
|
2008-04-21 13:57:01 +00:00
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
|
2007-10-12 19:05:33 +00:00
|
|
|
|
helma.Mail.flushQueue = function() {
|
|
|
|
|
|
if (app.data.mails.length > 0) {
|
|
|
|
|
|
app.debug("Flushing mail queue, sending " +
|
|
|
|
|
|
app.data.mails.length + " messages");
|
|
|
|
|
|
var mail;
|
|
|
|
|
|
while (app.data.mails.length > 0) {
|
|
|
|
|
|
mail = app.data.mails.pop();
|
|
|
|
|
|
mail.send();
|
|
|
|
|
|
if (mail.status > 0) {
|
2008-03-27 15:10:31 +00:00
|
|
|
|
app.debug("Error while sending e-mail (status " + mail.status + ")");
|
|
|
|
|
|
mail.writeToFile(getProperty("smtp.dir"));
|
2007-10-12 19:05:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
2008-04-21 13:57:01 +00:00
|
|
|
|
}
|
2007-10-12 19:05:33 +00:00
|
|
|
|
|
2007-11-03 22:02:30 +00:00
|
|
|
|
jala.i18n.setLocaleGetter(function() {
|
|
|
|
|
|
return res.handlers.site.getLocale();
|
|
|
|
|
|
});
|
2007-10-11 23:03:17 +00:00
|
|
|
|
|
2008-04-16 23:11:47 +00:00
|
|
|
|
function onStart() {
|
|
|
|
|
|
// FIXME: Does database exist?
|
|
|
|
|
|
/*var db = getDBConnection("antville");
|
|
|
|
|
|
var rows = db.executeRetrieval("select min(id) as id from site");
|
|
|
|
|
|
rows.next();
|
|
|
|
|
|
var id = rows.getColumnItem("id");
|
|
|
|
|
|
//Packages.helma.main.Server.getServer().stopApplication(app.name);
|
|
|
|
|
|
rows.release();*/
|
|
|
|
|
|
|
|
|
|
|
|
// call onStart methods of modules
|
|
|
|
|
|
for (var i in app.modules) {
|
|
|
|
|
|
if (app.modules[i].onStart)
|
|
|
|
|
|
app.modules[i].onStart();
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function defineConstants(ctor /*, arguments */) {
|
|
|
|
|
|
var constants = [], name;
|
|
|
|
|
|
for (var i=1; i<arguments.length; i+=1) {
|
|
|
|
|
|
name = arguments[i].toUpperCase().replace(/\s/g, "");
|
|
|
|
|
|
if (ctor[name]) {
|
2007-10-12 10:20:46 +00:00
|
|
|
|
//app.logger.warn("Constant already defined: " + ctor.name + "." + name);
|
2007-10-11 23:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
ctor[name] = arguments[i];
|
|
|
|
|
|
constants.push({
|
|
|
|
|
|
value: arguments[i],
|
|
|
|
|
|
display: arguments[i]
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
return function() {
|
|
|
|
|
|
return constants;
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function disableMacro(ctor, name) {
|
2008-03-27 15:10:31 +00:00
|
|
|
|
return ctor.prototype[name + "_macro"] = idle;
|
2007-10-12 19:05:33 +00:00
|
|
|
|
}
|
2007-09-27 17:39:02 +00:00
|
|
|
|
|
2007-09-17 21:43:50 +00:00
|
|
|
|
function scheduler() {
|
|
|
|
|
|
flushLog();
|
2007-10-12 19:05:33 +00:00
|
|
|
|
Stories.flushRequests();
|
|
|
|
|
|
helma.Mail.flushQueue();
|
2007-09-17 21:43:50 +00:00
|
|
|
|
// FIXME: root.manage.autoCleanUp();
|
|
|
|
|
|
// FIXME: pingUpdatedSites();
|
|
|
|
|
|
// FIXME: countUsers();
|
2007-10-06 10:26:30 +00:00
|
|
|
|
//app.data.lastAccessLogUpdate = new Date();
|
2007-09-17 21:43:50 +00:00
|
|
|
|
return 5000;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function logAction(context, action) {
|
|
|
|
|
|
if (context) {
|
|
|
|
|
|
root.admin.log.add(new LogEntry(context, action));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
root.admin.log.cache.add(new LogEntry(path[path.length - 1]));
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
/* FIXME: check whether request really should be logged
|
|
|
|
|
|
var site = res.handlers.site ? res.handlers.site: root;
|
|
|
|
|
|
var url = http.evalUrl(req.data.http_referer);
|
|
|
|
|
|
|
|
|
|
|
|
// no logging at all if the referrer comes from the same site
|
|
|
|
|
|
// or is not a http-request
|
|
|
|
|
|
if (!url)
|
|
|
|
|
|
return;
|
|
|
|
|
|
var referrer = url.toString();
|
|
|
|
|
|
var siteHref = site.href().toLowerCase();
|
|
|
|
|
|
if (referrer.toLowerCase().contains(siteHref.substring(0, siteHref.length-1)))
|
|
|
|
|
|
return;
|
|
|
|
|
|
var logObj = new Object();
|
|
|
|
|
|
logObj.storyID = path.Story ? path.Story._id : null;
|
|
|
|
|
|
logObj.siteID = site._id;
|
|
|
|
|
|
logObj.referrer = referrer;
|
|
|
|
|
|
logObj.remoteHost = req.data.http_remotehost;
|
|
|
|
|
|
logObj.browser = req.data.http_browser;
|
|
|
|
|
|
*/
|
|
|
|
|
|
return root.admin.syslogs.add(new SysLog(type, object, text, session.user));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function flushLog() {
|
|
|
|
|
|
var log = root.admin.log;
|
|
|
|
|
|
var n = log.cache.size();
|
|
|
|
|
|
if (n < 1) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
log.cache.forEach(function() {
|
|
|
|
|
|
return log.add(this);
|
|
|
|
|
|
});
|
|
|
|
|
|
res.commit();
|
|
|
|
|
|
log.clearCache();
|
|
|
|
|
|
app.logger.info("Wrote " + n + " log entries to DB");
|
|
|
|
|
|
return;
|
2007-09-14 23:25:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* Renders a string depending on the comparison of two values. If the first
|
|
|
|
|
|
* value equals the second value, the first result will be returned; the
|
|
|
|
|
|
* second result otherwise.
|
|
|
|
|
|
* <p>Example: <code><% if <% macro %> is "value" then "yes!" else "no :(" %></code>
|
|
|
|
|
|
* </p>
|
|
|
|
|
|
* Note that any value or result can be a macro, too. Thus, this can be used as
|
|
|
|
|
|
* a simple implementation of an if-then-else statement by using Helma macros
|
|
|
|
|
|
* only.
|
|
|
|
|
|
* @param {Object} param The default Helma macro parameter object
|
|
|
|
|
|
* @param {String} firstValue The first value
|
|
|
|
|
|
* @param {String} _is_ Syntactic sugar; should be "is" for legibility
|
|
|
|
|
|
* @param {String} secondValue The second value
|
|
|
|
|
|
* @param {String} _then_ Syntactic sugar; should be "then" for legibility
|
|
|
|
|
|
* @param {String} firstResult The first result, ie. the value that will be
|
|
|
|
|
|
* returned if the first value equals the second one
|
|
|
|
|
|
* @param {String} _else_ Syntactic sugar; should be "else" for legibility
|
|
|
|
|
|
* @param {String} secondResult The second result, ie. the value that will be
|
|
|
|
|
|
* returned if the first value does not equal the second one
|
|
|
|
|
|
* @returns The resulting value
|
|
|
|
|
|
* @type String
|
|
|
|
|
|
* @member Global
|
|
|
|
|
|
*/
|
|
|
|
|
|
function if_macro(param, firstValue, _is_, secondValue, _then_, firstResult,
|
|
|
|
|
|
_else_, secondResult) {
|
|
|
|
|
|
return (("" + firstValue) == ("" + secondValue)) ? firstResult : secondResult;
|
|
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function gettext_macro(param, text /*, value1, value2, ...*/) {
|
|
|
|
|
|
var args = [text];
|
|
|
|
|
|
for (var i=2; i<arguments.length; i+=1) {
|
|
|
|
|
|
args.push(arguments[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
return gettext.apply(this, args);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function ngettext_macro(param, singular, plural, value1 /*, value2, value3, ...*/) {
|
|
|
|
|
|
var args = [singular, plural, value1];
|
|
|
|
|
|
for (var i=4; i<arguments.length; i+=1) {
|
|
|
|
|
|
args.push(arguments[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
return ngettext.apply(this, args);
|
|
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-09-08 17:20:59 +00:00
|
|
|
|
function now_macro(param, format) {
|
|
|
|
|
|
return formatDate(new Date, format || param.format);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function link_macro() {
|
|
|
|
|
|
return renderLink.apply(this, arguments);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function renderLink(param, url, text, handler) {
|
|
|
|
|
|
url || (url = param.url || "");
|
|
|
|
|
|
text || (text = param.text || url);
|
|
|
|
|
|
if (!text) {
|
2007-10-08 23:55:29 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
delete param.url;
|
|
|
|
|
|
delete param.text;
|
2008-01-06 14:15:55 +00:00
|
|
|
|
param.title || (param.title = String.EMPTY);
|
2007-10-11 23:03:17 +00:00
|
|
|
|
if (!handler || url.contains(":")) {
|
|
|
|
|
|
param.href = url;
|
|
|
|
|
|
} else if (url.contains("/") || url.contains("?") || url.contains("#")) {
|
|
|
|
|
|
var parts = url.split(/(\/|\?|#)/);
|
|
|
|
|
|
param.href = handler.href(parts[0]) + parts.splice(1).join(String.EMPTY);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
param.href = handler.href(url);
|
|
|
|
|
|
}
|
2008-04-20 17:27:01 +00:00
|
|
|
|
html.link(param, text);
|
2007-10-16 21:36:41 +00:00
|
|
|
|
return;
|
2007-10-11 23:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function breadcrumbs_macro (param, delimiter) {
|
|
|
|
|
|
delimiter || (delimiter = param.separator || " : ");
|
2008-04-16 18:03:41 +00:00
|
|
|
|
var offset = res.handlers.site === root ? 0 : 1;
|
|
|
|
|
|
for (var i=offset; i<path.length-1; i+=1) {
|
2007-10-11 23:03:17 +00:00
|
|
|
|
html.link({href: path[i].href()}, path[i].getTitle());
|
|
|
|
|
|
res.write(delimiter);
|
|
|
|
|
|
}
|
|
|
|
|
|
var title = path[i].getTitle();
|
|
|
|
|
|
if (req.action !== "main" && path[i].main_action) {
|
|
|
|
|
|
html.link({href: path[i].href()}, title);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
res.write(title);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function story_macro(param, id, mode) {
|
|
|
|
|
|
var story = HopObject.getFromPath(id, "stories");
|
|
|
|
|
|
if (!story || !story.getPermission("main")) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
|
|
case "url":
|
|
|
|
|
|
res.write(story.href());
|
|
|
|
|
|
break;
|
|
|
|
|
|
case "link":
|
|
|
|
|
|
html.link({href: story.href()}, story.getTitle());
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
2008-05-12 10:26:01 +00:00
|
|
|
|
story.renderSkin("Story#" + (param.skin || "embed"));
|
2007-10-11 23:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function file_macro(param, id, mode) {
|
|
|
|
|
|
if (!id) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-08 23:55:29 +00:00
|
|
|
|
var file;
|
2007-10-11 23:03:17 +00:00
|
|
|
|
if (id.startsWith("/")) {
|
|
|
|
|
|
name = id.substring(1);
|
2007-10-08 23:55:29 +00:00
|
|
|
|
if (mode === "url") {
|
2007-10-11 23:03:17 +00:00
|
|
|
|
res.write(root.getStaticUrl(name));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
file = root.getStaticFile(name);
|
|
|
|
|
|
res.push();
|
|
|
|
|
|
File.prototype.contentLength_macro.call({
|
|
|
|
|
|
contentLength: file.getLength()
|
|
|
|
|
|
});
|
|
|
|
|
|
res.handlers.file = {
|
|
|
|
|
|
href: root.getStaticUrl(name),
|
|
|
|
|
|
name: name,
|
|
|
|
|
|
contentLength: res.pop()
|
|
|
|
|
|
};
|
|
|
|
|
|
File.prototype.renderSkin("File#main");
|
2007-10-08 23:55:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
file = HopObject.getFromPath(id, "files");
|
2007-10-08 23:55:29 +00:00
|
|
|
|
if (!file) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (mode === "url") {
|
|
|
|
|
|
res.write(file.getUrl());
|
|
|
|
|
|
} else {
|
2007-10-11 23:03:17 +00:00
|
|
|
|
file.renderSkin(param.skin || "File#main");
|
2007-10-08 23:55:29 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function image_macro(param, id, mode) {
|
|
|
|
|
|
if (!id) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
|
2007-10-08 23:55:29 +00:00
|
|
|
|
var image;
|
2007-11-03 11:51:49 +00:00
|
|
|
|
if (id.startsWith("/")) {
|
2008-05-08 16:15:22 +00:00
|
|
|
|
var name = id.substring(1);
|
|
|
|
|
|
image = Images.Default[name] || Images.Default[name + ".gif"];
|
2007-11-03 11:51:49 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
image = HopObject.getFromPath(id, "images");
|
|
|
|
|
|
if (!image && param.fallback) {
|
|
|
|
|
|
image = HopObject.getFromPath(param.fallback, "images");
|
2007-10-08 23:55:29 +00:00
|
|
|
|
}
|
2007-09-22 21:48:33 +00:00
|
|
|
|
}
|
2008-05-08 16:05:03 +00:00
|
|
|
|
|
2007-09-22 21:48:33 +00:00
|
|
|
|
if (!image) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
2007-09-22 21:48:33 +00:00
|
|
|
|
}
|
2008-05-08 16:05:03 +00:00
|
|
|
|
|
2007-09-22 21:48:33 +00:00
|
|
|
|
switch (mode) {
|
2008-01-05 17:57:39 +00:00
|
|
|
|
case "url":
|
2007-10-11 23:03:17 +00:00
|
|
|
|
res.write(image.getUrl());
|
|
|
|
|
|
break;
|
2007-09-22 21:48:33 +00:00
|
|
|
|
case "thumbnail":
|
2008-05-06 09:17:04 +00:00
|
|
|
|
case "popup":
|
|
|
|
|
|
var url = image.getUrl();
|
|
|
|
|
|
html.openTag("a", {href: url});
|
|
|
|
|
|
// FIXME: Bloody popups belong to compatibility layer
|
|
|
|
|
|
(mode === "popup") && (param.onclick = 'javascript:openPopup(\'' +
|
|
|
|
|
|
url + '\', ' + image.width + ', ' + image.height + '); return false;')
|
2007-10-11 23:03:17 +00:00
|
|
|
|
image.thumbnail_macro(param);
|
2008-05-06 09:17:04 +00:00
|
|
|
|
html.closeTag("a");
|
2007-10-11 23:03:17 +00:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
image.render_macro(param);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2007-10-08 23:55:29 +00:00
|
|
|
|
return;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function poll_macro(param, id, mode) {
|
|
|
|
|
|
if (!id) {
|
2007-09-14 00:16:06 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
var poll = HopObject.getFromPath(id, "polls");
|
|
|
|
|
|
if (!poll) {
|
|
|
|
|
|
return;
|
2007-09-30 23:59:13 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
switch (mode) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
case "url":
|
2007-10-11 23:03:17 +00:00
|
|
|
|
res.write(poll.href());
|
|
|
|
|
|
break;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
case "link":
|
2007-10-11 23:03:17 +00:00
|
|
|
|
html.link({
|
|
|
|
|
|
href: poll.href(poll.closed ? "results" : "")
|
|
|
|
|
|
}, poll.question);
|
|
|
|
|
|
break;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
default:
|
2007-10-11 23:03:17 +00:00
|
|
|
|
if (poll.status === Poll.CLOSED || mode === "results")
|
2008-04-27 09:15:03 +00:00
|
|
|
|
poll.renderSkin("$Poll#results");
|
2007-10-11 23:03:17 +00:00
|
|
|
|
else {
|
|
|
|
|
|
res.data.action = poll.href();
|
2008-04-27 09:15:03 +00:00
|
|
|
|
poll.renderSkin("$Poll#main");
|
2007-10-11 23:03:17 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2008-04-21 20:46:29 +00:00
|
|
|
|
function list_macro(param, id, limit) {
|
|
|
|
|
|
if (!id) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2008-05-09 18:42:22 +00:00
|
|
|
|
|
2008-05-12 15:46:36 +00:00
|
|
|
|
var max = Math.min(limit || 25, 50);
|
2007-10-11 23:03:17 +00:00
|
|
|
|
var collection, skin;
|
|
|
|
|
|
if (id === "sites") {
|
2008-01-05 00:44:34 +00:00
|
|
|
|
collection = root.sites.list(0, max);
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Site#preview";
|
2008-01-13 01:39:01 +00:00
|
|
|
|
} else if (id === "updates") {
|
2008-04-21 20:46:29 +00:00
|
|
|
|
collection = root.updates.list(0, limit);
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Site#preview";
|
2007-10-11 23:03:17 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
var site;
|
|
|
|
|
|
var parts = id.split("/");
|
|
|
|
|
|
if (parts.length > 1) {
|
|
|
|
|
|
type = parts[1];
|
|
|
|
|
|
site = root.sites.get(parts[0]);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
type = parts[0];
|
|
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
site || (site = res.handlers.site);
|
|
|
|
|
|
var filter = function(item, index) {
|
|
|
|
|
|
return index < max && item.getPermission("main");
|
2008-04-29 10:25:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var commentFilter = function(item) {
|
2008-04-29 14:36:25 +00:00
|
|
|
|
if (item.story.status !== Story.CLOSED &&
|
2008-04-29 10:25:10 +00:00
|
|
|
|
item.site.commentMode !== Site.DISABLED &&
|
|
|
|
|
|
item.story.commentMode !== Story.CLOSED) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
2008-01-05 00:44:34 +00:00
|
|
|
|
case "comments":
|
|
|
|
|
|
var comments = site.stories.comments;
|
2008-04-29 10:25:10 +00:00
|
|
|
|
collection = comments.list().filter(filter).filter(commentFilter);
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Story#preview";
|
2008-01-05 00:44:34 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case "featured":
|
|
|
|
|
|
collection = site.stories.featured.list(0, max);
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Story#preview";
|
2008-01-05 00:44:34 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
case "images":
|
|
|
|
|
|
collection = site.images.list(0, max);
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Image#preview";
|
2007-10-11 23:03:17 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
2008-01-05 00:44:34 +00:00
|
|
|
|
case "postings":
|
2008-04-28 09:02:34 +00:00
|
|
|
|
content = site.stories.union;
|
2008-04-29 14:36:25 +00:00
|
|
|
|
collection = content.list().filter(filter).filter(function(item) {
|
|
|
|
|
|
if (item.constructor === Comment) {
|
|
|
|
|
|
return commentFilter(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
});
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Story#preview";
|
2007-10-11 23:03:17 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case "stories":
|
|
|
|
|
|
var stories = site.stories.recent;
|
2008-01-05 00:44:34 +00:00
|
|
|
|
var counter = 0;
|
2007-10-11 23:03:17 +00:00
|
|
|
|
collection = stories.list().filter(function(item, index) {
|
2008-01-05 00:44:34 +00:00
|
|
|
|
return item.constructor === Story && filter(item, counter++);
|
2007-10-11 23:03:17 +00:00
|
|
|
|
});
|
2008-05-09 18:42:22 +00:00
|
|
|
|
skin = "Story#preview";
|
2007-10-11 23:03:17 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
2008-01-05 00:44:34 +00:00
|
|
|
|
case "tags":
|
2008-04-21 20:46:29 +00:00
|
|
|
|
return site.tags.list_macro(param, "$Tag#item");
|
2007-10-11 23:03:17 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
2007-06-23 14:53:39 +00:00
|
|
|
|
default:
|
2007-10-11 23:03:17 +00:00
|
|
|
|
break;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
param.skin && (skin = param.skin);
|
|
|
|
|
|
for each (var item in collection) {
|
|
|
|
|
|
item.renderSkin(skin);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
return;
|
2008-04-21 13:57:01 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-11-25 16:24:07 +00:00
|
|
|
|
function value_macro(param, name, value) {
|
2007-11-23 17:57:59 +00:00
|
|
|
|
if (!name) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2008-01-04 14:05:58 +00:00
|
|
|
|
name = name.toLowerCase();
|
2007-11-23 17:57:59 +00:00
|
|
|
|
if (!value) {
|
2008-01-19 17:36:33 +00:00
|
|
|
|
res.write(res.meta.values[name]);
|
2007-11-23 17:57:59 +00:00
|
|
|
|
} else {
|
2008-04-15 21:16:21 +00:00
|
|
|
|
//res.write("/* set " + name + " to " + value + " */");
|
2008-01-04 14:05:58 +00:00
|
|
|
|
res.meta.values[name] = value;
|
2007-11-23 17:57:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function randomize_macro(param, id) {
|
|
|
|
|
|
var getRandom = function(n) {
|
|
|
|
|
|
return Math.floor(Math.random() * n);
|
|
|
|
|
|
};
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
var site;
|
|
|
|
|
|
if (id === "sites") {
|
|
|
|
|
|
site = root.sites.get(getRandom(root.sites.size()));
|
|
|
|
|
|
site.renderSkin(param.skin || "Site#preview");
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
2007-10-11 23:03:17 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
var parts = id.split("/");
|
|
|
|
|
|
if (parts.length > 1) {
|
|
|
|
|
|
type = parts[1];
|
|
|
|
|
|
site = root.sites.get(parts[0]);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
} else {
|
2007-10-11 23:03:17 +00:00
|
|
|
|
type = parts[0];
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
site || (site = res.handlers.site);
|
|
|
|
|
|
switch (type) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
case "stories":
|
2007-10-11 23:03:17 +00:00
|
|
|
|
var stories = site.stories["public"];
|
|
|
|
|
|
var story = stories.get(getRandom(stories.size()));
|
|
|
|
|
|
story && story.renderSkin(param.skin || "Story#preview");
|
|
|
|
|
|
break;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
case "images":
|
2007-10-11 23:03:17 +00:00
|
|
|
|
var image = site.images.get(getRandom(site.images.size()));
|
|
|
|
|
|
image && image.renderSkin(param.skin || "Image#preview");
|
|
|
|
|
|
break;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function validateEmail(str) {
|
|
|
|
|
|
if (str.isEmail()) {
|
|
|
|
|
|
return str;
|
2007-08-23 17:17:40 +00:00
|
|
|
|
}
|
2007-09-08 17:20:59 +00:00
|
|
|
|
return null;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-11 23:03:17 +00:00
|
|
|
|
function validateUrl(str) {
|
|
|
|
|
|
if (str) {
|
|
|
|
|
|
if (url = helma.Http.evalUrl(str)) {
|
|
|
|
|
|
return String(url);
|
|
|
|
|
|
} else if (str.contains("@")) {
|
|
|
|
|
|
return "mailto:" + str;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
return "http://" + str;
|
|
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2007-10-11 23:03:17 +00:00
|
|
|
|
return null;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2008-01-04 14:05:58 +00:00
|
|
|
|
function quote(str) {
|
2008-05-09 19:04:18 +00:00
|
|
|
|
if (/[\W\D]/.test(str)) {
|
2008-01-04 14:05:58 +00:00
|
|
|
|
str = '"' + str + '"';
|
|
|
|
|
|
}
|
|
|
|
|
|
return str;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-04 18:48:35 +00:00
|
|
|
|
function formatNumber(number, pattern) {
|
|
|
|
|
|
return number.format(pattern);
|
2008-04-21 13:57:01 +00:00
|
|
|
|
}
|
2007-10-04 18:48:35 +00:00
|
|
|
|
|
2007-09-08 17:20:59 +00:00
|
|
|
|
function formatDate(date, pattern) {
|
2007-09-17 21:43:50 +00:00
|
|
|
|
if (!date) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2007-09-08 17:20:59 +00:00
|
|
|
|
pattern || (pattern = "short");
|
2007-09-14 23:25:23 +00:00
|
|
|
|
var site = res.handlers.site;
|
2008-04-22 15:20:10 +00:00
|
|
|
|
var format = global[pattern.toUpperCase() + "DATEFORMAT"];
|
2007-09-08 17:20:59 +00:00
|
|
|
|
if (!format) {
|
2007-09-29 00:58:04 +00:00
|
|
|
|
format = pattern;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
try {
|
2007-09-14 23:25:23 +00:00
|
|
|
|
return date.format(format, site.getLocale(), site.getTimeZone());
|
2007-09-17 21:43:50 +00:00
|
|
|
|
} catch (ex) {
|
2007-09-08 17:20:59 +00:00
|
|
|
|
app.log(ex);
|
|
|
|
|
|
return "[Macro error: Invalid date format]";
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2007-09-08 17:20:59 +00:00
|
|
|
|
return;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-12 10:20:46 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* Injects the XSLT stylesheet until Mozilla developers will have mercy.
|
|
|
|
|
|
* @param {String} xml The original XML code
|
|
|
|
|
|
* @returns The XML code with the appropriate element for the XSLT stylesheet
|
|
|
|
|
|
* @type String
|
|
|
|
|
|
*/
|
|
|
|
|
|
function injectXslDeclaration(xml) {
|
|
|
|
|
|
res.push();
|
|
|
|
|
|
renderSkin("Global#xslDeclaration");
|
|
|
|
|
|
return xml.replace(/(\?>\r?\n?)/, "$1" + res.pop());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-06-23 14:53:39 +00:00
|
|
|
|
/**
|
2007-10-12 19:05:33 +00:00
|
|
|
|
* General mail sending function. Mails will be queued in app.data.mails.
|
|
|
|
|
|
* @param {String} sender The sender's e-mail address
|
|
|
|
|
|
* @param {Object} recipient The recipient's email addresses
|
|
|
|
|
|
* @param {String} subject The e-mail's subject
|
|
|
|
|
|
* @param {String} body The body text of the e-mail
|
|
|
|
|
|
* @return The status code of the underlying helma.Mail instance.
|
|
|
|
|
|
* @type Number
|
2007-06-23 14:53:39 +00:00
|
|
|
|
*/
|
2007-10-12 19:05:33 +00:00
|
|
|
|
function sendMail(sender, recipient, subject, body) {
|
2007-11-23 17:57:59 +00:00
|
|
|
|
if (!recipient || !body) {
|
2007-10-15 23:29:03 +00:00
|
|
|
|
throw Error("Insufficient arguments in method sendMail()");
|
2007-10-12 19:05:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
var mail = new helma.Mail();
|
2007-11-23 17:57:59 +00:00
|
|
|
|
mail.setFrom("noreply@antville.org");
|
2007-10-12 19:05:33 +00:00
|
|
|
|
if (recipient instanceof Array) {
|
|
|
|
|
|
for (var i in recipient) {
|
|
|
|
|
|
mail.addBCC(recipient[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
mail.addTo(recipient);
|
|
|
|
|
|
}
|
|
|
|
|
|
mail.setSubject(subject);
|
|
|
|
|
|
mail.setText(body);
|
2008-04-21 13:35:50 +00:00
|
|
|
|
mail.addText(renderSkinAsString("$Global#disclaimer"));
|
2007-10-12 19:05:33 +00:00
|
|
|
|
mail.queue();
|
|
|
|
|
|
return mail.status;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getLocale(language) {
|
|
|
|
|
|
return java.util.Locale[(language || "english").toUpperCase()];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Creates an array of all available Java locales sorted by their names.
|
|
|
|
|
|
* @param {String} language The optional language of the locales
|
|
|
|
|
|
* @returns The sorted array containing the locales
|
|
|
|
|
|
* @type Array
|
|
|
|
|
|
* @member Global
|
|
|
|
|
|
*/
|
|
|
|
|
|
function getLocales(language) {
|
|
|
|
|
|
var result = [], locale;
|
|
|
|
|
|
var displayLocale = getLocale(language);
|
|
|
|
|
|
var locales = java.util.Locale.getAvailableLocales();
|
|
|
|
|
|
for (var i in locales) {
|
|
|
|
|
|
locale = locales[i].toString();
|
|
|
|
|
|
result.push({
|
|
|
|
|
|
value: locale,
|
|
|
|
|
|
display: locales[i].getDisplayName(displayLocale),
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
result.sort(new String.Sorter("display"));
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getTimeZones(language) {
|
|
|
|
|
|
var result = [], timeZone, offset;
|
|
|
|
|
|
var locale = getLocale(language);
|
|
|
|
|
|
var zones = java.util.TimeZone.getAvailableIDs();
|
|
|
|
|
|
for each (var zone in zones) {
|
|
|
|
|
|
timeZone = java.util.TimeZone.getTimeZone(zone);
|
|
|
|
|
|
offset = timeZone.getRawOffset();
|
|
|
|
|
|
/*res.debug("zone id: " + zone)
|
|
|
|
|
|
res.debug("offset: " + timeZone.getRawOffset())
|
|
|
|
|
|
res.debug("dst savings: " + timeZone.getDSTSavings())
|
|
|
|
|
|
res.debug("old code: " + formatter.format(offset / Date.ONEHOUR))
|
|
|
|
|
|
res.debug("new code: " + (offset / Date.ONEHOUR).format("+00;-00") + ":" +
|
|
|
|
|
|
(Math.abs(offset % Date.ONEHOUR) / Date.ONEMINUTE).format("00"))*/
|
|
|
|
|
|
result.push({
|
|
|
|
|
|
value: zone,
|
|
|
|
|
|
display: zone + " (UTC" + (offset / Date.ONEHOUR).format("+00;-00") +
|
|
|
|
|
|
":" + (Math.abs(offset % Date.ONEHOUR) /
|
|
|
|
|
|
Date.ONEMINUTE).format("00") + ")"
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
result.sort(new String.Sorter("display"));
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function getDateFormats(type, language) {
|
|
|
|
|
|
var patterns;
|
|
|
|
|
|
if (type === "short") {
|
|
|
|
|
|
patterns = [SHORTDATEFORMAT, "yyyy/MM/dd HH:mm",
|
|
|
|
|
|
"yyyy.MM.dd, HH:mm", "d. MMMM, HH:mm", "MMMM d, HH:mm",
|
|
|
|
|
|
"d. MMM, HH:mm", "MMM d, HH:mm", "EEE, d. MMM, HH:mm",
|
|
|
|
|
|
"EEE MMM d, HH:mm", "EEE, HH:mm", "EE, HH:mm", "HH:mm"];
|
|
|
|
|
|
} else if (type === "long") {
|
|
|
|
|
|
patterns = [LONGDATEFORMAT, "EEEE, MMMM dd, yyyy, HH:mm",
|
|
|
|
|
|
"EE, d. MMM. yyyy, HH:mm", "EE MMM dd, yyyy, HH:mm",
|
|
|
|
|
|
"EE yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm", "d. MMMM yyyy, HH:mm",
|
|
|
|
|
|
"MMMM d, yyyy, HH:mm", "d. MMM yyyy, HH:mm", "MMM d, yyyy, HH:mm"];
|
|
|
|
|
|
}
|
|
|
|
|
|
var result = [], sdf;
|
|
|
|
|
|
var locale = getLocale(language);
|
|
|
|
|
|
var now = new Date;
|
|
|
|
|
|
for each (var pattern in patterns) {
|
|
|
|
|
|
sdf = new java.text.SimpleDateFormat(pattern, locale);
|
|
|
|
|
|
result.push([encodeForm(pattern), sdf.format(now)]);
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function age_filter(value, param) {
|
|
|
|
|
|
if (!value || value.constructor !== Date) {
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
return value.getAge()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function link_filter(value, param, url) {
|
|
|
|
|
|
if (value) {
|
|
|
|
|
|
url || (url = value);
|
|
|
|
|
|
return renderLink(param, url, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function format_filter(value, param, pattern) {
|
|
|
|
|
|
if (!value && value !== 0) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
var f = global["format" + value.constructor.name];
|
|
|
|
|
|
if (f && f.constructor === Function) {
|
|
|
|
|
|
return f(value, pattern || param.pattern);
|
|
|
|
|
|
}
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function clip_filter(input, param, limit, clipping, delimiter) {
|
|
|
|
|
|
var len = 0;
|
|
|
|
|
|
if (input) {
|
|
|
|
|
|
len = input.length;
|
|
|
|
|
|
input = input.stripTags();
|
|
|
|
|
|
}
|
|
|
|
|
|
input || (input = ngettext("({0} character)", "({0} characters)", len));
|
|
|
|
|
|
limit || (limit = 20);
|
|
|
|
|
|
clipping || (clipping = "...");
|
|
|
|
|
|
delimiter || (delimiter = "\\s");
|
|
|
|
|
|
return String(input || "").head(limit, clipping, delimiter);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME:
|
2007-06-23 14:53:39 +00:00
|
|
|
|
function fixRssText(str) {
|
|
|
|
|
|
var re = new RegExp("<img src\\s*=\\s*\"?([^\\s\"]+)?\"?[^>]*?(alt\\s*=\\s*\"?([^\"]+)?\"?[^>]*?)?>", "gi");
|
|
|
|
|
|
str = str.replace(re, "[<a href=\"$1\" title=\"$3\">Image</a>]");
|
|
|
|
|
|
return str;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-12 19:05:33 +00:00
|
|
|
|
// FIXME:
|
2007-06-23 14:53:39 +00:00
|
|
|
|
function countUsers() {
|
|
|
|
|
|
app.data.activeUsers = new Array();
|
|
|
|
|
|
var l = app.getActiveUsers();
|
|
|
|
|
|
for (var i in l)
|
|
|
|
|
|
app.data.activeUsers[app.data.activeUsers.length] = l[i];
|
|
|
|
|
|
l = app.getSessions();
|
|
|
|
|
|
app.data.sessions = 0;
|
|
|
|
|
|
for (var i in l) {
|
|
|
|
|
|
if (!l[i].user)
|
|
|
|
|
|
app.data.sessions++;
|
|
|
|
|
|
}
|
|
|
|
|
|
app.data.activeUsers.sort();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-12 19:05:33 +00:00
|
|
|
|
// FIXME:
|
|
|
|
|
|
function pingUpdatedSites() {
|
|
|
|
|
|
var c = getDBConnection("antville");
|
|
|
|
|
|
var dbError = c.getLastError();
|
|
|
|
|
|
if (dbError) {
|
|
|
|
|
|
app.log("Error establishing DB connection: " + dbError);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2007-10-12 19:05:33 +00:00
|
|
|
|
|
|
|
|
|
|
var query = "select name from site where mode = 'online' and " +
|
|
|
|
|
|
"SITE_ENABLEPING = 1 and (SITE_LASTUPDATE > SITE_LASTPING or SITE_LASTPING is null)";
|
|
|
|
|
|
var rows = c.executeRetrieval(query);
|
|
|
|
|
|
var dbError = c.getLastError();
|
|
|
|
|
|
if (dbError) {
|
|
|
|
|
|
app.log("Error executing SQL query: " + dbError);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (rows.next()) {
|
|
|
|
|
|
var site = root.get(rows.getColumnItem("name"));
|
|
|
|
|
|
app.log("Notifying weblogs.com for updated site '" + site.alias +
|
|
|
|
|
|
"' (id " + site._id + ")");
|
|
|
|
|
|
site.ping();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
rows.release();
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-12 19:05:33 +00:00
|
|
|
|
// FIXME:
|
2007-06-23 14:53:39 +00:00
|
|
|
|
function extractContent(param, origContent) {
|
|
|
|
|
|
var result = {isMajorUpdate: false, exists: false, value: new HopObject()};
|
|
|
|
|
|
for (var i in param) {
|
|
|
|
|
|
if (i.startsWith("content_")) {
|
|
|
|
|
|
var partName = i.substring(8);
|
|
|
|
|
|
var newContentPart = param[i].trim();
|
|
|
|
|
|
// check if there's a difference between old and
|
|
|
|
|
|
// new text of more than 50 characters:
|
|
|
|
|
|
if (!result.isMajorUpdate && origContent) {
|
|
|
|
|
|
var len1 = origContent[partName] ? origContent[partName].length : 0;
|
|
|
|
|
|
var len2 = newContentPart.length;
|
|
|
|
|
|
result.isMajorUpdate = Math.abs(len1 - len2) >= 50;
|
|
|
|
|
|
}
|
|
|
|
|
|
result.value[partName] = newContentPart;
|
|
|
|
|
|
if (newContentPart)
|
|
|
|
|
|
result.exists = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2007-10-12 19:05:33 +00:00
|
|
|
|
// FIXME:
|
2007-06-23 14:53:39 +00:00
|
|
|
|
function doWikiStuff (src) {
|
|
|
|
|
|
// robert, disabled: didn't get the reason for this:
|
|
|
|
|
|
// var src= " "+src;
|
|
|
|
|
|
if (src == null || !src.contains("<*"))
|
|
|
|
|
|
return src;
|
|
|
|
|
|
|
|
|
|
|
|
// do the Wiki link thing, <*asterisk style*>
|
|
|
|
|
|
var regex = new RegExp ("<[*]([^*]+)[*]>");
|
|
|
|
|
|
regex.ignoreCase=true;
|
|
|
|
|
|
|
|
|
|
|
|
var text = "";
|
|
|
|
|
|
var start = 0;
|
|
|
|
|
|
while (true) {
|
|
|
|
|
|
var found = regex.exec (src.substring(start));
|
|
|
|
|
|
var to = found == null ? src.length : start + found.index;
|
|
|
|
|
|
text += src.substring(start, to);
|
|
|
|
|
|
if (found == null)
|
|
|
|
|
|
break;
|
|
|
|
|
|
var name = ""+(new java.lang.String (found[1])).trim();
|
|
|
|
|
|
var item = res.handlers.site.topics.get (name);
|
|
|
|
|
|
if (item == null && name.lastIndexOf("s") == name.length-1)
|
|
|
|
|
|
item = res.handlers.site.topics.get (name.substring(0, name.length-1));
|
|
|
|
|
|
if (item == null || !item.size())
|
|
|
|
|
|
text += format(name)+" <small>[<a href=\""+res.handlers.site.stories.href("create")+"?topic="+escape(name)+"\">define "+format(name)+"</a>]</small>";
|
|
|
|
|
|
else
|
|
|
|
|
|
text += "<a href=\""+item.href()+"\">"+name+"</a>";
|
|
|
|
|
|
start += found.index + found[1].length+4;
|
|
|
|
|
|
}
|
|
|
|
|
|
return text;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2008-01-13 01:39:01 +00:00
|
|
|
|
// FIXME: Rewrite with jala.ListRenderer?
|
2007-06-23 14:53:39 +00:00
|
|
|
|
function renderList(collection, funcOrSkin, itemsPerPage, pageIdx) {
|
2008-01-13 01:39:01 +00:00
|
|
|
|
var currIdx = 0, item;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
var isArray = collection instanceof Array;
|
|
|
|
|
|
var stop = size = isArray ? collection.length : collection.size();
|
|
|
|
|
|
|
|
|
|
|
|
if (itemsPerPage) {
|
|
|
|
|
|
var totalPages = Math.ceil(size/itemsPerPage);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
if (isNaN(pageIdx) || pageIdx > totalPages || pageIdx < 0) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
pageIdx = 0;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
currIdx = pageIdx * itemsPerPage;
|
|
|
|
|
|
stop = Math.min(currIdx + itemsPerPage, size);
|
|
|
|
|
|
}
|
2008-01-13 01:39:01 +00:00
|
|
|
|
|
2007-06-23 14:53:39 +00:00
|
|
|
|
var isFunction = (funcOrSkin instanceof Function) ? true : false;
|
|
|
|
|
|
res.push();
|
|
|
|
|
|
while (currIdx < stop) {
|
2008-01-13 01:39:01 +00:00
|
|
|
|
item = isArray ? collection[currIdx] : collection.get(currIdx);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
isFunction ? funcOrSkin(item) : item.renderSkin(funcOrSkin);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
currIdx += 1;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
return res.pop();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2008-01-13 01:39:01 +00:00
|
|
|
|
// FIXME: Rewrite using jala.ListRenderer?
|
|
|
|
|
|
function renderPager(collectionOrSize, url, itemsPerPage, pageIdx) {
|
|
|
|
|
|
// Render a single item for the navigation bar
|
2007-06-23 14:53:39 +00:00
|
|
|
|
var renderItem = function(text, cssClass, url, page) {
|
|
|
|
|
|
var param = {"class": cssClass};
|
2008-01-13 01:39:01 +00:00
|
|
|
|
if (!url) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
param.text = text;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
} else {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
if (url.contains("?"))
|
2007-09-27 17:39:02 +00:00
|
|
|
|
param.text = html.linkAsString({href: url + "&page=" + page}, text);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
else
|
2007-09-27 17:39:02 +00:00
|
|
|
|
param.text = html.linkAsString({href: url + "?page=" + page}, text);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2008-04-30 14:08:03 +00:00
|
|
|
|
renderSkin("$Global#pagerItem", param);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var maxItems = 10;
|
|
|
|
|
|
var size = 0;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
if (collectionOrSize instanceof Array) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
size = collectionOrSize.length;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
} else if (collectionOrSize instanceof HopObject) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
size = collectionOrSize.size();
|
2008-01-13 01:39:01 +00:00
|
|
|
|
} else if (!isNaN(collectionOrSize)) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
size = parseInt(collectionOrSize, 10);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
var lastPageIdx = Math.ceil(size/itemsPerPage)-1;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
// If there's just one page no navigation will be rendered
|
|
|
|
|
|
if (lastPageIdx <= 0) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
return null;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
2007-06-23 14:53:39 +00:00
|
|
|
|
|
2008-01-13 01:39:01 +00:00
|
|
|
|
// Initialize the parameter object
|
2007-06-23 14:53:39 +00:00
|
|
|
|
var param = {};
|
|
|
|
|
|
var pageIdx = parseInt(pageIdx, 10);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
// Check if the passed index is correct
|
|
|
|
|
|
if (isNaN(pageIdx) || pageIdx > lastPageIdx || pageIdx < 0) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
pageIdx = 0;
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
param.display = ((pageIdx * itemsPerPage) + 1) + "-" +
|
|
|
|
|
|
(Math.min((pageIdx * itemsPerPage) + itemsPerPage, size));
|
2007-06-23 14:53:39 +00:00
|
|
|
|
param.total = size;
|
|
|
|
|
|
|
2008-01-13 01:39:01 +00:00
|
|
|
|
// Render the navigation-bar
|
2007-06-23 14:53:39 +00:00
|
|
|
|
res.push();
|
2008-04-30 14:08:03 +00:00
|
|
|
|
(pageIdx > 0) && renderItem("[–]", "pageNavItem", url, pageIdx-1);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
var offset = Math.floor(pageIdx / maxItems) * maxItems;
|
|
|
|
|
|
(offset > 0) && renderItem("[..]", "pageNavItem", url, offset-1);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
var currPage = offset;
|
|
|
|
|
|
var stop = Math.min(currPage + maxItems, lastPageIdx+1);
|
|
|
|
|
|
while (currPage < stop) {
|
2008-01-13 01:39:01 +00:00
|
|
|
|
if (currPage === pageIdx) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
renderItem("[" + (currPage +1) + "]", "pageNavSelItem");
|
2008-01-13 01:39:01 +00:00
|
|
|
|
} else {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
renderItem("[" + (currPage +1) + "]", "pageNavItem", url, currPage);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
currPage += 1;
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2008-01-13 01:39:01 +00:00
|
|
|
|
if (currPage < lastPageIdx) {
|
2007-06-23 14:53:39 +00:00
|
|
|
|
renderItem("[..]", "pageNavItem", url, offset + maxItems);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
if (pageIdx < lastPageIdx) {
|
2008-04-30 14:08:03 +00:00
|
|
|
|
renderItem("[+]", "pageNavItem", url, pageIdx +1);
|
2008-01-13 01:39:01 +00:00
|
|
|
|
}
|
2008-01-13 01:44:36 +00:00
|
|
|
|
param.pager = res.pop();
|
2008-04-30 14:08:03 +00:00
|
|
|
|
return renderSkinAsString("$Global#pager", param);
|
2007-06-23 14:53:39 +00:00
|
|
|
|
}
|
2007-08-04 15:52:44 +00:00
|
|
|
|
|
|
|
|
|
|
function singularize(plural) {
|
|
|
|
|
|
if (plural.endsWith("ies")) {
|
|
|
|
|
|
return plural.substring(0, plural.length-3) + "y";
|
|
|
|
|
|
}
|
|
|
|
|
|
return plural.substring(0, plural.length-1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function pluralize(singular) {
|
|
|
|
|
|
if (singular.endsWith("y")) {
|
|
|
|
|
|
return singular.substring(0, singular.length-1) + "ies";
|
|
|
|
|
|
}
|
|
|
|
|
|
return singular + "s";
|
|
|
|
|
|
}
|