* Replaced occurrences of User.visisted with User.modified

* Set application's charset to UTF8
 * Added Layout.getFile() method returning the layout's directory as helma.File
 * Simplified Layout.getSkinPath() method (still work in progress)
 * Replaced occurrences of Site.language with Site.locale
 * Modified some wording
 * Added slight b/w compatibility fix in Story.macro_filter() method
 * Added timex factor in Story.getDelta() method to prevent counting  edits as site updates in-beteen 10 minutes
 * Moved site-related aspect hooks to Site prototype of compatibility module
 * Removed obsolete conversion code in compatibility module (has moved to updater app)
 * Re-included spacer_macro() method in compat. module
 * Temporarily overwrote HopObject.renderSkin() method to debug skin rendering process
 * Replaced individual legacy macros of Layout prototype by appropriate code in onUnhandledMacro() method (compat.)
 * Reflect legacy macros of Layout prototype in value() method of compat. module
 * Added and improved compatibility methods
 * Implemented support for renamed prototypes in updater app (still needs to be applied for database, too)
This commit is contained in:
Tobi Schäfer 2007-10-21 16:49:16 +00:00
parent 1df1c87525
commit aa11e5db88
23 changed files with 578 additions and 650 deletions

View file

@ -366,7 +366,7 @@ Admin.prototype.filterUsers = function(data) {
sql += "order by name "; break;
case "0":
default:
sql += "order by visited "; break;
sql += "order by modified "; break;
}
(data.dir == 1) || (sql += "desc");
this.users.subnodeRelation = sql;

View file

@ -232,7 +232,7 @@ If this site is open it will replace the default front page.
<a href="<% item.url %>"><% item.url %></a></div>
<div class="small">
registered: <% item.created | format "yyyy-MM-dd HH:mm" %><br />
last visit: <% item.visited | format "yyyy-MM-dd HH:mm" %>
last visit: <% item.modified | format "yyyy-MM-dd HH:mm" %>
</div>
</td>
<td class="small" valign="top" align="right">

View file

@ -206,12 +206,7 @@ Image.prototype.getFile = function(name) {
name || (name = this.name);
if (this.parent_type === "Layout") {
var layout = this.parent || res.handlers.layout;
res.push();
res.write("layouts/");
res.write(layout.name);
res.write("/");
res.write(name);
return layout.site.getStaticFile(res.pop());
return layout.getFile() + "/" + name;
}
var site = this.parent || res.handlers.site;
return site.getStaticFile("images/" + name);

View file

@ -285,19 +285,22 @@ Layout.prototype.getImage = function(name, fallback) {
return null;
};
Layout.prototype.getFile = function() {
return this.site.getStaticFile("layouts/" + this.name);
};
Layout.prototype.getSkinPath = function() {
// FIXME: Do we need this or not?
/* if (!this.site) {
return [app.dir];
} */
var skinPath = [];
var skinPath = [this.getFile().toString()];
this.parent && (skinPath.push(this.parent.getFile().toString()));
return skinPath;
var layout = this;
do {
res.push();
res.write(getProperty("staticPath"));
layout.site && res.write(layout.site.name + "/");
res.write("layouts/");
res.write(layout.alias);
res.write(layout.name);
skinPath.push(res.pop());
} while (layout = layout.parent);
return skinPath;

View file

@ -202,7 +202,7 @@ Root.prototype.updates_xml_action = function() {
feed.setLink(root.href());
feed.setTitle(root.title);
feed.setDescription(root.tagline);
feed.setLanguage(root.language.replace("_", "-"));
feed.setLanguage(root.locale.replace("_", "-"));
feed.setPublishedDate(now);
var entries = new java.util.ArrayList();
var entry, description;

View file

@ -34,8 +34,8 @@ Site.getWebHookModes = defineConstants(Site, "disabled", "enabled");
this.handleMetadata("archiveMode");
this.handleMetadata("commentMode");
this.handleMetadata("email");
this.handleMetadata("language");
this.handleMetadata("lastUpdate");
this.handleMetadata("locale");
this.handleMetadata("longDateFormat");
this.handleMetadata("notificationMode");
this.handleMetadata("notifiedOfBlocking");
@ -72,8 +72,7 @@ Site.prototype.constructor = function(name, title) {
notificationMode: Site.DISABLED,
pageMode: Site.DAYS,
pageSize: 3,
language: locale.getLanguage(),
country: locale.getCountry(),
locale: locale.toString(),
timeZone: root.getTimeZone().getID(),
longDateFormat: LONGDATEFORMAT,
shortDateFormat: SHORTDATEFORMAT
@ -117,6 +116,8 @@ Site.prototype.getPermission = function(action) {
Site.prototype.main_action = function() {
res.data.body = this.renderSkinAsString("Site#main");
res.data.body += '\n<script type="text/javascript" src="' +
root.getStaticUrl("jquery-1.1.3.1.pack.js") + '"></script>\n';
res.data.title = this.title;
this.renderSkin("page");
logAction();
@ -157,7 +158,7 @@ Site.prototype.getFormOptions = function(name) {
return Site.getArchiveModes();
case "commentMode":
return Site.getCommentModes();
case "language":
case "locale":
return getLocales();
case "layout":
return this.getLayouts();
@ -213,7 +214,7 @@ Site.prototype.update = function(data) {
timeZone: data.timeZone,
longDateFormat: data.longDateFormat,
shortDateFormat: data.shortDateFormat,
language: data.language,
locale: data.locale,
layout: Layout.getById(data.layout)
});
this.touch();
@ -268,7 +269,7 @@ Site.prototype.getXml = function() {
feed.setLink(this.href());
feed.setTitle(this.title);
feed.setDescription(this.tagline);
feed.setLanguage(this.language.replace("_", "-"));
feed.setLanguage(this.locale.replace("_", "-"));
feed.setPublishedDate(now);
/*
@ -427,6 +428,7 @@ Site.prototype.robots_txt_action = function() {
Site.prototype.getMacroHandler = function(name) {
switch (name) {
case "archive":
case "files":
case "images":
case "layouts":
@ -471,8 +473,7 @@ Site.prototype.calendar_macro = function(param) {
};
Site.prototype.age_macro = function(param) {
//res.write(this.createtime.getAge());
res.write(Math.floor((new Date() - this.createtime) / Date.ONEDAY));
res.write(Math.floor((new Date() - this.created) / Date.ONEDAY));
return;
};
@ -513,16 +514,13 @@ Site.prototype.getLayouts = function() {
};
Site.prototype.getLocale = function() {
var locale, language, country;
var locale;
if (locale = this.cache.locale) {
return locale;
}
if (language = this.language) {
if (country = this.country) {
locale = new java.util.Locale(language, country);
} else {
locale = new java.util.Locale(language);
}
} else if (this.locale) {
var parts = this.locale.split("_");
locale = new java.util.Locale(parts[0] || String.EMPTY,
parts[1] || String.EMPTY, parts.splice(2).join("_"));
} else {
locale = java.util.Locale.getDefault();
}

View file

@ -109,7 +109,7 @@ REGEDIT4
</tr>
<tr>
<td class="small">Language:</td>
<td><% site.select language %></td>
<td><% site.select locale %></td>
</tr>
<tr>
<td class="small">Time zone:</td>

View file

@ -73,7 +73,7 @@
<div class="boxheader">calendar</div>
<div class="box"><% site.calendar %></div>
<div class="boxheader">recent postings</div>
<div class="boxheader">recent updates</div>
<div class="box"><% list postings skin=Story#history %></div>
<div class="boxline"></div><br />

View file

@ -440,7 +440,7 @@ Story.prototype.format_filter = function(value, param, mode) {
};
Story.prototype.macro_filter = function(value, param) {
var skin = createSkin(format(value));
var skin = value.constructor === String ? createSkin(format(value)) : value;
skin.allowMacro("image");
skin.allowMacro("this.image");
skin.allowMacro("site.image");
@ -509,5 +509,7 @@ Story.prototype.getDelta = function(data) {
delta += deltify(data.key, this.metadata.get(key))
}
}
return delta;
// In-between updates (10 min) get zero delta
var timex = (new Date - this.modified) > Date.ONEMINUTE * 10 ? 1 : 0;
return delta * timex;
};

View file

@ -46,7 +46,6 @@ User.prototype.constructor = function(data) {
salt: session.data.token,
email: data.email,
status: User.REGULAR,
visited: now,
created: now,
modified: now
});
@ -87,7 +86,7 @@ User.prototype.update = function(data) {
};
User.prototype.touch = function() {
this.modified = this.visited = new Date;
this.modified = new Date;
return;
};

View file

@ -32,7 +32,6 @@ name
email
status
visited
created
modified

View file

@ -25,6 +25,7 @@
rootId = 1
rootPrototype = Root
charset = UTF8
skinCharset = UTF8
requestTimeout = 300

View file

@ -255,6 +255,16 @@ function username_macro(param) {
return;
}
function spacer_macro(param) {
param.width || (param.width = 2);
param.height || (param.height = 2);
param.border || (param.border = 0);
param.src = getProperty("staticUrl") + "www/pixel.gif";
param.alt = "";
html.tag("img", param);
return;
}
function renderColorAsString(c) {
if (c && c.isHexColor())
return "#" + c;

View file

@ -13,7 +13,7 @@ HopObject.prototype.onCodeUpdate = function() {
var param = args[0];
return [param, args[1] || param.to, args[2] || param.text];
});
};
}
Image.prototype.onCodeUpdate = function() {
helma.aspects.addAfter(this, "getUrl", function(value, args, func, obj) {
@ -26,39 +26,6 @@ ImageMgr.prototype.onCodeUpdate = function() {
return helma.aspects.addBefore(this, "evalImg", aspects.setTopics);
};
Site.prototype.onCodeUpdate = function() {
helma.aspects.addBefore(this, "navigation_macro", function(args, func, obj) {
var param = args[0];
if (param["for"] === "users" && !param.modules) {
// FIXME: this is left for backwards-compatibility
// sometime in the future we'll get rid of the usernavigation.skin
res.write("...&nbsp;");
html.link({href: "http://project.antville.org/stories/146"},
"<strong>README</strong>");
html.tag("br");
html.tag("br");
this.renderSkin("usernavigation");
}
return args;
});
return helma.aspects.addBefore(this, "update", function(args, func, obj) {
if (!obj.isTransient()) {
var data = args[0];
data.tagline || (data.tagline = data.properties_tagline);
data.pageSize || (data.pageSize = data.properties_days);
if (data.usermaycontrib && data.online) {
data.mode = Site.OPEN;
} else if (data.online) {
data.mode = Site.PUBLIC;
} else if (!data.mode) {
data.mode = Site.PRIVATE;
}
}
return args;
});
};
Story.prototype.onCodeUpdate = function() {
return helma.aspects.addBefore(this, "evalStory", aspects.setTopics);
};

View file

@ -1,455 +0,0 @@
Root.prototype.convert_action = function() {
return convert(req.data.type);
};
var convert = function(type) {
type || (type = String.EMPTY);
var rows, sql, counter = 1;
var db = getDBConnection("antville");
function quote(s) {
return "'" + s.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
}
function forEachRow(callback) {
return app.invokeAsync(null, function() {
if (!rows) {
return;
}
while (rows.next()) {
callback(rows);
write(".");
}
writeln("");
rows.release();
}, [], -1);
}
switch (type.toLowerCase()) {
case "files":
rows = db.executeRetrieval("select count(*) as max from av_file");
rows.next();
var max = rows.getColumnItem("max");
rows.release();
var query = "select file_id as id, file_name as fileName, " +
"file_alias as name, file_mimetype as type, file_size as size, " +
"file_description as description from av_file order by file_id";
rows = db.executeRetrieval(query);
writeln("Processing rows #1 - #" + max);
forEachRow(function(rows) {
var id = rows.getColumnItem("id");
var metadata = {
fileName: rows.getColumnItem("fileName"),
contentType: rows.getColumnItem("type"),
contentLength: rows.getColumnItem("size"),
description: rows.getColumnItem("description")
};
sql = "update av_file set prototype = 'File', parent_type = 'Site', " +
"parent_id = file_f_site, metadata = " +
quote(metadata.toSource()) + " where file_id = " + id;
db.executeCommand(sql);
//writeln(sql);
});
break;
case "images":
var where = "where img.image_f_image_thumb = thumb.id and " +
"thumb.image_width is not null and thumb.image_height is " +
"not null";
app.invokeAsync(null, function() {
rows = db.executeRetrieval("select count(*) as max from " +
"av_image img, av_image thumb " + where);
rows.next();
var max = rows.getColumnItem("max");
var offset = 0;
rows.release();
do {
var query = "select img.image_id as id, img.image_alias as " +
"name, img.image_filename as fileName, " +
"img.image_fileext as type, img.image_width as " +
"width, img.image_height as height, img.image_alttext as " +
"description, img.image_filesize as size, " +
"img.image_metadata as metadata, thumb.image_width as twd " +
"thumb.image_height as twh from av_image img, " +
"av_image thumb " + where + " order by image_id limit " +
"10000 offset " + offset;
rows = db.executeRetrieval(query);
writeln("Processing rows #" + offset + " - #" + (offset + 10000));
forEachRow(function(rows) {
var id = rows.getColumnItem("id");
var metadata = eval(rows.getColumnItem("metadata")) || {};
metadata.fileName = rows.getColumnItem("fileName") + "." +
rows.getColumnItem("type");
metadata.contentLength = rows.getColumnItem("size") || 0;
metadata.width = rows.getColumnItem("width");
metadata.height = rows.getColumnItem("height");
metadata.description = rows.getColumnItem("description");
metadata.thumbnailName = rows.getColumnItem("fileName") +
"_small" + rows.getColumnItem("type");
metadata.thumbnailWidth = rows.getColumnItem("twd");
metadata.thumbnailHeight = rows.getColumnItem("twh");
sql = "update av_image set image_metadata = " +
quote(metadata.toSource()) + " where image_id = " + id;
db.executeCommand(sql);
//writeln(sql);
}).waitForResult();
res.commit();
offset += 10000;
} while (offset < max);
}, [], -1);
break;
case "layouts":
var query = "select layout_id, layout_title, layout_description, " +
"layout_isimport, layout_preferences_new from av_layout";
rows = db.executeRetrieval(query);
forEachRow(function(rows) {
var id = rows.getColumnItem("layout_id");
var metadata = eval(rows.getColumnItem("layout_preferences_new"));
metadata.title = rows.getColumnItem("layout_title") ||
"Layout #" + id;
metadata.description = rows.getColumnItem("layout_description");
if (rows.getColumnItem("layout_isimport")) {
var layout = Layout.getById(id);
if (layout.site) {
// FIXME: metadata.origin = layout.href();
metadata.origin = "http://" + layout.site.name +
".antville.org/layouts/" + layout.alias + "/";
}
}
sql = "update av_layout set layout_preferences_new = " +
quote(metadata.toSource()) + " where layout_id = " + id;
db.executeCommand(sql);
writeln(sql);
});
break;
case "sites":
var query = "select site_email, site_lastupdate, site_lastoffline, " +
"site_lastblockwarn, site_lastdelwarn, site_lastping, " +
"site_enableping, metadata, mode, title, id from av_site";
rows = db.executeRetrieval(query);
forEachRow(function(rows) {
var id = rows.getColumnItem("id");
var metadata = eval(rows.getColumnItem("metadata"));
metadata.email = rows.getColumnItem("site_email");
metadata.title = rows.getColumnItem("title");
metadata.lastUpdate = rows.getColumnItem("site_lastupdate");
metadata.pageSize = metadata.days || 3;
metadata.pageMode = "days";
metadata.timeZone = metadata.timezone || "CET";
metadata.archiveMode = metadata.archive ? "online" : "offline";
metadata.commentMode = metadata.discussions ? "enabled" : "disabled";
metadata.shortDateFormat = metadata.shortdateformat;
metadata.longDateFormat = metadata.longdateformat;
metadata.offlineSince = rows.getColumnItem("site_lastoffline");
metadata.notifiedOfBlocking = rows.getColumnItem("site_lastblockwarn");
metadata.notifiedOfDeletion = rows.getColumnItem("site_lastdelwarn");
metadata.webHookMode = rows.getColumnItem("site_enableping") ?
"enabled" : "disabled";
metadata.webHookLastUpdate = rows.getColumnItem("site_lastping");
if (metadata.country) {
metadata.locale += "_" + metadata.country;
}
var mode = metadata.usercontrib ? 'open' : rows.getColumnItem("mode");
for each (var key in ["enableping", "usercontrib", "archive",
"discussions", "days", "shortdateformat", "longdateformat",
"linkcolor", "alinkcolor", "vlinkcolor", "smallcolor",
"titlecolor", "titlefont", "textfont", "textcolor", "smallsize",
"smallfont", "textsize", "titlesize", "timezone", "bgcolor",
"country"]) {
delete metadata[key];
}
sql = "update av_site set metadata = " + quote(metadata.toSource()) +
", mode = " + quote(mode) + " where id = " + id;
db.executeCommand(sql);
res.commit();
writeln(sql);
});
break;
case "users":
var query = "select user_id, hash, salt, user_url from av_user";
rows = db.executeRetrieval(query);
while (rows && rows.next()) {
sql = "update av_user set metadata = " + quote({
hash: rows.getColumnItem("hash"),
salt: rows.getColumnItem("salt"),
url: rows.getColumnItem("user_url")
}.toSource()) + " where user_id = " + rows.getColumnItem("user_id");
writeln(sql);
db.executeCommand(sql);
}
break;
}
return;
};
Root.prototype.topic2tag_action = function() {
return;
var db = getDBConnection("antville");
var tagCounter = 1;
var hubCounter = 1;
function quote(s) {
return "'" + s + "'";
}
function createTags(siteId, taggedType) {
var sql;
var query = "select text_topic as tag from av_text where text_f_site = " +
siteId + " and text_topic is not null group by text_topic";
if (taggedType === "Image") {
query = query.replace(/text/g, "image");
}
writeln(query);
var rows = db.executeRetrieval(query);
while (rows && rows.next()) {
sql = "insert into tag values (" + [tagCounter, siteId,
quote(rows.getColumnItem("tag").replace(/^[\/\.]*$/, "?")),
quote(taggedType)] + ")";
writeln(sql);
db.executeCommand(sql);
tagCounter += 1;
}
rows && rows.release();
return;
}
function createHubs(siteId, taggedType) {
var sql;
var query = "select text_topic as name, tag.id as tagId, " +
"text_content_new as meta, text_id as taggedId, " +
"text_f_user_modifier as modifier, text_f_user_creator as " +
"creator, text_f_site as siteId from av_text, tag where " +
"text_topic is not null and text_topic = tag.name and " +
"tag.type = '" + taggedType + "' and text_f_site = " + siteId;
if (taggedType === "Image") {
query = query.replace(/text/g, "image");
query = query.replace(/content_new/g, "metadata");
}
writeln(query);
var rows = db.executeRetrieval(query);
while (rows && rows.next()) {
sql = "insert into tag_hub values (" + [hubCounter,
rows.getColumnItem("tagId"), rows.getColumnItem("taggedId"),
quote(taggedType), rows.getColumnItem("modifier") ||
rows.getColumnItem("creator")] + ")";
writeln(sql);
db.executeCommand(sql);
data = rows.getColumnItem("meta");
if (data) {
data = eval(data);
data.tags = rows.getColumnItem("name");
} else {
data = {tags: rows.getColumnItem("name")};
}
data = data.toSource().replace(/\\/g, "\\\\").replace(/'/g, "\\'");
sql = "update av_text set text_content_new = '" + data +
"' where text_id = " + rows.getColumnItem("taggedId");
if (taggedType === "Image") {
sql = sql.replace(/text/g, "image");
sql = sql.replace(/content_new/g, "metadata");
}
writeln(sql);
db.executeCommand(sql);
hubCounter += 1;
}
rows && rows.release();
return;
}
//var id = 1184; //3;
app.invokeAsync(null, function() {
/* createTags(id, "Story");
createHubs(id, "Story");
createTags(id, "Image");
createHubs(id, "Image");
return; */
var max = root.size();
for (var i=1; i<=max; i+=1) {
var site = root.get(i-1); // Site.getById(11);
app.logger.info("Tagging stories of site " + site._id + " ``" +
site.alias + "'' (" + i + " of " + max + ")");
createTags(site._id, "Story");
createHubs(site._id, "Story");
createTags(site._id, "Image");
createHubs(site._id, "Image");
continue;
var smax = site.stories.size();
counter = 0;
for (var n=0; n<smax; n+=1) {
var story = site.stories.get(n);
if (story.topic) {
//app.logger.info("***** Tagging story " + (n+1) + " of " + smax);
story.tags.add(new TagJoin(story.topic, story, site,
story.modifier || story.creator));
story.content.set("tags", story.topic);
res.commit();
}
}
}
}, [], -1);
};
Root.prototype.xml2json_action = function() {
var db = getDBConnection("antville");
var table, chunkSize = 10000;
var getSql = function(type) {
var sql;
var column = (table === "TEXT" ? "CONTENT" : "PREFERENCES");
switch (type) {
case "create":
sql = "alter table AV_$T add $T_$C_NEW mediumtext default " +
"null after $T_$C";
break;
case "max":
//sql = "select 1 as max";
sql = "select max($T_ID) as max, count($T_ID) as amount from AV_$T";
break;
case "list":
//sql = "select $T_ID, $T_$C from AV_$T where TEXT_F_SITE = 3" +
// " order by $T_ID limit 1000";
sql = "select $T_ID, $T_$C as old, $T_$C_NEW as new from AV_$T " +
"where $T_ID > " + arguments[1] + " order by $T_ID limit " +
chunkSize;
break;
case "update":
sql = "update AV_$T set $T_$C_NEW = '" + arguments[2] +
"' where $T_ID = " + arguments[1];
break;
case "rename":
sql = "alter table AV_$T change $T_$C $T_$C_OLD " +
"mediumtext default null; alter table AV_$T change " +
"$T_$C_NEW $T_$C mediumtext default null";
break;
case "drop":
sql = "drop column $T_PREFERENCES from AV_$T";
break;
default:
throw Error("No such SQL");
}
sql = sql.replace(/\$T/g, table).replace(/\$C/g, column);
//(type !== "update") && writeln(sql);
return sql;
};
app.invokeAsync(null, function() {
var log = new java.io.FileWriter("apps/antville/conversion.log");
var rows, max, amount, data, counter, ref;
var id = 0;
main:
for each (table in ["TEXT"]) {
//for each (table in ["TEXT", "SITE", "LAYOUT"]) {
db.executeCommand(getSql("create"));
rows = db.executeRetrieval(getSql("max"));
rows.next();
max = rows.getColumnItem("max");
amount = rows.getColumnItem("amount");
rows.release();
counter = 0;
while (id < max) {
rows = db.executeRetrieval(getSql("list", id));
while (rows && rows.next()) {
id = rows.getColumnItem(table + "_ID");
if (rows.getColumnItem("new")) {
continue;
} else {
app.debug(id + " has no new data, yet!");
continue;
}
try {
data = rows.getColumnItem("old");
data = data.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
data = Xml.readFromString(data);
db.executeCommand(getSql("update", id,
data.toSource().replace(/\\/g,
"\\\\").replace(/'/g, "\\'")));
} catch (x) {
ref = Story.getById(id) || Comment.getById(id);
log.write(ref.href() + "\n");
log.write(x + "\n");
log.write("***\n");
log.flush();
//app.logger.error("!!! Error in XML data of TEXT_ID " + id);
//app.logger.error(x);
//break main;
}
}
rows && rows.release();
counter += chunkSize;
app.logger.info("Converted " + table + " " + counter + " of " +
amount + " records");
app.logger.info("Current ID: " + id + " of " + max);
}
//db.executeCommand(getSql("rename"));
//db.executeCommand(getSql("drop"));
}
log.write("### Finished conversion with ID " + id);
log.close();
}, [], -1);
};
Root.prototype.exportSkins_action = function() {
var db = getDBConnection("antville");
var exportSkins = function(query) {
var lastId;
var rows = db.executeRetrieval(query);
while (rows && rows.next()) {
var fpath = getProperty("staticPath") + rows.getColumnItem("SITE_ALIAS") +
"/layouts/" + rows.getColumnItem("LAYOUT_ALIAS") + "/" +
rows.getColumnItem("SKIN_PROTOTYPE");
var file = new java.io.File(fpath);
file.mkdirs();
file = new java.io.File(fpath,
rows.getColumnItem("SKIN_NAME").replace(/\//, "_") + ".skin");
//app.logger.info("Exporting skin #" + counter + ": " + file);
file["delete"]();
var fos = new java.io.FileOutputStream(file);
var bos = new java.io.BufferedOutputStream(fos);
var writer = new java.io.OutputStreamWriter(bos, "UTF-8");
//var writer = new java.io.FileWriter(file);
writer.write(rows.getColumnItem("SKIN_SOURCE") || "");
writer.close();
bos.close();
fos.close();
lastId = rows.getColumnItem("SKIN_ID");
}
rows && rows.release();
return lastId;
};
// Export skins of root layouts
exportSkins("select SKIN_ID, 'default' as SITE_ALIAS, LAYOUT_ALIAS, " +
"SKIN_PROTOTYPE, SKIN_NAME, SKIN_SOURCE from AV_LAYOUT, AV_SKIN " +
"where LAYOUT_F_SITE is null and SKIN_F_LAYOUT = LAYOUT_ID;");
// Export skins of site layouts
app.invokeAsync(null, function() {
var counter = 0;
var lastId = 0;
var rows = db.executeRetrieval("select max(SKIN_ID) as max, count(*) " +
"as amount from AV_SKIN");
rows.next()
var max = rows.getColumnItem("max");
var amount = rows.getColumnItem("amount");
rows.release();
while (lastId < max) {
lastId = exportSkins("select SKIN_ID, SITE_ALIAS, LAYOUT_ALIAS, " +
"SKIN_PROTOTYPE, SKIN_NAME, SKIN_SOURCE from AV_SITE, AV_LAYOUT, " +
"AV_SKIN where SKIN_F_LAYOUT = LAYOUT_ID and LAYOUT_F_SITE = " +
"SITE_ID and SKIN_ID > " + lastId + " order by SKIN_ID limit 100;");
counter += 100;
app.logger.info("Exported " + counter + " of " + amount + " skins");
app.logger.info("Current ID: " + lastId + " of " + max);
}
}, [], -1);
return;
};

View file

@ -1,3 +1,17 @@
(function() {
var renderSkin = HopObject.prototype.renderSkin;
HopObject.prototype.renderSkin = function(name) {
res.write(" [[" + this._prototype + "." + name + "]] ");
renderSkin.call(this, name);
}
})();
HopObject.prototype.renderSkinAsString = function(name) {
res.push();
this.renderSkin(name);
return res.pop();
}
HopObject.prototype.createtime_macro = function(param) {
return this.created_macro.apply(this, arguments);
};

View file

@ -74,109 +74,41 @@ Layout.prototype.activatelink_macro = function(param) {
return this.link_macro(param, "activate", param.text || gettext("activate"));
};
Layout.prototype.bgcolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("bgcolor", param));
else
renderColor(this.metadata.get("bgcolor"));
Layout.prototype.value_macro = function(param, name, value) {
if (!name) {
return;
}
var key = ["layout_" + name];
if (!value) {
if (value = this.metadata.get(name.toLowerCase())) {
return value;
}
return res.meta[key];
} else {
this.metadata.set(name.toLowerCase(), value);
res.meta[key] = value;
}
return;
};
Layout.prototype.textfont_macro = function(param) {
if (param.as == "editor") {
param.size = 40;
Html.input(this.metadata.createInputParam("textfont", param));
} else
res.write(this.metadata.get("textfont"));
Layout.prototype.onUnhandledMacro = function(name) {
// FIXME: editors?
switch (name) {
case "bgcolor":
case "linkcolor":
case "alinkcolor":
case "vlinkcolor":
case "titlecolor":
case "textcolor":
case "smallcolor":
renderColor(this.metadata.get(name)); break;
case "textfont":
case "textsize":
case "titlefont":
case "titlesize":
case "smallfont":
case "smallsize":
res.write(this.metadata.get(name)); break;
}
return;
};
Layout.prototype.textsize_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("textsize", param));
else
res.write(this.metadata.get("textsize"));
return;
};
Layout.prototype.textcolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("textcolor", param));
else
renderColor(this.metadata.get("textcolor"));
return;
};
Layout.prototype.linkcolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("linkcolor", param));
else
renderColor(this.metadata.get("linkcolor"));
return;
};
Layout.prototype.alinkcolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("alinkcolor", param));
else
renderColor(this.metadata.get("alinkcolor"));
return;
};
Layout.prototype.vlinkcolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("vlinkcolor", param));
else
renderColor(this.metadata.get("vlinkcolor"));
return;
};
Layout.prototype.titlefont_macro = function(param) {
if (param.as == "editor") {
param.size = 40;
Html.input(this.metadata.createInputParam("titlefont", param));
} else
res.write(this.metadata.get("titlefont"));
return;
};
Layout.prototype.titlesize_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("titlesize", param));
else
res.write(this.metadata.get("titlesize"));
return;
};
Layout.prototype.titlecolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("titlecolor", param));
else
renderColor(this.metadata.get("titlecolor"));
return;
};
Layout.prototype.smallfont_macro = function(param) {
if (param.as == "editor") {
param.size = 40;
Html.input(this.metadata.createInputParam("smallfont", param));
} else
res.write(this.metadata.get("smallfont"));
return;
};
Layout.prototype.smallsize_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("smallsize", param));
else
res.write(this.metadata.get("smallsize"));
return;
};
Layout.prototype.smallcolor_macro = function(param) {
if (param.as == "editor")
Html.input(this.metadata.createInputParam("smallcolor", param));
else
renderColor(this.metadata.get("smallcolor"));
return;
};
}

View file

@ -1,3 +1,28 @@
Site.prototype.onCodeUpdate = function() {
helma.aspects.addBefore(this, "main_action", function(args, func, site) {
res.handlers.day = site.archive;
res.push();
list_macro({}, "stories");
res.data.storylist = res.pop();
return args;
});
return helma.aspects.addBefore(this, "update", function(args, func, site) {
if (!site.isTransient()) {
var data = args[0];
data.tagline || (data.tagline = data.properties_tagline);
data.pageSize || (data.pageSize = data.properties_days);
if (data.usermaycontrib && data.online) {
data.mode = Site.OPEN;
} else if (data.online) {
data.mode = Site.PUBLIC;
} else if (!data.mode) {
data.mode = Site.PRIVATE;
}
}
return args;
});
};
relocateProperty(Site, "alias", "name");
relocateProperty(Site, "createtime", "created");
relocateProperty(Site, "modifytime", "modified");
@ -30,6 +55,46 @@ Site.prototype.__defineGetter__("discussions", function() {
return this.commentsMode === Comment.ONLINE;
});
/*
Site.prototype.renderSkin = function(name) {
switch (name) {
case "stylesheet":
name = "style"; break;
case "Site#main":
name = "main"; break;
}
HopObject.prototype.renderSkin.call(this, name);
}
*/
Site.prototype.link_macro = function(param) {
if (!param.to) {
return;
}
var handler;
var parts = param.to.split("/");
var action = parts[0];
switch (action) {
case "feeds":
case "files":
case "images":
case "layouts":
case "members":
case "polls":
case "stories":
handler = this[action];
if (!handler) {
return;
}
param.to = parts[1];
break;
default:
handler = this;
}
HopObject.prototype.link_macro.call(handler, param, param.to, param.text);
return;
};
Site.prototype.title_macro = function(param) {
if (param.as === "editor") {
this.input_macro(param, "title");
@ -47,6 +112,112 @@ Site.prototype.title_macro = function(param) {
return;
};
Site.prototype.loginstatus_macro = function(param) {
if (session.user) {
this.members.renderSkin("statusloggedin");
} else if (req.action !== "login") {
this.members.renderSkin("statusloggedout");
}
return;
}
Site.prototype.navigation_macro = function(param) {
if (param["for"] == "users" && !param.modules) {
// FIXME: this is left for backwards-compatibility
// sometime in the future we'll get rid of the usernavigation.skin
res.write("...&nbsp;");
Html.link({href: "http://project.antville.org/project/stories/146"}, "<strong>README</strong>");
Html.tag("br");
Html.tag("br");
this.renderSkin("usernavigation");
}
if (param["for"] === "admins") {
this.renderSkin("adminnavigation");
} else if (param["for"] === "contributors") {
this.renderSkin("contribnavigation");
}
return;
}
Site.prototype.xmlbutton_macro = function(param) {
param.href = this.href("rss.xml");
image_macro(param, "/xmlbutton");
return;
};
Site.prototype.renderStoryList = function(day) {
res.push();
list_macro(param, "stories");
res.write(res.pop());
return;
var site = param.of ? root.get(param.of) : res.handlers.site;
if (!site)
return;
// untrusted sites are only allowed to use "light" version
if (res.handlers.site && !res.handlers.site.trusted) {
param.limit = param.limit ? Math.min(site.allstories.count(), parseInt(param.limit), 50) : 25;
for (var i=0; i<param.limit; i++) {
var story = site.allcontent.get(i);
if (!story)
continue;
res.write(param.itemprefix);
Html.openLink({href: story.href()});
var str = story.title;
if (!str)
str = story.getRenderedContentPart("text").stripTags().clip(10, "...", "\\s").softwrap(30);
res.write(str ? str : "...");
Html.closeLink();
res.write(param.itemsuffix);
}
return;
}
// this is db-heavy action available for trusted users only (yet?)
if (param.sortby != "title" && param.sortby != "createtime" && param.sortby != "modifytime")
param.sortby = "modifytime";
if (param.order != "asc" && param.order != "desc")
param.order = "asc";
var order = " order by TEXT_" + param.sortby.toUpperCase() + " " + param.order;
var rel = "";
if (param.show == "stories")
rel += " and TEXT_PROTOTYPE = 'story'";
else if (param.show == "comments")
rel += " and TEXT_PROTOTYPE = 'comment'";
if (param.topic)
rel += " and TEXT_TOPIC = '" + param.topic + "'";
var query = "select TEXT_ID from AV_TEXT where TEXT_F_SITE = " + site._id + " and TEXT_ISONLINE > 0" + rel + order;
var connex = getDBConnection("antville");
var rows = connex.executeRetrieval(query);
if (rows) {
var cnt = 0;
param.limit = param.limit ? Math.min(parseInt(param.limit), 100) : 25;
while (rows.next() && (cnt < param.limit)) {
cnt++;
var id = rows.getColumnItem("TEXT_ID").toString();
var story = site.allcontent.get(id);
if (!story)
continue;
if (param.skin) {
story.renderSkin(param.skin);
} else {
res.write(param.itemprefix);
Html.openLink({href: story.href()});
var str = story.title;
if (!str)
str = story.getRenderedContentPart("text").stripTags().clip(10, "...", "\\s").softwrap(30);
res.write(str ? str : "...");
Html.closeLink();
res.write(param.itemsuffix);
}
}
}
rows.release();
return;
}
Site.prototype.lastUpdate_macro = function(param) {
var value;
if (value = this.created) {
@ -216,12 +387,6 @@ Site.renderDateFormat = function(type, site, param) {
return;
};
Site.prototype.xmlbutton_macro = function(param) {
param.href = this.href("rss.xml");
Images.Default.render("xmlbutton", param);
return;
};
Site.prototype.moduleNavigation_macro = function(param) {
if (!param.module)
return;

View file

@ -1,5 +0,0 @@
...&nbsp;<% site.link members %><br />
...&nbsp;<% site.link edit preferences %><br />
...&nbsp;<% site.link layouts %><br />
...&nbsp;<% site.link referrers %><br />
...&nbsp;<% site.link mostread "most read stories" %><br />

View file

@ -1,5 +0,0 @@
...&nbsp;<% site.link stories/create "add a story" %><br />
...&nbsp;<% site.link stories %><br />
...&nbsp;<% site.link images %><br />
...&nbsp;<% site.link files %><br />
...&nbsp;<% site.link polls %><br />

View file

@ -1,3 +1,7 @@
Story.prototype.allowTextMacros = function(skin) {
return Story.prototype.macro_filter(skin);
}
Story.prototype.commentform_macro = function(param) {
if (this.commentsMode === "closed") {
return;

View file

@ -0,0 +1,276 @@
-- MySQL dump 10.11
--
-- ------------------------------------------------------
-- Server version 5.0.45-log
--
-- Table structure for table `choice`
--
CREATE TABLE `choice` (
`id` mediumint(10) NOT NULL default '0',
`poll_id` mediumint(10) default NULL,
`title` varchar(255) default NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`),
KEY `IDX_CHOICE_F_POLL` (`poll_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `content`
--
CREATE TABLE `content` (
`id` mediumint(10) NOT NULL default '0',
`prototype` enum('Story','Comment') default NULL,
`name` varchar(255) default NULL,
`site_id` mediumint(10) default NULL,
`story_id` mediumint(10) default NULL,
`parent_id` mediumint(10) default NULL,
`parent_type` varchar(30) default NULL,
`metadata` mediumtext,
`status` enum('closed','pending','readonly','public','shared','open') default NULL,
`mode` enum('hidden','featured') default NULL,
`comment_mode` enum('disabled','readonly','moderated','enabled') default NULL,
`requests` mediumint(10) default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `story_id` (`story_id`),
KEY `parent_id` (`parent_id`),
KEY `creator_id` (`creator_id`),
KEY `type` (`site_id`,`prototype`,`status`,`created`,`modified`,`id`),
KEY `all` (`site_id`,`modified`,`status`,`prototype`,`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `file`
--
CREATE TABLE `file` (
`id` mediumint(10) NOT NULL default '0',
`prototype` varchar(30) default NULL,
`name` varchar(255) default NULL,
`site_id` mediumint(10) default NULL,
`parent_id` mediumint(10) default NULL,
`parent_type` varchar(30) default NULL,
`metadata` mediumtext,
`requests` mediumint(10) default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `site_id` (`site_id`),
KEY `name` (`name`(20)),
KEY `creator_id` (`creator_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `image`
--
CREATE TABLE `image` (
`id` mediumint(10) NOT NULL default '0',
`name` varchar(30) default NULL,
`prototype` varchar(30) default NULL,
`site_id` mediumint(10) default NULL,
`parent_id` mediumint(10) default NULL,
`parent_type` varchar(30) default NULL,
`metadata` mediumtext,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `creator_id` (`creator_id`),
KEY `type` (`site_id`,`name`,`prototype`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `layout`
--
CREATE TABLE `layout` (
`id` mediumint(10) NOT NULL default '0',
`name` varchar(30) default NULL,
`site_id` mediumint(10) default NULL,
`layout_id` mediumint(10) default NULL,
`metadata` mediumtext,
`mode` enum('default','shared') default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `site_id` (`site_id`),
KEY `layout_id` (`layout_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `log`
--
CREATE TABLE `log` (
`id` int(11) NOT NULL auto_increment,
`context_id` mediumint(10) default NULL,
`context_type` varchar(20) default NULL,
`referrer` mediumtext,
`action` varchar(255) default NULL,
`ip` varchar(20) default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `membership`
--
CREATE TABLE `membership` (
`id` mediumint(10) NOT NULL default '0',
`name` tinytext,
`site_id` mediumint(10) default NULL,
`role` enum('Subscriber','Contributor','Manager','Owner') NOT NULL default 'Subscriber',
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `site_id` (`site_id`),
KEY `creator_id` (`creator_id`),
KEY `name` (`name`(20))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `poll`
--
CREATE TABLE `poll` (
`id` mediumint(10) NOT NULL default '0',
`site_id` mediumint(10) default NULL,
`question` mediumtext,
`status` enum('closed','readonly','open') default NULL,
`closed` datetime default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `site_id` (`site_id`),
KEY `creator_id` (`creator_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `site`
--
CREATE TABLE `site` (
`id` mediumint(10) NOT NULL default '0',
`name` varchar(30) NOT NULL,
`layout_id` mediumint(10) default NULL,
`metadata` mediumtext,
`status` enum('blocked','regular','trusted') NOT NULL,
`mode` enum('closed','restricted','public','open') NOT NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`(20)),
KEY `creator_id` (`creator_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `skin`
--
CREATE TABLE `skin` (
`id` mediumint(10) NOT NULL default '0',
`name` varchar(30) default NULL,
`prototype` varchar(30) default NULL,
`layout_id` mediumint(10) default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
`modifier_id` mediumint(10) default NULL,
PRIMARY KEY (`id`),
KEY `type` (`layout_id`,`prototype`(10),`name`(10))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `tag`
--
CREATE TABLE `tag` (
`id` int(11) NOT NULL default '0',
`name` varchar(255) default NULL,
`site_id` int(11) default NULL,
`type` enum('Story','Image') default NULL,
PRIMARY KEY (`id`),
KEY `tags` (`site_id`,`type`,`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `tag_hub`
--
CREATE TABLE `tag_hub` (
`id` int(11) NOT NULL default '0',
`tag_id` int(11) default NULL,
`tagged_id` int(11) default NULL,
`tagged_type` enum('Story','Image') default NULL,
`user_id` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `tagged` (`tag_id`,`tagged_type`,`tagged_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `user`
--
CREATE TABLE `user` (
`id` mediumint(10) NOT NULL default '0',
`name` varchar(255) default NULL,
`metadata` mediumtext,
`email` varchar(255) default NULL,
`status` enum('blocked','regular','trusted','privileged') NOT NULL default 'regular',
`visited` datetime default NULL,
`created` datetime default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`(20))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `vote`
--
CREATE TABLE `vote` (
`id` mediumint(10) NOT NULL default '0',
`poll_id` mediumint(10) default NULL,
`choice_id` mediumint(10) default NULL,
`creator_name` varchar(255) default NULL,
`created` datetime default NULL,
`creator_id` mediumint(10) default NULL,
`modified` datetime default NULL,
PRIMARY KEY (`id`),
KEY `poll_id` (`poll_id`),
KEY `creator_id` (`creator_id`),
KEY `choice_id` (`choice_id`),
KEY `creator_name` (`creator_name`(20))
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`,`name`,`metadata`,`email`,`status`,`created`,`modified`) VALUES ('1','queen','({hash:"0e9f0fa4073104f670e236c85a55f9ee", salt:"4r0XkGb3FKA="})',NULL,'privileged',NULL,NULL);
INSERT INTO `site` (`id`,`name`,`status`,`mode`,`metadata`,`layout_id`,`created`,`creator_id`,`modified`,`modifier_id`) VALUES ('1','www','trusted','closed','({title:"Antville"})','1',NULL,'1',NULL,'1');
INSERT INTO `layout` (`id`,`name`,`site_id`,`layout_id`,`metadata`,`created`,`modified`,`creator_id`,`modifier_id`,`mode`) VALUES ('1','default','1', NULL,'({})',NULL,NULL,'1','1','default');
INSERT INTO `membership` (`id`,`name`,`site_id`,`role`,`created`,`creator_id`,`modified`,`modifier_id`) VALUES ('1','queen','1','Owner',NULL,'1',NULL,'1');
-- Dump completed on 2007-10-06 13:30:24

View file

@ -146,11 +146,11 @@ convert.xml = function(table) {
var metadata = function(xml) {
var clean = xml.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
try {
return Xml.readFromString(clean).toSource();
return Xml.readFromString(clean);
} catch (ex) {
app.debug(xml);
app.debug(ex);
}
return {}.toSource();
return {};
};
retrieve(sql("jsonize", table));
@ -160,7 +160,7 @@ convert.xml = function(table) {
}
var data = metadata(this.xml);
execute("update " + table + " set metadata = " +
quote(data) + " where id = " + this.id);
quote(data.toSource()) + " where id = " + this.id);
});
}
@ -193,11 +193,39 @@ convert.tags = function(table) {
}
convert.skins = function() {
var rename = function(prototype) {
switch (prototype) {
case "Day":
return "Archive";
case "LayoutImage":
return "Image";
case "LayoutImageMgr":
return "Images";
case "RootLayoutMgr":
return "Layouts";
case "StoryMgr":
return "Stories";
case "SysMgr":
return "Admin";
case "SysLog":
return "LogEntry";
case "Topic":
return "Tag";
case "TopicMgr":
return "Tags";
default:
if (prototype.lastIndexOf("Mgr") > 0) {
return prototype.substr(0, prototype.length - 3) + "s";
}
return prototype;
}
}
var dump = function(sql) {
retrieve(sql);
traverse(function() {
var fpath = app.dir + "/../static/" + this.site_name +
"/layouts/" + this.name + "/" + this["prototype"];
"/layouts/" + this.name + "/" + rename(this["prototype"]);
var file = new java.io.File(fpath);
file.mkdirs();
file = new java.io.File(file,