Intermediate commit:

* Improved tag framework 
 * Added support for image tags
 * Moved most code of StoryMgr.evalNewStory to Story.evalStory to decrease redundancy
 * Added compatibility module (including drafts for database conversions)
 * Moved code for topics to compatibility module
 * Removed obsolete code
This commit is contained in:
Tobi Schäfer 2007-08-03 19:41:51 +00:00
parent d5c59cf2ec
commit 09b39b2af3
48 changed files with 872 additions and 494 deletions

19
.gitattributes vendored
View file

@ -4,6 +4,7 @@ build/extra/launcher.jar -text
build/extra/mckoidb.jar -text build/extra/mckoidb.jar -text
code/AntvilleLib-1.4.zip -text code/AntvilleLib-1.4.zip -text
code/HelmaLib-1.0.zip -text code/HelmaLib-1.0.zip -text
code/TagHub/TagHub.skin -text
code/lucene-1.4.3.jar -text code/lucene-1.4.3.jar -text
database/data/062SYS_INFO_sUSRSequenceInfo.koi -text database/data/062SYS_INFO_sUSRSequenceInfo.koi -text
database/data/063SYS_INFO_sUSRSequence.koi -text database/data/063SYS_INFO_sUSRSequence.koi -text
@ -41,15 +42,6 @@ database/data/113APP_AV_IMAGE.koi -text
database/data/115APP_AV_SITE.koi -text database/data/115APP_AV_SITE.koi -text
database/data/BlobStore.koi -text database/data/BlobStore.koi -text
database/data/DefaultDatabase_sf.koi -text database/data/DefaultDatabase_sf.koi -text
static/default/default/big.gif -text
static/default/default/bullet.gif -text
static/default/default/dot.gif -text
static/default/default/headbg.gif -text
static/default/default/manage.gif -text
static/default/default/menu.gif -text
static/default/default/recent.gif -text
static/default/default/status.gif -text
static/default/default/webloghead.gif -text
static/default/images/dot.gif -text static/default/images/dot.gif -text
static/default/images/hop.gif -text static/default/images/hop.gif -text
static/default/images/marquee.gif -text static/default/images/marquee.gif -text
@ -59,3 +51,12 @@ static/default/images/smallchaos.gif -text
static/default/images/smallstraight.gif -text static/default/images/smallstraight.gif -text
static/default/images/smalltrans.gif -text static/default/images/smalltrans.gif -text
static/default/images/xmlbutton.gif -text static/default/images/xmlbutton.gif -text
static/default/layouts/antville-classic/big.gif -text
static/default/layouts/antville-classic/bullet.gif -text
static/default/layouts/antville-classic/dot.gif -text
static/default/layouts/antville-classic/headbg.gif -text
static/default/layouts/antville-classic/manage.gif -text
static/default/layouts/antville-classic/menu.gif -text
static/default/layouts/antville-classic/recent.gif -text
static/default/layouts/antville-classic/status.gif -text
static/default/layouts/antville-classic/webloghead.gif -text

View file

@ -314,6 +314,11 @@ Image.prototype.evalImg = function(param, modifier) {
this.alttext = param.alttext; this.alttext = param.alttext;
this.modifier = modifier; this.modifier = modifier;
this.modifytime = new Date(); this.modifytime = new Date();
param.tags = Story.prototype.setTopic.call(this,
param.topic || param.addToTopic);
Story.prototype.setTags.call(this, param.tags);
if (this.thumbnail) { if (this.thumbnail) {
this.thumbnail.alttext = this.alttext; this.thumbnail.alttext = this.alttext;
this.thumbnail.modifytime = this.modifytime; this.thumbnail.modifytime = this.modifytime;

View file

@ -22,6 +22,20 @@
<% image.alttext as="editor" class="formText" %><br /> <% image.alttext as="editor" class="formText" %><br />
</td> </td>
</tr> </tr>
<tr>
<td colspan="3">
Add this image to a topic<br />
<table style="margin-left:15px;">
<tr>
<td width="48%" class="small">Choose a topic...<br />
<% image.topicchooser firstOption="--- choose topic ---" %></td>
<td valign="top" width="4%">&nbsp;</td>
<td valign="top" width="48%" class="small">...or enter a new one<br />
<input type="text" name="topic" value="<% request.topic %>" /></td>
</tr>
</table>
</td>
</tr>
</table> </table>
<div class="small"><% image.creator as="link" prefix="Created by " %><% image.createtime format="short" prefix=" on " suffix="." %></div><br /> <div class="small"><% image.creator as="link" prefix="Created by " %><% image.createtime format="short" prefix=" on " suffix="." %></div><br />

View file

@ -61,6 +61,6 @@ modifier.foreign = USER_ID
tags = collection(TagHub) tags = collection(TagHub)
tags.local.1 = $id tags.local.1 = $id
tags.foreign.1 = parent_id tags.foreign.1 = tagged_id
tags.local.2 = $prototype tags.local.2 = $prototype
tags.foreign.2 = parent_type tags.foreign.2 = tagged_type

View file

@ -39,9 +39,8 @@ tags = mountpoint(Tags)
allTags = collection(Tag) allTags = collection(Tag)
allTags.local = site_id allTags.local = site_id
allTags.foreign = site_id allTags.foreign = site_id
allTags.filter = tag.type = 'Image' allTags.filter = type = 'Image'
allTags.group = tag.name allTags.accessname = tag.name
allTags.group.order = tag.name asc
alphabeticalTags = collection(Tag) alphabeticalTags = collection(Tag)
alphabeticalTags.accessname = name alphabeticalTags.accessname = name

View file

@ -516,7 +516,7 @@ Layout.prototype.evalLayout = function(param, modifier) {
this.title = param.title; this.title = param.title;
this.description = param.description; this.description = param.description;
// get preferences from param object // get preferences from param object
var prefs = this.preferences.getAll(); var prefs = this.preferences.get();
for (var i in param) { for (var i in param) {
if (i.startsWith("preferences_")) if (i.startsWith("preferences_"))
prefs[i.substring(12)] = param[i]; prefs[i.substring(12)] = param[i];
@ -640,7 +640,7 @@ Layout.prototype.setParentLayout = function(parent) {
this.shareable = 0; this.shareable = 0;
// copy relevant preferences from parent // copy relevant preferences from parent
var prefs = new HopObject(); var prefs = new HopObject();
var parentPrefs = parent.preferences.getAll(); var parentPrefs = parent.preferences.get();
prefs.bgcolor = parentPrefs.bgcolor; prefs.bgcolor = parentPrefs.bgcolor;
prefs.textfont = parentPrefs.textfont; prefs.textfont = parentPrefs.textfont;
prefs.textsize = parentPrefs.textsize; prefs.textsize = parentPrefs.textsize;
@ -673,7 +673,7 @@ Layout.prototype.dumpToZip = function(z, fullExport) {
cl.title = this.title; cl.title = this.title;
cl.alias = this.alias; cl.alias = this.alias;
cl.description = this.description; cl.description = this.description;
cl.preferences = this.preferences.getAll(); cl.preferences = this.preferences.get();
cl.creator = this.creator ? this.creator.name : null; cl.creator = this.creator ? this.creator.name : null;
cl.createtime = this.creator ? this.createtime : null; cl.createtime = this.creator ? this.createtime : null;
cl.exporttime = new Date(); cl.exporttime = new Date();

View file

@ -22,30 +22,6 @@
// $URL$ // $URL$
// //
//
// 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$
//
/** /**
* constructor function for site objects * constructor function for site objects
* @param String Title * @param String Title

View file

@ -1,4 +1,4 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

View file

@ -43,14 +43,12 @@ trusted = SITE_ISTRUSTED
createtime = SITE_CREATETIME createtime = SITE_CREATETIME
modifytime = SITE_MODIFYTIME modifytime = SITE_MODIFYTIME
topics = mountpoint(TopicMgr)
members = mountpoint(MemberMgr) members = mountpoint(MemberMgr)
images = mountpoint(ImageMgr) images = mountpoint(ImageMgr)
layouts = mountpoint(LayoutMgr) layouts = mountpoint(LayoutMgr)
files = mountpoint(FileMgr) files = mountpoint(FileMgr)
stories = mountpoint(StoryMgr) stories = mountpoint(StoryMgr)
polls = mountpoint(PollMgr) polls = mountpoint(PollMgr)
tags = mountpoint(Tags)
preferences = mountpoint(Metadata) preferences = mountpoint(Metadata)
preferences_data = SITE_PREFERENCES preferences_data = SITE_PREFERENCES
@ -106,3 +104,10 @@ tags = collection(Tag)
tags.accessname = tag.name tags.accessname = tag.name
tags.local = site_id tags.local = site_id
tags.foreign = site_id tags.foreign = site_id
tags.filter = type = 'Story'
slideshows = collection(Tag)
slideshows.accessname = tag.name
slideshows.local = site_id
slideshows.foreign = site_id
slideshows.filter = type = 'Image'

View file

@ -22,6 +22,20 @@
// $URL$ // $URL$
// //
/**
* constructor function for story objects
*/
Story.prototype.constructor = function(creator, createtime, ipaddress) {
this.reads = 0;
this.ipaddress = ipaddress;
this.creator = creator;
this.modifier = creator;
this.editableby = EDITABLEBY_ADMINS;
this.createtime = new Date();
this.modifytime = this.createtime;
return this;
};
/** /**
* main action * main action
*/ */
@ -197,23 +211,6 @@ Story.prototype.online_macro = function(param) {
return; return;
}; };
/**
* macro rendering the location of the story
*/
Story.prototype.location_macro = function(param) {
switch (this.online) {
case 1:
Html.link({href: this.site.topics.get(this.topic).href()}, "topic");
break;
case 2:
res.write("site");
break;
}
return;
};
/** /**
* macro rendering createtime of story, either as editor, * macro rendering createtime of story, either as editor,
* plain text or as link to the frontpage of the day * plain text or as link to the frontpage of the day
@ -473,52 +470,6 @@ Story.prototype.discussions_macro = function(param) {
return; return;
}; };
/**
* macro renders a list of existing topics as dropdown
*/
Story.prototype.topicchooser_macro = function(param) {
var size = path.Site.topics.size();
var options = new Array();
for (var i=0;i<size;i++) {
var topic = path.Site.topics.get(i);
if (topic.size()) {
options[i] = {value: topic.groupname, display: topic.groupname};
if (req.data.addToTopic)
var selected = req.data.addToTopic;
else if (this.topic == topic.groupname)
var selected = topic.groupname;
}
}
Html.dropDown({name: "addToTopic"}, options, selected, param.firstOption);
return;
};
/**
* macro renders the name of the topic this story belongs to
* either as link, image (if an image entiteld by the
* topic name is available) or plain text
*/
Story.prototype.topic_macro = function(param) {
if (!this.topic || !this.online)
return;
if (!param.as || param.as == "text")
res.write(this.topic);
else if (param.as == "link") {
Html.link({href: path.Site.topics.href(this.topic)},
param.text ? param.text : this.topic);
} else if (param.as == "image") {
if (!param.imgprefix)
param.imgprefix = "topic_";
var img = getPoolObj(param.imgprefix + this.topic, "images");
if (!img)
return;
Html.openLink({href: path.Site.topics.href(this.topic)});
renderImage(img.obj, param)
Html.closeLink();
}
return;
};
/** /**
* macro returns a list of references linking to a story * macro returns a list of references linking to a story
* since referrers are asynchronously written to database by scheduler * since referrers are asynchronously written to database by scheduler
@ -592,19 +543,6 @@ Story.prototype.addtofront_macro = function(param) {
} }
return; return;
}; };
/**
* constructor function for story objects
*/
Story.prototype.constructor = function(creator, ipaddress) {
this.reads = 0;
this.ipaddress = ipaddress;
this.creator = creator;
this.editableby = EDITABLEBY_ADMINS;
this.createtime = new Date();
this.modifytime = new Date();
return this;
};
/** /**
* check if story is ok; if true, save changed story * check if story is ok; if true, save changed story
@ -615,62 +553,66 @@ Story.prototype.constructor = function(creator, ipaddress) {
* - message (String): containing a message to user * - message (String): containing a message to user
*/ */
Story.prototype.evalStory = function(param, modifier) { Story.prototype.evalStory = function(param, modifier) {
var site = this.site || res.handlers.site;
// collect content // collect content
var content = extractContent(param, this.content.get()); var content = extractContent(param, this.content.get());
// if all story parts are null, return with error-message // if all story parts are null, return with error-message
if (!content.exists) if (!content.exists) {
throw new Exception("textMissing"); throw new Exception("textMissing");
}
// check if the createtime is set in param // check if the createtime is set in param
if (param.createtime) { if (param.createtime) {
try { try {
var ctime = param.createtime.toDate("yyyy-MM-dd HH:mm"); var ctime = param.createtime.toDate("yyyy-MM-dd HH:mm", site.getTimeZone());
} catch (err) { } catch (err) {
throw new Exception("timestampParse", param.createtime); throw new Exception("timestampParse", param.createtime);
} }
} }
// check name of topic (if specified)
var topicName = null;
if (param.topic) {
// FIXME: this should be solved more elegantly
if (String.URLPATTERN.test(param.topic))
throw new Exception("topicNoSpecialChars");
if (this.site.topics[param.topic] || this.site.topics[param.topic + "_action"])
throw new Exception("topicReservedWord");
topicName = param.topic;
} else if (param.addToTopic)
topicName = param.addToTopic;
// Update tags of the story
this.setTags(param.content_tags);
// store the new values of the story
if (param.publish) {
var newStatus = param.addToFront ? 2 : 1;
if (!this.online || content.isMajorUpdate)
this.site.lastupdate = new Date();
this.online = newStatus;
} else
this.online = 0;
if (content.isMajorUpdate)
this.modifytime = new Date();
this.content.set(content.value);
this.topic = topicName;
// let's keep the title property
this.title = content.value.title;
// re-create day of story with respect to site-timezone // re-create day of story with respect to site-timezone
if (ctime && ctime != this.createtime) { if (ctime && ctime != this.createtime) {
this.createtime = ctime; this.createtime = ctime;
this.day = ctime.format("yyyyMMdd", this.site.getLocale(), this.site.getTimeZone());
} }
if (modifier == this.creator)
if (!this.day) {
this.day = this.createtime.format("yyyyMMdd", site.getLocale(),
site.getTimeZone());
}
// FIXME: Set the story's topic (backwards-compatible)
content.value.tags = this.setTopic(param.topic || param.addToTopic);
// Update tags of the story
this.setTags(content.value.tags);
// store the new values of the story
if (param.publish) {
var newStatus = param.addToFront ? 2 : 1;
if (!this.online || content.isMajorUpdate) {
site.lastupdate = new Date();
}
this.online = newStatus;
} else {
this.online = 0;
}
if (content.isMajorUpdate) {
this.modifytime = new Date();
}
this.content.set(content.value);
// let's keep the title property
this.title = content.value.title;
if (!this.creator || modifier == this.creator) {
this.editableby = !isNaN(param.editableby) ? this.editableby = !isNaN(param.editableby) ?
parseInt(param.editableby, 10) : EDITABLEBY_ADMINS; parseInt(param.editableby, 10) : EDITABLEBY_ADMINS;
}
this.discussions = param.discussions ? 1 : 0; this.discussions = param.discussions ? 1 : 0;
this.modifier = modifier; this.modifier = modifier;
this.ipaddress = param.http_remotehost; this.ipaddress = param.http_remotehost;
// send e-mail notification // send e-mail notification
if (this.site.isNotificationEnabled() && newStatus != 0) { if (site.isNotificationEnabled() && newStatus != 0) {
// status changes from offline to online // status changes from offline to online
// (this is bad because somebody could send a bunch // (this is bad because somebody could send a bunch
// of e-mails simply by toggling the online status.) // of e-mails simply by toggling the online status.)
@ -678,13 +620,13 @@ Story.prototype.evalStory = function(param, modifier) {
// this.sendNotification("story", "create"); // this.sendNotification("story", "create");
// major update of an already online story // major update of an already online story
if (this.online != 0 && content.isMajorUpdate) if (this.online != 0 && content.isMajorUpdate)
this.site.sendNotification("update", this); site.sendNotification("update", this);
} }
var result = new Message("storyUpdate"); var result = new Message("storyUpdate");
result.url = this.online > 0 ? this.href() : this.site.stories.href(); result.url = this.online > 0 ? this.href() : site.stories.href();
result.id = this._id; result.id = this._id;
// add the modified story to search index // add the modified story to search index
app.data.indexManager.getQueue(this.site).add(this); app.data.indexManager.getQueue(site).add(this);
return result; return result;
}; };
@ -699,6 +641,7 @@ Story.prototype.setTags = function(input) {
diff[tag] = 1; diff[tag] = 1;
} }
} }
for (var tag in diff) { for (var tag in diff) {
switch (diff[tag]) { switch (diff[tag]) {
case 0: case 0:

View file

@ -11,10 +11,6 @@
<tr> <tr>
<td><fieldset><legend class="small">Options</legend> <td><fieldset><legend class="small">Options</legend>
<p><% story.addtofront as="editor" checked="checked" %>&nbsp;Show this story on the front page</p> <p><% story.addtofront as="editor" checked="checked" %>&nbsp;Show this story on the front page</p>
Tags:
<% story.content part="tags" as="editor" class="formText" %>
Add this story to a topic<br /> Add this story to a topic<br />
<table style="margin-left:15px;"> <table style="margin-left:15px;">
<tr> <tr>

View file

@ -29,7 +29,6 @@ _prototype = TEXT_PROTOTYPE
_parent = site.stories _parent = site.stories
day = TEXT_DAY day = TEXT_DAY
topic = TEXT_TOPIC
title = TEXT_TITLE title = TEXT_TITLE
text = TEXT_TEXT text = TEXT_TEXT
rawcontent = TEXT_RAWCONTENT rawcontent = TEXT_RAWCONTENT

View file

@ -110,64 +110,25 @@ StoryMgr.prototype.create_action = function() {
StoryMgr.prototype.evalNewStory = function(param, creator) { StoryMgr.prototype.evalNewStory = function(param, creator) {
var s = new Story(creator, param.http_remotehost); var s = new Story(creator, param.http_remotehost);
// collect content s.evalStory(param, creator);
var content = extractContent(param);
// if all story parts are null, return with error-message if (!this.add(s)) {
if (!content.exists)
throw new Exception("textMissing");
s.content.setAll(content.value);
// let's keep the title property
s.title = content.value.title;
// check if the create date is set in the param object
if (param.createtime) {
try {
s.createtime = param.createtime.toDate("yyyy-MM-dd HH:mm", this._parent.getTimeZone());
} catch (error) {
throw new Exception("timestampParse", param.createtime);
}
}
s.editableby = !isNaN(parseInt(param.editableby, 10)) ?
parseInt(param.editableby, 10) : EDITABLEBY_ADMINS;
s.discussions = param.discussions ? 1 : 0;
// create day of story with respect to site-timezone
s.day = formatTimestamp(s.createtime, "yyyyMMdd");
// check name of topic (if specified)
if (param.topic) {
// FIXME: this should be solved more elegantly
if (String.URLPATTERN.test(param.topic))
throw new Exception("topicNoSpecialChars");
if (this._parent.topics[param.topic] || this._parent.topics[param.topic + "_action"])
throw new Exception("topicReservedWord");
s.topic = param.topic;
} else if (param.addToTopic)
s.topic = param.addToTopic;
// check the online-status of the story
if (param.publish)
s.online = param.addToFront ? 2 : 1;
else
s.online = 0;
// store the story
if (!this.add(s))
throw new Exception("storyCreate"); throw new Exception("storyCreate");
}
// Update tags of the story
s.setTags(param.content_tags);
// send e-mail notification // send e-mail notification
if (s.site.isNotificationEnabled()) if (s.site.isNotificationEnabled()) {
s.site.sendNotification("create", s); s.site.sendNotification("create", s);
}
var result = new Message("storyCreate", null, s); var result = new Message("storyCreate", null, s);
result.id = s._id; result.id = s._id;
if (s.online) { if (s.online) {
s.site.lastupdate = s.modifytime; s.site.lastupdate = s.modifytime;
result.url = s.href(); result.url = s.href();
} else } else {
result.url = this.href(); result.url = this.href();
}
// add the new story to search index
app.data.indexManager.getQueue(this._parent).add(s);
return result; return result;
}; };

View file

@ -41,9 +41,8 @@ allTags = collection(Tag)
allTags.local = site_id allTags.local = site_id
allTags.foreign = site_id allTags.foreign = site_id
allTags.filter = tag.type = 'Story' allTags.filter = tag.type = 'Story'
allTags.group = tag.name allTags.accessname = tag.name
allTags.group.order = tag.name asc
alphabeticalTags = collection(Tag) alphabeticalTags = collection(Tag)
alphabeticalTags.accessname = name alphabeticalTags.accessname = name
alphabeticalTags.local = site_id alphabeticalTags.local = site_id

View file

@ -1,3 +1,27 @@
//
// 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$
//
Tag.prototype.constructor = function(name, site, type) { Tag.prototype.constructor = function(name, site, type) {
this.name = name; this.name = name;
this.site = site; this.site = site;
@ -6,7 +30,38 @@ Tag.prototype.constructor = function(name, site, type) {
}; };
Tag.prototype.main_action = function() { Tag.prototype.main_action = function() {
res.debug(this.name + ": " + this.size()); res.handlers.list = new jala.ListRenderer(this.getCollection(this.type));
res.data.body = this.renderSkinAsString("Tag");
res.handlers.site.renderSkin("page");
return;
};
Tag.prototype.href = function() {
var mountpoint;
switch (this.type) {
case "Story":
mountpoint = "stories";
break;
case "Image":
mountpoint = "images";
break;
}
return this.site[mountpoint].tags.href() + encodeURIComponent(this.name);
};
Tag.prototype.getCollection = function(type) {
switch (type) {
case "Story":
return this.stories;
case "Image":
return this.images;
default:
return this;
}
};
Tag.prototype.getNavigationName = function() {
return this.name;
}; };
Tag.prototype.toString = function() { Tag.prototype.toString = function() {

5
code/Tag/Tag.skin Normal file
View file

@ -0,0 +1,5 @@
<div class="pagelink"><% linkedpath %></div><br />
<% list.prevLink %>
<% list.render skin="TagHub" %>
<% list.nextLink %>

View file

@ -1,7 +1,31 @@
##
## 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: 3300 $
## $LastChangedBy: piefke3000 $
## $LastChangedDate: 2007-06-30 21:25:35 +0200 (Sat, 30 Jun 2007) $
## $URL$
##
_db = antville _db = antville
_table = tag _table = tag
_id = id _id = id
_parent = site.tags _parent = site.tags, site.slideshows
name name
type type
@ -17,9 +41,16 @@ _children.foreign = tag_id
stories = collection(TagHub) stories = collection(TagHub)
stories.local = id stories.local = id
stories.foreign = tag_id stories.foreign = tag_id
stories.filter = tagged_type = 'Story' stories.filter.additionalTables = av_text
stories.filter = av_text.text_f_site = ${site_id} and tagged_type = 'Story' \
and av_text.text_id = tagged_id
stories.order = av_text.text_createtime desc
images = collection(TagHub) images = collection(TagHub)
images.local = id images.local = id
images.foreign = tag_id images.foreign = tag_id
images.filter = tagged_type = 'Image' images.order = image_createtime desc
images.filter.additionalTables = av_image
images.filter = av_image.image_f_site = ${site_id} and tagged_type = 'Image' \
and av_image.image_id = tagged_id
images.order = av_image.image_createtime desc

View file

@ -1,2 +0,0 @@
<% #item %>
<% tagjoin.parent.skin name="preview" %>

View file

@ -1,7 +1,31 @@
//
// 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$
//
TagHub.prototype.constructor = function(name, tagged, user) { TagHub.prototype.constructor = function(name, tagged, user) {
var site = res.handlers.site; var site = res.handlers.site;
var tag = site.tags.get(name); var tag = site.tags.get(name);
if (!tag) { if (!tag || tag.type !== tagged._prototype) {
tag = new Tag(name, site, tagged._prototype); tag = new Tag(name, site, tagged._prototype);
site.tags.add(tag); site.tags.add(tag);
} }
@ -13,10 +37,10 @@ TagHub.prototype.constructor = function(name, tagged, user) {
TagHub.prototype.getMacroHandler = function(name) { TagHub.prototype.getMacroHandler = function(name) {
switch (name.toLowerCase()) { switch (name.toLowerCase()) {
case "parent": case "tagged":
case "story": case "story":
case "image": case "image":
return this.parent; return this.tagged;
break; break;
} }
}; };

1
code/TagHub/TagHub.skin Normal file
View file

@ -0,0 +1 @@
<% taghub.tagged.skin name="preview" %>

View file

@ -1,3 +1,27 @@
##
## 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: 3300 $
## $LastChangedBy: piefke3000 $
## $LastChangedDate: 2007-06-30 21:25:35 +0200 (Sat, 30 Jun 2007) $
## $URL$
##
_db = antville _db = antville
_table = tag_hub _table = tag_hub
_id = id _id = id

View file

@ -1,3 +1,27 @@
//
// 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$
//
Tags.prototype.main_action = function() { Tags.prototype.main_action = function() {
if (req.data.group) { if (req.data.group) {
this.setGroup(req.data.group) this.setGroup(req.data.group)
@ -7,14 +31,13 @@ Tags.prototype.main_action = function() {
this.setPage(req.data.page); this.setPage(req.data.page);
res.redirect(this.href()); res.redirect(this.href());
} }
res.data.body = this.renderSkinAsString("main"); res.data.body = this.renderSkinAsString("Tags");
res.handlers.context.renderSkin("page"); res.handlers.context.renderSkin("page");
return; return;
}; };
Tags.prototype.getChildElement = function(id) { Tags.prototype.getChildElement = function(id) {
res.debug(id) var child = this.getCollection("*").get(id);
var child = path.site.tags.get(id);
return child; return child;
/* if (child && child.size() > 0) { /* if (child && child.size() > 0) {
@ -61,12 +84,12 @@ Tags.prototype.getChildElement = function(id) {
}; };
Tags.prototype.alphabet_macro = function() { Tags.prototype.alphabet_macro = function() {
var collection = this.getCollection("+"); if (this.getCollection("*").size() < 50) {
if (collection.size() < 50) { return;
//return;
} }
var self = this; var self = this;
var collection = this.getCollection("+");
var prefix = "?group="; var prefix = "?group=";
var group = this.getGroup(); var group = this.getGroup();
@ -115,13 +138,16 @@ Tags.prototype.list_macro = function() {
var size = this.getPageSize(); var size = this.getPageSize();
var start = (page - 1) * size; var start = (page - 1) * size;
var collection = this.getCollection().list(start, size); var collection = this.getCollection().list(start, size);
var id; var id, href;
for each (var item in collection) { for each (var item in collection) {
id = item.groupname || item.name; if (item.constructor !== Tag) {
item = item.get(0);
}
Html.openTag("li"); Html.openTag("li");
Html.link({href: this.href() + encodeURIComponent(id)}, id); Html.link({href: item.href()}, item.name);
Html.closeTag("li"); Html.closeTag("li");
} }
return;
}; };
Tags.prototype.getCollection = function(group) { Tags.prototype.getCollection = function(group) {

15
code/Tags/Tags.skin Normal file
View file

@ -0,0 +1,15 @@
<div class="pagelink"><% linkedpath %></div><br />
<% tags.alphabet prefix='<div>' suffix='</div>' %>
<% tags.pager prefix='<div>' suffix='</div>' %>
<% tags.list prefix="<ul>" suffix="</ul>" %>
<% tags.pager prefix='<div>' suffix='</div>' %>
<% tags.alphabet prefix='<div>' suffix='</div>' %>
<% #TOBEDELETED %>
<div class="listSeparator">&nbsp;</div>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td><a href="<% tag.href %>"><% tag.id %></a></td>
</tr>
</table>

View file

@ -1,7 +0,0 @@
<div><% tags.alphabet %></div>
<div><% tags.pager %></div>
<ul>
<% tags.list %>
</ul>
<div><% tags.pager %></div>
<div><% tags.alphabet %></div>

View file

@ -1,6 +0,0 @@
<div class="listSeparator">&nbsp;</div>
<table border="0" cellspacing="0" cellpadding="0" width="100%">
<tr>
<td><a href="<% tag.href %>"><% tag.id %></a></td>
</tr>
</table>

View file

@ -1,26 +1,28 @@
_children = collection(TagJoin) ## TO BE DELETED
_children.local.1 = $id
_children.foreign.1 = site_id
_children.local.2 = $prototype #_children = collection(TagJoin)
_children.local.2 = parent_type #_children.local.1 = $id
#_children.foreign.1 = site_id
_children.filter.additionalTables = AV_TEXT #_children.local.2 = $prototype
_children.filter = AV_TEXT.TEXT_ID = parent_id #_children.local.2 = parent_type
#_children.order = tagjoin.id asc
_children.group = tagjoin.name #_children.filter.additionalTables = AV_TEXT
_children.group.order = tagjoin.name asc #_children.filter = AV_TEXT.TEXT_ID = parent_id
##_children.order = tagjoin.id asc
#_children.cachemode = aggressive #_children.group = tagjoin.name
#_children.group.order = tagjoin.name asc
cloud = collection(TagJoin) ##_children.cachemode = aggressive
cloud.local.1 = $id
cloud.foreign.1 = site_id
cloud.filter.additionalTables = AV_TEXT #cloud = collection(TagJoin)
cloud.filter = AV_TEXT.TEXT_ID = parent_id #cloud.local.1 = $id
#cloud.foreign.1 = site_id
cloud.group = tagjoin.name #cloud.filter.additionalTables = AV_TEXT
cloud.group.order = AV_TEXT.TEXT_CREATETIME desc #cloud.filter = AV_TEXT.TEXT_ID = parent_id
#cloud.group = tagjoin.name
#cloud.group.order = AV_TEXT.TEXT_CREATETIME desc

View file

@ -1,97 +0,0 @@
//
// 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$
//
/**
* Display a link to let the user add a new writeup
* to this topic.
*/
Topic.prototype.addstory_macro = function(param) {
try {
path.Site.stories.checkAdd(session.user, req.data.memberlevel);
} catch (deny) {
return;
}
param.linkto = "create";
param.urlparam = "topic=" + this.groupname;
Html.openTag("a", path.Site.stories.createLinkParam(param));
if (param.text)
res.format(param.text);
else
res.write(getMessage("Topic.addStoryToTopic"));
Html.closeTag("a");
return;
};
/**
* Return either the title of the story or
* the id prefixed with standard display name
* to be used in the global linkedpath macro
* @see hopobject.getNavigationName()
*/
Topic.prototype.getNavigationName = function() {
return this.groupname;
};
/**
* function renders the list of stories for day-pages
* and assigns the rendered list to res.data.storylist
* scrollnavigation-links to previous and next page(s) are also
* assigned to res.data (res.data.prevpage, res.data.nextpage)
* using this separate renderFunction instead of doing the stuff
* in storylist_macro() was necessary for completely independent
* placement of the prevpage- and nextpage-links
* @param Int Index-position to start with
*/
Topic.prototype.renderStorylist = function(idx) {
var size = this.size();
if (idx < 0 || isNaN (idx)|| idx > size-1)
idx = 0;
var max = Math.min (idx+10, size);
this.prefetchChildren(idx, max);
if (idx > 0) {
var sp = new Object();
sp.url = this.href() + "?start=" + Math.max(0, idx-10);
sp.text = getMessage("generic.previousPage");
res.data.prevpage = renderSkinAsString("prevpagelink", sp);
}
res.push();
var day;
while (idx < max) {
var s = this.get(idx++);
if (s.day != day) {
s.renderSkin("dayheader");
day = s.day;
}
s.renderSkin("preview");
}
res.data.storylist = res.pop();
if (idx < size) {
var sp = new Object();
sp.url = this.href() + "?start=" + idx;
sp.text = getMessage("generic.nextPage");
res.data.nextpage = renderSkinAsString("nextpagelink", sp);
}
return;
};

View file

@ -1,5 +0,0 @@
<div class="pagelink"><% linkedpath %><br /><br />
<% topic.addimage prefix="...&nbsp;" suffix="<br />" %>
<% response.prevpage %></div>
<% response.storylist %>
<% response.nextpage %>

View file

@ -1,5 +0,0 @@
<div class="pagelink"><% linkedpath %><br /><br />
<% topic.addstory prefix="...&nbsp;" suffix="<br />" %>
<% response.prevpage %></div>
<% response.storylist %>
<% response.nextpage %>

View file

@ -1,25 +0,0 @@
##
## 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$
##
_extends = Day

View file

@ -1,65 +0,0 @@
//
// 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$
//
/**
* main action
*/
TopicMgr.prototype.main_action = function() {
res.data.title = getMessage("TopicMgr.mainTitle", {title: this._parent.title});
res.data.body = this.renderSkinAsString ("main");
this._parent.renderSkin("page");
return;
};
/**
* function renders the list of topics as links
*/
TopicMgr.prototype.topiclist_macro = function(param) {
if (!this.size())
return;
for (var i=0;i<this.size();i++) {
var topic = this.get(i);
res.write(param.itemprefix);
Html.link({href: topic.href()}, topic.groupname);
res.write(param.itemsuffix);
}
return;
};
/**
* permission check (called by hopobject.onRequest())
* @param String name of action
* @param Obj User object
* @param Int Membership level
* @return Obj Exception object or null
*/
TopicMgr.prototype.checkAccess = function(action, usr, level) {
if (!this._parent.online)
checkIfLoggedIn();
try {
this._parent.checkView(usr, level);
} catch (deny) {
res.message = deny.toString();
res.redirect(root.href());
}
return;
};

View file

@ -1,3 +0,0 @@
<% linkedpath %>
<% topicmgr.topiclist prefix="<ul>" suffix="</ul>" itemprefix="<li>" itemsuffix="</li>" %>

View file

@ -1,32 +0,0 @@
##
## 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$
##
_children = collection(Story)
_children.local = SITE_ID
_children.foreign = TEXT_F_SITE
_children.filter = TEXT_PROTOTYPE = 'Story' and TEXT_ISONLINE > 0
_children.order = TEXT_CREATETIME desc
_children.group = TEXT_TOPIC
_children.group.prototype = Topic
_children.group.order = TEXT_TOPIC

View file

@ -0,0 +1,106 @@
Metadata.prototype.getProperty = Metadata.prototype.get;
Metadata.prototype.setProperty = Metadata.prototype.set;
Metadata.prototype.setAll = Metadata.prototype.setData;
Metadata.prototype.createInputParam = function(propName, param) {
param.name = this.__name__ + "_" + propName;
if (!req.data[param.name + "_array"] && req.data[param.name] != null)
param.value = req.data[param.name];
else
param.value = this.get(propName);
delete param.as;
return param;
};
Metadata.prototype.createCheckBoxParam = function(propName, param) {
param.name = this.__name__ + "_" + propName;
param.value = 1;
if (req.data[param.name] == 1 || this.get(propName) == 1)
param.checked = "checked";
delete param.as;
return param;
};
ImageMgr.prototype.link_macro = function(param) {
if (this.getContext() === "Layout" && param.to === "myimages") {
param.to = "default";
param.text = "default images";
}
return HopObject.prototype.link_macro.apply(this, arguments);
};
Story.prototype.location_macro = function(param) {
switch (this.online) {
case 1:
if (this.tags.size() > 0) {
Html.link({href: this.tags.get(0).tag.href()}, "topic");
}
break;
case 2:
res.write("site");
break;
}
return;
};
Story.prototype.topic_macro = function(param) {
if (!this.online || this.tags.size() < 1)
return;
var topic = this.tags.get(0).tag;
if (!param.as || param.as == "text")
res.write(topic.name);
else if (param.as == "link") {
Html.link({href: topic.href()}, param.text ? param.text : topic.name);
} else if (param.as == "image") {
if (!param.imgprefix) {
param.imgprefix = "topic_";
}
var img = getPoolObj(param.imgprefix + topic.name, "images");
if (img) {
Html.openLink({href: topic.href()});
renderImage(img.obj, param)
Html.closeLink();
}
}
return;
};
Story.prototype.topicchooser_macro = function(param) {
var site = this.site || res.handlers.site;
var currentTopic = this.tags.size() > 0 ? this.tags.get(0).tag : null;
var topics = site[this.constructor === Story ? "tags" : "slideshows"];
var options = [], topic;
for (var i=0; i<topics.size(); i++) {
topic = topics.get(i);
options[i] = {value: topic.name, display: topic.name};
if (req.data.addToTopic) {
var selected = req.data.addToTopic;
} else if (currentTopic === topic) {
var selected = topic.name;
}
}
Html.dropDown({name: "addToTopic"}, options, selected, param.firstOption);
return;
};
Story.prototype.setTopic = function(input) {
var site = this.site || res.handlers.site;
if (input) {
// FIXME: this should be solved more elegantly
if (String.URLPATTERN.test(input)) {
throw new Exception("topicNoSpecialChars");
}
if (site.tags[input] || site.tags[input + "_action"]) {
throw new Exception("topicReservedWord");
}
}
return input;
};
Image.prototype.topicchooser_macro = function() {
return Story.prototype.topicchooser_macro.apply(this, arguments);
};
Image.prototype.topic_macro = function() {
return Story.prototype.topic_macro.apply(this, arguments);
};

View file

@ -0,0 +1,265 @@
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")), 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

@ -0,0 +1,162 @@
Site.prototype.debug_action = function() {
res.debug(this.tags.get(1).stories.get(1).tagged.title);
return;
//res.debug(this.members.get(0).user);
var story = Story.getById(882443);
res.debug(story.content.set("tags", story.topic));
return;
var str = '<?xml version="1.0" encoding="UTF-8"?> <!-- printed by helma object publisher --> <!-- created Mon Sep 09 21:56:07 CEST 2002 --> <xmlroot xmlns:hop="http://www.helma.org/docs/guide/features/database"> <hopobject id="t801649" name="" prototype="hopobject" created="1031601367757" lastModified="1031601367757"> <title>Learning Futures</title> <text>Continuing my education is the first and foremost way I can build on my professional and academic developmdnt Accessing more information on my own time is another way. Listening is always a good way to generate thinking and doing. As I am sure I will be involved with other SLP&amp;#8217;s, I plan to discuss and share ideas. Subscribing to journals should help me to research material as I nedd at. As anyone in any profession should, I will anticipate and take advantage of any oppurtunities for inquiry by accepting a challenging client or project. I strive to meet the needs of my own learning by challenging myself to become more informed in any area needed. Michelle</text> </hopobject> </xmlroot>';
Xml.readFromString(str);
return;
res.debug(this.href());
res.debug(this.sys_url);
return;
this.properties.setData({
"date": new Date,
"regex": /abc.*/g,
});
this.properties.setData(this);
this.properties.set("foo", "bar");
//this.properties.set("date", new Date);
//this.properties.remove("date");
this.properties.set("number", 1024);
this.properties.set("list", [1,2,3]);
this.properties.set("object", {x: 10, y: 20});
res.debug(this.properties.get("foo").length);
res.debug(this.properties.get("date"));//.format("yyyy-dd-MM"));
res.debug(this.properties.get("number").format("00.00"));
res.debug(this.properties.get("list")[2]);
res.debug(this.properties.get("object").x);
return;
res.debug(escape("http://antville.org/tobi/blabla".rot13()));
return;
var s = "Hello, <% param.foo %>!";
var param = new Object();
param.foo = "World";
renderSkin(createSkin(s), param);
return;
};
Root.prototype.altdiff = function() {
//var diff = WDiffString(originalSkin, this.getSource());
//res.writeln(diff);
var diff = new diff_match_patch();
var delim = /\r\n|\r|\n/g;
var originalText = originalSkin.replace(delim, "\n");
var modifiedText = this.getSource().replace(delim, "\n");
var diffResult = diff.diff_main(originalText, modifiedText);
//res.debug(encode(diffResult.join("**************")))
//res.debug(diffResult.length)
diff.diff_cleanupSemantic(diffResult);
var modifiedLines = modifiedText.split(delim);
var lineNumber = 0;
var currentText, remainder;
res.writeln("<tt>");
for (var i=0; i<diffResult.length; i+=1) {
var parts = diffResult[i];
var type = parts[0];
var text = parts[1];
switch (type) {
case 0:
res.write(text);
break;
case 1:
res.write('<ins>');
res.encode(text);
res.write('</ins>');
break;
case -1:
res.write('<del>')
res.encode(text);
res.write('</del>');
break;
}
/*
if (type === 0) {
var pos = text.lastIndexOf("\n");
currentText = text.substring(0, pos);
remainder = pos > -1 ? text.substring(pos) : "";
} else if (type === 1){
res.
res.encode(text);
res.encode(remainder);
} else if (type === -1) {
res.write('<span style="background-color: yellow;">');
res.encode(modifiedLines[lineNumber]);
res.encode(remainder);
remainder = "";
res.encode(text);
}
*/
}
res.writeln("</tt>");
res.abort();
var remainder = String.EMPTY;
for (var i in modifiedLines) {
res.encode(modifiedLines[i]);
res.writeln(remainder);
while (true) {
var str = diffResult.shift();
var pos = str.indexOf("\n");
res.writeln(str.substring(0, pos));
if (pos < str.length) {
remainder = str.substring(pos+1);
}
}
}
res.encode(diffResult.toSource());
var diffHtml = diff.diff_prettyHtml(diffResult);
var modifiedLines = modifiedText.split(delim);
var diffLines = diffHtml.split("&para;<BR>");
res.writeln("<pre>");
for (var i in modifiedLines) {
var str1 = encode(modifiedLines[i]);
res.writeln(str1);
if (str1 !== diffLines[i]) {
res.writeln(diffLines[i]);
}
}
res.writeln("</pre>");
res.abort();
};
String.prototype.rot13 = function() {
var result = "";
Array.forEach(this, function(chr) {
var index = String.ALPHABET.indexOf(chr.toUpperCase());
if (index < 0) {
result += chr;
} else {
var rotated = String.ROT13.charAt(index);
result += (chr.toLowerCase() === chr ? rotated.toLowerCase() : rotated);
}
});
return result;
}
String.ALPHABET = (function() {
var alphabet = "";
for (var i=65; i<91; i+=1) {
alphabet += String.fromCharCode(i);
}
return alphabet;
})();
String.ROT13 = String.ALPHABET.substr(13) + String.ALPHABET.substr(0, 13);
Array.forEach = function(ref) {
return Array.prototype.forEach.call(ref, arguments[1]);
};
function alert(str) {
res.writeln('<script type="text/javascript">alert("' + str + '");</script>');
return;
}

View file

@ -0,0 +1 @@
topics = mountpoint(Topics)

View file

@ -0,0 +1,7 @@
Topics.prototype.main_action = function() {
return this._parent.stories.tags.main_action();
};
Topics.prototype.getChildElement = function(id) {
return this._parent.stories.alltags.get(id);
};

View file

@ -9,3 +9,6 @@ update AV_IMAGE add column IMAGE_PARENT varchar(20) default NULL:
update AV_IMAGE set IMAGE_PARENT = IMAGE_F_IMAGE_PARENT, IMAGE_PARENT_PROTOTYPE = "Image" where IMAGE_F_IMAGE_PARENT is not null; update AV_IMAGE set IMAGE_PARENT = IMAGE_F_IMAGE_PARENT, IMAGE_PARENT_PROTOTYPE = "Image" where IMAGE_F_IMAGE_PARENT is not null;
update AV_IMAGE set IMAGE_PARENT = IMAGE_F_SITE where IMAGE_F_SITE is not null and IMAGE_PARENT is null; update AV_IMAGE set IMAGE_PARENT = IMAGE_F_SITE where IMAGE_F_SITE is not null and IMAGE_PARENT is null;
update AV_IMAGE set IMAGE_PARENT = IMAGE_F_LAYOUT where IMAGE_F_LAYOUT is not null and IMAGE_PARENT is null; update AV_IMAGE set IMAGE_PARENT = IMAGE_F_LAYOUT where IMAGE_F_LAYOUT is not null and IMAGE_PARENT is null;
update AV_IMAGE add column IMAGE_METADATA mediumtext default NULL;

View file

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View file

Before

Width:  |  Height:  |  Size: 55 B

After

Width:  |  Height:  |  Size: 55 B

View file

Before

Width:  |  Height:  |  Size: 111 B

After

Width:  |  Height:  |  Size: 111 B

View file

Before

Width:  |  Height:  |  Size: 61 B

After

Width:  |  Height:  |  Size: 61 B

View file

Before

Width:  |  Height:  |  Size: 106 B

After

Width:  |  Height:  |  Size: 106 B

View file

Before

Width:  |  Height:  |  Size: 89 B

After

Width:  |  Height:  |  Size: 89 B

View file

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View file

Before

Width:  |  Height:  |  Size: 98 B

After

Width:  |  Height:  |  Size: 98 B

View file

Before

Width:  |  Height:  |  Size: 747 B

After

Width:  |  Height:  |  Size: 747 B