Reduced line indent from 3 to 2 spaces

This commit is contained in:
Tobi Schäfer 2014-07-04 15:32:18 +02:00
parent 3e769d3d6e
commit c7d78eba65
85 changed files with 13354 additions and 13354 deletions

510
build.xml
View file

@ -13,7 +13,7 @@
~ 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
~ 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,
@ -28,291 +28,291 @@
-->
<project name="antville" default="usage" basedir=".">
<target name="help" depends="usage"/>
<target name="usage">
<echo message="Antville Build Instructions"/>
<echo message="==========================="/>
<echo message="Available targets are:"/>
<echo message=" all Generate the Antville and AntClick packages"/>
<echo message=" antville Generate the Antville packages"/>
<echo message=" antclick Generate the AntClick packages"/>
<echo message=" release Copy packages to the download server"/>
<echo message=" docs Generate the API documentation"/>
<echo message=" pot Extract gettext call strings into POT file"/>
<echo message=" messages Generate JavaScript message files"/>
<echo message=" clean Clean up build directory"/>
<echo message=" patch Apply patch file to Antville installation"/>
<echo message=" usage Show these build instructions (default)"/>
</target>
<target name="help" depends="usage"/>
<target name="usage">
<echo message="Antville Build Instructions"/>
<echo message="==========================="/>
<echo message="Available targets are:"/>
<echo message=" all Generate the Antville and AntClick packages"/>
<echo message=" antville Generate the Antville packages"/>
<echo message=" antclick Generate the AntClick packages"/>
<echo message=" release Copy packages to the download server"/>
<echo message=" docs Generate the API documentation"/>
<echo message=" pot Extract gettext call strings into POT file"/>
<echo message=" messages Generate JavaScript message files"/>
<echo message=" clean Clean up build directory"/>
<echo message=" patch Apply patch file to Antville installation"/>
<echo message=" usage Show these build instructions (default)"/>
</target>
<target name="all" depends="antville, antclick"/>
<target name="all" depends="antville, antclick"/>
<target name="init">
<tstamp>
<format property="date" pattern="d MMM yyyy" locale="en"/>
</tstamp>
<target name="init">
<tstamp>
<format property="date" pattern="d MMM yyyy" locale="en"/>
</tstamp>
<property name="name" value="antville"/>
<property name="year" value="1998-${year}"/>
<property name="version" value="1.4"/>
<property name="package.name" value="${name}-${version}"/>
<property name="name" value="antville"/>
<property name="year" value="1998-${year}"/>
<property name="version" value="1.4"/>
<property name="package.name" value="${name}-${version}"/>
<property name="antville.src" value="http://antville.googlecode.com/svn/trunk"/>
<property name="helma.src" value="https://github.com/p3k/helma/trunk"/>
<property name="modules.src" value="https://github.com/p3k/helma-modules/trunk"/>
<property name="apps.src" value="https://github.com/p3k/helma-apps/trunk"/>
<property name="jala.src" value="https://github.com/p3k/helma-jala/trunk"/>
<property name="antville.src" value="http://antville.googlecode.com/svn/trunk"/>
<property name="helma.src" value="https://github.com/p3k/helma/trunk"/>
<property name="modules.src" value="https://github.com/p3k/helma-modules/trunk"/>
<property name="apps.src" value="https://github.com/p3k/helma-apps/trunk"/>
<property name="jala.src" value="https://github.com/p3k/helma-jala/trunk"/>
<property name="build.dir" location="${basedir}/build"/>
<property file="${build.dir}/build.properties"/>
<property name="build.dir" location="${basedir}/build"/>
<property file="${build.dir}/build.properties"/>
<property name="helma.dir" location="/opt/helma"/>
<property name="extra.dir" location="${build.dir}/extra"/>
<property name="dist.dir" location="${build.dir}/dist"/>
<property name="work.dir" location="${build.dir}/work"/>
<property name="export.dir" location="${work.dir}/export"/>
<property name="modules.dir" location="${work.dir}/modules"/>
<property name="apps.dir" location="${work.dir}/apps"/>
<property name="antville.dir" location="${apps.dir}/antville"/>
<property name="hopkit.dir" location="${helma.dir}/modules/jala/util/HopKit"/>
<property name="helma.dir" location="/opt/helma"/>
<property name="extra.dir" location="${build.dir}/extra"/>
<property name="dist.dir" location="${build.dir}/dist"/>
<property name="work.dir" location="${build.dir}/work"/>
<property name="export.dir" location="${work.dir}/export"/>
<property name="modules.dir" location="${work.dir}/modules"/>
<property name="apps.dir" location="${work.dir}/apps"/>
<property name="antville.dir" location="${apps.dir}/antville"/>
<property name="hopkit.dir" location="${helma.dir}/modules/jala/util/HopKit"/>
<property name="docs.title" value="Antville&amp;#32;${version}&amp;#32;API&amp;#32;Reference"/>
<property name="docs.infiles" location="${basedir}/code"/>
<property name="docs.outfiles" location="${basedir}/docs"/>
<property name="docs.title" value="Antville&amp;#32;${version}&amp;#32;API&amp;#32;Reference"/>
<property name="docs.infiles" location="${basedir}/code"/>
<property name="docs.outfiles" location="${basedir}/docs"/>
<property name="i18n.scan" value="code compat extra"/>
<property name="i18n.destination" location="${basedir}/i18n"/>
<property name="i18n.poDirectory" location="${i18n.destination}"/>
<property name="i18n.template" location="${i18n.destination}/antville.pot"/>
<property name="i18n.namespace" value=""/>
</target>
<property name="i18n.scan" value="code compat extra"/>
<property name="i18n.destination" location="${basedir}/i18n"/>
<property name="i18n.poDirectory" location="${i18n.destination}"/>
<property name="i18n.template" location="${i18n.destination}/antville.pot"/>
<property name="i18n.namespace" value=""/>
</target>
<target name="export" depends="init">
<mkdir dir="${export.dir}"/>
<mkdir dir="${apps.dir}"/>
<exec dir="${apps.dir}" executable="svn">
<arg line="--force export --ignore-externals ${antville.src} antville"/>
</exec>
<delete includeemptydirs="true">
<fileset dir="${antville.dir}" includes="build.xml build/** docs/** i18n/*.po*"/>
</delete>
<exec dir="${build.dir}" executable="sh" outputproperty="revision">
<arg value="-c"/>
<arg value="svn info ${antville.src} | awk &quot;/Last Changed Rev:/&quot;'{print $4;}'"/>
</exec>
<replace file="${antville.dir}/code/Root/Root.js" token="@version@" value="${version}"/>
<replace file="${antville.dir}/code/Root/Root.js" token="@revision@" value="${revision}"/>
<replace file="${antville.dir}/code/Root/Root.js" token="@buildDate@" value="${date}"/>
</target>
<target name="export" depends="init">
<mkdir dir="${export.dir}"/>
<mkdir dir="${apps.dir}"/>
<exec dir="${apps.dir}" executable="svn">
<arg line="--force export --ignore-externals ${antville.src} antville"/>
</exec>
<delete includeemptydirs="true">
<fileset dir="${antville.dir}" includes="build.xml build/** docs/** i18n/*.po*"/>
</delete>
<exec dir="${build.dir}" executable="sh" outputproperty="revision">
<arg value="-c"/>
<arg value="svn info ${antville.src} | awk &quot;/Last Changed Rev:/&quot;'{print $4;}'"/>
</exec>
<replace file="${antville.dir}/code/Root/Root.js" token="@version@" value="${version}"/>
<replace file="${antville.dir}/code/Root/Root.js" token="@revision@" value="${revision}"/>
<replace file="${antville.dir}/code/Root/Root.js" token="@buildDate@" value="${date}"/>
</target>
<target name="ville" depends="antville"/>
<target name="antville" depends="export">
<antcall target="make-tar">
<param name="filename" value="${package.name}"/>
<param name="path" value="${antville.dir}"/>
</antcall>
<antcall target="make-zip">
<param name="filename" value="${package.name}"/>
<param name="path" value="${antville.dir}"/>
</antcall>
</target>
<target name="ville" depends="antville"/>
<target name="antville" depends="export">
<antcall target="make-tar">
<param name="filename" value="${package.name}"/>
<param name="path" value="${antville.dir}"/>
</antcall>
<antcall target="make-zip">
<param name="filename" value="${package.name}"/>
<param name="path" value="${antville.dir}"/>
</antcall>
</target>
<target name="click" depends="antclick"/>
<target name="antclick" depends="export">
<target name="click" depends="antclick"/>
<target name="antclick" depends="export">
<!-- Export Helma, modules and apps to temporary directory -->
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${helma.src} helma"/>
</exec>
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${modules.src} modules"/>
</exec>
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${jala.src} modules/jala"/>
</exec>
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${apps.src} apps"/>
</exec>
<!-- Export Helma, modules and apps to temporary directory -->
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${helma.src} helma"/>
</exec>
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${modules.src} modules"/>
</exec>
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${jala.src} modules/jala"/>
</exec>
<exec dir="${export.dir}" executable="svn">
<arg line="--force export ${apps.src} apps"/>
</exec>
<!-- Copy exported files to final destinations -->
<copy todir="${work.dir}">
<fileset dir="${export.dir}/helma" includes="lib/** licenses/**"/>
</copy>
<copy todir="${modules.dir}">
<fileset dir="${export.dir}/modules" includes="core/** helma/** jala/**"/>
</copy>
<copy todir="${apps.dir}">
<fileset dir="${export.dir}/apps" includes="manage/**"/>
</copy>
<!-- Copy exported files to final destinations -->
<copy todir="${work.dir}">
<fileset dir="${export.dir}/helma" includes="lib/** licenses/**"/>
</copy>
<copy todir="${modules.dir}">
<fileset dir="${export.dir}/modules" includes="core/** helma/** jala/**"/>
</copy>
<copy todir="${apps.dir}">
<fileset dir="${export.dir}/apps" includes="manage/**"/>
</copy>
<copy file="${export.dir}/helma/license.txt" tofile="${work.dir}/licenses/helma.txt"/>
<copy file="${export.dir}/helma/license.txt" tofile="${work.dir}/licenses/helma.txt"/>
<!-- Copy extra files to final destinations -->
<copy todir="${work.dir}">
<fileset dir="${extra.dir}" includes="start.bat apps.properties
server.properties launcher.jar"/>
</copy>
<exec dir="${extra.dir}" executable="cp">
<arg line="-p start.sh ${work.dir}"/>
</exec>
<!-- Copy extra files to final destinations -->
<copy todir="${work.dir}">
<fileset dir="${extra.dir}" includes="start.bat apps.properties
server.properties launcher.jar"/>
</copy>
<exec dir="${extra.dir}" executable="cp">
<arg line="-p start.sh ${work.dir}"/>
</exec>
<copy file="${extra.dir}/helma.jar" todir="${work.dir}/lib"/>
<copy file="${extra.dir}/h2-1.3.155.jar" todir="${work.dir}/lib/ext"/>
<copy file="${extra.dir}/h2.txt" todir="${work.dir}/licenses"/>
<copy file="${extra.dir}/helma.jar" todir="${work.dir}/lib"/>
<copy file="${extra.dir}/h2-1.3.155.jar" todir="${work.dir}/lib/ext"/>
<copy file="${extra.dir}/h2.txt" todir="${work.dir}/licenses"/>
<copy todir="${build.dir}/work/db">
<fileset dir="${extra.dir}" includes="antville.h2.db"/>
</copy>
<copy todir="${work.dir}/licenses">
<fileset dir="${antville.dir}/legal" includes="**"/>
</copy>
<copy file="${modules.dir}/jala/licenses/jala.txt" todir="${work.dir}/licenses"/>
<copy todir="${build.dir}/work/db">
<fileset dir="${extra.dir}" includes="antville.h2.db"/>
</copy>
<copy todir="${work.dir}/licenses">
<fileset dir="${antville.dir}/legal" includes="**"/>
</copy>
<copy file="${modules.dir}/jala/licenses/jala.txt" todir="${work.dir}/licenses"/>
<!-- Delete unnecessary files -->
<delete>
<fileset dir="${modules.dir}/helma" includes="*.jar Search.js Ssh.js Chart.js"/>
</delete>
<delete includeemptydirs="true">
<fileset dir="${modules.dir}/jala" includes="build.properties docs/**
lib/** licenses/** tests/** util/**"/>
</delete>
<!-- Delete unnecessary files -->
<delete>
<fileset dir="${modules.dir}/helma" includes="*.jar Search.js Ssh.js Chart.js"/>
</delete>
<delete includeemptydirs="true">
<fileset dir="${modules.dir}/jala" includes="build.properties docs/**
lib/** licenses/** tests/** util/**"/>
</delete>
<delete dir="${antville.dir}/legal"/>
<delete dir="${export.dir}"/>
<delete dir="${antville.dir}/legal"/>
<delete dir="${export.dir}"/>
<!-- Create the packages -->
<antcall target="make-zip">
<param name="filename" value="antclick-${version}"/>
<param name="path" value="${work.dir}"/>
</antcall>
<antcall target="make-tar">
<param name="filename" value="antclick-${version}"/>
<param name="path" value="${work.dir}"/>
</antcall>
</target>
<!-- Create the packages -->
<antcall target="make-zip">
<param name="filename" value="antclick-${version}"/>
<param name="path" value="${work.dir}"/>
</antcall>
<antcall target="make-tar">
<param name="filename" value="antclick-${version}"/>
<param name="path" value="${work.dir}"/>
</antcall>
</target>
<target name="docs" depends="init">
<exec dir="${build.dir}/jsdoc/toolkit" executable="${build.dir}/jsdoc/jsrunwrapper.sh">
<arg line='-D="title:${docs.title}" -q -r=2 -p -t=../templates/codeview
<target name="docs" depends="init">
<exec dir="${build.dir}/jsdoc/toolkit" executable="${build.dir}/jsdoc/jsrunwrapper.sh">
<arg line='-D="title:${docs.title}" -q -r=2 -p -t=../templates/codeview
-d=${docs.outfiles} ${docs.infiles}'/>
</exec>
</target>
</exec>
</target>
<target name="pot" depends="init">
<java dir="${helma.dir}" classpath="${helma.dir}/launcher.jar" classname="helma.main.launcher.Commandline"
fork="true">
<!-- Root.extractMessages is currently located in Global/i18n.js -->
<arg value="antville.extractMessages"/>
<arg value="${build.dir}/MessageParser.js"/>
<arg value="${i18n.scan}"/>
<arg value="${i18n.template}"/>
</java>
</target>
<target name="pot" depends="init">
<java dir="${helma.dir}" classpath="${helma.dir}/launcher.jar" classname="helma.main.launcher.Commandline"
fork="true">
<!-- Root.extractMessages is currently located in Global/i18n.js -->
<arg value="antville.extractMessages"/>
<arg value="${build.dir}/MessageParser.js"/>
<arg value="${i18n.scan}"/>
<arg value="${i18n.template}"/>
</java>
</target>
<target name="messages" depends="init">
<java dir="${helma.dir}" classpath="${helma.dir}/lib/rhino.jar"
classname="org.mozilla.javascript.tools.shell.Main">
<arg value="${build.dir}/PoParser.js"/>
<arg value="${i18n.poDirectory}"/>
<arg value="${i18n.destination}"/>
<arg value="${i18n.namespace}"/>
</java>
</target>
<target name="messages" depends="init">
<java dir="${helma.dir}" classpath="${helma.dir}/lib/rhino.jar"
classname="org.mozilla.javascript.tools.shell.Main">
<arg value="${build.dir}/PoParser.js"/>
<arg value="${i18n.poDirectory}"/>
<arg value="${i18n.destination}"/>
<arg value="${i18n.namespace}"/>
</java>
</target>
<target name="make-tar" depends="init">
<mkdir dir="${dist.dir}"/>
<fixcrlf srcdir="${path}" eol="lf" eof="remove" includes="**/*.txt,
**/*.properties, **/*.hac, **/*.js, **/*.skin, **/.xml, **/.sh"/>
<tar tarfile="${dist.dir}/${filename}.tar" basedir="${path}" excludes="**">
<tarfileset prefix="${filename}" dir="${path}" mode="755">
<include name="**/*.sh"/>
</tarfileset>
<tarfileset prefix="${filename}" dir="${path}">
<include name="**"/>
<exclude name="**/*.sh"/>
</tarfileset>
</tar>
<bzip2 zipfile="${dist.dir}/${filename}.tbz" src="${dist.dir}/${filename}.tar"/>
<delete file="${dist.dir}/${filename}.tar"/>
</target>
<target name="make-tar" depends="init">
<mkdir dir="${dist.dir}"/>
<fixcrlf srcdir="${path}" eol="lf" eof="remove" includes="**/*.txt,
**/*.properties, **/*.hac, **/*.js, **/*.skin, **/.xml, **/.sh"/>
<tar tarfile="${dist.dir}/${filename}.tar" basedir="${path}" excludes="**">
<tarfileset prefix="${filename}" dir="${path}" mode="755">
<include name="**/*.sh"/>
</tarfileset>
<tarfileset prefix="${filename}" dir="${path}">
<include name="**"/>
<exclude name="**/*.sh"/>
</tarfileset>
</tar>
<bzip2 zipfile="${dist.dir}/${filename}.tbz" src="${dist.dir}/${filename}.tar"/>
<delete file="${dist.dir}/${filename}.tar"/>
</target>
<target name="make-zip" depends="init">
<mkdir dir="${dist.dir}"/>
<fixcrlf srcdir="${path}" eol="crlf" includes="**/*.txt, **/*.properties,
**/*.hac, **/*.js, **/*.skin, **/*.xml, **/.bat"/>
<zip zipfile="${dist.dir}/${filename}.zip">
<zipfileset dir="${path}" prefix="${filename}" includes="**"/>
</zip>
</target>
<target name="make-zip" depends="init">
<mkdir dir="${dist.dir}"/>
<fixcrlf srcdir="${path}" eol="crlf" includes="**/*.txt, **/*.properties,
**/*.hac, **/*.js, **/*.skin, **/*.xml, **/.bat"/>
<zip zipfile="${dist.dir}/${filename}.zip">
<zipfileset dir="${path}" prefix="${filename}" includes="**"/>
</zip>
</target>
<target name="release" depends="init">
<property name="antville.summary"
value="Helma application providing high performance, full featured weblog hosting"/>
<property name="antclick.summary"
value="The lightweight all-in-one package which contains everything you need to run Antville on your computer"/>
<antcall target="upload">
<param name="file" value="${dist.dir}/${package.name}.tbz"/>
<param name="summary" value="${antville.summary}"/>
<param name="labels" value="Type-Package, OpSys-All, Featured"/>
</antcall>
<antcall target="upload">
<param name="file" value="${dist.dir}/${package.name}.zip"/>
<param name="summary" value="${antville.summary}"/>
<param name="labels" value="Type-Package, OpSys-Windows"/>
</antcall>
<antcall target="upload">
<param name="file" value="${dist.dir}/antclick-${version}.tbz"/>
<param name="summary" value="${antclick.summary}"/>
<param name="labels" value="Type-Package, OpSys-All"/>
</antcall>
<antcall target="upload">
<param name="file" value="${dist.dir}/antclick-${version}.zip"/>
<param name="summary" value="${antclick.summary}"/>
<param name="labels" value="Type-Package, OpSys-Windows, Featured"/>
</antcall>
</target>
<target name="release" depends="init">
<property name="antville.summary"
value="Helma application providing high performance, full featured weblog hosting"/>
<property name="antclick.summary"
value="The lightweight all-in-one package which contains everything you need to run Antville on your computer"/>
<antcall target="upload">
<param name="file" value="${dist.dir}/${package.name}.tbz"/>
<param name="summary" value="${antville.summary}"/>
<param name="labels" value="Type-Package, OpSys-All, Featured"/>
</antcall>
<antcall target="upload">
<param name="file" value="${dist.dir}/${package.name}.zip"/>
<param name="summary" value="${antville.summary}"/>
<param name="labels" value="Type-Package, OpSys-Windows"/>
</antcall>
<antcall target="upload">
<param name="file" value="${dist.dir}/antclick-${version}.tbz"/>
<param name="summary" value="${antclick.summary}"/>
<param name="labels" value="Type-Package, OpSys-All"/>
</antcall>
<antcall target="upload">
<param name="file" value="${dist.dir}/antclick-${version}.zip"/>
<param name="summary" value="${antclick.summary}"/>
<param name="labels" value="Type-Package, OpSys-Windows, Featured"/>
</antcall>
</target>
<target name="test-upload" depends="init">
<antcall target="upload">
<param name="file" value="/Users/tobi/Desktop/test.txt"/>
<param name="summary" value="Test pls ignore"/>
<param name="labels" value="Deprecated"/>
</antcall>
</target>
<target name="test-upload" depends="init">
<antcall target="upload">
<param name="file" value="/Users/tobi/Desktop/test.txt"/>
<param name="summary" value="Test pls ignore"/>
<param name="labels" value="Deprecated"/>
</antcall>
</target>
<target name="upload" depends="file-exists" if="file.exists">
<taskdef classname="net.bluecow.googlecode.ant.GoogleCodeUploadTask"
classpath="${build.dir}/ant-googlecode-0.0.3.jar" name="gcupload"/>
<gcupload username="${google.username}" password="${google.password}" projectname="antville" filename="${file}"
targetfilename="${file}" summary="${summary}" labels="${labels}"/>
</target>
<target name="upload" depends="file-exists" if="file.exists">
<taskdef classname="net.bluecow.googlecode.ant.GoogleCodeUploadTask"
classpath="${build.dir}/ant-googlecode-0.0.3.jar" name="gcupload"/>
<gcupload username="${google.username}" password="${google.password}" projectname="antville" filename="${file}"
targetfilename="${file}" summary="${summary}" labels="${labels}"/>
</target>
<target name="patch" depends="init">
<input message="Please enter the patch ID: " addproperty="patch.id"/>
<loadfile property="patch" srcFile="${basedir}/extra/updater/patch-${patch.id}.js"/>
<echo message="${patch}"/>
<input message="Apply the displayed patch? " validargs="y,n" addproperty="patch.confirm"/>
<condition property="patch.abort">
<equals arg1="${patch.confirm}" arg2="n" casesensitive="false" trim="true"/>
</condition>
<fail if="patch.abort">Build aborted by user.</fail>
<java dir="${helma.dir}" classpath="${helma.dir}/launcher.jar" classname="helma.main.launcher.Commandline"
fork="true">
<arg value="antville.patch"/>
<arg value="${patch}"/>
</java>
</target>
<target name="patch" depends="init">
<input message="Please enter the patch ID: " addproperty="patch.id"/>
<loadfile property="patch" srcFile="${basedir}/extra/updater/patch-${patch.id}.js"/>
<echo message="${patch}"/>
<input message="Apply the displayed patch? " validargs="y,n" addproperty="patch.confirm"/>
<condition property="patch.abort">
<equals arg1="${patch.confirm}" arg2="n" casesensitive="false" trim="true"/>
</condition>
<fail if="patch.abort">Build aborted by user.</fail>
<java dir="${helma.dir}" classpath="${helma.dir}/launcher.jar" classname="helma.main.launcher.Commandline"
fork="true">
<arg value="antville.patch"/>
<arg value="${patch}"/>
</java>
</target>
<target name="clean" depends="init">
<delete dir="${work.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="clean" depends="init">
<delete dir="${work.dir}"/>
<delete dir="${dist.dir}"/>
</target>
<target name="file-exists" unless="file.exists">
<available property="file.exists" file="${file}"/>
</target>
<target name="file-exists" unless="file.exists">
<available property="file.exists" file="${file}"/>
</target>
<target name="debug" depends="init">
<!-- For debugging and testing purposes -->
</target>
<target name="debug" depends="init">
<!-- For debugging and testing purposes -->
</target>
</project>

View file

@ -7,7 +7,7 @@
// 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
// 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,
@ -39,10 +39,10 @@
* @constructor
*/
var Message = function(id, pluralId) {
this.id = id && String(id);
this.pluralId = pluralId && String(pluralId);
this.locations = [];
return this;
this.id = id && String(id);
this.pluralId = pluralId && String(pluralId);
this.locations = [];
return this;
};
/**
@ -54,11 +54,11 @@ var Message = function(id, pluralId) {
* @type String
*/
Message.getKey = function(id, pluralId) {
if (id && pluralId) {
return id + pluralId;
} else {
return id;
}
if (id && pluralId) {
return id + pluralId;
} else {
return id;
}
};
/**
@ -71,28 +71,28 @@ Message.getKey = function(id, pluralId) {
* @type String
*/
Message.formatId = function(str, wrap) {
var escapeQuotes = function(s) {
return s.replace(/(^|[^\\])"/g, '$1\\"');
};
var escapeQuotes = function(s) {
return s.replace(/(^|[^\\])"/g, '$1\\"');
};
var len = 80;
var buf = new java.lang.StringBuffer();
if (wrap == true && str.length > len) {
buf.append('""\n');
var offset = 0;
while (offset < str.length) {
buf.append('"');
buf.append(escapeQuotes(str.substring(offset, offset += len)));
buf.append('"');
buf.append("\n");
}
return buf.toString();
} else {
var len = 80;
var buf = new java.lang.StringBuffer();
if (wrap == true && str.length > len) {
buf.append('""\n');
var offset = 0;
while (offset < str.length) {
buf.append('"');
buf.append(escapeQuotes(str));
buf.append('"\n');
}
return buf.toString();
buf.append(escapeQuotes(str.substring(offset, offset += len)));
buf.append('"');
buf.append("\n");
}
return buf.toString();
} else {
buf.append('"');
buf.append(escapeQuotes(str));
buf.append('"\n');
}
return buf.toString();
};
/**
@ -103,7 +103,7 @@ Message.formatId = function(str, wrap) {
* was found at
*/
Message.prototype.addLocation = function(filePath, lineNum) {
this.locations.push(filePath + ":" + lineNum);
this.locations.push(filePath + ":" + lineNum);
};
/**
@ -113,34 +113,34 @@ Message.prototype.addLocation = function(filePath, lineNum) {
* to write into
*/
Message.prototype.write = function(buf) {
for (var i=0;i<this.locations.length;i++) {
buf.append("#: ");
buf.append(this.locations[i]);
buf.append("\n");
}
if (this.id.indexOf("{") > -1
|| (this.pluralId != null && this.pluralId.indexOf("{") > -1)) {
buf.append("#, java-format\n");
}
buf.append('msgid ');
buf.append(Message.formatId(this.id));
if (this.pluralId != null) {
buf.append('msgid_plural ');
buf.append(Message.formatId(this.pluralId));
buf.append('msgstr[0] ""\nmsgstr[1] ""\n')
} else {
buf.append('msgstr ""\n')
}
buf.append("\n");
return;
for (var i=0;i<this.locations.length;i++) {
buf.append("#: ");
buf.append(this.locations[i]);
buf.append("\n");
}
if (this.id.indexOf("{") > -1
|| (this.pluralId != null && this.pluralId.indexOf("{") > -1)) {
buf.append("#, java-format\n");
}
buf.append('msgid ');
buf.append(Message.formatId(this.id));
if (this.pluralId != null) {
buf.append('msgid_plural ');
buf.append(Message.formatId(this.pluralId));
buf.append('msgstr[0] ""\nmsgstr[1] ""\n')
} else {
buf.append('msgstr ""\n')
}
buf.append("\n");
return;
};
/**
* @constructor
*/
var MessageParser = function() {
this.messages = {};
return this;
this.messages = {};
return this;
};
/**
@ -150,11 +150,11 @@ var MessageParser = function() {
* @type Object
*/
MessageParser.FUNCTION_NAMES = {
"_": true,
"gettext": true,
"ngettext": true,
"markgettext": true,
"cgettext": true
"_": true,
"gettext": true,
"ngettext": true,
"markgettext": true,
"cgettext": true
};
/**
@ -198,7 +198,7 @@ MessageParser.REGEX_PARAM = /([\w]*)\s*=\s*["'](.*?)["']\s*(?=\w+=|$)/gm;
* @type Number
*/
MessageParser.getLineNum = function(str, idx) {
return str.substring(0, idx).split(/.*(?:\r\n|\n\r|\r|\n)/).length;
return str.substring(0, idx).split(/.*(?:\r\n|\n\r|\r|\n)/).length;
};
/**
@ -209,36 +209,36 @@ MessageParser.getLineNum = function(str, idx) {
* @param {String} encoding The encoding to use
*/
MessageParser.prototype.parse = function(file, encoding) {
if (file.isDirectory()) {
var list = file.list();
for (var i=0;i<list.length;i++) {
this.parse(new java.io.File(file, list[i]), encoding);
if (file.isDirectory()) {
var list = file.list();
for (var i=0;i<list.length;i++) {
this.parse(new java.io.File(file, list[i]), encoding);
}
} else {
var fName, dotIdx;
fName = file.getName();
if ((dotIdx = fName.lastIndexOf(".")) > -1) {
switch (String(fName.substring(dotIdx+1))) {
case "skin":
print("Parsing skin file " + file.getCanonicalPath() + "...");
this.parseSkinFile(file, encoding);
break;
case "hac":
case "js":
print("Parsing function file " + file.getCanonicalPath() + "...");
this.parseFunctionFile(file, encoding);
break;
default:
break;
}
} else {
var fName, dotIdx;
fName = file.getName();
if ((dotIdx = fName.lastIndexOf(".")) > -1) {
switch (String(fName.substring(dotIdx+1))) {
case "skin":
print("Parsing skin file " + file.getCanonicalPath() + "...");
this.parseSkinFile(file, encoding);
break;
case "hac":
case "js":
print("Parsing function file " + file.getCanonicalPath() + "...");
this.parseFunctionFile(file, encoding);
break;
default:
break;
}
}
}
return;
}
}
return;
};
/** @ignore */
MessageParser.prototype.toString = function() {
return "[Jala Message Parser]";
return "[Jala Message Parser]";
};
/**
@ -248,65 +248,65 @@ MessageParser.prototype.toString = function() {
* @param {String} encoding The encoding to use
*/
MessageParser.prototype.parseFunctionFile = function(file, encoding) {
var fis = new java.io.FileInputStream(file);
var isr = new java.io.InputStreamReader(fis, encoding || "UTF-8");
var reader = new java.io.BufferedReader(isr);
var tokenizer = new java.io.StreamTokenizer(reader);
var messages = [], stack = [];
var c;
while ((c = tokenizer.nextToken()) != java.io.StreamTokenizer.TT_EOF) {
switch (c) {
case java.io.StreamTokenizer.TT_WORD:
if (MessageParser.FUNCTION_NAMES[tokenizer.sval] == true) {
stack.push({name: tokenizer.sval, lineNr: tokenizer.lineno()});
} else if (stack.length > 0) {
// it's something else than a string argument inside a gettext method call
// so finalize the argument parsing here as we aren't interested in that
messages.push(stack.pop());
}
break;
case java.io.StreamTokenizer.TT_NUMBER:
break;
default:
if (stack.length > 0) {
if ("\u0028".charCodeAt(0) == c) {
// start of arguments (an opening bracket)
stack[stack.length-1].args = [];
} else if ("\u0029".charCodeAt(0) == c) {
// end of arguments (a closing bracket)
messages.push(stack.pop());
} else if ("\u0022".charCodeAt(0) == c || "\u0027".charCodeAt(0) == c) {
// a quoted string argument
stack[stack.length-1].args.push(tokenizer.sval);
}
}
break;
var fis = new java.io.FileInputStream(file);
var isr = new java.io.InputStreamReader(fis, encoding || "UTF-8");
var reader = new java.io.BufferedReader(isr);
var tokenizer = new java.io.StreamTokenizer(reader);
var messages = [], stack = [];
var c;
while ((c = tokenizer.nextToken()) != java.io.StreamTokenizer.TT_EOF) {
switch (c) {
case java.io.StreamTokenizer.TT_WORD:
if (MessageParser.FUNCTION_NAMES[tokenizer.sval] == true) {
stack.push({name: tokenizer.sval, lineNr: tokenizer.lineno()});
} else if (stack.length > 0) {
// it's something else than a string argument inside a gettext method call
// so finalize the argument parsing here as we aren't interested in that
messages.push(stack.pop());
}
break;
case java.io.StreamTokenizer.TT_NUMBER:
break;
default:
if (stack.length > 0) {
if ("\u0028".charCodeAt(0) == c) {
// start of arguments (an opening bracket)
stack[stack.length-1].args = [];
} else if ("\u0029".charCodeAt(0) == c) {
// end of arguments (a closing bracket)
messages.push(stack.pop());
} else if ("\u0022".charCodeAt(0) == c || "\u0027".charCodeAt(0) == c) {
// a quoted string argument
stack[stack.length-1].args.push(tokenizer.sval);
}
}
break;
}
}
if (messages.length > 0) {
var msgParam, key, msg;
for (var i=0;i<messages.length;i++) {
msgParam = messages[i];
if (msgParam.args && msgParam.args.length > 0) {
if (msgParam.name === "cgettext" || msgParam.name === "markgettext") {
msgParam.args[0] = cgettext.getKey(msgParam.args[0], msgParam.args[1]);
delete msgParam.args[1];
}
key = Message.getKey(msgParam.args[0]);
if (!(msg = this.messages[key])) {
this.messages[key] = msg = new Message(msgParam.args[0], msgParam.args[1]);
}
if (!msg.pluralId && msgParam.args.length > 1) {
msg.pluralId = msgParam.args[1];
}
msg.addLocation(file.getCanonicalPath(), msgParam.lineNr);
}
}
if (messages.length > 0) {
var msgParam, key, msg;
for (var i=0;i<messages.length;i++) {
msgParam = messages[i];
if (msgParam.args && msgParam.args.length > 0) {
if (msgParam.name === "cgettext" || msgParam.name === "markgettext") {
msgParam.args[0] = cgettext.getKey(msgParam.args[0], msgParam.args[1]);
delete msgParam.args[1];
}
key = Message.getKey(msgParam.args[0]);
if (!(msg = this.messages[key])) {
this.messages[key] = msg = new Message(msgParam.args[0], msgParam.args[1]);
}
if (!msg.pluralId && msgParam.args.length > 1) {
msg.pluralId = msgParam.args[1];
}
msg.addLocation(file.getCanonicalPath(), msgParam.lineNr);
}
}
}
fis.close();
isr.close();
reader.close();
return;
}
}
fis.close();
isr.close();
reader.close();
return;
};
/**
@ -324,72 +324,72 @@ MessageParser.prototype.parseFunctionFile = function(file, encoding) {
* @param {String} encoding The encoding to use
*/
MessageParser.prototype.parseSkinFile = function(file, encoding) {
var self = this;
var source = readFile(file.getAbsolutePath(), encoding || "UTF-8");
var self = this;
var source = readFile(file.getAbsolutePath(), encoding || "UTF-8");
var checkNestedMacros = function(iterator) {
var macros = [];
while (iterator.hasNext()) {
macro = iterator.next();
if (macro && macro.constructor !== String) {
macros.push(macro);
}
var checkNestedMacros = function(iterator) {
var macros = [];
while (iterator.hasNext()) {
macro = iterator.next();
if (macro && macro.constructor !== String) {
macros.push(macro);
}
processMacros(macros);
}
}
processMacros(macros);
}
var processMacros = function(macros) {
var re = gettext_macro.REGEX;
var id, pluralId, name, args, param, key, msg;
for each (var macro in macros) {
id = pluralId = null;
name = macro.getName();
param = macro.getNamedParams();
if (param) {
checkNestedMacros(param.values().iterator());
if (name === MessageParser.MACRO_NAME) {
id = param.get("text");
pluralId = param.get("plural");
} else if (param.containsKey("message") === MessageParser.ATTRIBUTE_NAME) {
id = param.get("message");
pluralId = param.get("plural");
}
}
args = macro.getPositionalParams();
if (args) {
checkNestedMacros(args.iterator());
if (name === "gettext" || name === "markgettext") {
id = cgettext.getKey(args.get(0), param && param.get("context"));
} else if (name === "ngettext") {
id = args.get(0);
pluralId = args.get(1);
}
}
if (id != null) {
if (id.constructor !== String) {
continue;
}
// create new Message instance or update the existing one
id = id.replace(re, String.SPACE);
pluralId && (pluralId = pluralId.replace(re, String.SPACE));
key = Message.getKey(id);
if (!(msg = self.messages[key])) {
self.messages[key] = msg = new Message(id, pluralId, file.getCanonicalPath());
}
msg.addLocation(file.getCanonicalPath(), MessageParser.getLineNum(source, macro.start));
}
var processMacros = function(macros) {
var re = gettext_macro.REGEX;
var id, pluralId, name, args, param, key, msg;
for each (var macro in macros) {
id = pluralId = null;
name = macro.getName();
param = macro.getNamedParams();
if (param) {
checkNestedMacros(param.values().iterator());
if (name === MessageParser.MACRO_NAME) {
id = param.get("text");
pluralId = param.get("plural");
} else if (param.containsKey("message") === MessageParser.ATTRIBUTE_NAME) {
id = param.get("message");
pluralId = param.get("plural");
}
}
}
args = macro.getPositionalParams();
if (args) {
checkNestedMacros(args.iterator());
if (name === "gettext" || name === "markgettext") {
id = cgettext.getKey(args.get(0), param && param.get("context"));
} else if (name === "ngettext") {
id = args.get(0);
pluralId = args.get(1);
}
}
if (id != null) {
if (id.constructor !== String) {
continue;
}
// create new Message instance or update the existing one
id = id.replace(re, String.SPACE);
pluralId && (pluralId = pluralId.replace(re, String.SPACE));
key = Message.getKey(id);
if (!(msg = self.messages[key])) {
self.messages[key] = msg = new Message(id, pluralId, file.getCanonicalPath());
}
msg.addLocation(file.getCanonicalPath(), MessageParser.getLineNum(source, macro.start));
}
}
}
var skin = createSkin(source);
if (skin.hasMainskin()) {
processMacros(skin.getMacros());
}
for each (var name in skin.getSubskinNames()) {
var subskin = skin.getSubskin(name);
processMacros(subskin.getMacros());
}
return;
var skin = createSkin(source);
if (skin.hasMainskin()) {
processMacros(skin.getMacros());
}
for each (var name in skin.getSubskinNames()) {
var subskin = skin.getSubskin(name);
processMacros(subskin.getMacros());
}
return;
}
/**
@ -399,58 +399,58 @@ MessageParser.prototype.parseSkinFile = function(file, encoding) {
* @see http://drupal.org/node/17564
*/
MessageParser.prototype.getPotString = function() {
var date = new Date;
var buf = new java.lang.StringBuffer();
buf.append('#\n');
buf.append('# The Antville Project\n');
buf.append('# http://code.google.com/p/antville\n');
buf.append('#\n');
buf.append('# Copyright 2001-' + date.getFullYear() + ' by The Antville People\n');
buf.append('#\n');
buf.append("# Licensed under the Apache License, Version 2.0 (the ``License''\n");
buf.append('# you may not use this file except in compliance with the License.\n');
buf.append('# You may obtain a copy of the License at\n');
buf.append('#\n');
buf.append('# http://www.apache.org/licenses/LICENSE-2.0\n');
buf.append('#\n');
buf.append('# Unless required by applicable law or agreed to in writing, software\n');
buf.append("# distributed under the License is distributed on an ``AS IS'' BASIS,\n");
buf.append('# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n');
buf.append('# See the License for the specific language governing permissions and\n');
buf.append('# limitations under the License.\n');
buf.append('#\n');
buf.append('# $Revision$\n');
buf.append('# $Author$\n');
buf.append('# $Date$\n');
buf.append('# $URL$\n');
buf.append('#\n');
buf.append('#, fuzzy\n');
buf.append('msgid ""\n');
buf.append('msgstr ""\n');
buf.append('"Project-Id-Version: Antville-' + Root.VERSION + '\\n"\n');
buf.append('"Report-Msgid-Bugs-To: mail@antville.org\\n"\n');
var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mmZ");
buf.append('"POT-Creation-Date: ' + sdf.format(new java.util.Date()) + '\\n"\n');
buf.append('"PO-Revision-Date: ' + sdf.format(new java.util.Date()) + '\\n"\n');
//buf.append('"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"\n');
buf.append('"Language-Team: The Antville People <mail@antville.org>\\n"\n');
buf.append('"MIME-Version: 1.0\\n"\n');
buf.append('"Content-Type: text/plain; charset=utf-8\\n"\n');
buf.append('"Content-Transfer-Encoding: 8bit\\n"\n');
buf.append('"Plural-Forms: nplurals=2; plural=(n != 1);\\n"\n');
buf.append('\n');
var date = new Date;
var buf = new java.lang.StringBuffer();
buf.append('#\n');
buf.append('# The Antville Project\n');
buf.append('# http://code.google.com/p/antville\n');
buf.append('#\n');
buf.append('# Copyright 2001-' + date.getFullYear() + ' by The Antville People\n');
buf.append('#\n');
buf.append("# Licensed under the Apache License, Version 2.0 (the ``License''\n");
buf.append('# you may not use this file except in compliance with the License.\n');
buf.append('# You may obtain a copy of the License at\n');
buf.append('#\n');
buf.append('# http://www.apache.org/licenses/LICENSE-2.0\n');
buf.append('#\n');
buf.append('# Unless required by applicable law or agreed to in writing, software\n');
buf.append("# distributed under the License is distributed on an ``AS IS'' BASIS,\n");
buf.append('# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n');
buf.append('# See the License for the specific language governing permissions and\n');
buf.append('# limitations under the License.\n');
buf.append('#\n');
buf.append('# $Revision$\n');
buf.append('# $Author$\n');
buf.append('# $Date$\n');
buf.append('# $URL$\n');
buf.append('#\n');
buf.append('#, fuzzy\n');
buf.append('msgid ""\n');
buf.append('msgstr ""\n');
buf.append('"Project-Id-Version: Antville-' + Root.VERSION + '\\n"\n');
buf.append('"Report-Msgid-Bugs-To: mail@antville.org\\n"\n');
var sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mmZ");
buf.append('"POT-Creation-Date: ' + sdf.format(new java.util.Date()) + '\\n"\n');
buf.append('"PO-Revision-Date: ' + sdf.format(new java.util.Date()) + '\\n"\n');
//buf.append('"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"\n');
buf.append('"Language-Team: The Antville People <mail@antville.org>\\n"\n');
buf.append('"MIME-Version: 1.0\\n"\n');
buf.append('"Content-Type: text/plain; charset=utf-8\\n"\n');
buf.append('"Content-Transfer-Encoding: 8bit\\n"\n');
buf.append('"Plural-Forms: nplurals=2; plural=(n != 1);\\n"\n');
buf.append('\n');
// sort all messages by their singular key
var keys = [];
for (var i in this.messages) {
keys[keys.length] = this.messages[i].id;
}
keys.sort();
// add all the messages
for (var i=0;i<keys.length;i++) {
this.messages[keys[i]].write(buf);
}
return new java.lang.String(buf);
// sort all messages by their singular key
var keys = [];
for (var i in this.messages) {
keys[keys.length] = this.messages[i].id;
}
keys.sort();
// add all the messages
for (var i=0;i<keys.length;i++) {
this.messages[keys[i]].write(buf);
}
return new java.lang.String(buf);
};
/**
@ -458,10 +458,10 @@ MessageParser.prototype.getPotString = function() {
* @param {java.io.File} file The file to write to
*/
MessageParser.prototype.writeToFile = function(file) {
var writer = new java.io.FileWriter(file);
writer.write(new java.lang.String(this.getPotString().getBytes("UTF-8")));
writer.close();
return;
var writer = new java.io.FileWriter(file);
writer.write(new java.lang.String(this.getPotString().getBytes("UTF-8")));
writer.close();
return;
};
/**
@ -471,24 +471,24 @@ var toParse = [];
var arg, outFile, file, fileEncoding;
for (var i=0;i<arguments.length;i++) {
arg = arguments[i];
if (arg.indexOf("-o") === 0 && i < arguments.length -1) {
outFile = new java.io.File(arguments[i += 1]);
} else if (arg.indexOf("-e") === 0 && i < arguments.length -1) {
fileEncoding = arguments[i += 1];
} else {
// add argument to list of files and directories to parse
toParse.push(new java.io.File(arg));
}
arg = arguments[i];
if (arg.indexOf("-o") === 0 && i < arguments.length -1) {
outFile = new java.io.File(arguments[i += 1]);
} else if (arg.indexOf("-e") === 0 && i < arguments.length -1) {
fileEncoding = arguments[i += 1];
} else {
// add argument to list of files and directories to parse
toParse.push(new java.io.File(arg));
}
}
// start parsing
var parser = new MessageParser();
for (var i=0;i<toParse.length;i++) {
parser.parse(toParse[i], fileEncoding);
parser.parse(toParse[i], fileEncoding);
}
if (outFile != null) {
parser.writeToFile(outFile);
parser.writeToFile(outFile);
} else {
print(parser.getPotString());
print(parser.getPotString());
}

View file

@ -7,7 +7,7 @@
// 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
// 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,
@ -49,24 +49,24 @@
* @constructor
*/
var PoParser = function(namespace) {
/**
* An array containing the parsed messages
* @type Array
*/
this.messages = [];
/**
* An array containing the parsed messages
* @type Array
*/
this.messages = [];
/**
* The locale key string (eg. "de_AT") of the .po file
* @type String
*/
this.localeKey = null;
/**
* The locale key string (eg. "de_AT") of the .po file
* @type String
*/
this.localeKey = null;
/**
* The namespace (optional) where to store the generated messages
* @type String
*/
this.namespace = namespace;
return this;
/**
* The namespace (optional) where to store the generated messages
* @type String
*/
this.namespace = namespace;
return this;
};
/**
@ -108,7 +108,7 @@ PoParser.REGEX_MSGSTR = /^\s*msgstr(?:\[(\d)\])?\s+\"(.*)\"\s*$/;
PoParser.REGEX_DATA = /^\s*msg/;
PoParser.isData = function(str) {
return PoParser.REGEX_DATA.test(str);
return PoParser.REGEX_DATA.test(str);
};
/**
@ -118,21 +118,21 @@ PoParser.isData = function(str) {
* @type java.lang.String
*/
PoParser.readFile = function(file) {
var inStream = new java.io.InputStreamReader(new java.io.FileInputStream(file), "UTF-8");
var buffer = new java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2048);
var read = 0;
var r = 0;
while ((r = inStream.read(buffer, read, buffer.length - read)) > -1) {
read += r;
if (read == buffer.length) {
// grow input buffer
var newBuffer = new java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, buffer.length * 2);
java.lang.System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
buffer = newBuffer;
}
}
inStream.close();
return new java.lang.String(buffer, 0, read);
var inStream = new java.io.InputStreamReader(new java.io.FileInputStream(file), "UTF-8");
var buffer = new java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 2048);
var read = 0;
var r = 0;
while ((r = inStream.read(buffer, read, buffer.length - read)) > -1) {
read += r;
if (read == buffer.length) {
// grow input buffer
var newBuffer = new java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, buffer.length * 2);
java.lang.System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
buffer = newBuffer;
}
}
inStream.close();
return new java.lang.String(buffer, 0, read);
}
/**
@ -141,63 +141,63 @@ PoParser.readFile = function(file) {
* @param {java.io.File} file The .po file to parse
*/
PoParser.prototype.parse = function(file) {
// parse the locale key out of the file name
var fileName = file.getName();
if (!(this.localeKey = fileName.substring(0, fileName.indexOf(".")))) {
throw "Invalid PO file name: " + fileName;
}
// parse the locale key out of the file name
var fileName = file.getName();
if (!(this.localeKey = fileName.substring(0, fileName.indexOf(".")))) {
throw "Invalid PO file name: " + fileName;
}
// read the PO file content and parse it into messages
var content = PoParser.readFile(file);
var start = new Date();
var lines = content.split(PoParser.REGEX_LINES);
var idx = -1;
var line = null;
var m, value, nr;
var msg;
// read the PO file content and parse it into messages
var content = PoParser.readFile(file);
var start = new Date();
var lines = content.split(PoParser.REGEX_LINES);
var idx = -1;
var line = null;
var m, value, nr;
var msg;
var hasMoreLines = function() {
return idx < lines.length - 1;
};
var hasMoreLines = function() {
return idx < lines.length - 1;
};
var nextLine = function() {
return (line = lines[idx += 1]) != null;
};
var nextLine = function() {
return (line = lines[idx += 1]) != null;
};
var getContinuation = function(str) {
var nLine;
while ((nLine = lines[idx + 1]) != null) {
if ((m = nLine.match(PoParser.REGEX_MSG_CONT)) != null) {
str += m[1];
nextLine();
} else {
break;
}
var getContinuation = function(str) {
var nLine;
while ((nLine = lines[idx + 1]) != null) {
if ((m = nLine.match(PoParser.REGEX_MSG_CONT)) != null) {
str += m[1];
nextLine();
} else {
break;
}
return str;
}
}
return str;
}
while (nextLine()) {
if ((m = line.match(PoParser.REGEX_MSGID)) != null) {
value = getContinuation(m[1]);
if (value) {
msg = this.messages[this.messages.length] = new Message(value);
}
} else if ((m = line.match(PoParser.REGEX_MSGID_PLURAL)) != null) {
value = getContinuation(m[1]);
if (value && msg != null) {
msg.pluralKey = value;
}
} else if ((m = line.match(PoParser.REGEX_MSGSTR)) != null) {
nr = m[1];
value = getContinuation(m[2]);
if (value && msg != null) {
nr = parseInt(nr, 10);
msg.translations[nr || 0] = value;
}
while (nextLine()) {
if ((m = line.match(PoParser.REGEX_MSGID)) != null) {
value = getContinuation(m[1]);
if (value) {
msg = this.messages[this.messages.length] = new Message(value);
}
}
return;
} else if ((m = line.match(PoParser.REGEX_MSGID_PLURAL)) != null) {
value = getContinuation(m[1]);
if (value && msg != null) {
msg.pluralKey = value;
}
} else if ((m = line.match(PoParser.REGEX_MSGSTR)) != null) {
nr = m[1];
value = getContinuation(m[2]);
if (value && msg != null) {
nr = parseInt(nr, 10);
msg.translations[nr || 0] = value;
}
}
}
return;
};
/**
@ -207,44 +207,44 @@ PoParser.prototype.parse = function(file) {
* file should be saved
*/
PoParser.prototype.writeToFile = function(output) {
var buf = new java.lang.StringBuffer();
// write header
buf.append('/**\n');
buf.append(' * Instantiate the messages namespace if it\'s not already existing\n');
buf.append(' */\n');
var buf = new java.lang.StringBuffer();
// write header
buf.append('/**\n');
buf.append(' * Instantiate the messages namespace if it\'s not already existing\n');
buf.append(' */\n');
var objPath = "";
if (this.namespace) {
objPath += this.namespace;
buf.append('if (!global.' + objPath + ') {\n');
buf.append(' global.' + objPath + ' = {};\n');
buf.append('}\n');
objPath += ".";
}
objPath += "messages";
buf.append('if (!global.' + objPath + ') {\n');
buf.append(' global.' + objPath + ' = {};\n');
buf.append('}\n\n');
if (this.namespace) {
objPath += this.namespace;
buf.append('if (!global.' + objPath + ') {\n');
buf.append(' global.' + objPath + ' = {};\n');
buf.append('}\n');
objPath += ".";
}
objPath += "messages";
buf.append('if (!global.' + objPath + ') {\n');
buf.append(' global.' + objPath + ' = {};\n');
buf.append('}\n\n');
buf.append('/**\n');
buf.append(' * Messages for locale "' + this.localeKey + '"\n');
buf.append(' */\n');
var fname = objPath + "." + this.localeKey + ".js";
objPath += "['" + this.localeKey + "']";
buf.append('global.' + objPath + ' = {\n');
// write messages
for (var i=0;i<this.messages.length; i++) {
this.messages[i].write(buf);
}
// write footer
buf.append('};\n');
buf.append('/**\n');
buf.append(' * Messages for locale "' + this.localeKey + '"\n');
buf.append(' */\n');
var fname = objPath + "." + this.localeKey + ".js";
objPath += "['" + this.localeKey + "']";
buf.append('global.' + objPath + ' = {\n');
// write messages
for (var i=0;i<this.messages.length; i++) {
this.messages[i].write(buf);
}
// write footer
buf.append('};\n');
// write the message catalog into the outFile
var file = new java.io.File(output, fname);
var writer = new java.io.FileWriter(file);
writer.write(new java.lang.String(buf.toString().getBytes("UTF-8")));
writer.close();
print("generated messages file " + file.getAbsolutePath());
return;
// write the message catalog into the outFile
var file = new java.io.File(output, fname);
var writer = new java.io.FileWriter(file);
writer.write(new java.lang.String(buf.toString().getBytes("UTF-8")));
writer.close();
print("generated messages file " + file.getAbsolutePath());
return;
};
/**
@ -255,10 +255,10 @@ PoParser.prototype.writeToFile = function(output) {
* @constructor
*/
var Message = function(singularKey) {
this.singularKey = singularKey;
this.pluralKey = null;
this.translations = [];
return this;
this.singularKey = singularKey;
this.pluralKey = null;
this.translations = [];
return this;
}
/**
@ -267,37 +267,37 @@ var Message = function(singularKey) {
* string to
*/
Message.prototype.write = function(buf) {
var writeLine = function(key, value) {
buf.append(' "');
buf.append(key);
buf.append('": "');
if (value !== null && value !== undefined) {
buf.append(value);
}
buf.append('",\n');
};
var writeLine = function(key, value) {
buf.append(' "');
buf.append(key);
buf.append('": "');
if (value !== null && value !== undefined) {
buf.append(value);
}
buf.append('",\n');
};
if (this.singularKey != null) {
writeLine(this.singularKey, this.translations[0]);
if (this.pluralKey != null) {
writeLine(this.pluralKey, this.translations[1]);
}
}
return;
if (this.singularKey != null) {
writeLine(this.singularKey, this.translations[0]);
if (this.pluralKey != null) {
writeLine(this.pluralKey, this.translations[1]);
}
}
return;
}
/**
* Main script body
*/
if (arguments.length < 2) {
print("Usage:");
print("PoParser.js <input> <output> [namespace]");
print("<input>: Either a single .po file or a directory containing .po files");
print("<output>: The directory where the generated messages files should be stored");
print("[namespace]: An optional global namespace where the messages should be");
print(" stored (eg. a namespace like 'jala' will lead to messages");
print(" stored in global.jala.messages by their locale.");
quit();
print("Usage:");
print("PoParser.js <input> <output> [namespace]");
print("<input>: Either a single .po file or a directory containing .po files");
print("<output>: The directory where the generated messages files should be stored");
print("[namespace]: An optional global namespace where the messages should be");
print(" stored (eg. a namespace like 'jala' will lead to messages");
print(" stored in global.jala.messages by their locale.");
quit();
}
var input = new java.io.File(arguments[0]);
@ -306,31 +306,31 @@ var namespace = arguments[2];
// check if the output destination is a directory
if (output.isFile()) {
print("Invalid arguments: the output destination must be a directory.");
quit();
print("Invalid arguments: the output destination must be a directory.");
quit();
}
if (namespace && namespace.indexOf(".") != -1) {
print("Invalid arguments: Please don't specify complex object paths, as this");
print("would corrupt the messages file.");
quit();
print("Invalid arguments: Please don't specify complex object paths, as this");
print("would corrupt the messages file.");
quit();
}
// parse the PO file(s) and create the message catalog files
var parser;
if (input.isDirectory()) {
var files = input.listFiles();
var file;
for (var i=0;i<files.length;i++) {
file = files[i];
if (file.getName().endsWith(".po")) {
parser = new PoParser(namespace);
parser.parse(file);
parser.writeToFile(output);
}
}
var files = input.listFiles();
var file;
for (var i=0;i<files.length;i++) {
file = files[i];
if (file.getName().endsWith(".po")) {
parser = new PoParser(namespace);
parser.parse(file);
parser.writeToFile(output);
}
}
} else {
parser = new PoParser(namespace);
parser.parse(input);
parser.writeToFile(output);
parser = new PoParser(namespace);
parser.parse(input);
parser.writeToFile(output);
}

View file

@ -2,74 +2,74 @@ CodeMirror.defineMode("helma-skin", function(config, parserConfig) {
//config settings
var macroStartRegex = parserConfig.macroStartRegex || /^<%/i,
macroEndRegex = parserConfig.macroEndRegex || /^%>/i;
macroEndRegex = parserConfig.macroEndRegex || /^%>/i;
//inner modes
var htmlMixedMode;
var macroMode = {
startState: function() {
return {}
},
token: function(stream, state) {
var c = stream.next();
return 'helma-macro';
}
}
startState: function() {
return {}
},
token: function(stream, state) {
var c = stream.next();
return 'helma-macro';
}
}
//tokenizer when in html mode
function htmlDispatch(stream, state) {
if (stream.match(macroStartRegex, false)) {
state.token=macroDispatch;
return macroMode.token(stream, state.macroState);
}
else
return htmlMixedMode.token(stream, state.htmlState);
}
if (stream.match(macroStartRegex, false)) {
state.token=macroDispatch;
return macroMode.token(stream, state.macroState);
}
else
return htmlMixedMode.token(stream, state.htmlState);
}
//tokenizer when in macro mode
function macroDispatch(stream, state) {
if (stream.match(macroEndRegex, false)) {
state.token=htmlDispatch;
return htmlMixedMode.token(stream, state.htmlState);
}
else{
var style = macroMode.token(stream, state.macroState);
return style;
}
if (stream.match(macroEndRegex, false)) {
state.token=htmlDispatch;
return htmlMixedMode.token(stream, state.htmlState);
}
else{
var style = macroMode.token(stream, state.macroState);
return style;
}
}
return {
startState: function() {
htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
return {
token : parserConfig.startOpen ? macroDispatch : htmlDispatch,
htmlState : htmlMixedMode.startState(),
macroState : macroMode.startState()
}
},
token: function(stream, state) {
return state.token(stream, state);
},
indent: function(state, textAfter) {
if (state.token == htmlDispatch)
return htmlMixedMode.indent(state.htmlState, textAfter);
else
return macroMode.indent(state.macroState, textAfter);
},
copyState: function(state) {
return {
token : state.token,
htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
macroState : CodeMirror.copyState(macroMode, state.macroState)
startState: function() {
htmlMixedMode = htmlMixedMode || CodeMirror.getMode(config, "htmlmixed");
return {
token : parserConfig.startOpen ? macroDispatch : htmlDispatch,
htmlState : htmlMixedMode.startState(),
macroState : macroMode.startState()
}
},
},
token: function(stream, state) {
return state.token(stream, state);
},
indent: function(state, textAfter) {
if (state.token == htmlDispatch)
return htmlMixedMode.indent(state.htmlState, textAfter);
else
return macroMode.indent(state.macroState, textAfter);
},
copyState: function(state) {
return {
token : state.token,
htmlState : CodeMirror.copyState(htmlMixedMode, state.htmlState),
macroState : CodeMirror.copyState(macroMode, state.macroState)
}
},
electricChars: "/{}:"
electricChars: "/{}:"
}
}, "htmlmixed");

View file

@ -1,33 +1,33 @@
/** Called automatically by JsDoc Toolkit. */
function publish(symbolSet) {
publish.conf = { // trailing slash expected for dirs
ext: ".html",
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
ext: ".html",
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
staticDir: "static/",
staticDir: "static/",
symbolsDir: "symbols/",
srcDir: "symbols/src/",
cssDir: "css/",
fontsDir: "css/fonts/",
jsDir: "javascript/",
srcDir: "symbols/src/",
cssDir: "css/",
fontsDir: "css/fonts/",
jsDir: "javascript/",
templateName: "Codeview",
templateVersion: "1.2",
templateLink: "http://www.thebrightlines.com/2010/05/06/new-template-for-jsdoctoolkit-codeview/"
};
// is source output is suppressed, just display the links to the source file
if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
Link.prototype._makeSrcLink = function(srcFilePath) {
return "&lt;"+srcFilePath+"&gt;";
}
}
// create the folders and subfolders to hold the output
IO.mkPath((publish.conf.outDir+publish.conf.cssDir));
IO.mkPath((publish.conf.outDir+publish.conf.fontsDir));
IO.mkPath((publish.conf.outDir+publish.conf.jsDir));
IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));
// used to allow Link to check the details of things being linked to
Link.symbolSet = symbolSet;
@ -39,15 +39,15 @@ function publish(symbolSet) {
print("Couldn't create the required templates: "+e);
quit();
}
// some utility filters
function hasNoParent($) {return ($.memberOf == "")}
function isaFile($) {return ($.is("FILE"))}
function isaClass($) {return (($.is("CONSTRUCTOR") || $.isNamespace) && ($.alias != "_global_" || !JSDOC.opt.D.noGlobal))}
// get an array version of the symbolset, useful for filtering
var symbols = symbolSet.toArray();
// create the hilited source code files
var files = JSDOC.opt.srcFiles;
for (var i = 0, l = files.length; i < l; i++) {
@ -55,74 +55,74 @@ function publish(symbolSet) {
var srcDir = publish.conf.outDir + publish.conf.srcDir;
makeSrcFile(file, srcDir);
}
// get a list of all the classes in the symbolset
publish.classes = symbols.filter(isaClass).sort(makeSortby("alias"));
// create a filemap in which outfiles must be to be named uniquely, ignoring case
if (JSDOC.opt.u) {
var filemapCounts = {};
Link.filemap = {};
for (var i = 0, l = publish.classes.length; i < l; i++) {
var lcAlias = publish.classes[i].alias.toLowerCase();
if (!filemapCounts[lcAlias]) filemapCounts[lcAlias] = 1;
else filemapCounts[lcAlias]++;
Link.filemap[publish.classes[i].alias] =
Link.filemap[publish.classes[i].alias] =
(filemapCounts[lcAlias] > 1)?
lcAlias+"_"+filemapCounts[lcAlias] : lcAlias;
}
}
// create each of the class pages
for (var i = 0, l = publish.classes.length; i < l; i++) {
var symbol = publish.classes[i];
symbol.events = symbol.getEvents(); // 1 order matters
symbol.events = symbol.getEvents(); // 1 order matters
symbol.methods = symbol.getMethods(); // 2
var output = "";
output = classTemplate.process(symbol);
IO.saveFile(publish.conf.outDir+publish.conf.symbolsDir, ((JSDOC.opt.u)? Link.filemap[symbol.alias] : symbol.alias) + publish.conf.ext, output);
}
// create the class index page
try {
var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
}
catch(e) { print(e.message); quit(); }
var classesIndex = classesindexTemplate.process(publish.classes);
IO.saveFile(publish.conf.outDir, (JSDOC.opt.D.index=="files"?"allclasses":"index")+publish.conf.ext, classesIndex);
classesindexTemplate = classesIndex = classes = null;
// create the file index page
try {
var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
}
catch(e) { print(e.message); quit(); }
var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
var allFiles = []; // not all files have file-level docs, but we need to list every one
for (var i = 0; i < files.length; i++) {
allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
}
for (var i = 0; i < documentedFiles.length; i++) {
var offset = files.indexOf(documentedFiles[i].alias);
allFiles[offset] = documentedFiles[i];
}
allFiles = allFiles.sort(makeSortby("name"));
// output the file index page
var filesIndex = fileindexTemplate.process(allFiles);
IO.saveFile(publish.conf.outDir, (JSDOC.opt.D.index=="files"?"index":"files")+publish.conf.ext, filesIndex);
fileindexTemplate = filesIndex = files = null;
// copy static files
IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"all.css", publish.conf.outDir+"/"+publish.conf.cssDir);
IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"screen.css", publish.conf.outDir+"/"+publish.conf.cssDir);
@ -181,14 +181,14 @@ function include(path) {
/** Turn a raw source file into a code-hilited page in the docs. */
function makeSrcFile(path, srcDir, name) {
if (JSDOC.opt.s) return;
if (!name) {
name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
name = name.replace(/\:/g, "_");
}
var src = {path: path, name:name, charset: IO.encoding, hilited: ""};
if (defined(JSDOC.PluginManager)) {
JSDOC.PluginManager.run("onPublishSrc", src);
}
@ -219,18 +219,18 @@ function makeSignature(params) {
/** Find symbol {@link ...} strings in text and turn into html links */
function resolveLinks(str, from) {
str = str.replace(/\{@link ([^}]+)\}/gi,
function(match, symbolName) {
str = str.replace(/\{@link ([^}]+)\}/gi,
function(match, symbolName) {
symbolName = symbolName.trim();
var index = symbolName.indexOf(' ');
if (index > 0) {
var label = symbolName.substring(index + 1);
symbolName = symbolName.substring(0, index);
return new Link().toSymbol(symbolName).withText(label);
var label = symbolName.substring(index + 1);
symbolName = symbolName.substring(0, index);
return new Link().toSymbol(symbolName).withText(label);
} else {
return new Link().toSymbol(symbolName);
return new Link().toSymbol(symbolName);
}
}
);
return str;
}
);
return str;
}

View file

@ -1,23 +1,23 @@
/** Called automatically by JsDoc Toolkit. */
function publish(symbolSet) {
publish.conf = { // trailing slash expected for dirs
ext: ".html",
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
ext: ".html",
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
symbolsDir: "symbols/",
srcDir: "symbols/src/"
srcDir: "symbols/src/"
};
// is source output is suppressed, just display the links to the source file
if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
Link.prototype._makeSrcLink = function(srcFilePath) {
return "&lt;"+srcFilePath+"&gt;";
}
}
// create the folders and subfolders to hold the output
IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));
// used to allow Link to check the details of things being linked to
Link.symbolSet = symbolSet;
@ -30,15 +30,15 @@ function publish(symbolSet) {
print("Couldn't create the required templates: "+e);
quit();
}
// some ustility filters
function hasNoParent($) {return ($.memberOf == "")}
function isaFile($) {return ($.is("FILE"))}
function isaClass($) {return ($.is("CONSTRUCTOR") || $.isNamespace)}
// get an array version of the symbolset, useful for filtering
var symbols = symbolSet.toArray();
// create the hilited source code files
var files = JSDOC.opt.srcFiles;
for (var i = 0, l = files.length; i < l; i++) {
@ -46,76 +46,76 @@ function publish(symbolSet) {
var srcDir = publish.conf.outDir + "symbols/src/";
makeSrcFile(file, srcDir);
}
// get a list of all the classes in the symbolset
var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
// create a filemap in which outfiles must be to be named uniquely, ignoring case
if (JSDOC.opt.u) {
var filemapCounts = {};
Link.filemap = {};
for (var i = 0, l = classes.length; i < l; i++) {
var lcAlias = classes[i].alias.toLowerCase();
if (!filemapCounts[lcAlias]) filemapCounts[lcAlias] = 1;
else filemapCounts[lcAlias]++;
Link.filemap[classes[i].alias] =
Link.filemap[classes[i].alias] =
(filemapCounts[lcAlias] > 1)?
lcAlias+"_"+filemapCounts[lcAlias] : lcAlias;
}
}
// create a class index, displayed in the left-hand column of every class page
Link.base = "../";
publish.classesIndex = classesTemplate.process(classes); // kept in memory
// create each of the class pages
for (var i = 0, l = classes.length; i < l; i++) {
var symbol = classes[i];
symbol.events = symbol.getEvents(); // 1 order matters
symbol.events = symbol.getEvents(); // 1 order matters
symbol.methods = symbol.getMethods(); // 2
Link.currentSymbol= symbol;
var output = "";
output = classTemplate.process(symbol);
IO.saveFile(publish.conf.outDir+"symbols/", ((JSDOC.opt.u)? Link.filemap[symbol.alias] : symbol.alias) + publish.conf.ext, output);
}
// regenerate the index with different relative links, used in the index pages
Link.base = "";
publish.classesIndex = classesTemplate.process(classes);
// create the class index page
try {
var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"index.tmpl");
}
catch(e) { print(e.message); quit(); }
var classesIndex = classesindexTemplate.process(classes);
IO.saveFile(publish.conf.outDir, "index"+publish.conf.ext, classesIndex);
classesindexTemplate = classesIndex = classes = null;
// create the file index page
try {
var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
}
catch(e) { print(e.message); quit(); }
var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
var allFiles = []; // not all files have file-level docs, but we need to list every one
for (var i = 0; i < files.length; i++) {
allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
}
for (var i = 0; i < documentedFiles.length; i++) {
var offset = files.indexOf(documentedFiles[i].alias);
allFiles[offset] = documentedFiles[i];
}
allFiles = allFiles.sort(makeSortby("name"));
// output the file index page
@ -153,14 +153,14 @@ function include(path) {
/** Turn a raw source file into a code-hilited page in the docs. */
function makeSrcFile(path, srcDir, name) {
if (JSDOC.opt.s) return;
if (!name) {
name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
name = name.replace(/\:/g, "_");
}
var src = {path: path, name:name, charset: IO.encoding, hilited: ""};
if (defined(JSDOC.PluginManager)) {
JSDOC.PluginManager.run("onPublishSrc", src);
}
@ -196,6 +196,6 @@ function resolveLinks(str, from) {
return new Link().toSymbol(symbolName);
}
);
return str;
}

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -37,21 +37,21 @@ Api.blogger = {};
* @param {String} content
*/
Api.blogger._getContentParts = function(content) {
content && (content = content.trim());
content || (content = String.EMPTY);
var result = {};
if (!content.startsWith("<title>")) {
content && (content = content.trim());
content || (content = String.EMPTY);
var result = {};
if (!content.startsWith("<title>")) {
result.text = content;
} else {
var pos = content.lastIndexOf("</title>");
if (pos > 0) {
result.title = content.substring(7, pos);
result.text = content.substring (pos + 8);
} else {
result.text = content;
} else {
var pos = content.lastIndexOf("</title>");
if (pos > 0) {
result.title = content.substring(7, pos);
result.text = content.substring (pos + 8);
} else {
result.text = content;
}
}
return result;
}
}
return result;
}
/**
@ -63,15 +63,15 @@ Api.blogger._getContentParts = function(content) {
* @returns {Object} Properties: userid, nickname and url
*/
Api.blogger.getUserInfo = function(appKey, name, password) {
var user = User.getByName(name);
if (!user) {
throw Error("User " + name + " does not exist on this server");
}
return {
userid: name,
nickname: name,
url: user.url
}
var user = User.getByName(name);
if (!user) {
throw Error("User " + name + " does not exist on this server");
}
return {
userid: name,
nickname: name,
url: user.url
}
}
/**
@ -83,20 +83,20 @@ Api.blogger.getUserInfo = function(appKey, name, password) {
* url
*/
Api.blogger.getUsersBlogs = function(appKey, name, password) {
var user = Api.getUser(name, password);
var result = [];
user.forEach(function() {
Api.constrain(this.site, user);
if (this.site.stories.getPermission("create")) {
result.push({
blogid: this.site.name,
blogName: this.site.title,
url: this.site.href()
});
}
return;
});
return result;
var user = Api.getUser(name, password);
var result = [];
user.forEach(function() {
Api.constrain(this.site, user);
if (this.site.stories.getPermission("create")) {
result.push({
blogid: this.site.name,
blogName: this.site.title,
url: this.site.href()
});
}
return;
});
return result;
}
/**
@ -111,28 +111,28 @@ Api.blogger.getUsersBlogs = function(appKey, name, password) {
* dateCreated and content
*/
Api.blogger.getRecentPosts = function(appKey, id, name, password, limit) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get recent posts of site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get recent posts of site " + site.name);
}
var result = [];
var stories = res.handlers.membership.stories;
var max = Math.min(stories.size(), Number(limit) || Infinity, 20);
for each (var story in stories.list(0, max)) {
result.push({
postid: story._id,
userid: story.creator.name,
dateCreated: story.created,
content: story.title ? "<title>" + story.title +
"</title>" + story.text : story.text
});
}
return result;
var result = [];
var stories = res.handlers.membership.stories;
var max = Math.min(stories.size(), Number(limit) || Infinity, 20);
for each (var story in stories.list(0, max)) {
result.push({
postid: story._id,
userid: story.creator.name,
dateCreated: story.created,
content: story.title ? "<title>" + story.title +
"</title>" + story.text : story.text
});
}
return result;
}
/**
@ -145,22 +145,22 @@ Api.blogger.getRecentPosts = function(appKey, id, name, password, limit) {
* @returns {Object} Properties: content, userid, postid, dateCreated
*/
Api.blogger.getPost = function(appKey, id, name, password) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("main")) {
throw Error("Permission denied for user " + name +
" to get post #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("main")) {
throw Error("Permission denied for user " + name +
" to get post #" + id);
}
return {
content: story.title ? html.elementAsString("title", story.title) +
story.text : story.text,
userid: story.creator.name,
postid: story._id,
dateCreated: story.created
}
return {
content: story.title ? html.elementAsString("title", story.title) +
story.text : story.text,
userid: story.creator.name,
postid: story._id,
dateCreated: story.created
}
}
/**
@ -175,25 +175,25 @@ Api.blogger.getPost = function(appKey, id, name, password) {
* @returns {Number} The ID of the new story
*/
Api.blogger.newPost = function(appKey, id, name, password, content, publish) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a post to site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a post to site " + site.name);
}
var parts = Api.blogger._getContentParts(content);
var parts = Api.blogger._getContentParts(content);
var story = Story.add({
title: parts.title,
text: parts.text,
status: publish ? Story.PUBLIC : Story.CLOSED,
mode: Story.FEATURED
}, site, user);
var story = Story.add({
title: parts.title,
text: parts.text,
status: publish ? Story.PUBLIC : Story.CLOSED,
mode: Story.FEATURED
}, site, user);
return story._id;
return story._id;
}
/**
@ -208,24 +208,24 @@ Api.blogger.newPost = function(appKey, id, name, password, content, publish) {
* @returns {Boolean} Always true
*/
Api.blogger.editPost = function(appkey, id, name, password, content, publish) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit post #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit post #" + id);
}
var parts = Api.blogger._getContentParts(content);
story.update({
title: parts.title,
text: parts.text,
status: publish ? Story.PUBLIC : Story.CLOSED,
modifier: user,
modified: new Date
});
return true;
var parts = Api.blogger._getContentParts(content);
story.update({
title: parts.title,
text: parts.text,
status: publish ? Story.PUBLIC : Story.CLOSED,
modifier: user,
modified: new Date
});
return true;
}
/**
@ -238,15 +238,15 @@ Api.blogger.editPost = function(appkey, id, name, password, content, publish) {
* @returns {Boolean} Always true
*/
Api.blogger.deletePost = function(appKey, id, name, password) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("delete")) {
throw Error("Permission denied for user " + name +
" to delete story #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("delete")) {
throw Error("Permission denied for user " + name +
" to delete story #" + id);
}
Story.remove.call(story);
return true;
Story.remove.call(story);
return true;
}

View file

@ -8,7 +8,7 @@
// 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
// 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,
@ -32,9 +32,9 @@
* @param {User} user
*/
Api.constrain = function(site, user) {
res.handlers.site = site;
res.handlers.membership = Membership.getByName(user.name);
return;
res.handlers.site = site;
res.handlers.membership = Membership.getByName(user.name);
return;
}
/** @ignore */
@ -49,16 +49,16 @@ Api.dispatch = function() {
* @returns {User}
*/
Api.getUser = function(name, password) {
var user = User.getByName(name);
if (!user) {
throw Error("User " + name + " does not exist on this server");
} else if (user.hash !== String(password + user.salt).md5()) {
throw Error("Authentication failed for user " + name);
} else if (user.status === User.BLOCKED) {
throw Error("The user account " + name + " is currently blocked");
}
session.login(user);
return user;
var user = User.getByName(name);
if (!user) {
throw Error("User " + name + " does not exist on this server");
} else if (user.hash !== String(password + user.salt).md5()) {
throw Error("Authentication failed for user " + name);
} else if (user.status === User.BLOCKED) {
throw Error("The user account " + name + " is currently blocked");
}
session.login(user);
return user;
}
/**
@ -68,13 +68,13 @@ Api.getUser = function(name, password) {
* @returns {Site}
*/
Api.getSite = function(name) {
var site = Site.getByName(String(name));
if (!site) {
throw Error("Site " + name + " does not exist on this server");
} else if (site.status === Site.BLOCKED) {
throw Error("The site " + name + " is blocked");
}
return site;
var site = Site.getByName(String(name));
if (!site) {
throw Error("Site " + name + " does not exist on this server");
} else if (site.status === Site.BLOCKED) {
throw Error("The site " + name + " is blocked");
}
return site;
}
/**
@ -84,11 +84,11 @@ Api.getSite = function(name) {
* @returns {Story}
*/
Api.getStory = function(id) {
var story = Story.getById(id);
if (!story) {
throw Error("Story #" + id + " does not exist on this server");
}
return story;
var story = Story.getById(id);
if (!story) {
throw Error("Story #" + id + " does not exist on this server");
}
return story;
}
/**
@ -101,42 +101,42 @@ Api.getStory = function(id) {
* @returns {Boolean}
*/
Api.prototype.getPermission = function(){
return true;
return true;
}
Api.prototype.main_action = function() {
res.data.title = gettext("Application Programming Interfaces");
res.data.body = this.renderSkinAsString("$Api#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Application Programming Interfaces");
res.data.body = this.renderSkinAsString("$Api#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Api.prototype.callback_action = function() {
var ping = function(data) {
if (data.type !== "Story" && data.type !== "Comment") {
return;
}
var remote = new Remote("http://rpc.weblogs.com/RPC2");
var call = remote.weblogUpdates.ping(data.site, data.origin);
if (call.error || call.result.flerror) {
app.debug("Error invoking weblogs.com ping() method for " +
data.site + ": " + call.error || call.result.message);
} else {
app.debug(call.result);
}
var ping = function(data) {
if (data.type !== "Story" && data.type !== "Comment") {
return;
};
}
var remote = new Remote("http://rpc.weblogs.com/RPC2");
var call = remote.weblogUpdates.ping(data.site, data.origin);
if (call.error || call.result.flerror) {
app.debug("Error invoking weblogs.com ping() method for " +
data.site + ": " + call.error || call.result.message);
} else {
app.debug(call.result);
}
return;
};
if (req.isGet()) {
res.data.title = gettext("Default Callback Url");
res.data.body = this.renderSkinAsString("$Api#callback",
{name: req.action, code: ping.toString()});
res.handlers.site.renderSkin("Site#page");
} else if (req.isPost()) {
app.debug("Invoked default callback with POST params: " + req.postParams);
app.invokeAsync(this, ping, [req.postParams], 1000);
}
return;
if (req.isGet()) {
res.data.title = gettext("Default Callback Url");
res.data.body = this.renderSkinAsString("$Api#callback",
{name: req.action, code: ping.toString()});
res.handlers.site.renderSkin("Site#page");
} else if (req.isPost()) {
app.debug("Invoked default callback with POST params: " + req.postParams);
app.invokeAsync(this, ping, [req.postParams], 1000);
}
return;
}
/**
@ -145,18 +145,18 @@ Api.prototype.callback_action = function() {
* @throws {Error}
*/
Api.prototype.main_action_xmlrpc = function(methodName) {
if (!methodName) {
return false;
}
var parts = methodName.split(".");
var method = parts[1];
if (method && !method.startsWith("_")) {
var handler = Api[parts[0]];
if (handler && handler[method]) {
var args = Array.prototype.splice.call(arguments, 1);
return handler[method].apply(null, args);
}
}
throw Error("Method " + methodName + "() is not implemented");
return;
if (!methodName) {
return false;
}
var parts = methodName.split(".");
var method = parts[1];
if (method && !method.startsWith("_")) {
var handler = Api[parts[0]];
if (handler && handler[method]) {
var args = Array.prototype.splice.call(arguments, 1);
return handler[method].apply(null, args);
}
}
throw Error("Method " + methodName + "() is not implemented");
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -36,24 +36,24 @@ Api.metaWeblog = {}
* @returns {Object}
*/
Api.metaWeblog._getStruct = function(story) {
return {
userid: story.creator.name,
postid: story._id,
dateCreated: story.created,
title: story.getTitle(),
description: story.text,
categories: story.getTags(),
flNotOnHomePage: story.mode === Story.HIDDEN ? true : false,
link: story.href(),
permaLink: story.href(),
mt_excerpt: null, // FIXME: What are these "mt_" prefixed properties?
mt_text_more: null,
mt_allow_comments: story.commentMode === Story.OPEN ? 1 : 0,
mt_allow_pings: 0,
mt_convert_breaks: null,
mt_keywords: null,
postSource: story.getMetadata('postSource')
}
return {
userid: story.creator.name,
postid: story._id,
dateCreated: story.created,
title: story.getTitle(),
description: story.text,
categories: story.getTags(),
flNotOnHomePage: story.mode === Story.HIDDEN ? true : false,
link: story.href(),
permaLink: story.href(),
mt_excerpt: null, // FIXME: What are these "mt_" prefixed properties?
mt_text_more: null,
mt_allow_comments: story.commentMode === Story.OPEN ? 1 : 0,
mt_allow_pings: 0,
mt_convert_breaks: null,
mt_keywords: null,
postSource: story.getMetadata('postSource')
}
}
/**
@ -66,22 +66,22 @@ Api.metaWeblog._getStruct = function(story) {
* @returns {Object[]}
*/
Api.metaWeblog.getRecentPosts = function(id, name, password, limit) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get recent posts from site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get recent posts from site " + site.name);
}
var result = [];
var stories = res.handlers.membership.stories;
var max = Math.min(stories.size(), Number(limit) || Infinity, 20);
for each (var story in stories.list(0, max)) {
result.push(Api.metaWeblog._getStruct(story));
}
return result;
var result = [];
var stories = res.handlers.membership.stories;
var max = Math.min(stories.size(), Number(limit) || Infinity, 20);
for each (var story in stories.list(0, max)) {
result.push(Api.metaWeblog._getStruct(story));
}
return result;
}
/**
@ -93,14 +93,14 @@ Api.metaWeblog.getRecentPosts = function(id, name, password, limit) {
* @returns {Object}
*/
Api.metaWeblog.getPost = function(id, name, password) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("main")) {
throw Error("Permission denied for user " + name +
" to get post #" + id);
}
return Api.metaWeblog._getStruct(story);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("main")) {
throw Error("Permission denied for user " + name +
" to get post #" + id);
}
return Api.metaWeblog._getStruct(story);
}
/**
@ -114,26 +114,26 @@ Api.metaWeblog.getPost = function(id, name, password) {
* @returns {Number}
*/
Api.metaWeblog.newPost = function(id, name, password, content, publish) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a post to site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a post to site " + site.name);
}
var story = Story.add({
title: content.title,
text: content.description,
status: publish ? Story.PUBLIC : Story.CLOSED,
mode: content.flNotOnHomePage ? Story.HIDDEN : Story.FEATURED,
commentMode: content.discussions === 0 ? Story.CLOSED : Story.OPEN,
tags: content.categories
}, site, user);
var story = Story.add({
title: content.title,
text: content.description,
status: publish ? Story.PUBLIC : Story.CLOSED,
mode: content.flNotOnHomePage ? Story.HIDDEN : Story.FEATURED,
commentMode: content.discussions === 0 ? Story.CLOSED : Story.OPEN,
tags: content.categories
}, site, user);
story.setMetadata('postSource', content.postSource);
return story._id;
story.setMetadata('postSource', content.postSource);
return story._id;
}
/**
@ -147,27 +147,27 @@ Api.metaWeblog.newPost = function(id, name, password, content, publish) {
* @returns {Boolean}
*/
Api.metaWeblog.editPost = function(id, name, password, content, publish) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit post #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit post #" + id);
}
story.update({
title: content.title,
text: content.description,
status: publish ? Story.PUBLIC : Story.CLOSED,
mode: content.flNotOnHomePage ? Story.HIDDEN : Story.FEATURED,
commentMode: content.discussions || content.mt_allow_comments ?
Story.OPEN : Story.CLOSED,
tags: content.categories
});
story.update({
title: content.title,
text: content.description,
status: publish ? Story.PUBLIC : Story.CLOSED,
mode: content.flNotOnHomePage ? Story.HIDDEN : Story.FEATURED,
commentMode: content.discussions || content.mt_allow_comments ?
Story.OPEN : Story.CLOSED,
tags: content.categories
});
story.setMetadata('postSource', content.postSource);
return true;
story.setMetadata('postSource', content.postSource);
return true;
}
/**
@ -179,25 +179,25 @@ Api.metaWeblog.editPost = function(id, name, password, content, publish) {
* @returns {Object[]}
*/
Api.metaWeblog.getCategories = function(id, name, password) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get categories from site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get categories from site " + site.name);
}
var result = [];
var tags = site.getTags("tags", Tags.ALL).list();
for each (var tag in tags) {
result.push({
description: tag.name,
htmlUrl: tag.href(),
rssUrl: tag.href("rss")
});
}
return result;
var result = [];
var tags = site.getTags("tags", Tags.ALL).list();
for each (var tag in tags) {
result.push({
description: tag.name,
htmlUrl: tag.href(),
rssUrl: tag.href("rss")
});
}
return result;
}
/**
@ -210,40 +210,40 @@ Api.metaWeblog.getCategories = function(id, name, password) {
* @returns {Object}
*/
Api.metaWeblog.newMediaObject = function(id, name, password, media) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
Api.constrain(site, user);
var result = {};
var data = {};
if (media.type && media.type.toLowerCase().startsWith("image/")) {
if (!site.images.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a media object to site " + site.name);
}
data.file = new Packages.helma.util.MimePart(media.name,
media.bits, media.type);
data.file_origin = media.name;
data.description = media.description;
if (media.maxWidth) {
data.maxWidth = media.maxWidth;
}
if (media.maxHeight) {
data.maxHeight = media.maxHeight;
}
result.url = Image.add(data, site, user).getUrl();
} else {
if (!site.files.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a media object to site " + site.name);
}
data.file = new Packages.helma.util.MimePart(media.name,
media.bits, media.type);
data.file_origin = media.name;
data.description = media.description;
result.url = File.add(data, site, user).getUrl();
}
var result = {};
var data = {};
if (media.type && media.type.toLowerCase().startsWith("image/")) {
if (!site.images.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a media object to site " + site.name);
}
data.file = new Packages.helma.util.MimePart(media.name,
media.bits, media.type);
data.file_origin = media.name;
data.description = media.description;
if (media.maxWidth) {
data.maxWidth = media.maxWidth;
}
if (media.maxHeight) {
data.maxHeight = media.maxHeight;
}
result.url = Image.add(data, site, user).getUrl();
} else {
if (!site.files.getPermission("create")) {
throw Error("Permission denied for user " + user.name +
" to add a media object to site " + site.name);
}
data.file = new Packages.helma.util.MimePart(media.name,
media.bits, media.type);
data.file_origin = media.name;
data.description = media.description;
result.url = File.add(data, site, user).getUrl();
}
return result;
return result;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -41,27 +41,27 @@ Api.mt = {};
* @returns {Object[]}
*/
Api.mt.getRecentPostTitles = function(id, name, password, limit) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get recent post titles from site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to get recent post titles from site " + site.name);
}
var result = [];
var stories = res.handlers.membership.stories;
var max = Math.min(stories.size(), Number(limit) || Infinity, 20);
for each (var story in stories.list(0, max)) {
result.push({
postid: story._id,
username: story.creator.name,
dateCreated: story.created,
title: story.getTitle()
});
}
return result;
var result = [];
var stories = res.handlers.membership.stories;
var max = Math.min(stories.size(), Number(limit) || Infinity, 20);
for each (var story in stories.list(0, max)) {
result.push({
postid: story._id,
username: story.creator.name,
dateCreated: story.created,
title: story.getTitle()
});
}
return result;
}
/**
@ -73,24 +73,24 @@ Api.mt.getRecentPostTitles = function(id, name, password, limit) {
* @returns {Object[]}
*/
Api.mt.getCategoryList = function(id, name, password) {
var site = Api.getSite(id);
var user = Api.getUser(name, password);
var site = Api.getSite(id);
var user = Api.getUser(name, password);
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to access site " + site.name);
}
Api.constrain(site, user);
if (!site.stories.getPermission("main")) {
throw Error("Permission denied for user " + user.name +
" to access site " + site.name);
}
var result = [];
var tags = site.getTags("tags", Tags.ALL).list();
for each (var tag in tags) {
result.push({
categoryId: tag.name, // FIXME: tag._id,
categoryName: tag.name
});
}
return result;
var result = [];
var tags = site.getTags("tags", Tags.ALL).list();
for each (var tag in tags) {
result.push({
categoryId: tag.name, // FIXME: tag._id,
categoryName: tag.name
});
}
return result;
}
/**
@ -102,24 +102,24 @@ Api.mt.getCategoryList = function(id, name, password) {
* @returns {Object[]}
*/
Api.mt.getPostCategories = function(id, name, password) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("main")) {
throw Error("Permission denied for user " + name +
" to access story #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("main")) {
throw Error("Permission denied for user " + name +
" to access story #" + id);
}
var result = [];
for each (var tag in story.getTags()) {
result.push({
categoryId: tag,
categoryName: tag,
isPrimary: true
});
}
return result;
var result = [];
for each (var tag in story.getTags()) {
result.push({
categoryId: tag,
categoryName: tag,
isPrimary: true
});
}
return result;
}
// FIXME: How do I post a new story?
@ -132,17 +132,17 @@ Api.mt.getPostCategories = function(id, name, password) {
* @returns {Boolean}
*/
Api.mt.publishPost = function(id, name, password) {
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit story #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit story #" + id);
}
story.mode = Story.FEATURED;
return true;
story.mode = Story.FEATURED;
return true;
}
/**
@ -155,21 +155,21 @@ Api.mt.publishPost = function(id, name, password) {
* @returns {Boolean}
*/
Api.mt.setPostCategories = function(id, name, password, categories) {
if (!categories || !categories.length) {
return;
}
if (!categories || !categories.length) {
return;
}
var story = Api.getStory(id);
var user = Api.getUser(name, password);
var story = Api.getStory(id);
var user = Api.getUser(name, password);
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit story #" + id);
}
Api.constrain(story.site, user);
if (!story.getPermission("edit")) {
throw Error("Permission denied for user " + name +
" to edit story #" + id);
}
story.setTags(categories);
return true;
story.setTags(categories);
return true;
}
/**
@ -177,7 +177,7 @@ Api.mt.setPostCategories = function(id, name, password, categories) {
* @returns {Array}
*/
Api.mt.supportedTextFilters = function() {
return [];
return [];
}
/**
@ -185,7 +185,7 @@ Api.mt.supportedTextFilters = function() {
* @returns {Array}
*/
Api.mt.getTrackbackPings = function() {
return [];
return [];
}
/**
@ -193,9 +193,9 @@ Api.mt.getTrackbackPings = function() {
* @returns {String[]}
*/
Api.mt.supportedMethods = function() {
var result = [];
for (var method in Api.mt) {
result.push(method);
}
return result.sort();
var result = [];
for (var method in Api.mt) {
result.push(method);
}
return result.sort();
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -43,10 +43,10 @@ Archive.COLLECTION = "collection";
* @extends HopObject
*/
Archive.prototype.constructor = function(name, type, parent) {
this.name = name;
this.type = type;
this.parent = parent;
return this;
this.name = name;
this.type = type;
this.parent = parent;
return this;
}
/**
@ -55,12 +55,12 @@ Archive.prototype.constructor = function(name, type, parent) {
* @returns {HopObject}
*/
Archive.prototype.getChildElement = function(name) {
if (name.startsWith(Archive.PAGER)) {
return new Archive(name, Archive.PAGER, this);
} else if (!isNaN(name)) {
return new Archive(name, Archive.COLLECTION, this);
}
return this.get(name);
if (name.startsWith(Archive.PAGER)) {
return new Archive(name, Archive.PAGER, this);
} else if (!isNaN(name)) {
return new Archive(name, Archive.COLLECTION, this);
}
return this.get(name);
}
/**
@ -69,50 +69,50 @@ Archive.prototype.getChildElement = function(name) {
* @returns {Boolean}
*/
Archive.prototype.getPermission = function(action) {
var site = res.handlers.site;
if (!site.getPermission("main") || site.archiveMode !== Site.PUBLIC) {
return false;
}
switch (action) {
case "main":
case "page1":
return true;
case "previous":
return this.getPage() > 1
case "next":
return this.getPage() < this.getSize() / this.getPageSize();
}
return false;
var site = res.handlers.site;
if (!site.getPermission("main") || site.archiveMode !== Site.PUBLIC) {
return false;
}
switch (action) {
case "main":
case "page1":
return true;
case "previous":
return this.getPage() > 1
case "next":
return this.getPage() < this.getSize() / this.getPageSize();
}
return false;
}
Archive.prototype.main_action = function() {
var date = this.getDate();
var dateString = String.EMPTY;
switch (path.length - (this.type === Archive.PAGER ? 4 : 3)) {
case 1:
dateString = formatDate(date, "yyyy");
break;
case 2:
dateString = formatDate(date, "MMM yyyy");
break;
case 3:
var type = java.text.DateFormat.LONG;
var locale = res.handlers.site.getLocale();
var pattern = java.text.DateFormat.getDateInstance(type, locale).toPattern()
dateString = formatDate(date, pattern);
break;
}
var page = gettext("Page {0} of {1}", this.getPage(),
Math.ceil(this.getSize() / this.getPageSize()));
res.data.title = gettext("Story Archive {0} ({1})", dateString, page);
res.data.body = this.renderSkinAsString("Archive#main");
res.handlers.site.renderSkin("Site#page");
res.handlers.site.log();
return;
var date = this.getDate();
var dateString = String.EMPTY;
switch (path.length - (this.type === Archive.PAGER ? 4 : 3)) {
case 1:
dateString = formatDate(date, "yyyy");
break;
case 2:
dateString = formatDate(date, "MMM yyyy");
break;
case 3:
var type = java.text.DateFormat.LONG;
var locale = res.handlers.site.getLocale();
var pattern = java.text.DateFormat.getDateInstance(type, locale).toPattern()
dateString = formatDate(date, pattern);
break;
}
var page = gettext("Page {0} of {1}", this.getPage(),
Math.ceil(this.getSize() / this.getPageSize()));
res.data.title = gettext("Story Archive {0} ({1})", dateString, page);
res.data.body = this.renderSkinAsString("Archive#main");
res.handlers.site.renderSkin("Site#page");
res.handlers.site.log();
return;
}
Archive.prototype.page1_action = function() {
return res.redirect(this.href());
return res.redirect(this.href());
}
/**
@ -121,21 +121,21 @@ Archive.prototype.page1_action = function() {
* @returns {String}
*/
Archive.prototype.href = function(action) {
var buffer = [];
var archive = this;
while (archive.parent) {
buffer.push(archive.name);
archive = archive.parent;
}
buffer.push(res.handlers.site.href("archive"));
buffer.reverse();
if (action) {
if (this.type === Archive.PAGER) {
buffer.pop();
}
buffer.push(action);
}
return buffer.join("/");
var buffer = [];
var archive = this;
while (archive.parent) {
buffer.push(archive.name);
archive = archive.parent;
}
buffer.push(res.handlers.site.href("archive"));
buffer.reverse();
if (action) {
if (this.type === Archive.PAGER) {
buffer.pop();
}
buffer.push(action);
}
return buffer.join("/");
}
/**
@ -146,76 +146,76 @@ Archive.prototype.href = function(action) {
* @see renderLink
*/
Archive.prototype.link_macro = function(param, action, text) {
if (!this.getPermission(action)) {
return;
}
switch (action) {
case "previous":
var page = this.getPage() - 1; break;
case "next":
var page = this.getPage() + 1; break;
}
var action = "page" + page;
return renderLink.call(global, param, action, text, this);
if (!this.getPermission(action)) {
return;
}
switch (action) {
case "previous":
var page = this.getPage() - 1; break;
case "next":
var page = this.getPage() + 1; break;
}
var action = "page" + page;
return renderLink.call(global, param, action, text, this);
}
/**
*
*/
Archive.prototype.stories_macro = function() {
var day, storyDay;
var page = this.getPage();
var pageSize = this.getPageSize();
var day, storyDay;
var page = this.getPage();
var pageSize = this.getPageSize();
var renderStory = function(story) {
storyDay = formatDate(story.created, 'yyyy-MM-dd');
if (day !== storyDay) {
story.renderSkin("Story#date");
day = storyDay;
}
story.renderSkin("Story#preview");
return;
}
var renderStory = function(story) {
storyDay = formatDate(story.created, 'yyyy-MM-dd');
if (day !== storyDay) {
story.renderSkin("Story#date");
day = storyDay;
}
story.renderSkin("Story#preview");
return;
}
// FIXME: This is a little bit inconsistent and thus needs special care
var archive = this.type === Archive.PAGER ? this.parent : this;
if (!archive.parent) {
var site = res.handlers.site;
var offset = (page - 1) * pageSize;
var stories = site.stories.featured.list(offset, pageSize);
for each (var story in stories) {
renderStory(story);
};
return;
}
var sql = new Sql;
sql.retrieve(Sql.ARCHIVE, res.handlers.site._id, this.getFilter(),
Sql.ARCHIVEORDER, pageSize, (page - 1) * pageSize);
sql.traverse(function() {
var story = Story.getById(this.id);
// FIXME: This is a little bit inconsistent and thus needs special care
var archive = this.type === Archive.PAGER ? this.parent : this;
if (!archive.parent) {
var site = res.handlers.site;
var offset = (page - 1) * pageSize;
var stories = site.stories.featured.list(offset, pageSize);
for each (var story in stories) {
renderStory(story);
});
return;
};
return;
}
var sql = new Sql;
sql.retrieve(Sql.ARCHIVE, res.handlers.site._id, this.getFilter(),
Sql.ARCHIVEORDER, pageSize, (page - 1) * pageSize);
sql.traverse(function() {
var story = Story.getById(this.id);
renderStory(story);
});
return;
}
/**
* @returns {Number}
*/
Archive.prototype.getSize = function() {
// FIXME: This is a little bit inconsistent and thus needs special care
var archive = this.type === Archive.PAGER ? this.parent : this;
if (!archive.parent) {
return res.handlers.site.stories.featured.size();
}
var size;
var sql = new Sql;
sql.retrieve(Sql.ARCHIVESIZE, res.handlers.site._id, this.getFilter());
sql.traverse(function() {
size = this.count;
return;
});
return size;
// FIXME: This is a little bit inconsistent and thus needs special care
var archive = this.type === Archive.PAGER ? this.parent : this;
if (!archive.parent) {
return res.handlers.site.stories.featured.size();
}
var size;
var sql = new Sql;
sql.retrieve(Sql.ARCHIVESIZE, res.handlers.site._id, this.getFilter());
sql.traverse(function() {
size = this.count;
return;
});
return size;
}
/**
@ -223,66 +223,66 @@ Archive.prototype.getSize = function() {
* @returns {String}
*/
Archive.prototype.getFilter = function() {
var buffer = [];
var archive = this;
do {
if (archive.type === Archive.COLLECTION) {
buffer.unshift(Number(archive.name));
}
} while (archive = archive.parent);
var buffer = [];
var archive = this;
do {
if (archive.type === Archive.COLLECTION) {
buffer.unshift(Number(archive.name));
}
} while (archive = archive.parent);
if (buffer.length < 0) {
var now = new Date;
buffer.push(now.getDate());
buffer.push(now.getMonth() + 1);
buffer.push(now.getFullYear());
}
if (buffer.length < 0) {
var now = new Date;
buffer.push(now.getDate());
buffer.push(now.getMonth() + 1);
buffer.push(now.getFullYear());
}
res.push();
var sql = new Sql;
var keys = ["year", "month", "day"];
for (var i in buffer) {
sql.retrieve(Sql.ARCHIVEPART, keys[i], buffer[i]);
res.write(sql);
}
return res.pop();
res.push();
var sql = new Sql;
var keys = ["year", "month", "day"];
for (var i in buffer) {
sql.retrieve(Sql.ARCHIVEPART, keys[i], buffer[i]);
res.write(sql);
}
return res.pop();
}
/**
* @returns {Number}
*/
Archive.prototype.getPage = function() {
if (this.type === Archive.PAGER) {
return Number(this.name.substr(4));
}
return 1;
if (this.type === Archive.PAGER) {
return Number(this.name.substr(4));
}
return 1;
}
/**
* @returns {Number}
*/
Archive.prototype.getPageSize = function() {
return res.handlers.site.pageSize;
return res.handlers.site.pageSize;
}
/**
* @returns {Date}
*/
Archive.prototype.getDate = function() {
var date = new Date;
var offset = path.contains(res.handlers.site.archive) + 1;
if (offset > -1) {
var archive;
var buffer = [];
for (var i=offset; i<path.length; i+=1) {
archive = path[i];
if (archive.type === Archive.COLLECTION) {
buffer.push(Number(archive.name));
}
var date = new Date;
var offset = path.contains(res.handlers.site.archive) + 1;
if (offset > -1) {
var archive;
var buffer = [];
for (var i=offset; i<path.length; i+=1) {
archive = path[i];
if (archive.type === Archive.COLLECTION) {
buffer.push(Number(archive.name));
}
}
buffer[0] && date.setYear(buffer[0]);
buffer[1] && date.setMonth(buffer[1] - 1);
buffer[2] && date.setDate(buffer[2]);
return date;
}
}
buffer[0] && date.setYear(buffer[0]);
buffer[1] && date.setMonth(buffer[1] - 1);
buffer[2] && date.setDate(buffer[2]);
return date;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,22 +34,22 @@ markgettext("choice");
*
*/
Choice.add = function(title, poll) {
HopObject.confirmConstructor(Choice);
var choice = new Choice(title);
choice.created = choice.modified = new Date;
poll.add(choice);
return choice;
HopObject.confirmConstructor(Choice);
var choice = new Choice(title);
choice.created = choice.modified = new Date;
poll.add(choice);
return choice;
}
/**
*
*/
Choice.remove = function() {
if (this.constructor === Choice) {
HopObject.remove.call(this);
this.remove();
}
return;
if (this.constructor === Choice) {
HopObject.remove.call(this);
this.remove();
}
return;
}
/**
@ -64,22 +64,22 @@ Choice.remove = function() {
* @extends HopObject
*/
Choice.prototype.constructor = function(title) {
HopObject.confirmConstructor.call(this);
this.title = title;
return this;
HopObject.confirmConstructor.call(this);
this.title = title;
return this;
}
/**
*
*/
Choice.prototype.selected_macro = function() {
var votes;
if (session.user && (votes = this._parent.votes.get(session.user.name))) {
res.write(this === votes.choice);
} else {
res.write(false);
}
return;
var votes;
if (session.user && (votes = this._parent.votes.get(session.user.name))) {
res.write(this === votes.choice);
} else {
res.write(false);
}
return;
}
/**
@ -88,28 +88,28 @@ Choice.prototype.selected_macro = function() {
* @param {String} variant
*/
Choice.prototype.votes_macro = function(param, variant) {
var votes = 0;
if (variant) {
if (variant.endsWith("%")) {
variant = parseInt(variant) || 1;
var max = this._parent.votes.size();
votes = this.size() / max * variant;
} else {
var max = 1;
this._parent.forEach(function() {
var n = this.size();
if (n > max) {
max = n;
}
return;
});
votes = Math.round(this.size() / max * variant);
}
} else {
votes = this.size();
}
if (!votes && param["default"]) {
return param["default"];
}
return votes;
var votes = 0;
if (variant) {
if (variant.endsWith("%")) {
variant = parseInt(variant) || 1;
var max = this._parent.votes.size();
votes = this.size() / max * variant;
} else {
var max = 1;
this._parent.forEach(function() {
var n = this.size();
if (n > max) {
max = n;
}
return;
});
votes = Math.round(this.size() / max * variant);
}
} else {
votes = this.size();
}
if (!votes && param["default"]) {
return param["default"];
}
return votes;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -33,8 +33,8 @@ markgettext("comment");
/**
* @see defineConstants
*/
Comment.getStatus = defineConstants(Comment, markgettext("deleted"),
markgettext("pending"), markgettext("readonly"), markgettext("public"));
Comment.getStatus = defineConstants(Comment, markgettext("deleted"),
markgettext("pending"), markgettext("readonly"), markgettext("public"));
/**
* Convenience method for easily adding a new comment to an existing story or comment.
@ -43,56 +43,56 @@ Comment.getStatus = defineConstants(Comment, markgettext("deleted"),
* @returns {Comment}
*/
Comment.add = function(data, parent) {
HopObject.confirmConstructor(Comment);
var story = parent.story || parent;
var comment = new Comment;
comment.name = String.EMPTY;
comment.site = parent.site;
comment.story = story;
comment.parent = parent;
comment.parent_type = parent._prototype; // FIXME: Set correct parent_type (Helma bug?)
comment.status = Story.PUBLIC;
comment.creator = comment.modifier = session.user;
comment.created = comment.modified = new Date;
comment.update(data);
story.comments.add(comment); // Force addition to aggressively cached collection
parent.add(comment);
return comment;
HopObject.confirmConstructor(Comment);
var story = parent.story || parent;
var comment = new Comment;
comment.name = String.EMPTY;
comment.site = parent.site;
comment.story = story;
comment.parent = parent;
comment.parent_type = parent._prototype; // FIXME: Set correct parent_type (Helma bug?)
comment.status = Story.PUBLIC;
comment.creator = comment.modifier = session.user;
comment.created = comment.modified = new Date;
comment.update(data);
story.comments.add(comment); // Force addition to aggressively cached collection
parent.add(comment);
return comment;
}
/**
* @returns {String}
*/
Comment.remove = function(options) {
if (this.constructor !== Comment) {
return;
}
// Remove all comments of this comments creator if corresponding option is set
if (options && options.mode === "user" && options.confirm === "1") {
var membership = Membership.getByName(this.creator.name, this.site);
// Not using HopObject.remove() because it will comepletely remove all comments
membership.comments.forEach(function() {
Comment.remove.call(this);
})
} else {
// Mark comment as deleted if not already done so or if there are child comments
if (this.size() > 0 && this.status !== Comment.DELETED) {
this.status = Comment.DELETED;
this.deleteMetadata();
this.touch();
return this.href();
}
// Completely remove comment and its children otherwise
while (this.size() > 0) {
Comment.remove.call(this.get(0));
}
// Explicitely remove comment from aggressively cached collections:
(this.parent || this).removeChild(this);
this.story.comments.removeChild(this);
if (this.constructor !== Comment) {
return;
}
// Remove all comments of this comments creator if corresponding option is set
if (options && options.mode === "user" && options.confirm === "1") {
var membership = Membership.getByName(this.creator.name, this.site);
// Not using HopObject.remove() because it will comepletely remove all comments
membership.comments.forEach(function() {
Comment.remove.call(this);
})
} else {
// Mark comment as deleted if not already done so or if there are child comments
if (this.size() > 0 && this.status !== Comment.DELETED) {
this.status = Comment.DELETED;
this.deleteMetadata();
this.remove();
}
return this.parent.href();
this.touch();
return this.href();
}
// Completely remove comment and its children otherwise
while (this.size() > 0) {
Comment.remove.call(this.get(0));
}
// Explicitely remove comment from aggressively cached collections:
(this.parent || this).removeChild(this);
this.story.comments.removeChild(this);
this.deleteMetadata();
this.remove();
}
return this.parent.href();
}
/**
@ -105,176 +105,176 @@ Comment.remove = function(options) {
* @extends Story
*/
Comment.prototype.constructor = function() {
HopObject.confirmConstructor.call(this);
return this;
HopObject.confirmConstructor.call(this);
return this;
}
/**
*
*
* @param {Object} action
* @returns {Boolean}
*/
Comment.prototype.getPermission = function(action) {
switch (action) {
case ".":
case "main":
if (this.status === Comment.DELETED) {
return false;
}
// Break statement missing here by purpose!
case "comment":
return this.site.commentMode === Site.ENABLED &&
this.story.getPermission(action) &&
this.status !== Comment.PENDING;
case "delete":
return this.story.getPermission.call(this, "delete");
case "edit":
return this.status !== Comment.DELETED &&
this.story.getPermission.call(this, "delete");
}
return false;
switch (action) {
case ".":
case "main":
if (this.status === Comment.DELETED) {
return false;
}
// Break statement missing here by purpose!
case "comment":
return this.site.commentMode === Site.ENABLED &&
this.story.getPermission(action) &&
this.status !== Comment.PENDING;
case "delete":
return this.story.getPermission.call(this, "delete");
case "edit":
return this.status !== Comment.DELETED &&
this.story.getPermission.call(this, "delete");
}
return false;
}
/**
*
*
* @param {Object} action
* @returns {String}
*/
Comment.prototype.href = function(action) {
var buffer = [];
switch (action) {
case null:
case undefined:
case "":
case ".":
case "main":
buffer.push(this.story.href(), "#", this._id);
break;
default:
buffer.push(this.story.comments.href(), this._id, "/", action);
}
return buffer.join(String.EMPTY);
var buffer = [];
switch (action) {
case null:
case undefined:
case "":
case ".":
case "main":
buffer.push(this.story.href(), "#", this._id);
break;
default:
buffer.push(this.story.comments.href(), this._id, "/", action);
}
return buffer.join(String.EMPTY);
}
Comment.prototype.edit_action = function() {
if (req.postParams.save) {
try {
this.update(req.postParams);
delete session.data.backup;
res.message = gettext("The comment was successfully updated.");;
res.redirect(this.story.href() + "#" + this._id);
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.handlers.parent = this.parent;
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Comment");
res.data.body = this.renderSkinAsString("Comment#edit");
this.site.renderSkin("Site#page");
return;
if (req.postParams.save) {
try {
this.update(req.postParams);
delete session.data.backup;
res.message = gettext("The comment was successfully updated.");;
res.redirect(this.story.href() + "#" + this._id);
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.handlers.parent = this.parent;
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Comment");
res.data.body = this.renderSkinAsString("Comment#edit");
this.site.renderSkin("Site#page");
return;
}
/**
*
*
* @param {Object} data
*/
Comment.prototype.update = function(data) {
if (!data.title && !data.text) {
throw Error(gettext("Please enter at least something into the “title” or “text” field."));
}
// Get difference to current content before applying changes
var delta = this.getDelta(data);
this.title = data.title;
this.text = data.text;
this.setMetadata(data);
if (!data.title && !data.text) {
throw Error(gettext("Please enter at least something into the “title” or “text” field."));
}
// Get difference to current content before applying changes
var delta = this.getDelta(data);
this.title = data.title;
this.text = data.text;
this.setMetadata(data);
if (this.story.commentMode === Story.MODERATED) {
this.status = Comment.PENDING;
} else if (delta > 50) {
this.modified = new Date;
if (this.story.status !== Story.CLOSED) {
this.site.modified = this.modified;
}
// We need persistence for adding the callback
this.isTransient() && this.persist();
res.handlers.site.callback(this);
// Notification is sent in Story.comment_action()
}
this.clearCache();
this.modifier = session.user;
return;
if (this.story.commentMode === Story.MODERATED) {
this.status = Comment.PENDING;
} else if (delta > 50) {
this.modified = new Date;
if (this.story.status !== Story.CLOSED) {
this.site.modified = this.modified;
}
// We need persistence for adding the callback
this.isTransient() && this.persist();
res.handlers.site.callback(this);
// Notification is sent in Story.comment_action()
}
this.clearCache();
this.modifier = session.user;
return;
}
/**
* @returns {String}
*/
Comment.prototype.getConfirmText = function() {
var size = this.size() + 1;
if (this.status === Comment.DELETED && size > 1) {
return gettext("You are about to delete a comment thread consisting of {0} postings.",
size);
}
return gettext("You are about to delete a comment by user {0}.",
this.creator.name);
var size = this.size() + 1;
if (this.status === Comment.DELETED && size > 1) {
return gettext("You are about to delete a comment thread consisting of {0} postings.",
size);
}
return gettext("You are about to delete a comment by user {0}.",
this.creator.name);
}
/**
*
*
* @param {String} name
* @returns {HopObject}
* @returns {HopObject}
*/
Comment.prototype.getMacroHandler = function(name) {
if (name === "related") {
var membership = Membership.getByName(this.creator.name, this.site);
if (!membership || membership.comments.size() < 2 || this.status === Comment.DELETED) {
return {}; // Work-around for issue 88
}
return membership.comments;
}
return null;
if (name === "related") {
var membership = Membership.getByName(this.creator.name, this.site);
if (!membership || membership.comments.size() < 2 || this.status === Comment.DELETED) {
return {}; // Work-around for issue 88
}
return membership.comments;
}
return null;
}
/**
*
*
*/
Comment.prototype.text_macro = function() {
if (this.status === Comment.DELETED) {
res.write("<em>");
res.write(this.modifier === this.creator ?
gettext("This comment was removed by the author.") :
gettext("This comment was removed."));
res.writeln("</em>");
} else {
res.write(this.text);
}
return;
if (this.status === Comment.DELETED) {
res.write("<em>");
res.write(this.modifier === this.creator ?
gettext("This comment was removed by the author.") :
gettext("This comment was removed."));
res.writeln("</em>");
} else {
res.write(this.text);
}
return;
}
/**
*
*/
Comment.prototype.creator_macro = function() {
return this.status === Comment.DELETED ? null :
HopObject.prototype.creator_macro.apply(this, arguments);
return this.status === Comment.DELETED ? null :
HopObject.prototype.creator_macro.apply(this, arguments);
}
/**
*
*
*/
Comment.prototype.modifier_macro = function() {
return this.status === Comment.DELETED ? null :
HopObject.prototype.modifier_macro.apply(this, arguments);
return this.status === Comment.DELETED ? null :
HopObject.prototype.modifier_macro.apply(this, arguments);
}
/**
*
*
* @param {Object} param
* @param {Object} action
* @param {Object} text
*/
Comment.prototype.link_macro = function(param, action, text) {
return HopObject.prototype.link_macro.call(this, param, action, text);
return HopObject.prototype.link_macro.call(this, param, action, text);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -43,40 +43,40 @@ this.handleMetadata("fileName");
* @returns {File}
*/
File.add = function(data, site, user) {
site || (site = res.handlers.site);
user || (user = session.user);
var file = new File;
file.site = site;
file.requests = 0;
file.creator = file.modifier = user;
file.created = file.modified = new Date;
file.update(data);
site.files.add(file);
return file;
site || (site = res.handlers.site);
user || (user = session.user);
var file = new File;
file.site = site;
file.requests = 0;
file.creator = file.modifier = user;
file.created = file.modified = new Date;
file.update(data);
site.files.add(file);
return file;
}
/**
*
*
*/
File.remove = function() {
if (this.constructor === File) {
this.getFile().remove();
this.deleteMetadata();
this.remove();
}
return;
if (this.constructor === File) {
this.getFile().remove();
this.deleteMetadata();
this.remove();
}
return;
}
/**
*
*
* @param {String} name
*/
File.getName = function(name) {
if (name) {
//return name.replace(/[^\w\d\s._-]/g, String.EMPTY);
return String(name).trim().replace(/[\/\\:;?+\[\]{}|#"`<>^]/g, String.EMPTY);
}
return null;
if (name) {
//return name.replace(/[^\w\d\s._-]/g, String.EMPTY);
return String(name).trim().replace(/[\/\\:;?+\[\]{}|#"`<>^]/g, String.EMPTY);
}
return null;
}
/**
@ -84,12 +84,12 @@ File.getName = function(name) {
* @param {String } url
*/
File.redirectOnUploadError = function(url) {
if (req.data.helma_upload_error) {
res.message = gettext("Sorry, the file exceeds the maximum upload limit of {0} kB.",
formatNumber(app.appsProperties.uploadLimit));
res.redirect(url);
}
return;
if (req.data.helma_upload_error) {
res.message = gettext("Sorry, the file exceeds the maximum upload limit of {0} kB.",
formatNumber(app.appsProperties.uploadLimit));
res.redirect(url);
}
return;
}
/**
@ -97,11 +97,11 @@ File.redirectOnUploadError = function(url) {
* @param {String} url
*/
File.redirectOnExceededQuota = function(url) {
if (res.handlers.site.getDiskSpace() < 0) {
res.message = gettext("Sorry, there is no disk space left. Please try to delete some files or images first.");
res.redirect(url);
}
return;
if (res.handlers.site.getDiskSpace() < 0) {
res.message = gettext("Sorry, there is no disk space left. Please try to delete some files or images first.");
res.redirect(url);
}
return;
}
/**
@ -121,177 +121,177 @@ File.redirectOnExceededQuota = function(url) {
* @extends HopObject
*/
File.prototype.constructor = function() {
return this;
return this;
}
/**
*
*
* @param {String} action
* @return {Boolean}
*/
File.prototype.getPermission = function(action) {
switch (action) {
case ".":
case "main":
return true;
case "delete":
case "edit":
return this._parent.getPermission("main") &&
this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
switch (action) {
case ".":
case "main":
return true;
case "delete":
case "edit":
return this._parent.getPermission("main") &&
this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
}
File.prototype.main_action = function() {
if (Membership.require(Membership.SUBSCRIBER) &&
User.require(User.REGULAR)) {
this.requests += 1;
}
return res.redirect(this.getUrl());
if (Membership.require(Membership.SUBSCRIBER) &&
User.require(User.REGULAR)) {
this.requests += 1;
}
return res.redirect(this.getUrl());
}
File.prototype.edit_action = function() {
File.redirectOnUploadError(this.href(req.action));
File.redirectOnUploadError(this.href(req.action));
if (req.postParams.save) {
try {
File.redirectOnExceededQuota(this.href(req.action));
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this._parent.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Edit File");
res.data.body = this.renderSkinAsString("$File#edit");
return this.site.renderSkin("Site#page");
if (req.postParams.save) {
try {
File.redirectOnExceededQuota(this.href(req.action));
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this._parent.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Edit File");
res.data.body = this.renderSkinAsString("$File#edit");
return this.site.renderSkin("Site#page");
}
/**
*
*
* @param {String} name
* @returns {Object}
*/
File.prototype.getFormValue = function(name) {
var self = this;
var getOrigin = function(str) {
var origin = req.postParams.file_origin || self.origin;
if (origin && origin.contains("://")) {
return origin;
}
return null;
}
if (req.isPost()) {
if (name === "file") {
return getOrigin();
}
return req.postParams[name];
}
switch (name) {
case "file":
var self = this;
var getOrigin = function(str) {
var origin = req.postParams.file_origin || self.origin;
if (origin && origin.contains("://")) {
return origin;
}
return null;
}
if (req.isPost()) {
if (name === "file") {
return getOrigin();
}
return this[name];
}
return req.postParams[name];
}
switch (name) {
case "file":
return getOrigin();
}
return this[name];
}
/**
*
*
* @param {Object} data
*/
File.prototype.update = function(data) {
if (data.uploadError) {
app.log(data.uploadError);
// Looks like the file uploaded has exceeded the upload limit ...
throw Error(gettext("File size is exceeding the upload limit."));
}
if (!data.file_origin) {
if (this.isTransient()) {
throw Error(gettext("There was nothing to upload. Please be sure to choose a file."));
}
} else if (data.file_origin !== this.origin) {
var mime = data.file;
if (mime.contentLength < 1) {
mime = getURL(data.file_origin);
if (!mime) {
throw Error(gettext("Could not fetch the file from the given URL."));
}
}
if (data.uploadError) {
app.log(data.uploadError);
// Looks like the file uploaded has exceeded the upload limit ...
throw Error(gettext("File size is exceeding the upload limit."));
}
this.origin = data.file_origin;
var mimeName = mime.normalizeFilename(mime.name);
this.contentLength = mime.contentLength;
this.contentType = mime.contentType;
if (!this.name) {
var name = File.getName(data.name) || mimeName.split(".")[0];
this.name = this.site.files.getAccessName(name);
if (!data.file_origin) {
if (this.isTransient()) {
throw Error(gettext("There was nothing to upload. Please be sure to choose a file."));
}
} else if (data.file_origin !== this.origin) {
var mime = data.file;
if (mime.contentLength < 1) {
mime = getURL(data.file_origin);
if (!mime) {
throw Error(gettext("Could not fetch the file from the given URL."));
}
}
// Make the file persistent before proceeding with writing
// it to disk (also see Helma bug #607)
this.isTransient() && this.persist();
this.origin = data.file_origin;
var mimeName = mime.normalizeFilename(mime.name);
this.contentLength = mime.contentLength;
this.contentType = mime.contentType;
var extension = mimeName.substr(mimeName.lastIndexOf(".")) || String.EMPTY;
var fileName = this.name + extension;
if (fileName !== this.fileName) {
// Remove existing file if the file name has changed
this.getFile().remove();
}
this.fileName = fileName;
var file = this.getFile();
mime.writeToFile(file.getParent(), file.getName());
}
// FIXME: one day?
//this.setTags(data.tags || data.tag_array);
this.description = data.description;
this.touch();
return;
if (!this.name) {
var name = File.getName(data.name) || mimeName.split(".")[0];
this.name = this.site.files.getAccessName(name);
}
// Make the file persistent before proceeding with writing
// it to disk (also see Helma bug #607)
this.isTransient() && this.persist();
var extension = mimeName.substr(mimeName.lastIndexOf(".")) || String.EMPTY;
var fileName = this.name + extension;
if (fileName !== this.fileName) {
// Remove existing file if the file name has changed
this.getFile().remove();
}
this.fileName = fileName;
var file = this.getFile();
mime.writeToFile(file.getParent(), file.getName());
}
// FIXME: one day?
//this.setTags(data.tags || data.tag_array);
this.description = data.description;
this.touch();
return;
}
/**
*
*
*/
File.prototype.url_macro = function() {
return res.write(this.url || this.getUrl());
return res.write(this.url || this.getUrl());
}
/**
*
*
* @param {Object} param
*/
File.prototype.contentLength_macro = function(param) {
return res.write((this.contentLength / 1024).format("###,###") + " KB");
return res.write((this.contentLength / 1024).format("###,###") + " KB");
}
/**
*
*
*/
File.prototype.getFile = function() {
var site = this.site || res.handlers.site;
return site.getStaticFile("files/" + this.fileName);
var site = this.site || res.handlers.site;
return site.getStaticFile("files/" + this.fileName);
}
/**
*
*
*/
File.prototype.getUrl = function() {
var site = this.site || res.handlers.site;
return site.getStaticUrl("files/" + this.fileName);
var site = this.site || res.handlers.site;
return site.getStaticUrl("files/" + this.fileName);
}
/**
* @returns {String}
*/
File.prototype.getConfirmText = function() {
return gettext("You are about to delete the file {0}.", this.name);
return gettext("You are about to delete the file {0}.", this.name);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -37,69 +37,69 @@ markgettext("files");
*/
/**
*
*
* @param {String} action
* @returns {Boolean}
*/
Files.prototype.getPermission = function(action) {
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
return Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
return Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
}
Files.prototype.create_action = function() {
File.redirectOnUploadError(this.href(req.action));
File.redirectOnExceededQuota(this.href());
File.redirectOnUploadError(this.href(req.action));
File.redirectOnExceededQuota(this.href());
if (req.postParams.save) {
try {
var file = File.add(req.postParams);
file.notify(req.action);
res.message = gettext('The file was successfully added.');
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Add File");
HopObject.confirmConstructor(File);
res.data.body = (new File).renderSkinAsString("$File#edit");
this._parent.renderSkin("Site#page");
return;
if (req.postParams.save) {
try {
var file = File.add(req.postParams);
file.notify(req.action);
res.message = gettext('The file was successfully added.');
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Add File");
HopObject.confirmConstructor(File);
res.data.body = (new File).renderSkinAsString("$File#edit");
this._parent.renderSkin("Site#page");
return;
}
Files.prototype.main_action = function() {
var files = User.getMembership().files;
res.data.list = renderList(files, "$File#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(files, this.href(),
10, req.queryParams.page);
res.data.title = gettext("Member Files");
res.data.body = this.renderSkinAsString("$Files#main");
this._parent.renderSkin("Site#page");
return;
var files = User.getMembership().files;
res.data.list = renderList(files, "$File#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(files, this.href(),
10, req.queryParams.page);
res.data.title = gettext("Member Files");
res.data.body = this.renderSkinAsString("$Files#main");
this._parent.renderSkin("Site#page");
return;
}
Files.prototype.all_action = function() {
res.data.list = renderList(this, "$File#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("All Files");
res.data.body = this.renderSkinAsString("$Files#main");
this._parent.renderSkin("Site#page");
return;
res.data.list = renderList(this, "$File#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("All Files");
res.data.body = this.renderSkinAsString("$Files#main");
this._parent.renderSkin("Site#page");
return;
}

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -40,77 +40,77 @@ var Exporter = {}
* @param {User} user The user whose content will be exported.
*/
Exporter.run = function(site, user) {
try {
var file;
if (site.export_id && (file = File.getById(site.export_id))) {
File.remove.call(file);
}
try {
var file;
if (site.export_id && (file = File.getById(site.export_id))) {
File.remove.call(file);
}
var rssUrl = site.href("rss.xml");
var baseDir = site.getStaticFile();
var member = site.members.get(user.name);
var rssUrl = site.href("rss.xml");
var baseDir = site.getStaticFile();
var member = site.members.get(user.name);
var xml = new helma.File(baseDir, "export.xml");
xml.remove();
xml.open();
var xml = new helma.File(baseDir, "export.xml");
xml.remove();
xml.open();
var add = function(s) {
return xml.write(s);
}
var add = function(s) {
return xml.write(s);
}
add('<?xml version="1.0" encoding="UTF-8"?>');
add('<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>');
add('<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0">');
add('<id>tag:blogger.com,1999:blog-' + site._id + '.archive</id>');
add('<updated>' + site.modified.format(Date.ISOFORMAT) + '</updated>');
add('<title type="text">' + encodeXml(site.title) + '</title>');
add('<link rel="http://schemas.google.com/g/2005#feed" type="application/rss+xml" href="' + rssUrl + '"/>');
add('<link rel="self" type="application/rss+xml" href="' + rssUrl + '"/>');
add('<link rel="http://schemas.google.com/g/2005#post" type="application/rss+xml" href="' + rssUrl + '"/>');
add('<link rel="alternate" type="text/html" href="' + site.href() + '"/>');
add('<?xml version="1.0" encoding="UTF-8"?>');
add('<?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?>');
add('<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:thr="http://purl.org/syndication/thread/1.0">');
add('<id>tag:blogger.com,1999:blog-' + site._id + '.archive</id>');
add('<updated>' + site.modified.format(Date.ISOFORMAT) + '</updated>');
add('<title type="text">' + encodeXml(site.title) + '</title>');
add('<link rel="http://schemas.google.com/g/2005#feed" type="application/rss+xml" href="' + rssUrl + '"/>');
add('<link rel="self" type="application/rss+xml" href="' + rssUrl + '"/>');
add('<link rel="http://schemas.google.com/g/2005#post" type="application/rss+xml" href="' + rssUrl + '"/>');
add('<link rel="alternate" type="text/html" href="' + site.href() + '"/>');
add('<author>');
add('<name>' + site.creator.name + '</name>');
add('<email>' + site.creator.email + '</email>');
add('</author>');
// Currently, blogger.com does not accept other generators
//add('<generator version="' + Root.VERSION + '" uri="' + root.href() + '">Antville</generator>');
add('<generator version="7.00" uri="http://www.blogger.com">Blogger</generator>');
member.stories.forEach(function() {
add('<entry>');
add('<id>tag:blogger.com,1999:blog-' + site._id + '.post-' + this._id + '</id>');
add('<published>' + this.created.format(Date.ISOFORMAT) + '</published>');
add('<updated>' + this.modified.format(Date.ISOFORMAT) + '</updated>');
add('<title type="text">' + (this.title ? encodeXml(this.title.stripTags()) : '') + '</title>');
add('<content type="html">' + encodeXml(this.format_filter(this.text, {})) + '</content>');
add('<link rel="alternate" type="text/html" href="' + this.href() + '"></link>');
add('<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/blogger/2008/kind#post"/>');
add('<author>');
add('<name>' + site.creator.name + '</name>');
add('<email>' + site.creator.email + '</email>');
add('<name>' + this.creator.name + '</name>');
this.creator.url && add('<uri>' + this.creator.url + '</uri>');
add('<email>' + this.creator.email + '</email>');
add('</author>');
// Currently, blogger.com does not accept other generators
//add('<generator version="' + Root.VERSION + '" uri="' + root.href() + '">Antville</generator>');
add('<generator version="7.00" uri="http://www.blogger.com">Blogger</generator>');
member.stories.forEach(function() {
add('<entry>');
add('<id>tag:blogger.com,1999:blog-' + site._id + '.post-' + this._id + '</id>');
add('<published>' + this.created.format(Date.ISOFORMAT) + '</published>');
add('<updated>' + this.modified.format(Date.ISOFORMAT) + '</updated>');
add('<title type="text">' + (this.title ? encodeXml(this.title.stripTags()) : '') + '</title>');
add('<content type="html">' + encodeXml(this.format_filter(this.text, {})) + '</content>');
add('<link rel="alternate" type="text/html" href="' + this.href() + '"></link>');
add('<category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/blogger/2008/kind#post"/>');
add('<author>');
add('<name>' + this.creator.name + '</name>');
this.creator.url && add('<uri>' + this.creator.url + '</uri>');
add('<email>' + this.creator.email + '</email>');
add('</author>');
add('</entry>');
});
add('</feed>');
add('</entry>');
});
add('</feed>');
xml.close();
// Provide the exported data as downloadable file
// FIXME: Adding a file to a site could be a little bit simpler :/
file = new File;
file.site = site;
file.update({file: {contentLength: 0}, file_origin: "file://" +
xml.getPath(), name: site.name + "-export"});
site.files.add(file);
file.creator = user;
site.export_id = file._id;
} catch (ex) {
app.log(ex);
} finally {
xml.close();
xml.remove();
}
xml.close();
// Provide the exported data as downloadable file
// FIXME: Adding a file to a site could be a little bit simpler :/
file = new File;
file.site = site;
file.update({file: {contentLength: 0}, file_origin: "file://" +
xml.getPath(), name: site.name + "-export"});
site.files.add(file);
file.creator = user;
site.export_id = file._id;
} catch (ex) {
app.log(ex);
} finally {
xml.close();
xml.remove();
}
// Reset the sites export status
site.job = null;
return;
// Reset the sites export status
site.job = null;
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,11 +34,11 @@
* @param {String} id The identifier of the desired feature.
*/
global.feature_macro = function(param, id) {
var func, feature = Feature.get(id);
if (feature && (func = feature.main)) {
func.constructor === Function && func(param);
}
return;
var func, feature = Feature.get(id);
if (feature && (func = feature.main)) {
func.constructor === Function && func(param);
}
return;
}
/**
@ -49,19 +49,19 @@ global.feature_macro = function(param, id) {
* @param {Object} feature The initial properties of the feature.
*/
var Feature = function(id, url, feature) {
var self = this;
var self = this;
this.__defineGetter__("id", function() {return id});
this.__defineGetter__("id", function() {return id});
for (let i in feature) {
this[i] = feature[i];
}
for (let i in feature) {
this[i] = feature[i];
}
this.toString = function() {
return "[Feature: " + html.linkAsString({href: url}, id) + "]";
}
this.toString = function() {
return "[Feature: " + html.linkAsString({href: url}, id) + "]";
}
return this;
return this;
}
/**
@ -70,18 +70,18 @@ var Feature = function(id, url, feature) {
* @returns {Feature}
*/
Feature.add = function(id, url, feature) {
if (!id || !url) {
throw Error("Insufficient arguments");
}
if (!id || !url) {
throw Error("Insufficient arguments");
}
var existingFeature = Feature.get(id);
if (existingFeature) {
app.log("Warning! Overwriting already present feature with ID " + id);
Feature.remove(existingFeature);
}
var existingFeature = Feature.get(id);
if (existingFeature) {
app.log("Warning! Overwriting already present feature with ID " + id);
Feature.remove(existingFeature);
}
Feature.list().push(new Feature(id, url, feature));
return this;
Feature.list().push(new Feature(id, url, feature));
return this;
}
/**
@ -90,14 +90,14 @@ Feature.add = function(id, url, feature) {
* @returns {Number} The resulting number of features still in the registry.
*/
Feature.remove = function(feature) {
var features = Feature.list();
if (feature === "*") {
features.length = 0;
} else if (feature) {
var index = features.indexOf(feature);
(index > -1) && features.splice(index, 1);
}
return features.length;
var features = Feature.list();
if (feature === "*") {
features.length = 0;
} else if (feature) {
var index = features.indexOf(feature);
(index > -1) && features.splice(index, 1);
}
return features.length;
}
/**
@ -105,7 +105,7 @@ Feature.remove = function(feature) {
* @returns {Feature[]}
*/
Feature.list = function() {
return app.data.features;
return app.data.features;
}
/**
@ -114,12 +114,12 @@ Feature.list = function() {
* @returns {Feature}
*/
Feature.get = function(id) {
for each (let feature in Feature.list()) {
if (feature.id === id) {
return feature;
}
}
return;
for each (let feature in Feature.list()) {
if (feature.id === id) {
return feature;
}
}
return;
}
/**
@ -129,32 +129,32 @@ Feature.get = function(id) {
* @returns {Object}
*/
Feature.invoke = function(id, callback) {
id || (id = "*");
if (callback) {
var feature, method, result;
var args = Array.prototype.slice.call(arguments, 2);
if (id === "*") {
for each (feature in Feature.list()) {
method = feature[String(callback)];
if (method && method.constructor === Function) {
result = method.apply(feature, args);
}
}
} else {
feature = Feature.get(id);
if (feature) {
if (callback.constructor === Function) {
result = callback.apply(feature, args);
} else {
method = feature[callback];
if (method && method.constructor === Function) {
result = method.apply(feature, args);
}
}
}
id || (id = "*");
if (callback) {
var feature, method, result;
var args = Array.prototype.slice.call(arguments, 2);
if (id === "*") {
for each (feature in Feature.list()) {
method = feature[String(callback)];
if (method && method.constructor === Function) {
result = method.apply(feature, args);
}
}
}
return result;
} else {
feature = Feature.get(id);
if (feature) {
if (callback.constructor === Function) {
result = callback.apply(feature, args);
} else {
method = feature[callback];
if (method && method.constructor === Function) {
result = method.apply(feature, args);
}
}
}
}
}
return result;
}
/**
@ -163,11 +163,11 @@ Feature.invoke = function(id, callback) {
* @returns {Boolean}
*/
Feature.getPermission = function(action) {
for each (let feature in Feature.list()) {
let method = feature._getPermission;
if (method && method.constructor === Function && method.call(this, action)) {
return true;
}
}
return false;
for each (let feature in Feature.list()) {
let method = feature._getPermission;
if (method && method.constructor === Function && method.call(this, action)) {
return true;
}
}
return false;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -28,53 +28,53 @@
*/
var FlexiPath = function(name, parent) {
var self = this;
var self = this;
this._id = name;
this._parent = parent;
this._patterns = {};
this._id = name;
this._parent = parent;
this._patterns = {};
this.__defineGetter__("patterns", function() {
var ref = this;
while (ref._parent.constructor === FlexiPath) {
ref = ref._parent;
}
return ref._patterns;
});
this.__defineGetter__("patterns", function() {
var ref = this;
while (ref._parent.constructor === FlexiPath) {
ref = ref._parent;
}
return ref._patterns;
});
this.addUrlPattern = function(pattern, callback) {
this._patterns[pattern] = callback;
return;
}
this.addUrlPattern = function(pattern, callback) {
this._patterns[pattern] = callback;
return;
}
this.href = function(action) {
var href = [];
var ref = this;
while (ref._parent === this.constructor) {
href.unshift(ref._id);
ref = ref._parent;
}
//href.push("/");
if (action) {
href.push(action);
}
return root.api.href() + href.join("/");
}
this.href = function(action) {
var href = [];
var ref = this;
while (ref._parent === this.constructor) {
href.unshift(ref._id);
ref = ref._parent;
}
//href.push("/");
if (action) {
href.push(action);
}
return root.api.href() + href.join("/");
}
this.getChildElement = function(name) {
return new this.constructor(name, self);
}
this.getChildElement = function(name) {
return new this.constructor(name, self);
}
return this;
return this;
};
FlexiPath.prototype.main_action = function() {
for (let pattern in this.patterns) {
let match;
let re = new RegExp(pattern);
if (match = req.path.match(re)) {
return this.patterns[pattern].apply(this, match);
}
}
return;
for (let pattern in this.patterns) {
let match;
let re = new RegExp(pattern);
if (match = req.path.match(re)) {
return this.patterns[pattern].apply(this, match);
}
}
return;
}

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -39,36 +39,36 @@ var Importer = {}
* @param {User} user The user who will become the creator of the sites imported content.
*/
Importer.run = function(site, user) {
try {
var xml = File.getById(site.import_id);
if (xml) {
var file = new java.io.File(xml.getFile());
var reader = new rome.XmlReader(file);
var input = new rome.SyndFeedInput(true);
var feed = input.build(reader);
Api.constrain(site, user);
for (var i=0; i<feed.entries.size(); i+=1) {
var entry = feed.entries.get(i);
var category = entry.categories.get(0);
if (category.name !== "http://schemas.google.com/blogger/2008/kind#post") {
continue;
}
var story = Story.add({
title: entry.title,
text: entry.description || entry.contents.get(0).value,
created: entry.publishedDate.format("yyyy-MM-dd HH:mm"),
status: Story.CLOSED,
mode: Story.FEATURED
}, site, user);
}
File.remove.call(xml);
try {
var xml = File.getById(site.import_id);
if (xml) {
var file = new java.io.File(xml.getFile());
var reader = new rome.XmlReader(file);
var input = new rome.SyndFeedInput(true);
var feed = input.build(reader);
Api.constrain(site, user);
for (var i=0; i<feed.entries.size(); i+=1) {
var entry = feed.entries.get(i);
var category = entry.categories.get(0);
if (category.name !== "http://schemas.google.com/blogger/2008/kind#post") {
continue;
}
var story = Story.add({
title: entry.title,
text: entry.description || entry.contents.get(0).value,
created: entry.publishedDate.format("yyyy-MM-dd HH:mm"),
status: Story.CLOSED,
mode: Story.FEATURED
}, site, user);
}
} catch (ex) {
app.log(ex);
}
File.remove.call(xml);
}
} catch (ex) {
app.log(ex);
}
// Reset the sites export status
site.job = null;
site.import_id = null;
return;
// Reset the sites export status
site.job = null;
site.import_id = null;
return;
}

View file

@ -13,14 +13,14 @@
* @function
* @param {Object} value Any JavaScript value, usually an object or array.
* @param {Function|String[]} [replacer] An optional parameter that determines how object
* values are stringified for objects. It can be a
* function or an array of strings.
* values are stringified for objects. It can be a
* function or an array of strings.
* @param {String|Number} [space] An optional parameter that specifies the indentation
* of nested structures. If it is omitted, the text will
* be packed without extra whitespace. If it is a number,
* it will specify the number of spaces to indent at each
* level. If it is a string (such as '\t' or '&nbsp;'),
* it contains the characters used to indent at each level.
* of nested structures. If it is omitted, the text will
* be packed without extra whitespace. If it is a number,
* it will specify the number of spaces to indent at each
* level. If it is a string (such as '\t' or '&nbsp;'),
* it contains the characters used to indent at each level.
* @returns {String}
*/
@ -39,160 +39,160 @@
/*
http://www.JSON.org/json2.js
2011-02-23
http://www.JSON.org/json2.js
2011-02-23
Public Domain.
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
See http://www.JSON.org/js.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
This file creates a global JSON object containing two methods: stringify
and parse.
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
This is a reference implementation. You are free to copy, modify, or
redistribute.
*/
/*jslint evil: true, strict: false, regexp: false */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
@ -201,197 +201,197 @@
var JSON;
if (!JSON) {
JSON = {};
JSON = {};
}
(function () {
"use strict";
"use strict";
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
Date.prototype.toJSON = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
escapable.lastIndex = 0;
return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' : '"' + string + '"';
}
function str(key, holder) {
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' : gap ?
'[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
v = partial.length === 0 ? '[]' : gap ?
'[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
if (typeof rep[i] === 'string') {
k = rep[i];
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
} else {
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' : gap ?
'{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
'{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
v = partial.length === 0 ? '{}' : gap ?
'{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
'{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
@ -399,86 +399,86 @@ if (!JSON) {
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
var j;
function walk(holder, key) {
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.prototype.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
return reviver.call(holder, key, value);
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
text = String(text);
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
@ -493,30 +493,30 @@ if (!JSON) {
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
if (/^[\],:{}\s]*$/
.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
.replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
throw new SyntaxError('JSON.parse');
};
}
}());
// Do not enumerate the new JSON methods.
@ -530,10 +530,10 @@ Object.prototype.dontEnum("parseJSON");
* @param {Object} data An arbitrary JavaScript object
*/
JSON.pad = function(data, callback) {
if (!callback) {
return;
}
return callback + "(" + JSON.stringify(data) + ")";
if (!callback) {
return;
}
return callback + "(" + JSON.stringify(data) + ")";
}
/**
@ -544,11 +544,11 @@ JSON.pad = function(data, callback) {
* @param {Boolean} resume Switch to define whether further processing should be continued or not
*/
JSON.sendPaddedResponse = function(data, key, resume) {
var callback = req.data[key || "callback"];
if (callback) {
res.contentType = "text/javascript";
res.write(JSON.pad(data, callback));
resume || res.stop();
}
return;
var callback = req.data[key || "callback"];
if (callback) {
res.contentType = "text/javascript";
res.write(JSON.pad(data, callback));
resume || res.stop();
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -31,131 +31,131 @@
* @constructor
*/
var Sql = function(options) {
options || (options = {});
var db = getDBConnection("antville");
var query;
options || (options = {});
var db = getDBConnection("antville");
var query;
var log = new function() {
var fname = getProperty("sqlLog", "helma." + app.getName() + ".sql");
return Packages.org.apache.commons.logging.LogFactory.getLog(fname);
}
var log = new function() {
var fname = getProperty("sqlLog", "helma." + app.getName() + ".sql");
return Packages.org.apache.commons.logging.LogFactory.getLog(fname);
}
var SqlData = function(result) {
var columns = [];
this.values = {};
var SqlData = function(result) {
var columns = [];
this.values = {};
for (var i=1; i<=result.getColumnCount(); i+=1) {
columns.push(result.getColumnName(i).toLowerCase());
}
for (var i=1; i<=result.getColumnCount(); i+=1) {
columns.push(result.getColumnName(i).toLowerCase());
}
this.next = function() {
for each (var key in columns) {
this.values[key] = result.getColumnItem(key);
}
return;
}
return this;
}
var quote = function(str) {
if (!options.quote || str === null) {
return str;
}
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
}
var value = function(obj) {
if (obj === null) {
return obj;
}
if (obj === undefined) {
obj = String(obj);
}
switch (obj.constructor) {
case Number:
return obj;
case String:
return quote(obj);
case Date:
return "from_unixtime(" + (obj.getTime() / 1000) + ")";
case HopObject:
case Object:
return quote(obj.toSource());
}
return quote(String(obj));
}
var resolve = function(args) {
var sql = args[0];
if (args.length > 1) {
var values = Array.prototype.splice.call(args, 1);
if (typeof values[0] === "object") {
values = values[0];
}
sql = sql.replace(/\$(\w*)/g, function() {
return value(values[arguments[1]]);
});
}
return sql;
}
/**
* Executes an SQL command.
* @param {String} sql The SQL command.
* @returns {Object} The result of the SQL command.
*/
this.execute = function(sql) {
sql = resolve(arguments);
log.info(sql);
if (options.test) {
return app.log(sql);
}
var error;
var result = db.executeCommand(sql);
if (error = db.getLastError()) {
app.log(error);
}
return result;
}
/**
* Retrieves an SQL query.
* @example sql.retrieve('select $1 from $2 order by $1', 'date', 'foo')
* ===> 'select date from foo order by date'
* @returns {String}
*/
this.retrieve = function() {
return log.info(query = resolve(arguments));
}
/**
* Traverses over the results of an SQL query.
* @param {Function} callback The callback function executed for each record.
*/
this.traverse = function(callback) {
var rows = db.executeRetrieval(query);
if (rows && rows.next()) {
do {
var sql = new SqlData(rows);
sql.next();
if (!options.test) {
callback.call(sql.values, rows);
}
} while (record = rows.next());
rows.release();
this.next = function() {
for each (var key in columns) {
this.values[key] = result.getColumnItem(key);
}
return;
}
}
/**
* @return {String}
*/
this.toString = function() {
return query;
}
return this;
}
return this;
var quote = function(str) {
if (!options.quote || str === null) {
return str;
}
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
}
var value = function(obj) {
if (obj === null) {
return obj;
}
if (obj === undefined) {
obj = String(obj);
}
switch (obj.constructor) {
case Number:
return obj;
case String:
return quote(obj);
case Date:
return "from_unixtime(" + (obj.getTime() / 1000) + ")";
case HopObject:
case Object:
return quote(obj.toSource());
}
return quote(String(obj));
}
var resolve = function(args) {
var sql = args[0];
if (args.length > 1) {
var values = Array.prototype.splice.call(args, 1);
if (typeof values[0] === "object") {
values = values[0];
}
sql = sql.replace(/\$(\w*)/g, function() {
return value(values[arguments[1]]);
});
}
return sql;
}
/**
* Executes an SQL command.
* @param {String} sql The SQL command.
* @returns {Object} The result of the SQL command.
*/
this.execute = function(sql) {
sql = resolve(arguments);
log.info(sql);
if (options.test) {
return app.log(sql);
}
var error;
var result = db.executeCommand(sql);
if (error = db.getLastError()) {
app.log(error);
}
return result;
}
/**
* Retrieves an SQL query.
* @example sql.retrieve('select $1 from $2 order by $1', 'date', 'foo')
* ===> 'select date from foo order by date'
* @returns {String}
*/
this.retrieve = function() {
return log.info(query = resolve(arguments));
}
/**
* Traverses over the results of an SQL query.
* @param {Function} callback The callback function executed for each record.
*/
this.traverse = function(callback) {
var rows = db.executeRetrieval(query);
if (rows && rows.next()) {
do {
var sql = new SqlData(rows);
sql.next();
if (!options.test) {
callback.call(sql.values, rows);
}
} while (record = rows.next());
rows.release();
}
return;
}
/**
* @return {String}
*/
this.toString = function() {
return query;
}
return this;
}
/**
@ -169,47 +169,47 @@ Sql.COUNT = "select count(*) as count from $0";
* @constant
*/
Sql.REFERRERS = "select referrer, count(*) as requests from " +
"log where context_type = '$0' and context_id = $1 and action = " +
"'main' and created > now() - interval '2 days' group " +
"by referrer order by requests desc, referrer asc";
"log where context_type = '$0' and context_id = $1 and action = " +
"'main' and created > now() - interval '2 days' group " +
"by referrer order by requests desc, referrer asc";
/**
* SQL command for deleting all log entries older than 2 days.
* @constant
*/
Sql.PURGEREFERRERS = "delete from log where action = 'main' and " +
"created < now() - interval '2 days'";
"created < now() - interval '2 days'";
/**
* SQL query for searching stories and comments.
* @constant
*/
Sql.SEARCH = "select content.id from content, site, metadata where site.id = $0 and " +
"site.id = content.site_id and content.status in ('public', 'shared', 'open') and " +
"content.id = metadata.parent_id and metadata.name in ('title', 'text') and " +
"lower(metadata.value) like lower('%$1%') group by content.id, content.created " +
"order by content.created desc limit $2";
"site.id = content.site_id and content.status in ('public', 'shared', 'open') and " +
"content.id = metadata.parent_id and metadata.name in ('title', 'text') and " +
"lower(metadata.value) like lower('%$1%') group by content.id, content.created " +
"order by content.created desc limit $2";
/**
* SQL query for searching members.
* @constant
*/
Sql.MEMBERSEARCH = "select name from account where name $0 '$1' " +
"order by name asc limit $2";
"order by name asc limit $2";
/**
* SQL query for retrieving all story IDs in a sites archive.
* @constant
*/
Sql.ARCHIVE = "select id from content where site_id = $0 and prototype = 'Story' and " +
"status in ('public', 'shared', 'open') $1 $2 limit $3 offset $4";
"status in ('public', 'shared', 'open') $1 $2 limit $3 offset $4";
/**
* SQL command for retrieving the size of a sites archive.
* @constant
*/
Sql.ARCHIVESIZE = "select count(*) as count from content where site_id = $0 " +
"and prototype = 'Story' and status in ('public', 'shared', 'open') $1";
"and prototype = 'Story' and status in ('public', 'shared', 'open') $1";
/**
* SQL part filtering the archive query.

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -27,62 +27,62 @@ app.addRepository("modules/helma/Aspects.js");
(function() {
function skinMayDisplayEditLink(name) {
return req.cookies[User.COOKIE + 'LayoutSandbox'] &&
res.handlers.layout.getPermission('main') &&
typeof name === 'string' &&
!name.startsWith('$') &&
res.contentType === 'text/html';
}
function skinMayDisplayEditLink(name) {
return req.cookies[User.COOKIE + 'LayoutSandbox'] &&
res.handlers.layout.getPermission('main') &&
typeof name === 'string' &&
!name.startsWith('$') &&
res.contentType === 'text/html';
}
function renderSkin(args, func, object) {
res.meta.skins || (res.meta.skins = {});
function renderSkin(args, func, object) {
res.meta.skins || (res.meta.skins = {});
var name = args[0];
if (name.startsWith('#')) {
// Fix names using short form (ie. missing prototype)
name = object.constructor.name + name;
var name = args[0];
if (name.startsWith('#')) {
// Fix names using short form (ie. missing prototype)
name = object.constructor.name + name;
}
var id = name.replace('#', '-').toLowerCase();
if (skinMayDisplayEditLink(name) && !res.meta.skins[name]) {
res.meta.skins[name] = true;
var parts = name.split('#');
var prototype = parts[0];
var skinName = parts[1];
var skin = new Skin(prototype, skinName);
res.writeln('<!-- Begin of #skin-' + id + ' -->');
res.writeln('<div id="skin-' + id + '" class="skin" data-name="' +
name + '" data-href="' + skin.href('edit') + '">');
func.apply(object, args);
res.writeln('</div>\n<!-- End of #skin-' + id + ' -->');
} else {
func.apply(object, args);
}
return;
}
function renderSkinAsString(args, func, object) {
var name = args[0];
if (skinMayDisplayEditLink(name)) {
res.push();
object.renderSkin.apply(object, args);
return res.pop();
}
return func.apply(object, args);
}
var prototypes = app.__app__.getPrototypes().toArray();
for each (var prototype in prototypes) {
if (prototype.name in global) {
global[prototype.name].prototype.onCodeUpdate = function() {
this.__renderSkin__ = this.renderSkin;
this.__renderSkinAsString__ = this.renderSkinAsString;
helma.aspects.addAround(this, 'renderSkin', renderSkin);
helma.aspects.addAround(this, 'renderSkinAsString', renderSkinAsString);
}
var id = name.replace('#', '-').toLowerCase();
if (skinMayDisplayEditLink(name) && !res.meta.skins[name]) {
res.meta.skins[name] = true;
var parts = name.split('#');
var prototype = parts[0];
var skinName = parts[1];
var skin = new Skin(prototype, skinName);
res.writeln('<!-- Begin of #skin-' + id + ' -->');
res.writeln('<div id="skin-' + id + '" class="skin" data-name="' +
name + '" data-href="' + skin.href('edit') + '">');
func.apply(object, args);
res.writeln('</div>\n<!-- End of #skin-' + id + ' -->');
} else {
func.apply(object, args);
}
return;
}
function renderSkinAsString(args, func, object) {
var name = args[0];
if (skinMayDisplayEditLink(name)) {
res.push();
object.renderSkin.apply(object, args);
return res.pop();
}
return func.apply(object, args);
}
var prototypes = app.__app__.getPrototypes().toArray();
for each (var prototype in prototypes) {
if (prototype.name in global) {
global[prototype.name].prototype.onCodeUpdate = function() {
this.__renderSkin__ = this.renderSkin;
this.__renderSkinAsString__ = this.renderSkinAsString;
helma.aspects.addAround(this, 'renderSkin', renderSkin);
helma.aspects.addAround(this, 'renderSkinAsString', renderSkinAsString);
}
}
}
}
}
}());

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -35,29 +35,29 @@
* @param {String} potFile The filename for the output POT file.
*/
Root.prototype.extractMessages = function(script, scanDirs, potFile) {
var temp = {print: global.print, readFile: global.readFile};
global.print = function(str) {app.log(str);}
global.readFile = function(fpath, encoding) {
res.push();
var file = new helma.File(fpath);
file.open({charset: encoding || "UTF-8"});
var str;
while ((str = file.readln()) !== null) {
res.writeln(str);
}
file.close();
return res.pop();
}
var args = ["-o", potFile, "-e", "utf-8"];
for each (var dir in scanDirs.split(" ")) {
args.push(app.dir + "/../" + dir);
}
var file = new helma.File(script);
var MessageParser = new Function(file.readAll());
MessageParser.apply(global, args);
global.print = temp.print;
global.readFile = temp.readFile;
return;
var temp = {print: global.print, readFile: global.readFile};
global.print = function(str) {app.log(str);}
global.readFile = function(fpath, encoding) {
res.push();
var file = new helma.File(fpath);
file.open({charset: encoding || "UTF-8"});
var str;
while ((str = file.readln()) !== null) {
res.writeln(str);
}
file.close();
return res.pop();
}
var args = ["-o", potFile, "-e", "utf-8"];
for each (var dir in scanDirs.split(" ")) {
args.push(app.dir + "/../" + dir);
}
var file = new helma.File(script);
var MessageParser = new Function(file.readAll());
MessageParser.apply(global, args);
global.print = temp.print;
global.readFile = temp.readFile;
return;
}
/**
@ -68,9 +68,9 @@ Root.prototype.extractMessages = function(script, scanDirs, potFile) {
* @returns {String}
*/
function cgettext(key, context) {
var msgId = cgettext.getKey(key, context);
var text = jala.i18n.translate(msgId);
return text === msgId ? key : text;
var msgId = cgettext.getKey(key, context);
var text = jala.i18n.translate(msgId);
return text === msgId ? key : text;
}
/**
@ -81,7 +81,7 @@ function cgettext(key, context) {
* @example cgettext.getKey('comment', 'verb') ===> 'comment // verb'
*/
cgettext.getKey = function(key, context) {
return context ? key + " // " + context : key;
return context ? key + " // " + context : key;
}
/**
@ -92,18 +92,18 @@ cgettext.getKey = function(key, context) {
* @see jala.i18n.gettext
*/
function gettext_macro(param, text /*, value1, value2, ...*/) {
if (!text) {
return;
}
var re = gettext_macro.REGEX;
var args = [text.toString().replace(re, String.SPACE)];
for (var i=2; i<arguments.length; i+=1) {
args.push(arguments[i]);
}
if (param.context) {
return cgettext.call(this, args[0], param.context);
}
return gettext.apply(this, args);
if (!text) {
return;
}
var re = gettext_macro.REGEX;
var args = [text.toString().replace(re, String.SPACE)];
for (var i=2; i<arguments.length; i+=1) {
args.push(arguments[i]);
}
if (param.context) {
return cgettext.call(this, args[0], param.context);
}
return gettext.apply(this, args);
}
/**
@ -121,15 +121,15 @@ gettext_macro.REGEX = /\s+/g;
* @see jala.i18n.ngettext
*/
function ngettext_macro(param, singular, plural /*, value1, value2, ...*/) {
if (!singular || !plural) {
return;
}
var re = gettext_macro.REGEX;
var args = [singular.toString().replace(re, String.SPACE), plural.replace(re, String.SPACE)];
for (var i=3; i<arguments.length; i+=1) {
args.push(arguments[i]);
}
return ngettext.apply(this, args);
if (!singular || !plural) {
return;
}
var re = gettext_macro.REGEX;
var args = [singular.toString().replace(re, String.SPACE), plural.replace(re, String.SPACE)];
for (var i=3; i<arguments.length; i+=1) {
args.push(arguments[i]);
}
return ngettext.apply(this, args);
}
/**
@ -140,5 +140,5 @@ function ngettext_macro(param, singular, plural /*, value1, value2, ...*/) {
* @see jala.i18n.markgettext
*/
function markgettext_macro(param, singular, plural) {
return markgettext.call(this, singular, plural);
return markgettext.call(this, singular, plural);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -37,19 +37,19 @@ app.addRepository('modules/helma/Aspects');
* conditional checks of individual prototypes remove() methods
*/
HopObject.remove = function(options) {
var item;
while (this.size() > 0) {
item = this.get(0);
if (item.constructor.remove) {
item.constructor.remove.call(item, options);
} else if (!options) {
item.remove();
} else {
throw Error("Missing static " + item.constructor.name +
".remove() method");
}
}
return;
var item;
while (this.size() > 0) {
item = this.get(0);
if (item.constructor.remove) {
item.constructor.remove.call(item, options);
} else if (!options) {
item.remove();
} else {
throw Error("Missing static " + item.constructor.name +
".remove() method");
}
}
return;
}
/**
@ -58,20 +58,20 @@ HopObject.remove = function(options) {
* @param {HopObject} collection
*/
HopObject.getFromPath = function(name, collection) {
if (name) {
var site;
if (name.contains("/")) {
var parts = name.split("/");
site = root.get(parts[0]);
name = parts[1];
} else {
site = res.handlers.site;
}
if (site && site.getPermission("main")) {
return site[collection].get(name);
}
}
return null;
if (name) {
var site;
if (name.contains("/")) {
var parts = name.split("/");
site = root.get(parts[0]);
name = parts[1];
} else {
site = res.handlers.site;
}
if (site && site.getPermission("main")) {
return site[collection].get(name);
}
}
return null;
}
/**
@ -79,21 +79,21 @@ HopObject.getFromPath = function(name, collection) {
* should be replaced with static add() method.
*/
HopObject.confirmConstructor = function(ref) {
var KEY = '__confirmedConstructors__';
if (!res.meta[KEY]) {
res.meta[KEY] = {};
}
var confirmed = res.meta[KEY];
if (typeof ref === 'function') {
confirmed[ref.name] = true;
} else {
ref = (ref || this).constructor.name;
if (!confirmed[ref]) {
app.logger.warn('Calling unconfirmed constructor for ' +
ref + ' prototype please check!');
}
}
return;
var KEY = '__confirmedConstructors__';
if (!res.meta[KEY]) {
res.meta[KEY] = {};
}
var confirmed = res.meta[KEY];
if (typeof ref === 'function') {
confirmed[ref.name] = true;
} else {
ref = (ref || this).constructor.name;
if (!confirmed[ref]) {
app.logger.warn('Calling unconfirmed constructor for ' +
ref + ' prototype please check!');
}
}
return;
}
/**
@ -106,63 +106,63 @@ HopObject.confirmConstructor = function(ref) {
*
*/
HopObject.prototype.onRequest = function() {
// Checking if we are on the correct host to prevent at least some XSS issues
if (req.action !== "notfound" && req.action !== "error" &&
this.href().contains("://") &&
!this.href().toLowerCase().startsWith(req.servletRequest.scheme +
"://" + req.servletRequest.serverName.toLowerCase())) {
res.redirect(this.href(req.action === "main" ? String.EMPTY : req.action));
}
// Checking if we are on the correct host to prevent at least some XSS issues
if (req.action !== "notfound" && req.action !== "error" &&
this.href().contains("://") &&
!this.href().toLowerCase().startsWith(req.servletRequest.scheme +
"://" + req.servletRequest.serverName.toLowerCase())) {
res.redirect(this.href(req.action === "main" ? String.EMPTY : req.action));
}
User.autoLogin();
res.handlers.membership = User.getMembership();
User.autoLogin();
res.handlers.membership = User.getMembership();
if (User.getCurrentStatus() === User.BLOCKED) {
session.data.status = 403;
session.data.error = gettext("Your account has been blocked.") + String.SPACE +
gettext("Please contact an administrator for further information.");
User.logout();
res.redirect(root.href("error"));
}
if (User.getCurrentStatus() === User.BLOCKED) {
session.data.status = 403;
session.data.error = gettext("Your account has been blocked.") + String.SPACE +
gettext("Please contact an administrator for further information.");
User.logout();
res.redirect(root.href("error"));
}
if (res.handlers.site.status === Site.BLOCKED &&
!User.require(User.PRIVILEGED)) {
session.data.status = 403;
session.data.error = gettext("The site you requested has been blocked.") +
String.SPACE + gettext("Please contact an administrator for further information.");
res.redirect(root.href("error"));
}
if (res.handlers.site.status === Site.BLOCKED &&
!User.require(User.PRIVILEGED)) {
session.data.status = 403;
session.data.error = gettext("The site you requested has been blocked.") +
String.SPACE + gettext("Please contact an administrator for further information.");
res.redirect(root.href("error"));
}
HopObject.confirmConstructor(Layout);
res.handlers.layout = res.handlers.site.layout || new Layout;
res.skinpath = res.handlers.layout.getSkinPath();
HopObject.confirmConstructor(Layout);
res.handlers.layout = res.handlers.site.layout || new Layout;
res.skinpath = res.handlers.layout.getSkinPath();
if (!this.getPermission(req.action)) {
if (!session.user) {
User.setLocation(root.href() + req.path);
res.message = gettext("Please login first.");
res.redirect(res.handlers.site.members.href("login"));
}
User.getLocation();
res.status = 401;
res.data.title = gettext("{0} 401 Error", root.title);
res.data.body = root.renderSkinAsString("$Root#error", {error:
gettext("You are not allowed to access this part of the site.")});
res.handlers.site.renderSkin("Site#page");
session.data.error = null;
res.stop();
}
if (!this.getPermission(req.action)) {
if (!session.user) {
User.setLocation(root.href() + req.path);
res.message = gettext("Please login first.");
res.redirect(res.handlers.site.members.href("login"));
}
User.getLocation();
res.status = 401;
res.data.title = gettext("{0} 401 Error", root.title);
res.data.body = root.renderSkinAsString("$Root#error", {error:
gettext("You are not allowed to access this part of the site.")});
res.handlers.site.renderSkin("Site#page");
session.data.error = null;
res.stop();
}
res.meta.values = {};
res.handlers.site.renderSkinAsString("Site#values");
return;
res.meta.values = {};
res.handlers.site.renderSkinAsString("Site#values");
return;
}
/**
* @returns Boolean
*/
HopObject.prototype.getPermission = function() {
return true;
return true;
}
// Marking some prototype names used in res.message of HopObject.delete_action()
@ -174,45 +174,45 @@ markgettext("Poll");
markgettext("Story");
HopObject.prototype.delete_action = function() {
if (req.postParams.proceed) {
try {
var parent = this._parent;
var url = this.constructor.remove.call(this, req.postParams) ||
parent.href();
res.message = gettext("{0} was successfully deleted.", gettext(this._prototype));
res.redirect(User.getLocation() || url);
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
if (req.postParams.proceed) {
try {
var parent = this._parent;
var url = this.constructor.remove.call(this, req.postParams) ||
parent.href();
res.message = gettext("{0} was successfully deleted.", gettext(this._prototype));
res.redirect(User.getLocation() || url);
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Confirm Deletion");
res.data.body = this.renderSkinAsString("$HopObject#confirm", {
text: this.getConfirmText()
});
res.handlers.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext("Confirm Deletion");
res.data.body = this.renderSkinAsString("$HopObject#confirm", {
text: this.getConfirmText()
});
res.handlers.site.renderSkin("Site#page");
return;
}
/**
* @returns {Object}
*/
HopObject.prototype.touch = function() {
return this.map({
modified: new Date,
modifier: session.user
});
return this.map({
modified: new Date,
modifier: session.user
});
}
/**
*
*/
HopObject.prototype.log = function() {
var entry = new LogEntry(this, "main");
app.data.entries.push(entry);
return;
var entry = new LogEntry(this, "main");
app.data.entries.push(entry);
return;
}
/**
@ -220,79 +220,79 @@ HopObject.prototype.log = function() {
* @param {String} action
*/
HopObject.prototype.notify = function(action) {
var self = this;
var site = res.handlers.site;
var self = this;
var site = res.handlers.site;
var getPermission = function(scope, mode, status) {
if (scope === Admin.NONE || mode === Site.NOBODY ||
status === Site.BLOCKED) {
return false;
}
var scopes = [Admin.REGULAR, Admin.TRUSTED];
if (scopes.indexOf(status) < scopes.indexOf(scope)) {
return false;
}
if (!Membership.require(mode)) {
return false;
}
return true;
}
var getPermission = function(scope, mode, status) {
if (scope === Admin.NONE || mode === Site.NOBODY ||
status === Site.BLOCKED) {
return false;
}
var scopes = [Admin.REGULAR, Admin.TRUSTED];
if (scopes.indexOf(status) < scopes.indexOf(scope)) {
return false;
}
if (!Membership.require(mode)) {
return false;
}
return true;
}
// Helper method for debugging
var renderMatrix = function() {
var buf = ['<table border=1 cellspacing=0>'];
for each (var scope in Admin.getNotificationScopes()) {
for each (var mode in Site.getNotificationModes()) {
for each (var status in Site.getStatus()) {
var perm = getPermission(scope.value, mode.value, status.value);
buf.push('<tr style="');
perm && buf.push('color: blue;');
if (scope.value === root.notificationScope && mode.value ===
site.notificationMode && status.value === site.status) {
buf.push(' background-color: yellow;');
}
buf.push('">');
buf.push('<td>', scope.value, '</td>');
buf.push('<td>', status.value, '</td>');
buf.push('<td>', mode.value, '</td>');
buf.push('<td>', perm, '</td>');
buf.push('</tr>');
}
}
// Helper method for debugging
var renderMatrix = function() {
var buf = ['<table border=1 cellspacing=0>'];
for each (var scope in Admin.getNotificationScopes()) {
for each (var mode in Site.getNotificationModes()) {
for each (var status in Site.getStatus()) {
var perm = getPermission(scope.value, mode.value, status.value);
buf.push('<tr style="');
perm && buf.push('color: blue;');
if (scope.value === root.notificationScope && mode.value ===
site.notificationMode && status.value === site.status) {
buf.push(' background-color: yellow;');
}
buf.push('">');
buf.push('<td>', scope.value, '</td>');
buf.push('<td>', status.value, '</td>');
buf.push('<td>', mode.value, '</td>');
buf.push('<td>', perm, '</td>');
buf.push('</tr>');
}
}
buf.push('</table>');
res.write(buf.join(""));
return;
}
}
buf.push('</table>');
res.write(buf.join(""));
return;
}
switch (action) {
case "comment":
action = "create"; break;
}
switch (action) {
case "comment":
action = "create"; break;
}
var currentMembership = res.handlers.membership;
site.members.forEach(function() {
var membership = res.handlers.membership = this;
if (getPermission(root.notificationScope, site.notificationMode, site.status)) {
sendMail(membership.creator.email, gettext("[{0}] Notification of site changes",
root.title), self.renderSkinAsString("$HopObject#notify_" + action));
}
});
res.handlers.membership = currentMembership;
return;
var currentMembership = res.handlers.membership;
site.members.forEach(function() {
var membership = res.handlers.membership = this;
if (getPermission(root.notificationScope, site.notificationMode, site.status)) {
sendMail(membership.creator.email, gettext("[{0}] Notification of site changes",
root.title), self.renderSkinAsString("$HopObject#notify_" + action));
}
});
res.handlers.membership = currentMembership;
return;
}
/**
* @returns {Tag[]}
*/
HopObject.prototype.getTags = function() {
var tags = [];
if (typeof this.tags === "object") {
this.tags.list().forEach(function(item) {
item.tag && tags.push(item.tag.name);
});
}
return tags;
var tags = [];
if (typeof this.tags === "object") {
this.tags.list().forEach(function(item) {
item.tag && tags.push(item.tag.name);
});
}
return tags;
}
/**
@ -300,48 +300,48 @@ HopObject.prototype.getTags = function() {
* @param {Tag[]|String} tags
*/
HopObject.prototype.setTags = function(tags) {
if (typeof this.tags !== "object") {
return String.EMPTY;
}
if (typeof this.tags !== "object") {
return String.EMPTY;
}
if (!tags) {
tags = [];
} else if (tags.constructor === String) {
tags = tags.split(/\s*,\s*/);
}
if (!tags) {
tags = [];
} else if (tags.constructor === String) {
tags = tags.split(/\s*,\s*/);
}
var diff = {};
var tag;
for (var i in tags) {
// Trim and remove troublesome characters (like ../.. etc.)
// We call getAccessName with a virgin HopObject to allow most names
tag = tags[i] = this.getAccessName.call(new HopObject, File.getName(tags[i]));
if (tag && diff[tag] == null) {
diff[tag] = 1;
}
}
this.tags.forEach(function() {
if (!this.tag) {
return;
}
diff[this.tag.name] = (tags.indexOf(this.tag.name) < 0) ? this : 0;
});
var diff = {};
var tag;
for (var i in tags) {
// Trim and remove troublesome characters (like ../.. etc.)
// We call getAccessName with a virgin HopObject to allow most names
tag = tags[i] = this.getAccessName.call(new HopObject, File.getName(tags[i]));
if (tag && diff[tag] == null) {
diff[tag] = 1;
}
}
this.tags.forEach(function() {
if (!this.tag) {
return;
}
diff[this.tag.name] = (tags.indexOf(this.tag.name) < 0) ? this : 0;
});
for (var tag in diff) {
switch (diff[tag]) {
case 0:
// Do nothing (tag already exists)
break;
case 1:
// Add tag to story
this.addTag(tag);
break;
default:
// Remove tag
this.removeTag(diff[tag]);
}
}
return;
for (var tag in diff) {
switch (diff[tag]) {
case 0:
// Do nothing (tag already exists)
break;
case 1:
// Add tag to story
this.addTag(tag);
break;
default:
// Remove tag
this.removeTag(diff[tag]);
}
}
return;
}
/**
@ -349,8 +349,8 @@ HopObject.prototype.setTags = function(tags) {
* @param {String} name
*/
HopObject.prototype.addTag = function(name) {
TagHub.add(name, this, session.user);
return;
TagHub.add(name, this, session.user);
return;
}
/**
@ -358,12 +358,12 @@ HopObject.prototype.addTag = function(name) {
* @param {String} tag
*/
HopObject.prototype.removeTag = function(tag) {
var parent = tag._parent;
if (parent.size() === 1) {
parent.remove();
}
tag.remove();
return;
var parent = tag._parent;
if (parent.size() === 1) {
parent.remove();
}
tag.remove();
return;
}
/**
@ -371,10 +371,10 @@ HopObject.prototype.removeTag = function(tag) {
* @param {Object} values
*/
HopObject.prototype.map = function(values) {
for (var i in values) {
this[i] = values[i];
}
return;
for (var i in values) {
this[i] = values[i];
}
return;
}
/**
@ -383,16 +383,16 @@ HopObject.prototype.map = function(values) {
* @param {String} name
*/
HopObject.prototype.skin_macro = function(param, name) {
if (!name) {
return;
}
if (name.contains("#")) {
this.renderSkin(name);
} else {
var prototype = this._prototype || "Global";
this.renderSkin(prototype + "#" + name);
}
return;
if (!name) {
return;
}
if (name.contains("#")) {
this.renderSkin(name);
} else {
var prototype = this._prototype || "Global";
this.renderSkin(prototype + "#" + name);
}
return;
}
/**
@ -401,10 +401,10 @@ HopObject.prototype.skin_macro = function(param, name) {
* @param {String} name
*/
HopObject.prototype.input_macro = function(param, name) {
param.name = name;
param.id = name;
param.value = this.getFormValue(name);
return html.input(param);
param.name = name;
param.id = name;
param.value = this.getFormValue(name);
return html.input(param);
}
/**
@ -413,10 +413,10 @@ HopObject.prototype.input_macro = function(param, name) {
* @param {String} name
*/
HopObject.prototype.textarea_macro = function(param, name) {
param.name = name;
param.id = name;
param.value = this.getFormValue(name);
return html.textArea(param);
param.name = name;
param.id = name;
param.value = this.getFormValue(name);
return html.textArea(param);
}
/**
@ -425,13 +425,13 @@ HopObject.prototype.textarea_macro = function(param, name) {
* @param {String} name
*/
HopObject.prototype.select_macro = function(param, name) {
param.name = name;
param.id = name;
var options = this.getFormOptions(name);
if (options.length < 2) {
param.disabled = "disabled";
}
return html.dropDown(param, options, this.getFormValue(name));
param.name = name;
param.id = name;
var options = this.getFormOptions(name);
if (options.length < 2) {
param.disabled = "disabled";
}
return html.dropDown(param, options, this.getFormValue(name));
}
/**
@ -440,21 +440,21 @@ HopObject.prototype.select_macro = function(param, name) {
* @param {String} name
*/
HopObject.prototype.checkbox_macro = function(param, name) {
param.name = name;
param.id = name;
var options = this.getFormOptions(name);
if (options.length < 2) {
param.disabled = "disabled";
}
param.value = String((options[1] || options[0]).value);
param.selectedValue = String(this.getFormValue(name));
var label = param.label;
delete param.label;
html.checkBox(param);
if (label) {
html.element("label", label, {"for": name});
}
return;
param.name = name;
param.id = name;
var options = this.getFormOptions(name);
if (options.length < 2) {
param.disabled = "disabled";
}
param.value = String((options[1] || options[0]).value);
param.selectedValue = String(this.getFormValue(name));
var label = param.label;
delete param.label;
html.checkBox(param);
if (label) {
html.element("label", label, {"for": name});
}
return;
}
/**
@ -463,21 +463,21 @@ HopObject.prototype.checkbox_macro = function(param, name) {
* @param {String} name
*/
HopObject.prototype.radiobutton_macro = function(param, name) {
param.name = name;
param.id = name;
var options = this.getFormOptions(name);
if (options.length < 2) {
param.disabled = "disabled";
}
param.value = String(options[0].value);
param.selectedValue = String(this.getFormValue(name));
var label = param.label;
delete param.label;
html.radioButton(param);
if (label) {
html.element("label", label, {"for": name});
}
return;
param.name = name;
param.id = name;
var options = this.getFormOptions(name);
if (options.length < 2) {
param.disabled = "disabled";
}
param.value = String(options[0].value);
param.selectedValue = String(this.getFormValue(name));
var label = param.label;
delete param.label;
html.radioButton(param);
if (label) {
html.element("label", label, {"for": name});
}
return;
}
/**
@ -486,11 +486,11 @@ HopObject.prototype.radiobutton_macro = function(param, name) {
* @param {String} name
*/
HopObject.prototype.upload_macro = function(param, name) {
param.name = name;
param.id = name;
param.value = this.getFormValue(name);
renderSkin("$Global#upload", param);
return;
param.name = name;
param.id = name;
param.value = this.getFormValue(name);
renderSkin("$Global#upload", param);
return;
}
/**
@ -499,30 +499,30 @@ HopObject.prototype.upload_macro = function(param, name) {
* @param {HopObject} [handler]
*/
HopObject.prototype.macro_macro = function(param, handler) {
var ctor = this.constructor;
if ([Story, Image, File, Poll].indexOf(ctor) > -1) {
res.write('<span class="macro-code">');
res.encode("<% ");
res.write(handler || ctor.name.toLowerCase());
res.write(String.SPACE);
res.write(quote(this.name || this._id));
res.encode(" %>");
res.write('</span>');
}
return;
var ctor = this.constructor;
if ([Story, Image, File, Poll].indexOf(ctor) > -1) {
res.write('<span class="macro-code">');
res.encode("<% ");
res.write(handler || ctor.name.toLowerCase());
res.write(String.SPACE);
res.write(quote(this.name || this._id));
res.encode(" %>");
res.write('</span>');
}
return;
}
/**
*
*/
HopObject.prototype.kind_macro = function() {
var type = this.constructor.name.toLowerCase();
switch (type) {
default:
res.write(gettext(type));
break;
}
return;
var type = this.constructor.name.toLowerCase();
switch (type) {
default:
res.write(gettext(type));
break;
}
return;
}
/**
@ -531,19 +531,19 @@ HopObject.prototype.kind_macro = function() {
* @returns {Number|String}
*/
HopObject.prototype.getFormValue = function(name) {
if (req.isPost()) {
return req.postParams[name];
} else {
var value = this[name] || req.queryParams[name] || String.EMPTY;
return value instanceof HopObject ? value._id : value;
}
if (req.isPost()) {
return req.postParams[name];
} else {
var value = this[name] || req.queryParams[name] || String.EMPTY;
return value instanceof HopObject ? value._id : value;
}
}
/**
* @returns {Object[]}
*/
HopObject.prototype.getFormOptions = function() {
return [{value: true, display: "enabled"}];
return [{value: true, display: "enabled"}];
}
/**
@ -552,14 +552,14 @@ HopObject.prototype.getFormOptions = function() {
* @param {String} property
*/
HopObject.prototype.self_macro = function(param, property) {
return property ? this[property] : this;
return property ? this[property] : this;
}
/**
*
*/
HopObject.prototype.type_macro = function() {
return res.write(this.constructor.name);
return res.write(this.constructor.name);
}
/**
@ -569,15 +569,15 @@ HopObject.prototype.type_macro = function() {
* @param {String} text
*/
HopObject.prototype.link_macro = function(param, url, text) {
if (url && text) {
var action = url.split(/#|\?/)[0];
if (this.getPermission(action)) {
renderLink.call(global, param, url, text, this);
}
} else {
res.write("[Insufficient link parameters]");
}
return;
if (url && text) {
var action = url.split(/#|\?/)[0];
if (this.getPermission(action)) {
renderLink.call(global, param, url, text, this);
}
} else {
res.write("[Insufficient link parameters]");
}
return;
}
/**
@ -586,11 +586,11 @@ HopObject.prototype.link_macro = function(param, url, text) {
* @param {String} format
*/
HopObject.prototype.created_macro = function(param, format) {
if (this.isPersistent()) {
format || (format = param.format);
res.write(formatDate(this.created, format));
}
return;
if (this.isPersistent()) {
format || (format = param.format);
res.write(formatDate(this.created, format));
}
return;
}
/**
@ -599,11 +599,11 @@ HopObject.prototype.created_macro = function(param, format) {
* @param {String} format
*/
HopObject.prototype.modified_macro = function(param, format) {
if (this.isPersistent()) {
format || (format = param.format);
res.write(formatDate(this.modified, format));
}
return;
if (this.isPersistent()) {
format || (format = param.format);
res.write(formatDate(this.modified, format));
}
return;
}
/**
@ -612,17 +612,17 @@ HopObject.prototype.modified_macro = function(param, format) {
* @param {String} mode
*/
HopObject.prototype.creator_macro = function(param, mode) {
if (!this.creator || this.isTransient()) {
return;
}
mode || (mode = param.as);
if (mode === "link" && this.creator.url) {
html.link({href: this.creator.url}, this.creator.name);
} else if (mode === "url") {
res.write(this.creator.url);
} else {
res.write(this.creator.name);
} return;
if (!this.creator || this.isTransient()) {
return;
}
mode || (mode = param.as);
if (mode === "link" && this.creator.url) {
html.link({href: this.creator.url}, this.creator.name);
} else if (mode === "url") {
res.write(this.creator.url);
} else {
res.write(this.creator.name);
} return;
}
/**
@ -631,32 +631,32 @@ HopObject.prototype.creator_macro = function(param, mode) {
* @param {String} mode
*/
HopObject.prototype.modifier_macro = function(param, mode) {
if (!this.modifier || this.isTransient()) {
return;
}
mode || (mode = param.as);
if (mode === "link" && this.modifier.url) {
html.link({href: this.modifier.url}, this.modifier.name);
} else if (mode === "url") {
res.write(this.modifier.url);
} else {
res.write(this.modifier.name);
}
return;
if (!this.modifier || this.isTransient()) {
return;
}
mode || (mode = param.as);
if (mode === "link" && this.modifier.url) {
html.link({href: this.modifier.url}, this.modifier.name);
} else if (mode === "url") {
res.write(this.modifier.url);
} else {
res.write(this.modifier.name);
}
return;
}
/**
* @returns {String}
*/
HopObject.prototype.getTitle = function() {
return this.title || gettext(this.__name__.capitalize());
return this.title || gettext(this.__name__.capitalize());
}
/**
* @returns {String}
*/
HopObject.prototype.toString = function() {
return this.constructor.name + " #" + this._id;
return this.constructor.name + " #" + this._id;
}
/**
@ -667,8 +667,8 @@ HopObject.prototype.toString = function() {
* @returns {String}
*/
HopObject.prototype.link_filter = function(text, param, action) {
action || (action = ".");
res.push();
renderLink(param, action, text, this);
return res.pop();
action || (action = ".");
res.push();
renderLink(param, action, text, this);
return res.pop();
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -33,20 +33,20 @@
* @param {String} name
*/
HopObject.prototype.handleMetadata = function(name) {
this.__defineGetter__(name, function() {
return this.getMetadata(name);
});
this.__defineSetter__(name, function(value) {
return this.setMetadata(name, value);
});
this[name + "_macro"] = function(param) {
var value;
if (value = this[name]) {
res.write(value);
}
return;
};
return;
this.__defineGetter__(name, function() {
return this.getMetadata(name);
});
this.__defineSetter__(name, function(value) {
return this.setMetadata(name, value);
});
this[name + "_macro"] = function(param) {
var value;
if (value = this[name]) {
res.write(value);
}
return;
};
return;
}
/**
@ -55,31 +55,31 @@ HopObject.prototype.handleMetadata = function(name) {
* @returns {Object}
*/
HopObject.prototype.getMetadata = function(name) {
if (!this.metadata) {
throw Error("No metadata collection defined for prototype " + this.constructor.name);
} else {
this.metadata.prefetchChildren();
}
if (!this.metadata) {
throw Error("No metadata collection defined for prototype " + this.constructor.name);
} else {
this.metadata.prefetchChildren();
}
var self = this;
var self = this;
if (!name) {
var result = {};
this.metadata.forEach(function() {
var name = this.name;
if (name) {
result[name] = self.getMetadata(name);
}
});
return result;
}
if (!name) {
var result = {};
this.metadata.forEach(function() {
var name = this.name;
if (name) {
result[name] = self.getMetadata(name);
}
});
return result;
}
var meta = this.metadata.get(name);
if (!meta) {
return null;
}
var meta = this.metadata.get(name);
if (!meta) {
return null;
}
return meta.getValue();
return meta.getValue();
}
/**
@ -88,33 +88,33 @@ HopObject.prototype.getMetadata = function(name) {
* @param {Object} value
*/
HopObject.prototype.setMetadata = function(name, value) {
if (!this.metadata) {
throw Error("No metadata collection defined for prototype " + this.constructor.name);
}
if (!this.metadata) {
throw Error("No metadata collection defined for prototype " + this.constructor.name);
}
if (!name) {
throw Error("Insufficient arguments");
}
if (!name) {
throw Error("Insufficient arguments");
}
if (typeof name === "object") {
for (var i in name) {
this.setMetadata(i, name[i]);
}
return;
}
if (typeof name === "object") {
for (var i in name) {
this.setMetadata(i, name[i]);
}
return;
}
var metadata = this.metadata.get(name);
var metadata = this.metadata.get(name);
if (metadata) {
metadata.setValue(value);
} else {
metadata = new Metadata(this, name, value);
if (metadata.value !== null) {
// metadata.persist() is not enough or there will be redundant records!
this.metadata.add(metadata);
}
}
return;
if (metadata) {
metadata.setValue(value);
} else {
metadata = new Metadata(this, name, value);
if (metadata.value !== null) {
// metadata.persist() is not enough or there will be redundant records!
this.metadata.add(metadata);
}
}
return;
}
/**
@ -122,22 +122,22 @@ HopObject.prototype.setMetadata = function(name, value) {
* @param {String} name
*/
HopObject.prototype.deleteMetadata = function(name) {
if (!this.metadata) {
throw Error("No metadata collection defined for prototype " + this.constructor.name);
}
if (!this.metadata) {
throw Error("No metadata collection defined for prototype " + this.constructor.name);
}
var self = this;
var self = this;
if (arguments.length === 0) {
return HopObject.remove.call(this.metadata);
}
if (arguments.length === 0) {
return HopObject.remove.call(this.metadata);
}
Array.prototype.forEach.call(arguments, function(name) {
var metadata = self.metadata.get(name);
metadata && metadata.remove();
return;
});
return;
Array.prototype.forEach.call(arguments, function(name) {
var metadata = self.metadata.get(name);
metadata && metadata.remove();
return;
});
return;
}
/**
@ -146,7 +146,7 @@ HopObject.prototype.deleteMetadata = function(name) {
* @param {String} name
*/
HopObject.prototype.metadata_macro = function(param, name) {
var value = this.getMetadata(name);
value && res.write(value);
return;
var value = this.getMetadata(name);
value && res.write(value);
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -46,8 +46,8 @@ Image.THUMBNAILWIDTH = 100;
/** @constant */
Image.KEYS = ["name", "created", "modified", "origin", "description",
"contentType", "contentLength", "width", "height", "thumbnailName",
"thumbnailWidth", "thumbnailHeight", "fileName", "site"];
"contentType", "contentLength", "width", "height", "thumbnailName",
"thumbnailWidth", "thumbnailHeight", "fileName", "site"];
/**
* @param {Object} data
@ -56,34 +56,34 @@ Image.KEYS = ["name", "created", "modified", "origin", "description",
* @returns {Image}
*/
Image.add = function(data, parent, user) {
HopObject.confirmConstructor(Image);
parent || (parent = res.handlers.site);
user || (user = session.user);
var image = new Image;
if (data) {
for each (var key in Image.KEYS) {
image[key] = data[key];
}
}
image.parent = parent;
image.created = image.modified = new Date;
image.creator = image.modifier = user;
image.update(data);
parent.images.add(image);
return image;
HopObject.confirmConstructor(Image);
parent || (parent = res.handlers.site);
user || (user = session.user);
var image = new Image;
if (data) {
for each (var key in Image.KEYS) {
image[key] = data[key];
}
}
image.parent = parent;
image.created = image.modified = new Date;
image.creator = image.modifier = user;
image.update(data);
parent.images.add(image);
return image;
}
/**
*
*/
Image.remove = function() {
if (this.constructor === Image) {
this.removeFiles();
this.setTags(null);
this.deleteMetadata();
this.remove();
}
return;
if (this.constructor === Image) {
this.removeFiles();
this.setTags(null);
this.deleteMetadata();
this.remove();
}
return;
}
/**
@ -92,25 +92,25 @@ Image.remove = function() {
* @returns {String}
*/
Image.getFileExtension = function(type) {
type = String(type);
// Sometimes type is like "image/jpeg;charset=ISO-8859-1"
var index = type.lastIndexOf(";");
if (index > -1) {
type = type.substr(0, index);
}
switch (type) {
//case "image/x-icon":
//return ".ico";
case "image/gif":
return ".gif";
case "image/jpeg":
case "image/pjpeg":
return ".jpg";
case "image/png":
case "image/x-png":
return ".png";
}
return null;
type = String(type);
// Sometimes type is like "image/jpeg;charset=ISO-8859-1"
var index = type.lastIndexOf(";");
if (index > -1) {
type = type.substr(0, index);
}
switch (type) {
//case "image/x-icon":
//return ".ico";
case "image/gif":
return ".gif";
case "image/jpeg":
case "image/pjpeg":
return ".jpg";
case "image/png":
case "image/x-png":
return ".png";
}
return null;
}
/**
@ -141,8 +141,8 @@ Image.getFileExtension = function(type) {
* @extends HopObject
*/
Image.prototype.constructor = function(data) {
HopObject.confirmConstructor.call(this);
return this;
HopObject.confirmConstructor.call(this);
return this;
}
/**
@ -151,23 +151,23 @@ Image.prototype.constructor = function(data) {
* @return {Boolean}
*/
Image.prototype.getPermission = function(action) {
var defaultGrant = this._parent.getPermission("main");
switch (action) {
case ".":
case "main":
return true;
case "delete":
return defaultGrant && this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
case "edit":
return defaultGrant && this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED) &&
this.parent_type !== "Layout" ||
this.parent === path.layout;
}
return false;
var defaultGrant = this._parent.getPermission("main");
switch (action) {
case ".":
case "main":
return true;
case "delete":
return defaultGrant && this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
case "edit":
return defaultGrant && this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED) &&
this.parent_type !== "Layout" ||
this.parent === path.layout;
}
return false;
}
/**
@ -176,43 +176,43 @@ Image.prototype.getPermission = function(action) {
* @returns {String}
*/
Image.prototype.href = function(action) {
if (action !== "replace") {
if (this.parent_type === "Layout" && this.parent !== path.layout) {
return this.getUrl();
}
} else {
return res.handlers.images.href("create") + "?name=" + this.name;
}
return HopObject.prototype.href.apply(this, arguments);
if (action !== "replace") {
if (this.parent_type === "Layout" && this.parent !== path.layout) {
return this.getUrl();
}
} else {
return res.handlers.images.href("create") + "?name=" + this.name;
}
return HopObject.prototype.href.apply(this, arguments);
}
Image.prototype.main_action = function() {
res.data.title = gettext("Image: {0}", this.getTitle());
res.data.body = this.renderSkinAsString("Image#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Image: {0}", this.getTitle());
res.data.body = this.renderSkinAsString("Image#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Image.prototype.edit_action = function() {
File.redirectOnUploadError(this.href(req.action));
File.redirectOnUploadError(this.href(req.action));
if (req.postParams.save) {
try {
File.redirectOnExceededQuota(this.href(req.action));
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
if (req.postParams.save) {
try {
File.redirectOnExceededQuota(this.href(req.action));
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Image");
res.data.body = this.renderSkinAsString("$Image#edit");
res.handlers.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Image");
res.data.body = this.renderSkinAsString("$Image#edit");
res.handlers.site.renderSkin("Site#page");
return;
}
/**
@ -221,32 +221,32 @@ Image.prototype.edit_action = function() {
* @returns {Object}
*/
Image.prototype.getFormValue = function(name) {
var self = this;
var self = this;
var getOrigin = function(str) {
var origin = req.postParams.file_origin || self.origin;
if (origin && origin.contains("://")) {
return origin;
}
return null;
}
var getOrigin = function(str) {
var origin = req.postParams.file_origin || self.origin;
if (origin && origin.contains("://")) {
return origin;
}
return null;
}
if (req.isPost()) {
if (name === "file") {
return getOrigin();
}
return req.postParams[name];
}
switch (name) {
case "file":
if (req.isPost()) {
if (name === "file") {
return getOrigin();
case "maxWidth":
case "maxHeight":
return this[name] || 400;
case "tags":
return this.getTags();
}
return this[name] || req.queryParams[name];
}
return req.postParams[name];
}
switch (name) {
case "file":
return getOrigin();
case "maxWidth":
case "maxHeight":
return this[name] || 400;
case "tags":
return this.getTags();
}
return this[name] || req.queryParams[name];
}
/**
@ -254,102 +254,102 @@ Image.prototype.getFormValue = function(name) {
* @param {Object} data
*/
Image.prototype.update = function(data) {
var origin = data.file_origin;
var origin = data.file_origin;
if (!origin) {
if (this.isTransient()) {
throw Error(gettext("There was nothing to upload. Please be sure to choose a file."));
}
} else if (origin !== this.origin) {
var mime = data.file;
// Check if mime is not null to allow post requests with no file upload at all
if (!mime || mime.contentLength < 1) {
mime = getURL(origin);
if (!mime) {
throw Error(gettext("Could not fetch the image from the given URL."));
}
if (!origin) {
if (this.isTransient()) {
throw Error(gettext("There was nothing to upload. Please be sure to choose a file."));
}
} else if (origin !== this.origin) {
var mime = data.file;
// Check if mime is not null to allow post requests with no file upload at all
if (!mime || mime.contentLength < 1) {
mime = getURL(origin);
if (!mime) {
throw Error(gettext("Could not fetch the image from the given URL."));
}
}
var extension = Image.getFileExtension(mime.contentType);
if (!extension) {
throw Error(gettext("This does not seem to be a (valid) JPG, PNG or GIF image file."));
}
var extension = Image.getFileExtension(mime.contentType);
if (!extension) {
throw Error(gettext("This does not seem to be a (valid) JPG, PNG or GIF image file."));
}
this.origin = origin;
var mimeName = mime.normalizeFilename(mime.name);
this.contentLength = mime.contentLength;
this.contentType = mime.contentType;
this.origin = origin;
var mimeName = mime.normalizeFilename(mime.name);
this.contentLength = mime.contentLength;
this.contentType = mime.contentType;
if (!this.name) {
var name = File.getName(data.name) || mimeName.split(".")[0];
this.name = this.parent.images.getAccessName(name);
}
if (!this.name) {
var name = File.getName(data.name) || mimeName.split(".")[0];
this.name = this.parent.images.getAccessName(name);
}
var image = this.getConstraint(mime, data.maxWidth, data.maxHeight);
this.height = image.height;
this.width = image.width;
var image = this.getConstraint(mime, data.maxWidth, data.maxHeight);
this.height = image.height;
this.width = image.width;
var thumbnail;
if (image.width > Image.THUMBNAILWIDTH) {
thumbnail = this.getConstraint(mime, Image.THUMBNAILWIDTH);
this.thumbnailWidth = thumbnail.width;
this.thumbnailHeight = thumbnail.height;
} else if (this.isPersistent()) {
this.getThumbnailFile().remove();
// NOTE: delete operator won't work here due to getter/setter methods
this.deleteMetadata("thumbnailName", "thumbnailWidth", "thumbnailHeight");
}
var thumbnail;
if (image.width > Image.THUMBNAILWIDTH) {
thumbnail = this.getConstraint(mime, Image.THUMBNAILWIDTH);
this.thumbnailWidth = thumbnail.width;
this.thumbnailHeight = thumbnail.height;
} else if (this.isPersistent()) {
this.getThumbnailFile().remove();
// NOTE: delete operator won't work here due to getter/setter methods
this.deleteMetadata("thumbnailName", "thumbnailWidth", "thumbnailHeight");
}
// Make the image persistent before proceeding with writing files and
// setting tags (also see Helma bug #607)
this.isTransient() && this.persist();
// Make the image persistent before proceeding with writing files and
// setting tags (also see Helma bug #607)
this.isTransient() && this.persist();
var fileName = this.name + extension;
if (fileName !== this.fileName) {
// Remove existing image files if the file name has changed
this.removeFiles();
}
this.fileName = fileName;
thumbnail && (this.thumbnailName = this.name + "_small" + extension);
this.writeFiles(image.resized || mime, thumbnail && thumbnail.resized);
image.resized && (this.contentLength = this.getFile().getLength());
}
var fileName = this.name + extension;
if (fileName !== this.fileName) {
// Remove existing image files if the file name has changed
this.removeFiles();
}
this.fileName = fileName;
thumbnail && (this.thumbnailName = this.name + "_small" + extension);
this.writeFiles(image.resized || mime, thumbnail && thumbnail.resized);
image.resized && (this.contentLength = this.getFile().getLength());
}
if (this.parent_type !== "Layout") {
this.setTags(data.tags || data.tag_array);
}
this.description = data.description;
this.touch();
return;
if (this.parent_type !== "Layout") {
this.setTags(data.tags || data.tag_array);
}
this.description = data.description;
this.touch();
return;
}
/**
*
*/
Image.prototype.tags_macro = function() {
return res.write(this.getFormValue("tags"));
return res.write(this.getFormValue("tags"));
}
/**
*
*/
Image.prototype.contentLength_macro = function() {
return res.write((this.contentLength / 1024).format("###,###") + " KB");
return res.write((this.contentLength / 1024).format("###,###") + " KB");
}
/**
*
*/
Image.prototype.url_macro = function() {
return res.write(this.getUrl());
return res.write(this.getUrl());
}
/**
*
*/
Image.prototype.macro_macro = function() {
return HopObject.prototype.macro_macro.call(this, null,
this.parent.constructor === Layout ? "layout.image" : "image");
return HopObject.prototype.macro_macro.call(this, null,
this.parent.constructor === Layout ? "layout.image" : "image");
}
/**
@ -357,17 +357,17 @@ Image.prototype.macro_macro = function() {
* @param {Object} param
*/
Image.prototype.thumbnail_macro = function(param) {
if (!this.thumbnailName) {
return this.render_macro(param);
}
param.src = this.getUrl(this.getThumbnailFile().getName());
param.title || (param.title = encode(this.description));
param.alt = encode(param.alt || param.title);
param.width = this.thumbnailWidth || String.EMPTY;
param.height = this.thumbnailHeight || String.EMPTY;
param.border = (param.border = 0);
html.tag("img", param);
return;
if (!this.thumbnailName) {
return this.render_macro(param);
}
param.src = this.getUrl(this.getThumbnailFile().getName());
param.title || (param.title = encode(this.description));
param.alt = encode(param.alt || param.title);
param.width = this.thumbnailWidth || String.EMPTY;
param.height = this.thumbnailHeight || String.EMPTY;
param.border = (param.border = 0);
html.tag("img", param);
return;
}
/**
@ -375,14 +375,14 @@ Image.prototype.thumbnail_macro = function(param) {
* @param {Object} param
*/
Image.prototype.render_macro = function(param) {
param.src = this.getUrl();
param.title || (param.title = encode(this.description));
param.alt = encode(param.alt || param.title);
param.width || (param.width = this.width);
param.height || (param.height = this.height);
param.border || (param.border = 0);
html.tag("img", param);
return;
param.src = this.getUrl();
param.title || (param.title = encode(this.description));
param.alt = encode(param.alt || param.title);
param.width || (param.width = this.width);
param.height || (param.height = this.height);
param.border || (param.border = 0);
html.tag("img", param);
return;
}
/**
@ -392,13 +392,13 @@ Image.prototype.render_macro = function(param) {
* @see Site#getStaticFile
*/
Image.prototype.getFile = function(name) {
name || (name = this.fileName);
if (this.parent_type === "Layout") {
var layout = this.parent || res.handlers.layout;
return layout.getFile(name);
}
var site = this.parent || res.handlers.site;
return site.getStaticFile("images/" + name);
name || (name = this.fileName);
if (this.parent_type === "Layout") {
var layout = this.parent || res.handlers.layout;
return layout.getFile(name);
}
var site = this.parent || res.handlers.site;
return site.getStaticFile("images/" + name);
}
/**
@ -408,42 +408,42 @@ Image.prototype.getFile = function(name) {
* @see Site#getStaticUrl
*/
Image.prototype.getUrl = function(name) {
name || (name = this.fileName);
if (this.parent_type === "Layout") {
var layout = this.parent || res.handlers.layout;
return layout.site.getStaticUrl('layout/' + name);
}
var site = this.parent || res.handlers.site;
return site.getStaticUrl("images/" + name);
name || (name = this.fileName);
if (this.parent_type === "Layout") {
var layout = this.parent || res.handlers.layout;
return layout.site.getStaticUrl('layout/' + name);
}
var site = this.parent || res.handlers.site;
return site.getStaticUrl("images/" + name);
}
/**
* @returns {helma.File}
*/
Image.prototype.getThumbnailFile = function() {
return this.getFile(this.thumbnailName);
return this.getFile(this.thumbnailName);
}
/**
* @returns {String}
*/
Image.prototype.getJSON = function() {
return {
name: this.name,
origin: this.origin,
description: this.description,
contentType: this.contentType,
contentLength: this.contentLength,
width: this.width,
height: this.height,
thumbnailName: this.thumbnailName,
thumbnailWidth: this.thumbnailWidth,
thumbnailHeight: this.thumbnailHeight,
created: this.created,
creator: this.creator ? this.creator.name : null,
modified: this.modified,
modifier: this.modifier ? this.modifier.name : null,
}.toSource();
return {
name: this.name,
origin: this.origin,
description: this.description,
contentType: this.contentType,
contentLength: this.contentLength,
width: this.width,
height: this.height,
thumbnailName: this.thumbnailName,
thumbnailWidth: this.thumbnailWidth,
thumbnailHeight: this.thumbnailHeight,
created: this.created,
creator: this.creator ? this.creator.name : null,
modified: this.modified,
modifier: this.modifier ? this.modifier.name : null,
}.toSource();
}
/**
@ -455,31 +455,31 @@ Image.prototype.getJSON = function() {
* @returns {Object}
*/
Image.prototype.getConstraint = function(mime, maxWidth, maxHeight) {
try {
var image = new helma.Image(mime.inputStream);
var factorH = 1, factorV = 1;
if (maxWidth && image.width > maxWidth) {
factorH = maxWidth / image.width;
try {
var image = new helma.Image(mime.inputStream);
var factorH = 1, factorV = 1;
if (maxWidth && image.width > maxWidth) {
factorH = maxWidth / image.width;
}
if (maxHeight && image.height > maxHeight) {
factorV = maxHeight / image.height;
}
if (factorH !== 1 || factorV !== 1) {
var width = Math.ceil(image.width *
(factorH < factorV ? factorH : factorV));
var height = Math.ceil(image.height *
(factorH < factorV ? factorH : factorV));
image.resize(width, height);
if (mime.contentType.endsWith("gif")) {
image.reduceColors(256);
}
if (maxHeight && image.height > maxHeight) {
factorV = maxHeight / image.height;
}
if (factorH !== 1 || factorV !== 1) {
var width = Math.ceil(image.width *
(factorH < factorV ? factorH : factorV));
var height = Math.ceil(image.height *
(factorH < factorV ? factorH : factorV));
image.resize(width, height);
if (mime.contentType.endsWith("gif")) {
image.reduceColors(256);
}
return {resized: image, width: image.width, height: image.height};
}
return {width: image.width, height: image.height};
} catch (ex) {
app.log(ex);
throw Error(gettext("Could not resize the image."));
}
return {resized: image, width: image.width, height: image.height};
}
return {width: image.width, height: image.height};
} catch (ex) {
app.log(ex);
throw Error(gettext("Could not resize the image."));
}
}
/**
@ -489,47 +489,47 @@ Image.prototype.getConstraint = function(mime, maxWidth, maxHeight) {
* @throws {Error}
*/
Image.prototype.writeFiles = function(data, thumbnail) {
if (data) {
try {
// If data is a MimeObject (ie. has the writeToFile method)
// the image was not resized and thus, we directly write it to disk
var file = this.getFile();
if (data.saveAs) {
data.saveAs(file);
} else if (data.writeToFile) {
data.writeToFile(file.getParent(), file.getName());
}
if (thumbnail) {
thumbnail.saveAs(this.getThumbnailFile());
}
} catch (ex) {
app.log(ex);
throw Error(gettext("Could not save the image file on disk."));
if (data) {
try {
// If data is a MimeObject (ie. has the writeToFile method)
// the image was not resized and thus, we directly write it to disk
var file = this.getFile();
if (data.saveAs) {
data.saveAs(file);
} else if (data.writeToFile) {
data.writeToFile(file.getParent(), file.getName());
}
}
return;
if (thumbnail) {
thumbnail.saveAs(this.getThumbnailFile());
}
} catch (ex) {
app.log(ex);
throw Error(gettext("Could not save the image file on disk."));
}
}
return;
}
/**
* @throws {Error}
*/
Image.prototype.removeFiles = function() {
try {
this.getFile().remove();
var thumbnail = this.getThumbnailFile();
if (thumbnail) {
thumbnail.remove();
}
} catch (ex) {
app.log(ex);
throw Error(gettext("Could not remove the image file from disk."));
}
return;
try {
this.getFile().remove();
var thumbnail = this.getThumbnailFile();
if (thumbnail) {
thumbnail.remove();
}
} catch (ex) {
app.log(ex);
throw Error(gettext("Could not remove the image file from disk."));
}
return;
}
/**
* @returns {String}
*/
Image.prototype.getConfirmText = function() {
return gettext("You are about to delete the image {0}.", this.name);
return gettext("You are about to delete the image {0}.", this.name);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -46,86 +46,86 @@ markgettext("images");
* @returns {Boolean}
*/
Images.prototype.getPermission = function(action) {
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
// FIXME: case "tags":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
return this._parent.constructor !== Layout &&
(Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED));
}
return false;
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
// FIXME: case "tags":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
return this._parent.constructor !== Layout &&
(Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED));
}
return false;
}
Images.prototype.main_action = function() {
var images, skin;
switch (this._parent.constructor) {
case Root:
case Site:
images = User.getMembership().images;
skin = "$Images#main";
res.data.title = gettext("Member Images");
break;
var images, skin;
switch (this._parent.constructor) {
case Root:
case Site:
images = User.getMembership().images;
skin = "$Images#main";
res.data.title = gettext("Member Images");
break;
case Layout:
images = res.handlers.layout.images;
skin = "$Images#layout";
res.data.title = gettext("Layout Images");
break;
}
res.data.list = renderList(images, "$Image#listItem",
10, req.queryParams.page);
res.data.pager = renderPager(images,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString(skin);
res.handlers.site.renderSkin("Site#page");
return;
case Layout:
images = res.handlers.layout.images;
skin = "$Images#layout";
res.data.title = gettext("Layout Images");
break;
}
res.data.list = renderList(images, "$Image#listItem",
10, req.queryParams.page);
res.data.pager = renderPager(images,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString(skin);
res.handlers.site.renderSkin("Site#page");
return;
}
Images.prototype.create_action = function() {
File.redirectOnUploadError(this.href(req.action));
File.redirectOnExceededQuota(this.href());
File.redirectOnUploadError(this.href(req.action));
File.redirectOnExceededQuota(this.href());
if (req.data.save) {
try {
var image = Image.add(req.params, this._parent);
image.notify(req.action);
JSON.sendPaddedResponse(image._id);
res.message = gettext('The image was successfully added.');
res.redirect(image.href());
} catch (ex) {
JSON.sendPaddedResponse(null);
res.status = 400;
res.message = ex.toString();
app.log(ex);
}
}
if (req.data.save) {
try {
var image = Image.add(req.params, this._parent);
image.notify(req.action);
JSON.sendPaddedResponse(image._id);
res.message = gettext('The image was successfully added.');
res.redirect(image.href());
} catch (ex) {
JSON.sendPaddedResponse(null);
res.status = 400;
res.message = ex.toString();
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Add Image");
HopObject.confirmConstructor(Image);
res.data.body = (new Image).renderSkinAsString("$Image#edit");
res.handlers.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext("Add Image");
HopObject.confirmConstructor(Image);
res.data.body = (new Image).renderSkinAsString("$Image#edit");
res.handlers.site.renderSkin("Site#page");
return;
}
Images.prototype.all_action = function() {
res.data.pager = renderPager(this, this.href(req.action),
10, req.queryParams.page);
res.data.list = renderList(this, "$Image#listItem",
10, req.queryParams.page);
res.data.title = gettext("All Images");
res.data.body = this.renderSkinAsString("$Images#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.pager = renderPager(this, this.href(req.action),
10, req.queryParams.page);
res.data.list = renderList(this, "$Image#listItem",
10, req.queryParams.page);
res.data.title = gettext("All Images");
res.data.body = this.renderSkinAsString("$Images#main");
res.handlers.site.renderSkin("Site#page");
return;
}
/**
@ -133,70 +133,70 @@ Images.prototype.all_action = function() {
* @field
*/
Images.Default = new function() {
var Image = function(name, description) {
var dir = new helma.File(app.appsProperties['static'], "www");
var image = new helma.Image(new helma.File(dir, name));
this.__defineGetter__('parent', function() {return root});
this.name = this.fileName = name;
this.description = description;
this.width = image.width;
this.height = image.height;
this.getUrl = function() {
// Cannot use global.Image.getUrl() here because these images are
// located in the top-level of the static directory.
return root.getStaticUrl(name);
}
this.render_macro = global.Image.prototype.render_macro;
this.thumbnail_macro = global.Image.prototype.thumbnail_macro;
return this;
}
var Image = function(name, description) {
var dir = new helma.File(app.appsProperties['static'], "www");
var image = new helma.Image(new helma.File(dir, name));
this.__defineGetter__('parent', function() {return root});
this.name = this.fileName = name;
this.description = description;
this.width = image.width;
this.height = image.height;
this.getUrl = function() {
// Cannot use global.Image.getUrl() here because these images are
// located in the top-level of the static directory.
return root.getStaticUrl(name);
}
this.render_macro = global.Image.prototype.render_macro;
this.thumbnail_macro = global.Image.prototype.thumbnail_macro;
return this;
}
var images = {};
var add = function(name, description) {
images[name] = new Image(name, description);
return;
}
var images = {};
var add = function(name, description) {
images[name] = new Image(name, description);
return;
}
add("ant.png", "Ant");
add("ant-icon.png", "Tiny Ant");
add("big.gif", String.EMPTY);
add("bullet.gif", "*");
add("dot.gif", String.EMPTY);
add("headbg.gif", String.EMPTY);
add("helma.png", "Helma Object Publisher");
add("hop.gif", "Helma Object Publisher");
add("manage.gif", "manage");
add("marquee.gif", String.EMPTY);
add("menu.gif", "menu");
add("pixel.gif", String.EMPTY);
add("recent.gif", "recent");
add("rss.png", "RSS feed");
add("smallanim.gif", "Made with Antville");
add("smallchaos.gif", "Made with Antville");
add("smallstraight.gif", "Made with Antville");
add("smalltrans.gif", "Made with Antville");
add("status.gif", "status");
add("webloghead.gif", "Antville");
add("xmlbutton.gif", "XML version of this page");
return images;
add("ant.png", "Ant");
add("ant-icon.png", "Tiny Ant");
add("big.gif", String.EMPTY);
add("bullet.gif", "*");
add("dot.gif", String.EMPTY);
add("headbg.gif", String.EMPTY);
add("helma.png", "Helma Object Publisher");
add("hop.gif", "Helma Object Publisher");
add("manage.gif", "manage");
add("marquee.gif", String.EMPTY);
add("menu.gif", "menu");
add("pixel.gif", String.EMPTY);
add("recent.gif", "recent");
add("rss.png", "RSS feed");
add("smallanim.gif", "Made with Antville");
add("smallchaos.gif", "Made with Antville");
add("smallstraight.gif", "Made with Antville");
add("smalltrans.gif", "Made with Antville");
add("status.gif", "status");
add("webloghead.gif", "Antville");
add("xmlbutton.gif", "XML version of this page");
return images;
}
/**
* @returns {Image[]}
*/
Images.prototype.mergeImages = function() {
var images = [];
var layout = this._parent;
while (layout) {
layout.images.forEach(function() {
if (images.indexOf(this) < 0) {
images.push(this);
}
return;
});
layout = layout.parent;
}
return images.sort(Number.Sorter("created", Number.Sorter.DESC));
var images = [];
var layout = this._parent;
while (layout) {
layout.images.forEach(function() {
if (images.indexOf(this) < 0) {
images.push(this);
}
return;
});
layout = layout.parent;
}
return images.sort(Number.Sorter("created", Number.Sorter.DESC));
}
/**
@ -206,5 +206,5 @@ Images.prototype.mergeImages = function() {
* @see Site#getTags
*/
Images.prototype.getTags = function(group) {
return this._parent.getTags("galleries", group);
return this._parent.getTags("galleries", group);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -32,19 +32,19 @@ markgettext("layout");
/** @constant */
Layout.VALUES = [
"background color",
"link color",
"active link color",
"visited link color",
"big font",
"big font size",
"big font color",
"base font",
"base font size",
"base font color",
"small font",
"small font size",
"small font color"
"background color",
"link color",
"active link color",
"visited link color",
"big font",
"big font size",
"big font color",
"base font",
"base font size",
"base font color",
"small font",
"small font size",
"small font color"
];
/**
@ -53,16 +53,16 @@ Layout.VALUES = [
* @returns {Layout}
*/
Layout.add = function(site, user) {
HopObject.confirmConstructor(Layout);
var layout = new Layout;
layout.site = site;
layout.creator = user || session.user;
layout.created = new Date;
layout.mode = Layout.DEFAULT;
layout.reset();
layout.touch();
site.layout = layout;
return layout
HopObject.confirmConstructor(Layout);
var layout = new Layout;
layout.site = site;
layout.creator = user || session.user;
layout.created = new Date;
layout.mode = Layout.DEFAULT;
layout.reset();
layout.touch();
site.layout = layout;
return layout
}
/**
@ -71,26 +71,26 @@ Layout.add = function(site, user) {
* @param {Boolean} includeSelf
*/
Layout.remove = function(options) {
if (this.constructor === Layout) {
// Backup current layout in temporary directory if possible
var dir = this.getFile();
// FIXME: Evaluate if using res.skinpath is necessary; dir could be fully sufficient.
if (res.skinpath && res.skinpath[0] && res.skinpath[0].equals(dir) &&
dir.exists() && dir.list().length > 0) {
var zip = this.getArchive(res.skinpath);
var file = java.io.File.createTempFile(this.site.name + "-layout-", ".zip");
zip.save(file);
}
HopObject.remove.call(this.skins);
HopObject.remove.call(this.images);
this.getFile().removeDirectory();
// The “force” flag is set e.g. when a whole site is removed
if (options && options.force) {
this.deleteMetadata();
this.remove();
}
}
return;
if (this.constructor === Layout) {
// Backup current layout in temporary directory if possible
var dir = this.getFile();
// FIXME: Evaluate if using res.skinpath is necessary; dir could be fully sufficient.
if (res.skinpath && res.skinpath[0] && res.skinpath[0].equals(dir) &&
dir.exists() && dir.list().length > 0) {
var zip = this.getArchive(res.skinpath);
var file = java.io.File.createTempFile(this.site.name + "-layout-", ".zip");
zip.save(file);
}
HopObject.remove.call(this.skins);
HopObject.remove.call(this.images);
this.getFile().removeDirectory();
// The “force” flag is set e.g. when a whole site is removed
if (options && options.force) {
this.deleteMetadata();
this.remove();
}
}
return;
}
/**
@ -99,16 +99,16 @@ Layout.remove = function(options) {
* @returns {Boolean}
*/
Layout.sandbox = function(value) {
var cookie = User.COOKIE + 'LayoutSandbox';
if (typeof value === 'undefined') {
return req.cookies[cookie] === 'true';
}
if (value === true) {
res.setCookie(cookie, true);
} else if (value === false) {
res.unsetCookie(cookie);
}
return value;
var cookie = User.COOKIE + 'LayoutSandbox';
if (typeof value === 'undefined') {
return req.cookies[cookie] === 'true';
}
if (value === true) {
res.setCookie(cookie, true);
} else if (value === false) {
res.unsetCookie(cookie);
}
return value;
}
/**
@ -140,8 +140,8 @@ this.handleMetadata("originated");
* @extends HopObject
*/
Layout.prototype.constructor = function() {
HopObject.confirmConstructor.call(this);
return this;
HopObject.confirmConstructor.call(this);
return this;
}
/**
@ -150,20 +150,20 @@ Layout.prototype.constructor = function() {
* @returns {Boolean}
*/
Layout.prototype.getPermission = function(action) {
switch (action) {
case ".":
case "main":
case "export":
case "images":
case "import":
case "reset":
case "skins":
case "sandbox":
return res.handlers.site.getPermission("main") &&
Membership.require(Membership.OWNER) ||
User.require(User.PRIVILEGED);
}
return false;
switch (action) {
case ".":
case "main":
case "export":
case "images":
case "import":
case "reset":
case "skins":
case "sandbox":
return res.handlers.site.getPermission("main") &&
Membership.require(Membership.OWNER) ||
User.require(User.PRIVILEGED);
}
return false;
}
// FIXME: The Layout.href method is overwritten to guarantee that
@ -174,28 +174,28 @@ Layout.prototype.getPermission = function(action) {
* @returns {String}
*/
Layout.prototype.href = function(action) {
res.push();
res.write(res.handlers.site.href());
res.write("layout/");
action && res.write(action);
return res.pop();
res.push();
res.write(res.handlers.site.href());
res.write("layout/");
action && res.write(action);
return res.pop();
}
Layout.prototype.main_action = function() {
if (req.postParams.save) {
try {
this.update(req.postParams);
res.message = gettext("Successfully updated the layout.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.title = gettext("Layout");
res.data.body = this.renderSkinAsString("$Layout#main");
res.handlers.site.renderSkin("Site#page");
return;
if (req.postParams.save) {
try {
this.update(req.postParams);
res.message = gettext("Successfully updated the layout.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.title = gettext("Layout");
res.data.body = this.renderSkinAsString("$Layout#main");
res.handlers.site.renderSkin("Site#page");
return;
}
/**
@ -204,12 +204,12 @@ Layout.prototype.main_action = function() {
* @returns {Object}
*/
Layout.prototype.getFormOptions = function(name) {
switch (name) {
case "mode":
return Layout.getModes();
case "parent":
return this.getParentOptions();
}
switch (name) {
case "mode":
return Layout.getModes();
case "parent":
return this.getParentOptions();
}
}
/**
@ -217,104 +217,104 @@ Layout.prototype.getFormOptions = function(name) {
* @param {Object} data
*/
Layout.prototype.update = function(data) {
var skin = this.skins.getSkin("Site", "values");
if (!skin) {
Skin.add("Site", "values", this);
}
res.push();
for (var key in data) {
if (key.startsWith("value_")) {
var value = data[key];
key = key.substr(6);
res.write("<% value ");
res.write(quote(key));
res.write(" ");
res.write(quote(value));
res.write(" %>\n");
}
}
res.write("\n");
skin.setSource(res.pop());
Layout.sandbox(!!data.sandbox);
this.description = data.description;
this.mode = data.mode;
this.touch();
return;
var skin = this.skins.getSkin("Site", "values");
if (!skin) {
Skin.add("Site", "values", this);
}
res.push();
for (var key in data) {
if (key.startsWith("value_")) {
var value = data[key];
key = key.substr(6);
res.write("<% value ");
res.write(quote(key));
res.write(" ");
res.write(quote(value));
res.write(" %>\n");
}
}
res.write("\n");
skin.setSource(res.pop());
Layout.sandbox(!!data.sandbox);
this.description = data.description;
this.mode = data.mode;
this.touch();
return;
}
Layout.prototype.reset_action = function() {
if (req.data.proceed) {
try {
Layout.remove.call(this);
this.reset();
res.message = gettext("{0} was successfully reset.", gettext("Layout"));
res.redirect(this.href());
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
if (req.data.proceed) {
try {
Layout.remove.call(this);
this.reset();
res.message = gettext("{0} was successfully reset.", gettext("Layout"));
res.redirect(this.href());
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Confirm Reset");
res.data.body = this.renderSkinAsString("$HopObject#confirm", {
text: this.getConfirmText()
});
res.handlers.site.renderSkin("Site#page");
res.data.action = this.href(req.action);
res.data.title = gettext("Confirm Reset");
res.data.body = this.renderSkinAsString("$HopObject#confirm", {
text: this.getConfirmText()
});
res.handlers.site.renderSkin("Site#page");
}
Layout.prototype.export_action = function() {
res.contentType = "application/zip";
var zip = this.getArchive(res.skinpath);
res.setHeader("Content-Disposition",
"attachment; filename=" + this.site.name + "-layout.zip");
res.writeBinary(zip.getData());
return;
res.contentType = "application/zip";
var zip = this.getArchive(res.skinpath);
res.setHeader("Content-Disposition",
"attachment; filename=" + this.site.name + "-layout.zip");
res.writeBinary(zip.getData());
return;
}
Layout.prototype.import_action = function() {
var self = this;
var data = req.postParams;
if (data.submit) {
try {
if (!data.upload || data.upload.contentLength === 0) {
throw Error(gettext("Please upload a zipped layout archive"));
}
// Extract zipped layout to temporary directory
var dir = this.site.getStaticFile();
var temp = new helma.File(dir, "import.temp");
var fname = data.upload.writeToFile(dir);
var zip = new helma.File(dir, fname);
(new helma.Zip(zip)).extractAll(temp);
zip.remove();
var data = Xml.read(new helma.File(temp, "data.xml"));
if (!data.version) {
throw Error(gettext("Sorry, this layout is not compatible with Antville."));
}
// Remove current layout and replace it with imported one
Layout.remove.call(this);
temp.renameTo(this.getFile());
this.origin = data.origin;
this.originator = data.originator;
this.originated = data.originated;
data.images.forEach(function() {
Image.add(this);
});
this.touch();
res.message = gettext("The layout was successfully imported.");
} catch (ex) {
res.message = ex;
app.log(ex);
temp && temp.removeDirectory();
res.redirect(this.href(req.action));
var self = this;
var data = req.postParams;
if (data.submit) {
try {
if (!data.upload || data.upload.contentLength === 0) {
throw Error(gettext("Please upload a zipped layout archive"));
}
res.redirect(this.href());
return;
}
res.data.title = gettext("Import Layout");
res.data.body = this.renderSkinAsString("$Layout#import");
res.handlers.site.renderSkin("Site#page");
return;
// Extract zipped layout to temporary directory
var dir = this.site.getStaticFile();
var temp = new helma.File(dir, "import.temp");
var fname = data.upload.writeToFile(dir);
var zip = new helma.File(dir, fname);
(new helma.Zip(zip)).extractAll(temp);
zip.remove();
var data = Xml.read(new helma.File(temp, "data.xml"));
if (!data.version) {
throw Error(gettext("Sorry, this layout is not compatible with Antville."));
}
// Remove current layout and replace it with imported one
Layout.remove.call(this);
temp.renameTo(this.getFile());
this.origin = data.origin;
this.originator = data.originator;
this.originated = data.originated;
data.images.forEach(function() {
Image.add(this);
});
this.touch();
res.message = gettext("The layout was successfully imported.");
} catch (ex) {
res.message = ex;
app.log(ex);
temp && temp.removeDirectory();
res.redirect(this.href(req.action));
}
res.redirect(this.href());
return;
}
res.data.title = gettext("Import Layout");
res.data.body = this.renderSkinAsString("$Layout#import");
res.handlers.site.renderSkin("Site#page");
return;
}
/**
@ -324,18 +324,18 @@ Layout.prototype.import_action = function() {
* @returns {Image}
*/
Layout.prototype.getImage = function(name, fallback) {
var layout = this;
while (layout) {
layout.images.prefetchChildren();
if (layout.images.get(name)) {
return layout.images.get(name);
}
if (fallback && layout.images.get(fallback)) {
return layout.images.get(fallback);
}
layout = layout.parent;
}
return null;
var layout = this;
while (layout) {
layout.images.prefetchChildren();
if (layout.images.get(name)) {
return layout.images.get(name);
}
if (fallback && layout.images.get(fallback)) {
return layout.images.get(fallback);
}
layout = layout.parent;
}
return null;
}
/**
@ -344,48 +344,48 @@ Layout.prototype.getImage = function(name, fallback) {
* @returns {helma.File}
*/
Layout.prototype.getFile = function(name) {
name || (name = String.EMPTY);
return this.site.getStaticFile("layout/" + name);
name || (name = String.EMPTY);
return this.site.getStaticFile("layout/" + name);
}
/**
* @returns {String[]}
*/
Layout.prototype.getSkinPath = function() {
if (!this.site) {
return null;
}
var skinPath = [this.getFile().toString()];
return skinPath;
if (!this.site) {
return null;
}
var skinPath = [this.getFile().toString()];
return skinPath;
}
/**
*
*/
Layout.prototype.reset = function() {
var skinFiles = app.getSkinfilesInPath([app.dir]);
var content, dir, file;
for (var name in skinFiles) {
if (content = skinFiles[name][name]) {
dir = this.getFile(name);
file = new helma.File(dir, name + ".skin");
dir.makeDirectory();
file.open();
file.write(content);
file.close();
}
}
var skinFiles = app.getSkinfilesInPath([app.dir]);
var content, dir, file;
for (var name in skinFiles) {
if (content = skinFiles[name][name]) {
dir = this.getFile(name);
file = new helma.File(dir, name + ".skin");
dir.makeDirectory();
file.open();
file.write(content);
file.close();
}
}
// FIXME: Reset the Site skin of root separately
content = skinFiles.Root.Site;
file = new helma.File(this.getFile("Root"), "Site.skin");
dir.makeDirectory();
file.open();
file.write(content);
file.close()
// FIXME: Reset the Site skin of root separately
content = skinFiles.Root.Site;
file = new helma.File(this.getFile("Root"), "Site.skin");
dir.makeDirectory();
file.open();
file.write(content);
file.close()
this.touch();
return;
this.touch();
return;
}
/**
@ -394,47 +394,47 @@ Layout.prototype.reset = function() {
* @returns {helma.Zip}
*/
Layout.prototype.getArchive = function(skinPath) {
var zip = new helma.Zip();
var skinFiles = app.getSkinfilesInPath(skinPath);
for (var name in skinFiles) {
if (skinFiles[name][name]) {
var file = new helma.File(this.getFile(name), name + ".skin");
if (file.exists()) {
zip.add(file, name);
}
var zip = new helma.Zip();
var skinFiles = app.getSkinfilesInPath(skinPath);
for (var name in skinFiles) {
if (skinFiles[name][name]) {
var file = new helma.File(this.getFile(name), name + ".skin");
if (file.exists()) {
zip.add(file, name);
}
}
}
}
// FIXME: Add the Site skin of root separately
file = new helma.File(this.getFile("Root"), "Site.skin");
file.exists() && zip.add(file, "Root");
// FIXME: Add the Site skin of root separately
file = new helma.File(this.getFile("Root"), "Site.skin");
file.exists() && zip.add(file, "Root");
var data = new HopObject;
data.images = new HopObject;
this.images.forEach(function() {
zip.add(this.getFile());
try {
zip.add(this.getThumbnailFile());
} catch (ex) {
/* Most likely the thumbnail file is identical to the image */
}
var image = new HopObject;
for each (var key in Image.KEYS) {
image[key] = this[key];
data.images.add(image);
}
});
var data = new HopObject;
data.images = new HopObject;
this.images.forEach(function() {
zip.add(this.getFile());
try {
zip.add(this.getThumbnailFile());
} catch (ex) {
/* Most likely the thumbnail file is identical to the image */
}
var image = new HopObject;
for each (var key in Image.KEYS) {
image[key] = this[key];
data.images.add(image);
}
});
data.version = Root.VERSION.toString();
data.origin = this.origin || this.site.href();
data.originator = this.originator || session.user.name;
data.originated = this.originated || new Date;
data.version = Root.VERSION.toString();
data.origin = this.origin || this.site.href();
data.originator = this.originator || session.user.name;
data.originated = this.originated || new Date;
// FIXME: XML encoder is losing all mixed-case properties :(
var xml = new java.lang.String(Xml.writeToString(data));
zip.addData(xml.getBytes("UTF-8"), "data.xml");
zip.close();
return zip;
// FIXME: XML encoder is losing all mixed-case properties :(
var xml = new java.lang.String(Xml.writeToString(data));
zip.addData(xml.getBytes("UTF-8"), "data.xml");
zip.close();
return zip;
}
@ -442,8 +442,8 @@ Layout.prototype.getArchive = function(skinPath) {
* @returns {String}
*/
Layout.prototype.getConfirmText = function() {
return gettext("You are about to reset the layout of site {0}.",
this.site.name);
return gettext("You are about to reset the layout of site {0}.",
this.site.name);
}
/**
*
@ -451,13 +451,13 @@ Layout.prototype.getConfirmText = function() {
* @returns {HopObject}
*/
Layout.prototype.getMacroHandler = function(name) {
switch (name) {
case "skins":
return this[name];
switch (name) {
case "skins":
return this[name];
default:
return null;
}
default:
return null;
}
}
/**
@ -467,56 +467,56 @@ Layout.prototype.getMacroHandler = function(name) {
* @param {String} mode
*/
Layout.prototype.image_macro = function(param, name, mode) {
name || (name = param.name);
if (!name) {
return;
}
name || (name = param.name);
if (!name) {
return;
}
var image = this.getImage(name, param.fallback);
if (!image) {
return;
}
var image = this.getImage(name, param.fallback);
if (!image) {
return;
}
mode || (mode = param.as);
var action = param.linkto;
delete(param.name);
delete(param.as);
delete(param.linkto);
mode || (mode = param.as);
var action = param.linkto;
delete(param.name);
delete(param.as);
delete(param.linkto);
switch (mode) {
case "url" :
return res.write(image.getUrl());
case "thumbnail" :
action || (action = image.getUrl());
return image.thumbnail_macro(param);
}
image.render_macro(param);
return;
switch (mode) {
case "url" :
return res.write(image.getUrl());
case "thumbnail" :
action || (action = image.getUrl());
return image.thumbnail_macro(param);
}
image.render_macro(param);
return;
}
/**
*
*/
Layout.prototype.values_macro = function() {
var values = [];
for (var key in res.meta.values) {
values.push({key: key, value: res.meta.values[key]});
}
values.sort(new String.Sorter("key"));
for each (var pair in values) {
this.renderSkin("$Layout#value", {
key: pair.key.capitalize(),
value: pair.value
});
}
return;
var values = [];
for (var key in res.meta.values) {
values.push({key: key, value: res.meta.values[key]});
}
values.sort(new String.Sorter("key"));
for each (var pair in values) {
this.renderSkin("$Layout#value", {
key: pair.key.capitalize(),
value: pair.value
});
}
return;
}
/**
*
*/
Layout.prototype.sandbox_macro = function() {
res.write(Layout.sandbox());
return;
res.write(Layout.sandbox());
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -45,23 +45,23 @@ markgettext("log entry");
* @extends HopObject
*/
LogEntry.prototype.constructor = function(context, action) {
this.context = context;
this.action = action;
this.referrer = req.data.http_referer;
this.creator = session.user;
this.created = new Date;
this.ip = req.data.http_remotehost; // Won't be stored in database
this.site = res.handlers.site;
return this;
this.context = context;
this.action = action;
this.referrer = req.data.http_referer;
this.creator = session.user;
this.created = new Date;
this.ip = req.data.http_remotehost; // Won't be stored in database
this.site = res.handlers.site;
return this;
}
/**
* @returns {String}
*/
LogEntry.prototype.toString = function() {
return "[LogEntry #" + this._id + ": " + (this.creator || "anonymous") +
" requested " + this.action + " action of " + this.context_type +
" #" + this.context_id + " on " + formatDate(this.created) + "]";
return "[LogEntry #" + this._id + ": " + (this.creator || "anonymous") +
" requested " + this.action + " action of " + this.context_type +
" #" + this.context_id + " on " + formatDate(this.created) + "]";
}
/**
@ -70,11 +70,11 @@ LogEntry.prototype.toString = function() {
* @returns {HopObject}
*/
LogEntry.prototype.getMacroHandler = function(name) {
switch (name) {
case "context":
return this.context || {name: this.context_id};
}
return null;
switch (name) {
case "context":
return this.context || {name: this.context_id};
}
return null;
}
/**
@ -82,18 +82,18 @@ LogEntry.prototype.getMacroHandler = function(name) {
* @param {Object} param
*/
LogEntry.prototype.label_macro = function(param) {
if (!User.require(User.PRIVILEGED)) {
return;
}
switch (this.context_type) {
case "Site" :
res.write("<span class=\"flagDark\" style=\"background-color:#006600;\">SITE</span>");
break;
case "User" :
res.write("<span class=\"flagDark\" style=\"background-color:#009900;\">USER</span>");
break;
default :
res.write("<span class=\"flagLight\" style=\"background-color:#FFCC00;\">ROOT</span>");
}
return;
if (!User.require(User.PRIVILEGED)) {
return;
}
switch (this.context_type) {
case "Site" :
res.write("<span class=\"flagDark\" style=\"background-color:#006600;\">SITE</span>");
break;
case "User" :
res.write("<span class=\"flagDark\" style=\"background-color:#009900;\">USER</span>");
break;
default :
res.write("<span class=\"flagLight\" style=\"background-color:#FFCC00;\">ROOT</span>");
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -47,306 +47,306 @@ markgettext("members");
* @returns {Boolean}
*/
Members.prototype.getPermission = function(action) {
switch (action) {
case "login":
case "logout":
case "register":
case "reset":
case "salt.txt":
return true;
}
switch (action) {
case "login":
case "logout":
case "register":
case "reset":
case "salt.txt":
return true;
}
var sitePermission = this._parent.getPermission("main");
var sitePermission = this._parent.getPermission("main");
switch (action) {
case "edit":
case "privileges":
case "subscriptions":
case "updated":
return sitePermission && !!session.user;
switch (action) {
case "edit":
case "privileges":
case "subscriptions":
case "updated":
return sitePermission && !!session.user;
case ".":
case "main":
case "add":
case "owners":
case "managers":
case "contributors":
case "subscribers":
return sitePermission && (Membership.require(Membership.OWNER) ||
User.require(User.PRIVILEGED));
}
case ".":
case "main":
case "add":
case "owners":
case "managers":
case "contributors":
case "subscribers":
return sitePermission && (Membership.require(Membership.OWNER) ||
User.require(User.PRIVILEGED));
}
return Feature.getPermission.apply(this, arguments);
return Feature.getPermission.apply(this, arguments);
}
Members.prototype.main_action = function() {
res.data.title = gettext("Site Members");
res.data.list = renderList(this, "$Membership#member",
10, req.queryParams.page);
res.data.pager = renderPager(this, this.href(req.action),
10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Site Members");
res.data.list = renderList(this, "$Membership#member",
10, req.queryParams.page);
res.data.pager = renderPager(this, this.href(req.action),
10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.register_action = function() {
if (req.postParams.register) {
try {
var title = res.handlers.site.title;
var user = User.register(req.postParams);
var membership = Membership.add(user, Membership.SUBSCRIBER, this._parent);
membership.notify(req.action, user.email,
gettext('[{0}] Welcome to {1}!', root.title, title));
res.message = gettext('Welcome to “{0}”, {1}. Have fun!',
title, user.name);
res.redirect(User.getLocation() || this._parent.href());
} catch (ex) {
res.message = ex;
}
}
if (req.postParams.register) {
try {
var title = res.handlers.site.title;
var user = User.register(req.postParams);
var membership = Membership.add(user, Membership.SUBSCRIBER, this._parent);
membership.notify(req.action, user.email,
gettext('[{0}] Welcome to {1}!', root.title, title));
res.message = gettext('Welcome to “{0}”, {1}. Have fun!',
title, user.name);
res.redirect(User.getLocation() || this._parent.href());
} catch (ex) {
res.message = ex;
}
}
session.data.token = User.getSalt();
res.data.action = this.href(req.action);
res.data.title = gettext("Register");
res.data.body = this.renderSkinAsString("$Members#register");
this._parent.renderSkin("Site#page");
return;
session.data.token = User.getSalt();
res.data.action = this.href(req.action);
res.data.title = gettext("Register");
res.data.body = this.renderSkinAsString("$Members#register");
this._parent.renderSkin("Site#page");
return;
}
Members.prototype.reset_action = function() {
if (req.postParams.reset) {
try {
if (!req.postParams.name || !req.postParams.email) {
throw Error(gettext("Please enter a user name and e-mail address."));
}
var user = User.getByName(req.postParams.name);
if (!user || user.email !== req.postParams.email) {
throw Error(gettext("User name and e-mail address do not match."))
}
var token = User.getSalt();
user.setMetadata("resetToken", token);
sendMail(user.email, gettext("[{0}] Password reset confirmation", root.title),
user.renderSkinAsString("$User#notify_reset", {
href: this.href("reset"),
token: token
}));
res.message = gettext("A confirmation mail was sent to your e-mail address.");
res.redirect(this._parent.href());
} catch(ex) {
res.message = ex;
if (req.postParams.reset) {
try {
if (!req.postParams.name || !req.postParams.email) {
throw Error(gettext("Please enter a user name and e-mail address."));
}
} else if (req.data.user && req.data.token) {
var user = User.getById(req.data.user);
if (user) {
var token = user.getMetadata("resetToken");
if (token && token === req.data.token) {
session.login(user);
if (req.postParams.save) {
var password = req.postParams.password;
if (!password) {
res.message = gettext("Please enter a new password.");
} else if (password !== req.postParams.passwordConfirm) {
res.message = gettext("The passwords do not match.");
} else {
user.hash = (password + user.salt).md5();
user.setMetadata("resetToken", null);
res.message = gettext("Your password was changed.");
res.redirect(this._parent.href());
}
}
res.data.title = gettext("Reset Password");
res.data.body = this.renderSkinAsString("$Members#password");
this._parent.renderSkin("Site#page");
return;
}
var user = User.getByName(req.postParams.name);
if (!user || user.email !== req.postParams.email) {
throw Error(gettext("User name and e-mail address do not match."))
}
res.message = gettext("This URL is not valid for resetting your password.");
res.redirect(this.href(req.action));
}
res.data.action = this.href(req.action);
res.data.title = gettext("Request Password Reset");
res.data.body = this.renderSkinAsString("$Members#reset");
this._parent.renderSkin("Site#page");
return;
var token = User.getSalt();
user.setMetadata("resetToken", token);
sendMail(user.email, gettext("[{0}] Password reset confirmation", root.title),
user.renderSkinAsString("$User#notify_reset", {
href: this.href("reset"),
token: token
}));
res.message = gettext("A confirmation mail was sent to your e-mail address.");
res.redirect(this._parent.href());
} catch(ex) {
res.message = ex;
}
} else if (req.data.user && req.data.token) {
var user = User.getById(req.data.user);
if (user) {
var token = user.getMetadata("resetToken");
if (token && token === req.data.token) {
session.login(user);
if (req.postParams.save) {
var password = req.postParams.password;
if (!password) {
res.message = gettext("Please enter a new password.");
} else if (password !== req.postParams.passwordConfirm) {
res.message = gettext("The passwords do not match.");
} else {
user.hash = (password + user.salt).md5();
user.setMetadata("resetToken", null);
res.message = gettext("Your password was changed.");
res.redirect(this._parent.href());
}
}
res.data.title = gettext("Reset Password");
res.data.body = this.renderSkinAsString("$Members#password");
this._parent.renderSkin("Site#page");
return;
}
}
res.message = gettext("This URL is not valid for resetting your password.");
res.redirect(this.href(req.action));
}
res.data.action = this.href(req.action);
res.data.title = gettext("Request Password Reset");
res.data.body = this.renderSkinAsString("$Members#reset");
this._parent.renderSkin("Site#page");
return;
}
Members.prototype.login_action = function() {
if (req.postParams.login) {
try {
var user = User.login(req.postParams);
res.message = gettext('Welcome to {0}, {1}. Have fun!',
res.handlers.site.getTitle(), user.name);
res.redirect(User.getLocation() || this._parent.href());
} catch (ex) {
res.message = ex;
}
}
session.data.token = User.getSalt();
res.data.action = this.href(req.action);
res.data.title = gettext("Login");
res.data.body = this.renderSkinAsString("$Members#login");
this._parent.renderSkin("Site#page");
return;
if (req.postParams.login) {
try {
var user = User.login(req.postParams);
res.message = gettext('Welcome to {0}, {1}. Have fun!',
res.handlers.site.getTitle(), user.name);
res.redirect(User.getLocation() || this._parent.href());
} catch (ex) {
res.message = ex;
}
}
session.data.token = User.getSalt();
res.data.action = this.href(req.action);
res.data.title = gettext("Login");
res.data.body = this.renderSkinAsString("$Members#login");
this._parent.renderSkin("Site#page");
return;
}
Members.prototype.logout_action = function() {
if (session.user) {
res.message = gettext("Good bye, {0}! Looking forward to seeing you again!",
session.user.name);
User.logout();
}
res.redirect(this._parent.href());
return;
if (session.user) {
res.message = gettext("Good bye, {0}! Looking forward to seeing you again!",
session.user.name);
User.logout();
}
res.redirect(this._parent.href());
return;
}
Members.prototype.edit_action = function() {
if (req.postParams.save) {
try {
session.user.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this._parent.href());
} catch (err) {
res.message = err.toString();
}
}
if (req.postParams.save) {
try {
session.user.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this._parent.href());
} catch (err) {
res.message = err.toString();
}
}
session.data.token = User.getSalt();
session.data.salt = session.user.salt; // FIXME
res.data.title = gettext("User Profile");
res.data.body = session.user.renderSkinAsString("$User#edit");
this._parent.renderSkin("Site#page");
return;
session.data.token = User.getSalt();
session.data.salt = session.user.salt; // FIXME
res.data.title = gettext("User Profile");
res.data.body = session.user.renderSkinAsString("$User#edit");
this._parent.renderSkin("Site#page");
return;
}
Members.prototype.salt_txt_action = function() {
res.contentType = "text/plain";
var user;
if (user = User.getByName(req.queryParams.user)) {
res.write(user.salt || String.EMPTY);
}
return;
res.contentType = "text/plain";
var user;
if (user = User.getByName(req.queryParams.user)) {
res.write(user.salt || String.EMPTY);
}
return;
}
Members.prototype.owners_action = function() {
res.data.title = gettext("Site Owners");
res.data.list = renderList(this.owners,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.owners,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Site Owners");
res.data.list = renderList(this.owners,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.owners,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.managers_action = function() {
res.data.title = gettext("Site Managers");
res.data.list = renderList(this.managers,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.managers,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Site Managers");
res.data.list = renderList(this.managers,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.managers,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.contributors_action = function() {
res.data.title = gettext("Site Contributors");
res.data.list = renderList(this.contributors,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.contributors,
this.href(req.action), 10, req.data.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Site Contributors");
res.data.list = renderList(this.contributors,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.contributors,
this.href(req.action), 10, req.data.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.subscribers_action = function() {
res.data.title = gettext("Site Subscribers");
res.data.list = renderList(this.subscribers,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.subscribers,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Site Subscribers");
res.data.list = renderList(this.subscribers,
"$Membership#member", 10, req.queryParams.page);
res.data.pager = renderPager(this.subscribers,
this.href(req.action), 10, req.queryParams.page);
res.data.body = this.renderSkinAsString("$Members#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.updated_action = function() {
res.data.title = gettext("Updates");
res.data.list = session.user.renderSkinAsString("$User#sites");
res.data.body = session.user.renderSkinAsString("$User#subscriptions");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Updates");
res.data.list = session.user.renderSkinAsString("$User#sites");
res.data.body = session.user.renderSkinAsString("$User#subscriptions");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.privileges_action = function() {
var site = res.handlers.site;
res.data.title = gettext("Privileges");
res.data.list = renderList(session.user.memberships, function(item) {
res.handlers.subscription = item.site;
item.renderSkin("$Membership#subscription");
return;
});
res.handlers.site = site;
res.data.body = session.user.renderSkinAsString("$User#subscriptions");
res.handlers.site.renderSkin("Site#page");
return;
var site = res.handlers.site;
res.data.title = gettext("Privileges");
res.data.list = renderList(session.user.memberships, function(item) {
res.handlers.subscription = item.site;
item.renderSkin("$Membership#subscription");
return;
});
res.handlers.site = site;
res.data.body = session.user.renderSkinAsString("$User#subscriptions");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.subscriptions_action = function() {
var site = res.handlers.site;
res.data.title = gettext("Subscriptions");
res.data.list = renderList(session.user.subscriptions, function(item) {
res.handlers.subscription = item.site;
item.renderSkin("$Membership#subscription");
return;
});
res.handlers.site = site;
res.data.body = session.user.renderSkinAsString("$User#subscriptions");
res.handlers.site.renderSkin("Site#page");
return;
var site = res.handlers.site;
res.data.title = gettext("Subscriptions");
res.data.list = renderList(session.user.subscriptions, function(item) {
res.handlers.subscription = item.site;
item.renderSkin("$Membership#subscription");
return;
});
res.handlers.site = site;
res.data.body = session.user.renderSkinAsString("$User#subscriptions");
res.handlers.site.renderSkin("Site#page");
return;
}
Members.prototype.add_action = function() {
if (req.postParams.term) {
try {
var result = this.search(req.postParams.term);
if (result.length < 1) {
res.message = gettext("No user found to add as member.");
} else {
if (result.length >= 100) {
res.message = gettext("Too many users found, displaying the first {0} matches only.",
result.length);
} else {
res.message = ngettext("One user found.", "{0} users found.",
result.length);
}
res.data.result = this.renderSkinAsString("$Members#results", result);
}
} catch (ex) {
res.message = ex;
app.log(ex);
if (req.postParams.term) {
try {
var result = this.search(req.postParams.term);
if (result.length < 1) {
res.message = gettext("No user found to add as member.");
} else {
if (result.length >= 100) {
res.message = gettext("Too many users found, displaying the first {0} matches only.",
result.length);
} else {
res.message = ngettext("One user found.", "{0} users found.",
result.length);
}
res.data.result = this.renderSkinAsString("$Members#results", result);
}
} else if (req.postParams.add) {
try {
var membership = this.addMembership(req.postParams);
membership.notify(req.action, membership.creator.email,
gettext('[{0}] Notification of membership change', root.title));
res.message = gettext("Successfully added {0} to the list of members.",
req.postParams.name);
res.redirect(membership.href("edit"));
} catch (ex) {
res.message = ex;
app.log(ex);
}
res.redirect(this.href());
}
res.data.action = this.href(req.action);
res.data.title = gettext('Add Member');
res.data.body = this.renderSkinAsString("$Members#add");
res.handlers.site.renderSkin("Site#page");
return;
} catch (ex) {
res.message = ex;
app.log(ex);
}
} else if (req.postParams.add) {
try {
var membership = this.addMembership(req.postParams);
membership.notify(req.action, membership.creator.email,
gettext('[{0}] Notification of membership change', root.title));
res.message = gettext("Successfully added {0} to the list of members.",
req.postParams.name);
res.redirect(membership.href("edit"));
} catch (ex) {
res.message = ex;
app.log(ex);
}
res.redirect(this.href());
}
res.data.action = this.href(req.action);
res.data.title = gettext('Add Member');
res.data.body = this.renderSkinAsString("$Members#add");
res.handlers.site.renderSkin("Site#page");
return;
}
/**
@ -355,27 +355,27 @@ Members.prototype.add_action = function() {
* @returns {Object}
*/
Members.prototype.search = function(searchString) {
var self = this;
var mode = "=";
if (searchString.contains("*")) {
searchString = searchString.replace(/\*/g, "%");
mode = "like";
}
var sql = new Sql;
sql.retrieve(Sql.MEMBERSEARCH, mode, searchString, 100);
var counter = 0, name;
res.push();
sql.traverse(function() {
// Check if the user is not already a member
if (!self.get(this.name)) {
self.renderSkin("$Members#result", {name: this.name});
counter += 1;
}
});
return {
result: res.pop(),
length: counter
};
var self = this;
var mode = "=";
if (searchString.contains("*")) {
searchString = searchString.replace(/\*/g, "%");
mode = "like";
}
var sql = new Sql;
sql.retrieve(Sql.MEMBERSEARCH, mode, searchString, 100);
var counter = 0, name;
res.push();
sql.traverse(function() {
// Check if the user is not already a member
if (!self.get(this.name)) {
self.renderSkin("$Members#result", {name: this.name});
counter += 1;
}
});
return {
result: res.pop(),
length: counter
};
}
/**
@ -384,12 +384,12 @@ Members.prototype.search = function(searchString) {
* @returns {Membership}
*/
Members.prototype.addMembership = function(data) {
var user = root.users.get(data.name);
if (!user) {
throw Error(gettext("Sorry, your input did not match any registered user."));
} else if (this.get(data.name)) {
throw Error(gettext("This user is already a member of this site."));
}
var membership = Membership.add(user, Membership.SUBSCRIBER, this._parent);
return membership;
var user = root.users.get(data.name);
if (!user) {
throw Error(gettext("Sorry, your input did not match any registered user."));
} else if (this.get(data.name)) {
throw Error(gettext("This user is already a member of this site."));
}
var membership = Membership.add(user, Membership.SUBSCRIBER, this._parent);
return membership;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -37,7 +37,7 @@ markgettext("membership");
* @returns {Membership}
*/
Membership.getByName = function(name, site) {
return (site || res.handlers.site).members.get(name);
return (site || res.handlers.site).members.get(name);
}
/**
@ -46,10 +46,10 @@ Membership.getByName = function(name, site) {
* @returns {Boolean}
*/
Membership.require = function(role) {
if (res.handlers.membership) {
return res.handlers.membership.require(role);
}
return false;
if (res.handlers.membership) {
return res.handlers.membership.require(role);
}
return false;
}
/**
@ -58,7 +58,7 @@ Membership.require = function(role) {
* @see defineConstants
*/
Membership.getRoles = defineConstants(Membership, markgettext("Subscriber"),
markgettext("Contributor"), markgettext("Manager"), markgettext("Owner"));
markgettext("Contributor"), markgettext("Manager"), markgettext("Owner"));
/**
@ -67,13 +67,13 @@ Membership.getRoles = defineConstants(Membership, markgettext("Subscriber"),
* @param {Site} site
*/
Membership.add = function(user, role, site) {
HopObject.confirmConstructor(Membership);
user || (user = session.user);
var membership = new Membership(user, role);
membership.created = new Date;
membership.touch();
site.members.add(membership);
return membership;
HopObject.confirmConstructor(Membership);
user || (user = session.user);
var membership = new Membership(user, role);
membership.created = new Date;
membership.touch();
site.members.add(membership);
return membership;
}
/**
*
@ -81,20 +81,20 @@ Membership.add = function(user, role, site) {
* @param {Object} options
*/
Membership.remove = function(options) {
options || (options = {});
if (this.constructor !== Membership) {
return;
}
if (!options.force && !this.getPermission("delete")) {
throw Error(gettext("Sorry, an owner of a site cannot be removed."));
}
var recipient = this.creator.email;
this.remove();
if (!options.force) {
this.notify(req.action, recipient,
gettext("[{0}] Notification of membership cancellation", root.title));
}
return;
options || (options = {});
if (this.constructor !== Membership) {
return;
}
if (!options.force && !this.getPermission("delete")) {
throw Error(gettext("Sorry, an owner of a site cannot be removed."));
}
var recipient = this.creator.email;
this.remove();
if (!options.force) {
this.notify(req.action, recipient,
gettext("[{0}] Notification of membership cancellation", root.title));
}
return;
}
/**
@ -118,16 +118,16 @@ Membership.remove = function(options) {
* @extends HopObject
*/
Membership.prototype.constructor = function(user, role) {
HopObject.confirmConstructor(this);
user || (user = session.user);
if (user) {
this.map({
creator: user,
name: user.name,
role: role
});
}
return this;
HopObject.confirmConstructor(this);
user || (user = session.user);
if (user) {
this.map({
creator: user,
name: user.name,
role: role
});
}
return this;
}
/**
@ -136,18 +136,18 @@ Membership.prototype.constructor = function(user, role) {
* @return {Boolean}
*/
Membership.prototype.getPermission = function(action) {
if (!res.handlers.site.getPermission("main")) {
return false;
}
switch (action) {
case "contact":
return true;
case "edit":
case "delete":
return User.require(User.PRIVILEGED) ||
this.role !== Membership.OWNER || this.creator !== session.user;
}
return false;
if (!res.handlers.site.getPermission("main")) {
return false;
}
switch (action) {
case "contact":
return true;
case "edit":
case "delete":
return User.require(User.PRIVILEGED) ||
this.role !== Membership.OWNER || this.creator !== session.user;
}
return false;
}
/**
@ -156,30 +156,30 @@ Membership.prototype.getPermission = function(action) {
* @returns {Object}
*/
Membership.prototype.getFormOptions = function(name) {
switch (name) {
case "role":
return Membership.getRoles();
}
return;
switch (name) {
case "role":
return Membership.getRoles();
}
return;
}
Membership.prototype.edit_action = function() {
if (req.postParams.save) {
try {
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this._parent.href());
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
if (req.postParams.save) {
try {
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
res.redirect(this._parent.href());
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Membership: {0}", this.name);
res.data.body = this.renderSkinAsString("$Membership#edit");
this.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Membership: {0}", this.name);
res.data.body = this.renderSkinAsString("$Membership#edit");
this.site.renderSkin("Site#page");
return;
}
/**
@ -187,55 +187,55 @@ Membership.prototype.edit_action = function() {
* @param {Object} data
*/
Membership.prototype.update = function(data) {
if (!data.role) {
throw Error(gettext("Please choose a role for this member."));
} else if (this.user === session.user) {
throw Error(gettext("Sorry, you are not allowed to edit your own membership."));
} else if (data.role !== this.role) {
this.role = data.role || Membership.SUBSCRIBER;
this.touch();
this.notify(req.action, this.creator.email,
gettext("[{0}] Notification of membership change", root.title));
}
return;
if (!data.role) {
throw Error(gettext("Please choose a role for this member."));
} else if (this.user === session.user) {
throw Error(gettext("Sorry, you are not allowed to edit your own membership."));
} else if (data.role !== this.role) {
this.role = data.role || Membership.SUBSCRIBER;
this.touch();
this.notify(req.action, this.creator.email,
gettext("[{0}] Notification of membership change", root.title));
}
return;
}
Membership.prototype.contact_action = function() {
if (req.postParams.send) {
try {
if (!req.postParams.text) {
throw Error(gettext("Please enter the message text."));
}
Feature.invoke("recaptcha", function() {
return this.verify(req.postParams);
});
this.notify(req.action, this.creator.email, session.user ?
gettext('[{0}] Message from user {1}', root.title, session.user.name) :
gettext('[{0}] Message from anonymous user', root.title));
res.message = gettext("Your message was sent successfully.");
res.redirect(this._parent.getPermission() ?
this._parent.href() : this.site.href());
} catch(ex) {
res.message = ex;
app.log(ex);
if (req.postParams.send) {
try {
if (!req.postParams.text) {
throw Error(gettext("Please enter the message text."));
}
}
Feature.invoke("recaptcha", function() {
return this.verify(req.postParams);
});
this.notify(req.action, this.creator.email, session.user ?
gettext('[{0}] Message from user {1}', root.title, session.user.name) :
gettext('[{0}] Message from anonymous user', root.title));
res.message = gettext("Your message was sent successfully.");
res.redirect(this._parent.getPermission() ?
this._parent.href() : this.site.href());
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext('Contact User: {0}', this.name);
res.data.body = this.renderSkinAsString("$Membership#contact");
this.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext('Contact User: {0}', this.name);
res.data.body = this.renderSkinAsString("$Membership#contact");
this.site.renderSkin("Site#page");
return;
}
Membership.prototype.content_action = function() {
res.data.list = renderList(this.content, "$Story#listItem",
10, req.queryParams.page);
res.data.pager = renderPager(this.content,
this.href(), 10, req.queryParams.page);
res.data.title = gettext("Content of User: {0}", this.name);
res.data.body = this.renderSkinAsString("$Membership#content");
this.site.renderSkin("Site#page");
res.data.list = renderList(this.content, "$Story#listItem",
10, req.queryParams.page);
res.data.pager = renderPager(this.content,
this.href(), 10, req.queryParams.page);
res.data.title = gettext("Content of User: {0}", this.name);
res.data.body = this.renderSkinAsString("$Membership#content");
this.site.renderSkin("Site#page");
}
/**
@ -244,11 +244,11 @@ Membership.prototype.content_action = function() {
* @returns {HopObject}
*/
Membership.prototype.getMacroHandler = function(name) {
switch (name) {
case "user":
return this.creator;
}
return null;
switch (name) {
case "user":
return this.creator;
}
return null;
}
/**
@ -257,12 +257,12 @@ Membership.prototype.getMacroHandler = function(name) {
* @returns {Boolean}
*/
Membership.prototype.require = function(role) {
var roles = [Membership.SUBSCRIBER, Membership.CONTRIBUTOR,
Membership.MANAGER, Membership.OWNER];
if (role) {
return roles.indexOf(this.role) >= roles.indexOf(role);
}
return false;
var roles = [Membership.SUBSCRIBER, Membership.CONTRIBUTOR,
Membership.MANAGER, Membership.OWNER];
if (role) {
return roles.indexOf(this.role) >= roles.indexOf(role);
}
return false;
}
/**
@ -272,33 +272,33 @@ Membership.prototype.require = function(role) {
* @param {String} subject
*/
Membership.prototype.notify = function(action, recipient, subject) {
switch (action) {
case "add":
case "contact":
case "delete":
case "edit":
case "register":
res.handlers.sender = User.getMembership();
sendMail(recipient, subject, this.renderSkinAsString("$Membership#notify_" + action),
{footer: action !== "contact"});
break;
}
return;
switch (action) {
case "add":
case "contact":
case "delete":
case "edit":
case "register":
res.handlers.sender = User.getMembership();
sendMail(recipient, subject, this.renderSkinAsString("$Membership#notify_" + action),
{footer: action !== "contact"});
break;
}
return;
}
/**
* @returns {String}
*/
Membership.prototype.getConfirmText = function() {
return gettext("You are about to delete the membership of user {0}.",
this.creator.name);
return gettext("You are about to delete the membership of user {0}.",
this.creator.name);
}
/**
* @returns {String}
*/
Membership.prototype.toString = function() {
return (this.role || "Transient") + " membership of user " + this.name;
return (this.role || "Transient") + " membership of user " + this.name;
}
/**
@ -311,16 +311,16 @@ Membership.prototype.valueOf = Membership.prototype.toString;
*
*/
Membership.prototype.status_macro = function() {
this.renderSkin(session.user ? "Membership#status" : "Membership#login");
return;
this.renderSkin(session.user ? "Membership#status" : "Membership#login");
return;
}
/**
*
*/
Membership.prototype.role_macro = function() {
this.role && res.write(gettext(this.role.capitalize()));
return;
this.role && res.write(gettext(this.role.capitalize()));
return;
}
/**
@ -331,9 +331,9 @@ Membership.prototype.role_macro = function() {
* @see HopObject#link_filter
*/
Membership.prototype.link_filter = function(value, param) {
if (!session.user || !session.user.url) {
return value;
}
return HopObject.prototype.link_filter.call(this, value,
param, session.user.url); // || this.href());
if (!session.user || !session.user.url) {
return value;
}
return HopObject.prototype.link_filter.call(this, value,
param, session.user.url); // || this.href());
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,14 +34,14 @@
* @see <a href="http://helma.org/wiki/Defining+HopObject+mappings+programmatically">Helma documentation</a>
*/
Metadata.getTypeProperties = function() {
return {
collection: "Metadata",
"local.1": "$id",
"foreign.1": "parent_id",
"local.2": "$prototype",
"foreign.2": "parent_type",
accessName: "name"
}
return {
collection: "Metadata",
"local.1": "$id",
"foreign.1": "parent_id",
"local.2": "$prototype",
"foreign.2": "parent_type",
accessName: "name"
}
}
/**
@ -54,30 +54,30 @@ Metadata.getTypeProperties = function() {
* the (normalized) metadata value and its type.
*/
Metadata.normalize = function(value) {
if (value === null || value === undefined) {
return [null, null];
}
if (value === null || value === undefined) {
return [null, null];
}
if (!value.constructor) {
value = String(value);
}
if (!value.constructor) {
value = String(value);
}
var Constructor = value.constructor;
switch (Constructor) {
case Boolean:
case String:
case Number:
value = String(value);
break;
var Constructor = value.constructor;
switch (Constructor) {
case Boolean:
case String:
case Number:
value = String(value);
break;
case Date:
value = Number(value);
break;
case Date:
value = Number(value);
break;
default:
value = value.toSource();
}
return [value, Constructor.name];
default:
value = value.toSource();
}
return [value, Constructor.name];
}
/**
@ -94,12 +94,12 @@ Metadata.normalize = function(value) {
* @property {String} type The type of the metadata object.
*/
Metadata.prototype.constructor = function(parent, name, value) {
if (parent && name && value) {
this.parent = parent;
this.name = name;
this.setValue(value);
}
return this;
if (parent && name && value) {
this.parent = parent;
this.name = name;
this.setValue(value);
}
return this;
}
/**
@ -108,11 +108,11 @@ Metadata.prototype.constructor = function(parent, name, value) {
* @param {Object} value The desired metadata value.
*/
Metadata.prototype.setValue = function(value) {
[this.value, this.type] = Metadata.normalize(value);
if (this.value === null) {
this.remove();
}
return;
[this.value, this.type] = Metadata.normalize(value);
if (this.value === null) {
this.remove();
}
return;
}
/**
@ -120,25 +120,25 @@ Metadata.prototype.setValue = function(value) {
* @returns {Object} The value of the metadata object.
*/
Metadata.prototype.getValue = function() {
var Constructor = global[this.type];
switch (Constructor) {
case null:
case undefined:
return null;
var Constructor = global[this.type];
switch (Constructor) {
case null:
case undefined:
return null;
case Boolean:
return eval(this.value).valueOf();
case Boolean:
return eval(this.value).valueOf();
case Date:
return new Date(Number(this.value));
case Date:
return new Date(Number(this.value));
case Number:
case String:
return (new Constructor(this.value)).valueOf();
case Number:
case String:
return (new Constructor(this.value)).valueOf();
default:
return eval(this.value);
}
default:
return eval(this.value);
}
}
/**
@ -146,7 +146,7 @@ Metadata.prototype.getValue = function() {
* @returns {String} A textual representation of the metadata object.
*/
Metadata.prototype.toString = function() {
return "Metadata of " + this.parent + " (" + this.name + " = " + this.value + ")";
return "Metadata of " + this.parent + " (" + this.name + " = " + this.value + ")";
}
/**
@ -156,5 +156,5 @@ Metadata.prototype.toString = function() {
*/
// FIXME: Is this obsolete?
Metadata.prototype.onUnhandledMacro = function(name) {
return this.get(name);
return this.get(name);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -42,24 +42,24 @@ Poll.getStatus = defineConstants(Poll, markgettext("closed"), markgettext("open"
* @param {String} question
*/
Poll.add = function(data, site) {
HopObject.confirmConstructor(Poll);
var poll = new Poll;
poll.creator = session.user;
poll.created = new Date;
poll.update(data);
site.polls.add(poll);
return poll;
HopObject.confirmConstructor(Poll);
var poll = new Poll;
poll.creator = session.user;
poll.created = new Date;
poll.update(data);
site.polls.add(poll);
return poll;
}
/**
*
*/
Poll.remove = function() {
if (this.constructor === Poll) {
HopObject.remove.call(this);
this.remove();
}
return;
if (this.constructor === Poll) {
HopObject.remove.call(this);
this.remove();
}
return;
}
/**
@ -79,8 +79,8 @@ Poll.remove = function() {
* @extends HopObject
*/
Poll.prototype.constructor = function() {
HopObject.confirmConstructor(this);
return this;
HopObject.confirmConstructor(this);
return this;
}
/**
@ -89,25 +89,25 @@ Poll.prototype.constructor = function() {
* @returns {Boolean}
*/
Poll.prototype.getPermission = function(action) {
if (!this.site.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
return !!session.user;
case "result":
return true;
case "edit":
return Membership.require(Membership.OWNER) ||
User.require(User.PRIVILEGED);
case "rotate":
case "delete":
return this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
if (!this.site.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
return !!session.user;
case "result":
return true;
case "edit":
return Membership.require(Membership.OWNER) ||
User.require(User.PRIVILEGED);
case "rotate":
case "delete":
return this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
}
/**
@ -116,33 +116,33 @@ Poll.prototype.getPermission = function(action) {
* @returns {Object}
*/
Poll.prototype.getFormOptions = function(name) {
switch (name) {
case "status":
return Poll.getStatus();
}
return;
switch (name) {
case "status":
return Poll.getStatus();
}
return;
}
Poll.prototype.main_action = function() {
if (this.status !== Poll.OPEN) {
if (this.status !== Poll.OPEN) {
res.redirect(this.href("result"));
return;
}
if (req.postParams.vote) {
try {
this.vote(req.postParams);
res.message = gettext("Thanks, your vote was registered. You can change your mind until the poll is closed.");
res.redirect(this.href("result"));
return;
}
if (req.postParams.vote) {
try {
this.vote(req.postParams);
res.message = gettext("Thanks, your vote was registered. You can change your mind until the poll is closed.");
res.redirect(this.href("result"));
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href();
res.data.title = gettext("Poll: {0}", this.question);
res.data.body = this.renderSkinAsString("$Poll#main", {header: true});
this.site.renderSkin("Site#page");
return;
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href();
res.data.title = gettext("Poll: {0}", this.question);
res.data.body = this.renderSkinAsString("$Poll#main", {header: true});
this.site.renderSkin("Site#page");
return;
}
/**
@ -151,7 +151,7 @@ Poll.prototype.main_action = function() {
*/
Poll.prototype.vote = function(data) {
if (!data.choice) {
throw Error(gettext("You did not vote, yet. You can vote until the poll is closed."));
throw Error(gettext("You did not vote, yet. You can vote until the poll is closed."));
}
var choice = this.get(data.choice);
var vote = session.user && this.votes.get(session.user.name);
@ -159,27 +159,27 @@ Poll.prototype.vote = function(data) {
vote.choice = choice;
vote.modified = new Date;
} else {
vote = Vote.add(choice, this);
vote = Vote.add(choice, this);
}
return vote;
}
Poll.prototype.edit_action = function() {
if (req.postParams.save) {
try {
this.update(req.postParams);
res.message = gettext("The poll was updated successfully.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Poll: {0}", this.question);
res.data.body = this.renderSkinAsString("$Poll#edit");
this.site.renderSkin("Site#page");
return;
if (req.postParams.save) {
try {
this.update(req.postParams);
res.message = gettext("The poll was updated successfully.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Edit Poll: {0}", this.question);
res.data.body = this.renderSkinAsString("$Poll#edit");
this.site.renderSkin("Site#page");
return;
}
/**
@ -187,66 +187,66 @@ Poll.prototype.edit_action = function() {
* @param {Object} data
*/
Poll.prototype.update = function(data) {
var choices = [];
for each (var title in data.title_array) {
if (title = title.trim()) {
choices.push(title);
}
}
if (choices.length < 2 || !data.question) {
throw Error(gettext("Please fill out the whole form to create a valid poll."));
}
var size = this.size();
// Update or remove choices
for (var i=size-1; i>-1; i-=1) {
var choice = this.get(i);
var title = choices[i];
if (title) {
choice.title = title;
choice.touch();
} else {
Choice.remove.call(choice);
}
}
// Add new choices
for (var i=size; i<choices.length; i+=1) {
Choice.add(choices[i], this);
}
if (data.save !== Poll.CLOSED) {
delete this.closed;
} else if (this.status === Poll.OPEN) {
this.closed = new Date;
}
this.status = data.save;
this.question = data.question;
this.touch();
return;
var choices = [];
for each (var title in data.title_array) {
if (title = title.trim()) {
choices.push(title);
}
}
if (choices.length < 2 || !data.question) {
throw Error(gettext("Please fill out the whole form to create a valid poll."));
}
var size = this.size();
// Update or remove choices
for (var i=size-1; i>-1; i-=1) {
var choice = this.get(i);
var title = choices[i];
if (title) {
choice.title = title;
choice.touch();
} else {
Choice.remove.call(choice);
}
}
// Add new choices
for (var i=size; i<choices.length; i+=1) {
Choice.add(choices[i], this);
}
if (data.save !== Poll.CLOSED) {
delete this.closed;
} else if (this.status === Poll.OPEN) {
this.closed = new Date;
}
this.status = data.save;
this.question = data.question;
this.touch();
return;
}
Poll.prototype.result_action = function() {
res.data.title = gettext('Poll Results: {0}', this.question);
res.data.body = this.renderSkinAsString("$Poll#results", {header: true});
this.site.renderSkin("Site#page");
return;
res.data.title = gettext('Poll Results: {0}', this.question);
res.data.body = this.renderSkinAsString("$Poll#results", {header: true});
this.site.renderSkin("Site#page");
return;
}
Poll.prototype.rotate_action = function() {
if (this.status === Poll.CLOSED) {
this.status = Poll.OPEN;
} else if (this.status === Poll.OPEN) {
this.status = Poll.CLOSED;
this.closed = new Date;
}
this.touch();
return res.redirect(this.href());
if (this.status === Poll.CLOSED) {
this.status = Poll.OPEN;
} else if (this.status === Poll.OPEN) {
this.status = Poll.CLOSED;
this.closed = new Date;
}
this.touch();
return res.redirect(this.href());
}
/**
* @returns {String}
*/
Poll.prototype.getConfirmText = function() {
return gettext("You are about to delete a poll by user {0}.",
this.creator.name);
return gettext("You are about to delete a poll by user {0}.",
this.creator.name);
}
/**
@ -257,22 +257,22 @@ Poll.prototype.getConfirmText = function() {
* @see HopObject#link_macro
*/
Poll.prototype.link_macro = function(param, action, text) {
switch (action) {
case ".":
case "main":
if (this.status === Poll.CLOSED) {
return;
}
break;
case "rotate":
if (this.status === Poll.OPEN) {
text = gettext("Stop");
} else {
text = this.closed ? gettext("Re-run") : gettext("Run");
}
break;
switch (action) {
case ".":
case "main":
if (this.status === Poll.CLOSED) {
return;
}
break;
case "rotate":
if (this.status === Poll.OPEN) {
text = gettext("Stop");
} else {
text = this.closed ? gettext("Re-run") : gettext("Run");
}
break;
}
return HopObject.prototype.link_macro.call(this, param, action, text);
return HopObject.prototype.link_macro.call(this, param, action, text);
}
/**
@ -282,34 +282,34 @@ Poll.prototype.link_macro = function(param, action, text) {
* @see HopObject#link_macro
*/
Poll.prototype.input_macro = function(param, name) {
switch (name) {
case "choices":
var index = 0;
var add = function(choice) {
index += 1;
return choice.renderSkin("$Choice#edit", {index: index});
};
var choices;
if (choices = req.postParams.title_array) {
HopObject.confirmConstructor(Choice);
choices.forEach(function(title) {
return add(new Choice(title));
});
} else {
this.forEach(function() {
return add(this);
});
}
return;
}
return HopObject.prototype.input_macro.apply(this, arguments);
switch (name) {
case "choices":
var index = 0;
var add = function(choice) {
index += 1;
return choice.renderSkin("$Choice#edit", {index: index});
};
var choices;
if (choices = req.postParams.title_array) {
HopObject.confirmConstructor(Choice);
choices.forEach(function(title) {
return add(new Choice(title));
});
} else {
this.forEach(function() {
return add(this);
});
}
return;
}
return HopObject.prototype.input_macro.apply(this, arguments);
}
/**
*
*/
Poll.prototype.votes_macro = function() {
return this.votes.size();
return this.votes.size();
}
/**
@ -318,8 +318,8 @@ Poll.prototype.votes_macro = function() {
* @param {String} format
*/
Poll.prototype.closed_macro = function(param, format) {
if (this.status === Poll.CLOSED) {
res.write(formatDate(this.closed, param.format || format));
}
return;
if (this.status === Poll.CLOSED) {
res.write(formatDate(this.closed, param.format || format));
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -44,73 +44,73 @@ markgettext("polls");
* @returns {Boolean}
*/
Polls.prototype.getPermission = function(action) {
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
case "running":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
return Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
case "running":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
return Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
}
Polls.prototype.main_action = function() {
var polls = User.getMembership().polls;
res.data.list = renderList(polls, "$Poll#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(polls, this.href(req.action),
10, req.queryParams.page);
res.data.title = gettext("Member Polls");
res.data.body = this.renderSkinAsString("$Polls#main");
this._parent.renderSkin("Site#page");
return;
var polls = User.getMembership().polls;
res.data.list = renderList(polls, "$Poll#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(polls, this.href(req.action),
10, req.queryParams.page);
res.data.title = gettext("Member Polls");
res.data.body = this.renderSkinAsString("$Polls#main");
this._parent.renderSkin("Site#page");
return;
}
Polls.prototype.create_action = function() {
if (req.postParams.save) {
try {
var poll = Poll.add(req.postParams, this._parent);
poll.notify(req.action);
res.message = gettext("The poll was created successfully.");
res.redirect(poll.href());
} catch (err) {
res.message = err.toString();
}
} else {
req.postParams.title_array = [null, null];
}
res.data.action = this.href(req.action);
res.data.title = gettext("Add Poll");
HopObject.confirmConstructor(Poll);
res.data.body = (new Poll).renderSkinAsString("$Poll#edit");
this._parent.renderSkin("Site#page");
return;
if (req.postParams.save) {
try {
var poll = Poll.add(req.postParams, this._parent);
poll.notify(req.action);
res.message = gettext("The poll was created successfully.");
res.redirect(poll.href());
} catch (err) {
res.message = err.toString();
}
} else {
req.postParams.title_array = [null, null];
}
res.data.action = this.href(req.action);
res.data.title = gettext("Add Poll");
HopObject.confirmConstructor(Poll);
res.data.body = (new Poll).renderSkinAsString("$Poll#edit");
this._parent.renderSkin("Site#page");
return;
}
Polls.prototype.running_action = function() {
res.data.list = renderList(this.running,
"$Poll#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this.running,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("Running Polls");
res.data.body = this.renderSkinAsString("$Polls#main");
this._parent.renderSkin("Site#page");
return;
res.data.list = renderList(this.running,
"$Poll#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this.running,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("Running Polls");
res.data.body = this.renderSkinAsString("$Polls#main");
this._parent.renderSkin("Site#page");
return;
}
Polls.prototype.all_action = function() {
res.data.list = renderList(this, "$Poll#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this,
this.href(), 10, req.queryParams.page);
res.data.title = gettext("All Polls");
res.data.body = this.renderSkinAsString("$Polls#main");
this._parent.renderSkin("Site#page");
return;
res.data.list = renderList(this, "$Poll#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this,
this.href(), 10, req.queryParams.page);
res.data.title = gettext("All Polls");
res.data.body = this.renderSkinAsString("$Polls#main");
this._parent.renderSkin("Site#page");
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -29,27 +29,27 @@
/** @constant */
Root.VERSION = (function(versionString, buildDate) {
// A valid version string is e.g. "1.2.3alpha.4711".
// Repositories could add something like "-compatible" to it,
// FIXME: This should be refactored for modular extension.
var re = /^(\d+)\.(\d+)(?:\.(\d+))?(.+)?\.(\d+)(?:-(.*))?$/;
var parts = re.exec(versionString);
if (parts) {
var result = {
parts: parts,
toString: function() {return parts[0]},
major: parseInt(parts[1]),
revision: parseInt(parts[5]),
date: new Date(buildDate)
};
result.minor = result.major + parseInt(parts[2] || 0) / 10;
result.bugfix = result.minor + "." + (parts[3] || 0);
result.development = parts[4] || "";
result["default"] = result[parts[3] ? "bugfix" : "minor"] + result.development +
(parts[6] ? "-" + parts[6] : String.EMPTY);
return result;
}
return versionString;
// A valid version string is e.g. "1.2.3alpha.4711".
// Repositories could add something like "-compatible" to it,
// FIXME: This should be refactored for modular extension.
var re = /^(\d+)\.(\d+)(?:\.(\d+))?(.+)?\.(\d+)(?:-(.*))?$/;
var parts = re.exec(versionString);
if (parts) {
var result = {
parts: parts,
toString: function() {return parts[0]},
major: parseInt(parts[1]),
revision: parseInt(parts[5]),
date: new Date(buildDate)
};
result.minor = result.major + parseInt(parts[2] || 0) / 10;
result.bugfix = result.minor + "." + (parts[3] || 0);
result.development = parts[4] || "";
result["default"] = result[parts[3] ? "bugfix" : "minor"] + result.development +
(parts[6] ? "-" + parts[6] : String.EMPTY);
return result;
}
return versionString;
})("@version@.@revision@", "@buildDate@");
this.handleMetadata("creationDelay");
@ -92,243 +92,243 @@ this.handleMetadata("replyTo");
* @returns {Boolean}
*/
Root.prototype.getPermission = function(action) {
if (action && action.contains("admin")) {
return User.require(User.PRIVILEGED);
}
switch (action) {
case "debug":
case "default.hook":
case "health":
case "jala.test":
case "jala.test.css":
case "mrtg":
case "sites":
case "updates.xml":
return true;
case "create":
return this.getCreationPermission();
}
return Site.prototype.getPermission.apply(this, arguments);
if (action && action.contains("admin")) {
return User.require(User.PRIVILEGED);
}
switch (action) {
case "debug":
case "default.hook":
case "health":
case "jala.test":
case "jala.test.css":
case "mrtg":
case "sites":
case "updates.xml":
return true;
case "create":
return this.getCreationPermission();
}
return Site.prototype.getPermission.apply(this, arguments);
}
Root.prototype.main_action = function() {
if (this.users.size() < 1) {
this.title = "Antville";
this.created = new Date;
this.replyTo = "root@localhost";
this.locale = java.util.Locale.getDefault().getLanguage();
this.timeZone = java.util.TimeZone.getDefault().getID();
this.layout.reset();
res.redirect(this.members.href("register"));
} else if (session.user && this.members.owners.size() < 1) {
this.creator = this.modifier = this.layout.creator =
this.layout.modifier = session.user;
this.created = this.modified = this.layout.created =
this.layout.modified = new Date;
session.user.role = User.PRIVILEGED;
res.handlers.membership.role = Membership.OWNER;
}
return Site.prototype.main_action.apply(this);
if (this.users.size() < 1) {
this.title = "Antville";
this.created = new Date;
this.replyTo = "root@localhost";
this.locale = java.util.Locale.getDefault().getLanguage();
this.timeZone = java.util.TimeZone.getDefault().getID();
this.layout.reset();
res.redirect(this.members.href("register"));
} else if (session.user && this.members.owners.size() < 1) {
this.creator = this.modifier = this.layout.creator =
this.layout.modifier = session.user;
this.created = this.modified = this.layout.created =
this.layout.modified = new Date;
session.user.role = User.PRIVILEGED;
res.handlers.membership.role = Membership.OWNER;
}
return Site.prototype.main_action.apply(this);
}
Root.prototype.error_action = function() {
res.message = String.EMPTY;
var param = res.error ? res : session.data;
res.status = param.status || 500;
res.data.title = gettext("{0} {1} Error", root.getTitle(), param.status);
res.data.body = root.renderSkinAsString("$Root#error", param);
res.handlers.site.renderSkin("Site#page");
return;
res.message = String.EMPTY;
var param = res.error ? res : session.data;
res.status = param.status || 500;
res.data.title = gettext("{0} {1} Error", root.getTitle(), param.status);
res.data.body = root.renderSkinAsString("$Root#error", param);
res.handlers.site.renderSkin("Site#page");
return;
}
Root.prototype.notfound_action = function() {
res.status = 404;
res.data.title = gettext("{0} {1} Error", root.getTitle(), res.status);
res.data.body = root.renderSkinAsString("$Root#notfound", req);
res.handlers.site.renderSkin("Site#page");
return;
res.status = 404;
res.data.title = gettext("{0} {1} Error", root.getTitle(), res.status);
res.data.body = root.renderSkinAsString("$Root#notfound", req);
res.handlers.site.renderSkin("Site#page");
return;
}
Root.prototype.create_action = function() {
if (req.postParams.create) {
try {
var site = Site.add(req.postParams);
Membership.add(session.user, Membership.OWNER, site);
root.admin.log(root, "Added site " + site.name);
res.message = gettext("Successfully created your site.");
res.redirect(site.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
if (req.postParams.create) {
try {
var site = Site.add(req.postParams);
Membership.add(session.user, Membership.OWNER, site);
root.admin.log(root, "Added site " + site.name);
res.message = gettext("Successfully created your site.");
res.redirect(site.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
// Cannot use res.handlers.site because somehow it is always root
res.handlers.newSite = new Site;
res.handlers.example = new Site;
res.handlers.example.name = "foo";
res.data.action = this.href(req.action);
res.data.title = gettext("Add Site");
res.data.body = root.renderSkinAsString("$Root#create");
root.renderSkin("Site#page");
return;
// Cannot use res.handlers.site because somehow it is always root
res.handlers.newSite = new Site;
res.handlers.example = new Site;
res.handlers.example.name = "foo";
res.data.action = this.href(req.action);
res.data.title = gettext("Add Site");
res.data.body = root.renderSkinAsString("$Root#create");
root.renderSkin("Site#page");
return;
}
Root.prototype.sites_action = function() {
var now = new Date;
if (!this.cache.sites || (now - this.cache.sites.modified > Date.ONEHOUR)) {
var sites = this.sites.list();
sites.sort(new String.Sorter("title"));
this.cache.sites = {list: sites, modified: now};
}
res.data.list = renderList(this.cache.sites.list,
"$Site#listItem", 25, req.queryParams.page);
res.data.pager = renderPager(this.cache.sites.list,
this.href(req.action), 25, req.queryParams.page);
res.data.title = gettext("Public Sites");
res.data.body = this.renderSkinAsString("$Root#sites");
root.renderSkin("Site#page");
return;
var now = new Date;
if (!this.cache.sites || (now - this.cache.sites.modified > Date.ONEHOUR)) {
var sites = this.sites.list();
sites.sort(new String.Sorter("title"));
this.cache.sites = {list: sites, modified: now};
}
res.data.list = renderList(this.cache.sites.list,
"$Site#listItem", 25, req.queryParams.page);
res.data.pager = renderPager(this.cache.sites.list,
this.href(req.action), 25, req.queryParams.page);
res.data.title = gettext("Public Sites");
res.data.body = this.renderSkinAsString("$Root#sites");
root.renderSkin("Site#page");
return;
}
Root.prototype.updates_xml_action = function() {
res.contentType = "application/rss+xml";
var now = new Date;
var feed = new rome.SyndFeedImpl();
feed.setFeedType("rss_2.0");
feed.setLink(root.href());
feed.setTitle("Recently updated sites at " + root.title);
feed.setDescription(root.tagline || String.EMPTY);
feed.setLanguage(root.locale.replace("_", "-"));
feed.setPublishedDate(now);
var entries = new java.util.ArrayList();
var entry, description;
var sites = root.updates.list(0, 25).sort(Number.Sorter("modified",
Number.Sorter.DESC));
for each (var site in sites) {
entry = new rome.SyndEntryImpl();
entry.setTitle(site.title);
entry.setLink(site.href());
entry.setAuthor(site.creator.name);
entry.setPublishedDate(site.modified);
description = new rome.SyndContentImpl();
description.setType("text/plain");
description.setValue(site.tagline);
entry.setDescription(description);
entries.add(entry);
}
feed.setEntries(entries);
var output = new rome.SyndFeedOutput();
//output.output(feed, res.servletResponse.writer); return;
var xml = output.outputString(feed);
res.write(xml); //injectXslDeclaration(xml));
return;
res.contentType = "application/rss+xml";
var now = new Date;
var feed = new rome.SyndFeedImpl();
feed.setFeedType("rss_2.0");
feed.setLink(root.href());
feed.setTitle("Recently updated sites at " + root.title);
feed.setDescription(root.tagline || String.EMPTY);
feed.setLanguage(root.locale.replace("_", "-"));
feed.setPublishedDate(now);
var entries = new java.util.ArrayList();
var entry, description;
var sites = root.updates.list(0, 25).sort(Number.Sorter("modified",
Number.Sorter.DESC));
for each (var site in sites) {
entry = new rome.SyndEntryImpl();
entry.setTitle(site.title);
entry.setLink(site.href());
entry.setAuthor(site.creator.name);
entry.setPublishedDate(site.modified);
description = new rome.SyndContentImpl();
description.setType("text/plain");
description.setValue(site.tagline);
entry.setDescription(description);
entries.add(entry);
}
feed.setEntries(entries);
var output = new rome.SyndFeedOutput();
//output.output(feed, res.servletResponse.writer); return;
var xml = output.outputString(feed);
res.write(xml); //injectXslDeclaration(xml));
return;
}
// Sitemap for Google Webmaster Tools
// (Unfortunately, utterly useless.)
Root.prototype.sitemap_xml_action = function() {
res.contentType = "text/xml";
res.writeln('<?xml version="1.0" encoding="UTF-8"?>');
res.writeln('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');
this.sites.forEach(function() {
res.writeln('<url>');
res.writeln('<loc>' + this.href() + '</loc>');
if (this.modified) {
res.writeln('<lastmod>' + this.modified.format("yyyy-MM-dd") + '</lastmod>');
}
res.writeln('</url>');
});
res.writeln('</urlset>');
return;
res.contentType = "text/xml";
res.writeln('<?xml version="1.0" encoding="UTF-8"?>');
res.writeln('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">');
this.sites.forEach(function() {
res.writeln('<url>');
res.writeln('<loc>' + this.href() + '</loc>');
if (this.modified) {
res.writeln('<lastmod>' + this.modified.format("yyyy-MM-dd") + '</lastmod>');
}
res.writeln('</url>');
});
res.writeln('</urlset>');
return;
}
Root.prototype.health_action = function() {
var jvm = java.lang.Runtime.getRuntime();
var totalMemory = jvm.totalMemory() / 1024 / 1024;
var freeMemory = jvm.freeMemory() / 1024 / 1024;
var jvm = java.lang.Runtime.getRuntime();
var totalMemory = jvm.totalMemory() / 1024 / 1024;
var freeMemory = jvm.freeMemory() / 1024 / 1024;
var param = {
uptime: formatNumber((new Date - app.upSince.getTime()) /
Date.ONEDAY, "0.##"),
freeMemory: formatNumber(freeMemory),
totalMemory: formatNumber(totalMemory),
usedMemory: formatNumber(totalMemory - freeMemory),
sessions: formatNumber(app.countSessions()),
cacheSize: formatNumber(getProperty("cacheSize"))
};
var param = {
uptime: formatNumber((new Date - app.upSince.getTime()) /
Date.ONEDAY, "0.##"),
freeMemory: formatNumber(freeMemory),
totalMemory: formatNumber(totalMemory),
usedMemory: formatNumber(totalMemory - freeMemory),
sessions: formatNumber(app.countSessions()),
cacheSize: formatNumber(getProperty("cacheSize"))
};
for each (key in ["activeThreads", "freeThreads", "requestCount",
"errorCount", "xmlrpcCount", "cacheusage"]) {
param[key] = formatNumber(app[key]);
}
for each (key in ["activeThreads", "freeThreads", "requestCount",
"errorCount", "xmlrpcCount", "cacheusage"]) {
param[key] = formatNumber(app[key]);
}
param.errorRatio = formatNumber(100 * app.errorCount / app.requestCount || 0);
param.errorRatioPerUnit = formatNumber(Admin.health.errorsPerUnit / Admin.health.requestsPerUnit || 0);
if (Admin.health) {
param.requestsPerUnit = formatNumber(Admin.health.requestsPerUnit);
param.errorsPerUnit = formatNumber(Admin.health.errorsPerUnit);
}
param.errorRatio = formatNumber(100 * app.errorCount / app.requestCount || 0);
param.errorRatioPerUnit = formatNumber(Admin.health.errorsPerUnit / Admin.health.requestsPerUnit || 0);
if (Admin.health) {
param.requestsPerUnit = formatNumber(Admin.health.requestsPerUnit);
param.errorsPerUnit = formatNumber(Admin.health.errorsPerUnit);
}
param.entries = app.data.entries.length;
param.mails = app.data.mails.length;
param.requests = 0;
for (var i in app.data.requests) {
param.requests += 1;
}
param.callbacks = app.data.callbacks.length;
param.entries = app.data.entries.length;
param.mails = app.data.mails.length;
param.requests = 0;
for (var i in app.data.requests) {
param.requests += 1;
}
param.callbacks = app.data.callbacks.length;
res.data.title = gettext("{0} Health", root.getTitle());
res.data.body = this.renderSkinAsString("$Root#health", param);
this.renderSkin("Site#page");
res.data.title = gettext("{0} Health", root.getTitle());
res.data.body = this.renderSkinAsString("$Root#health", param);
this.renderSkin("Site#page");
}
Root.prototype.mrtg_action = function() {
res.contentType = "text/plain";
var target = req.queryParams.target;
if (!target) {
return;
}
switch (target) {
case "cache":
res.writeln(0);
res.writeln(app.cacheusage * 100 / getProperty("cacheSize", 100));
break;
case "threads":
res.writeln(0);
res.writeln(app.activeThreads * 100 / app.freeThreads);
break;
case "requests":
res.writeln(app.errorCount);
res.writeln(app.requestCount);
break;
case "users":
res.writeln(app.countSessions());
res.writeln(root.users.size());
break;
case "postings":
res.writeln(0);
var sql = new Sql;
sql.retrieve(Sql.COUNT, "content");
sql.traverse(function() {
res.writeln(this.count);
});
break;
case "uploads":
var sql = new Sql;
sql.retrieve(Sql.COUNT, "file");
sql.traverse(function() {
res.writeln(this.count);
});
sql.retrieve(Sql.COUNT, "image");
sql.traverse(function() {
res.writeln(this.count);
});
break;
}
res.writeln(app.upSince);
res.writeln("mrtg." + target + " of Antville version " + Root.VERSION);
return;
res.contentType = "text/plain";
var target = req.queryParams.target;
if (!target) {
return;
}
switch (target) {
case "cache":
res.writeln(0);
res.writeln(app.cacheusage * 100 / getProperty("cacheSize", 100));
break;
case "threads":
res.writeln(0);
res.writeln(app.activeThreads * 100 / app.freeThreads);
break;
case "requests":
res.writeln(app.errorCount);
res.writeln(app.requestCount);
break;
case "users":
res.writeln(app.countSessions());
res.writeln(root.users.size());
break;
case "postings":
res.writeln(0);
var sql = new Sql;
sql.retrieve(Sql.COUNT, "content");
sql.traverse(function() {
res.writeln(this.count);
});
break;
case "uploads":
var sql = new Sql;
sql.retrieve(Sql.COUNT, "file");
sql.traverse(function() {
res.writeln(this.count);
});
sql.retrieve(Sql.COUNT, "image");
sql.traverse(function() {
res.writeln(this.count);
});
break;
}
res.writeln(app.upSince);
res.writeln("mrtg." + target + " of Antville version " + Root.VERSION);
return;
}
/**
@ -338,13 +338,13 @@ Root.prototype.mrtg_action = function() {
* @see Site#getMacroHandler
*/
Root.prototype.getMacroHandler = function(name) {
switch (name) {
case "admin":
case "api":
case "sites":
return this[name];
}
return Site.prototype.getMacroHandler.apply(this, arguments);
switch (name) {
case "admin":
case "api":
case "sites":
return this[name];
}
return Site.prototype.getMacroHandler.apply(this, arguments);
}
/**
@ -354,54 +354,54 @@ Root.prototype.getMacroHandler = function(name) {
* @see Site#getFormOptions
*/
Root.prototype.getFormOptions = function(name) {
switch (name) {
case "creationScope":
return Admin.getCreationScopes();
case "notificationScope":
return Admin.getNotificationScopes();
case "phaseOutMode":
return Admin.getPhaseOutModes();
}
return Site.prototype.getFormOptions.apply(root, arguments);
switch (name) {
case "creationScope":
return Admin.getCreationScopes();
case "notificationScope":
return Admin.getNotificationScopes();
case "phaseOutMode":
return Admin.getPhaseOutModes();
}
return Site.prototype.getFormOptions.apply(root, arguments);
}
/**
* @returns {Boolean}
*/
Root.prototype.getCreationPermission = function() {
var user;
if (!(user = session.user)) {
return false;
} if (User.require(User.PRIVILEGED)) {
return true;
}
var user;
if (!(user = session.user)) {
return false;
} if (User.require(User.PRIVILEGED)) {
return true;
}
switch (root.creationScope) {
case User.PRIVILEGED:
return false;
case User.TRUSTED:
return User.require(User.TRUSTED);
default:
case User.REGULAR:
var now = new Date, delta;
if (root.probationPeriod) {
delta = root.probationPeriod - Math.floor((now -
user.created) / Date.ONEDAY);
if (delta > 0) {
session.data.error = gettext("You need to wait {0} before you are allowed to create a new site.",
ngettext("{0} day", "{0} days", delta));
return false;
}
switch (root.creationScope) {
case User.PRIVILEGED:
return false;
case User.TRUSTED:
return User.require(User.TRUSTED);
default:
case User.REGULAR:
var now = new Date, delta;
if (root.probationPeriod) {
delta = root.probationPeriod - Math.floor((now -
user.created) / Date.ONEDAY);
if (delta > 0) {
session.data.error = gettext("You need to wait {0} before you are allowed to create a new site.",
ngettext("{0} day", "{0} days", delta));
return false;
}
if (root.creationDelay && user.sites.count() > 0) {
delta = root.creationDelay - Math.floor((now -
user.sites.get(0).created) / Date.ONEDAY);
if (delta > 0) {
session.data.error = gettext("You need to wait {0} before you are allowed to create a new site.",
ngettext("{0} day", "{0} days", delta));
return false;
}
}
if (root.creationDelay && user.sites.count() > 0) {
delta = root.creationDelay - Math.floor((now -
user.sites.get(0).created) / Date.ONEDAY);
if (delta > 0) {
session.data.error = gettext("You need to wait {0} before you are allowed to create a new site.",
ngettext("{0} day", "{0} days", delta));
return false;
}
}
return true;
}
}
return true;
}

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@
// 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
// 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,
@ -35,14 +35,14 @@ markgettext("skin");
* @returns {Skin}
*/
Skin.getByName = function(group, name) {
var skinSet = (res.handlers.layout || path.layout).skins.get(group);
if (skinSet) {
var skin = skinSet.get(name);
if (skin) {
return skin;
}
}
return null;
var skinSet = (res.handlers.layout || path.layout).skins.get(group);
if (skinSet) {
var skin = skinSet.get(name);
if (skin) {
return skin;
}
}
return null;
}
/**
@ -51,9 +51,9 @@ Skin.getByName = function(group, name) {
* @param {Layout} layout
*/
Skin.add = function(prototype, name, layout) {
var skin = new Skin(prototype, name);
layout.skins.add(skin);
return skin;
var skin = new Skin(prototype, name);
layout.skins.add(skin);
return skin;
}
/**
@ -61,31 +61,31 @@ Skin.add = function(prototype, name, layout) {
* @param {Skin} skin
*/
Skin.remove = function() {
if (this.constructor === Skin) {
this.setSource(this.source);
this.source = null;
this.remove();
}
return;
if (this.constructor === Skin) {
this.setSource(this.source);
this.source = null;
this.remove();
}
return;
}
/**
* @returns {String[]}
*/
Skin.getPrototypeOptions = function() {
var prototypes = [];
var content, file;
var skinFiles = app.getSkinfilesInPath(res.skinpath);
for (var name in skinFiles) {
// Include root skins only for root site
if (name === root.constructor.name && res.handlers.site !== root) {
continue;
}
if (skinFiles[name][name]) {
prototypes.push({value: name, display: name});
}
}
return prototypes.sort(new String.Sorter("display"));
var prototypes = [];
var content, file;
var skinFiles = app.getSkinfilesInPath(res.skinpath);
for (var name in skinFiles) {
// Include root skins only for root site
if (name === root.constructor.name && res.handlers.site !== root) {
continue;
}
if (skinFiles[name][name]) {
prototypes.push({value: name, display: name});
}
}
return prototypes.sort(new String.Sorter("display"));
}
/**
@ -103,12 +103,12 @@ Skin.getPrototypeOptions = function() {
* @extends HopObject
*/
Skin.prototype.constructor = function(prototype, name) {
HopObject.confirmConstructor(this);
this.prototype = prototype || String.EMPTY;
this.name = name || String.EMPTY;
this.creator = this.modifier = session.user;
this.created = this.modified = new Date;
return this;
HopObject.confirmConstructor(this);
this.prototype = prototype || String.EMPTY;
this.name = name || String.EMPTY;
this.creator = this.modifier = session.user;
this.created = this.modified = new Date;
return this;
}
/**
@ -117,12 +117,12 @@ Skin.prototype.constructor = function(prototype, name) {
* @returns {Boolean}
*/
Skin.prototype.getPermission = function(action) {
switch (action) {
case ".":
case "main":
return true;
}
return res.handlers.skins.getPermission("main");
switch (action) {
case ".":
case "main":
return true;
}
return res.handlers.skins.getPermission("main");
}
/**
@ -131,47 +131,47 @@ Skin.prototype.getPermission = function(action) {
* @returns {String}
*/
Skin.prototype.href = function(action) {
res.push();
res.write(res.handlers.layout.skins.href());
res.write(this.prototype);
res.write("/");
res.write(this.name);
res.write("/");
action && (res.write(action));
return res.pop();
res.push();
res.write(res.handlers.layout.skins.href());
res.write(this.prototype);
res.write("/");
res.write(this.name);
res.write("/");
action && (res.write(action));
return res.pop();
}
Skin.prototype.main_action = function() {
if (res.handlers.site === root) {
res.contentType = "text/plain";
res.write(this.getSource());
return;
}
res.redirect(this.href("edit"));
return;
if (res.handlers.site === root) {
res.contentType = "text/plain";
res.write(this.getSource());
return;
}
res.redirect(this.href("edit"));
return;
}
Skin.prototype.edit_action = function() {
if (req.postParams.save) {
try {
var url = this.href(req.action);
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
if (req.postParams.save == 1) {
res.redirect(url);
} else {
res.redirect(res.handlers.layout.skins.href("modified"));
}
} catch (ex) {
res.message = ex;
app.log(ex);
if (req.postParams.save) {
try {
var url = this.href(req.action);
this.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
if (req.postParams.save == 1) {
res.redirect(url);
} else {
res.redirect(res.handlers.layout.skins.href("modified"));
}
}
res.data.action = this.href(req.action);
res.data.title = gettext('Edit Skin: {0}.{1}', this.prototype, this.name);
res.data.body = this.renderSkinAsString("$Skin#edit");
res.handlers.skins.renderSkin("$Skins#page");
return;
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext('Edit Skin: {0}.{1}', this.prototype, this.name);
res.data.body = this.renderSkinAsString("$Skin#edit");
res.handlers.skins.renderSkin("$Skins#page");
return;
}
/**
@ -179,96 +179,96 @@ Skin.prototype.edit_action = function() {
* @param {Object} data
*/
Skin.prototype.update = function(data) {
if (this.isTransient()) {
res.handlers.layout.skins.add(this);
this.source = this.getSource(); // Copies the skin file source to database
}
if (this.prototype === "Site" && this.name === "page") {
var macro = "response.body";
if (!createSkin(data.source).containsMacro(macro)) {
var macro = ["<code><%", macro, "%></code>"].join(String.EMPTY);
throw Error(gettext("The {0} macro is missing. It is essential for accessing the site and must be present in this skin.", macro));
}
}
this.setSource(data.source);
this.touch();
return;
if (this.isTransient()) {
res.handlers.layout.skins.add(this);
this.source = this.getSource(); // Copies the skin file source to database
}
if (this.prototype === "Site" && this.name === "page") {
var macro = "response.body";
if (!createSkin(data.source).containsMacro(macro)) {
var macro = ["<code><%", macro, "%></code>"].join(String.EMPTY);
throw Error(gettext("The {0} macro is missing. It is essential for accessing the site and must be present in this skin.", macro));
}
}
this.setSource(data.source);
this.touch();
return;
}
Skin.prototype.reset_action = function() {
if (req.postParams.proceed) {
try {
Skin.remove.call(this);
res.message = gettext("{0} was successfully reset.", gettext("Skin"));
res.redirect(res.handlers.layout.skins.href("modified"));
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
if (req.postParams.proceed) {
try {
Skin.remove.call(this);
res.message = gettext("{0} was successfully reset.", gettext("Skin"));
res.redirect(res.handlers.layout.skins.href("modified"));
} catch(ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext("Confirm Reset");
res.data.body = this.renderSkinAsString("$HopObject#confirm", {
text: this.getConfirmText()
});
res.handlers.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext("Confirm Reset");
res.data.body = this.renderSkinAsString("$HopObject#confirm", {
text: this.getConfirmText()
});
res.handlers.site.renderSkin("Site#page");
return;
}
Skin.prototype.compare_action = function() {
var originalSkin = this.source || String.EMPTY;
var diff = this.getSource().diff(originalSkin);
if (!diff) {
res.message = gettext("No differences were found.");
} else {
res.push();
var param = {}, leftLineNumber = rightLineNumber = 0;
for each (let line in diff) {
if (line.deleted) {
param.right = encode(line.value);
param.leftStatus = "added";
param.rightStatus = '';
for (let i=0; i<line.deleted.length; i++) {
leftLineNumber += 1;
param.leftLineNumber = leftLineNumber;
param.rightLineNumber = '';
param.left = encode(line.deleted[i]);
param.right = '';
this.renderSkin("$Skin#difference", param);
}
}
if (line.inserted) {
param.left = encode(line.value);
param.leftStatus = '';
param.rightStatus = 'removed';
for (let i=0; i<line.inserted.length; i++) {
rightLineNumber += 1;
param.leftLineNumber = '';
param.rightLineNumber = rightLineNumber;
param.left = '';
param.right = encode(line.inserted[i]);
this.renderSkin("$Skin#difference", param);
}
}
if (line.value !== null) {
leftLineNumber += 1;
rightLineNumber += 1;
param.leftLineNumber = leftLineNumber;
param.rightLineNumber = rightLineNumber;
param.leftStatus = param.rightStatus = '';
param.left = encode(line.value);
param.right = param.left;
this.renderSkin("$Skin#difference", param);
}
var originalSkin = this.source || String.EMPTY;
var diff = this.getSource().diff(originalSkin);
if (!diff) {
res.message = gettext("No differences were found.");
} else {
res.push();
var param = {}, leftLineNumber = rightLineNumber = 0;
for each (let line in diff) {
if (line.deleted) {
param.right = encode(line.value);
param.leftStatus = "added";
param.rightStatus = '';
for (let i=0; i<line.deleted.length; i++) {
leftLineNumber += 1;
param.leftLineNumber = leftLineNumber;
param.rightLineNumber = '';
param.left = encode(line.deleted[i]);
param.right = '';
this.renderSkin("$Skin#difference", param);
}
}
res.data.diff = res.pop();
}
if (line.inserted) {
param.left = encode(line.value);
param.leftStatus = '';
param.rightStatus = 'removed';
for (let i=0; i<line.inserted.length; i++) {
rightLineNumber += 1;
param.leftLineNumber = '';
param.rightLineNumber = rightLineNumber;
param.left = '';
param.right = encode(line.inserted[i]);
this.renderSkin("$Skin#difference", param);
}
}
if (line.value !== null) {
leftLineNumber += 1;
rightLineNumber += 1;
param.leftLineNumber = leftLineNumber;
param.rightLineNumber = rightLineNumber;
param.leftStatus = param.rightStatus = '';
param.left = encode(line.value);
param.right = param.left;
this.renderSkin("$Skin#difference", param);
}
}
res.data.diff = res.pop();
}
res.data.title = gettext("Compare Skin: {0}", this.getTitle());
res.data.body = this.renderSkinAsString("$Skin#compare");
res.handlers.skins.renderSkin("$Skins#page");
return;
res.data.title = gettext("Compare Skin: {0}", this.getTitle());
res.data.body = this.renderSkinAsString("$Skin#compare");
res.handlers.skins.renderSkin("$Skins#page");
return;
}
/**
@ -276,7 +276,7 @@ Skin.prototype.compare_action = function() {
* @return {String}
*/
Skin.prototype.getTitle = function() {
return this.prototype + '.' + this.name;
return this.prototype + '.' + this.name;
}
/**
@ -285,37 +285,37 @@ Skin.prototype.getTitle = function() {
* @return {Object}
*/
Skin.prototype.getFormOptions = function(name) {
switch (name) {
case "prototype":
return Skin.getPrototypeOptions();
}
switch (name) {
case "prototype":
return Skin.getPrototypeOptions();
}
}
Skin.prototype.getFormValue = function(name) {
switch (name) {
case "source":
return req.data.source || this.getSource();
}
return HopObject.prototype.getFormValue.apply(this, arguments);
switch (name) {
case "source":
return req.data.source || this.getSource();
}
return HopObject.prototype.getFormValue.apply(this, arguments);
}
/**
* @returns {String}
*/
Skin.prototype.getSource = function() {
var skin;
// FIXME: Maintain skin inheritance by checking if we target the Site skin of root
if (res.handlers.site === root && this.prototype === "Site") {
skin = this.getSubskin("Root");
if (skin) {
return skin.getSource();
}
}
skin = this.getSubskin();
if (skin) {
var skin;
// FIXME: Maintain skin inheritance by checking if we target the Site skin of root
if (res.handlers.site === root && this.prototype === "Site") {
skin = this.getSubskin("Root");
if (skin) {
return skin.getSource();
}
return null;
}
}
skin = this.getSubskin();
if (skin) {
return skin.getSource();
}
return null;
}
/**
@ -323,43 +323,43 @@ Skin.prototype.getSource = function() {
* @param {String} source
*/
Skin.prototype.setSource = function(source) {
// FIXME: Maintain skin inheritance by checking if we target the Site skin of root
var prototype = (res.handlers.site === root && this.prototype === "Site") ? "Root" : this.prototype;
var skin = this.getMainSkin(prototype);
if (!skin) {
return;
}
// FIXME: Maintain skin inheritance by checking if we target the Site skin of root
var prototype = (res.handlers.site === root && this.prototype === "Site") ? "Root" : this.prototype;
var skin = this.getMainSkin(prototype);
if (!skin) {
return;
}
res.push();
if (source != null) {
res.writeln("<% #" + this.name + " %>");
res.writeln(source.trim().replace(/(<%\s*)#/g, "$1// #"));
}
var subskins = skin.getSubskinNames();
for (var i in subskins) {
if (subskins[i] !== this.name) {
res.writeln("<% #" + subskins[i] + " %>");
source = skin.getSubskin(subskins[i]).source;
source && res.writeln(source.trim());
}
}
source = res.pop();
res.push();
if (source != null) {
res.writeln("<% #" + this.name + " %>");
res.writeln(source.trim().replace(/(<%\s*)#/g, "$1// #"));
}
var subskins = skin.getSubskinNames();
for (var i in subskins) {
if (subskins[i] !== this.name) {
res.writeln("<% #" + subskins[i] + " %>");
source = skin.getSubskin(subskins[i]).source;
source && res.writeln(source.trim());
}
}
source = res.pop();
var file = this.getStaticFile();
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
var fos = new java.io.FileOutputStream(file);
var bos = new java.io.BufferedOutputStream(fos);
var writer = new java.io.OutputStreamWriter(bos, "UTF-8");
writer.write(source);
writer.close();
bos.close();
fos.close();
var file = this.getStaticFile();
if (!file.exists()) {
file.getParentFile().mkdirs();
file.createNewFile();
}
var fos = new java.io.FileOutputStream(file);
var bos = new java.io.BufferedOutputStream(fos);
var writer = new java.io.OutputStreamWriter(bos, "UTF-8");
writer.write(source);
writer.close();
bos.close();
fos.close();
this.clearCache();
return;
this.clearCache();
return;
}
/**
@ -367,9 +367,9 @@ Skin.prototype.setSource = function(source) {
* @returns {java.io.File}
*/
Skin.prototype.getStaticFile = function() {
// FIXME: Maintain skin inheritance by checking if we target the Site skin of root
var prototype = (res.handlers.site === root && this.prototype === "Site") ? "Root" : this.prototype;
return new java.io.File(res.skinpath[0], prototype + "/" + this.prototype + ".skin");
// FIXME: Maintain skin inheritance by checking if we target the Site skin of root
var prototype = (res.handlers.site === root && this.prototype === "Site") ? "Root" : this.prototype;
return new java.io.File(res.skinpath[0], prototype + "/" + this.prototype + ".skin");
}
/**
@ -377,14 +377,14 @@ Skin.prototype.getStaticFile = function() {
* @returns {Skin}
*/
Skin.prototype.getMainSkin = function(prototype) {
var source, skinSet = app.getSkinfilesInPath(res.skinpath)[prototype || this.prototype];
if (skinSet) {
source = skinSet[this.prototype];
if (source !== null) {
return createSkin(source);
}
}
return null;
var source, skinSet = app.getSkinfilesInPath(res.skinpath)[prototype || this.prototype];
if (skinSet) {
source = skinSet[this.prototype];
if (source !== null) {
return createSkin(source);
}
}
return null;
}
/**
@ -394,18 +394,18 @@ Skin.prototype.getMainSkin = function(prototype) {
* @returns {Skin}
*/
Skin.prototype.getSubskin = function(prototype, name) {
var mainSkin = this.getMainSkin(prototype);
if (mainSkin) {
return mainSkin.getSubskin(name || this.name);
}
return null;
var mainSkin = this.getMainSkin(prototype);
if (mainSkin) {
return mainSkin.getSubskin(name || this.name);
}
return null;
}
/**
*
*/
Skin.prototype.render = function() {
return renderSkin(createSkin(this.getSource()));
return renderSkin(createSkin(this.getSource()));
}
/**
@ -414,39 +414,39 @@ Skin.prototype.render = function() {
* @returns {Boolean}
*/
Skin.prototype.equals = function(source) {
// FIXME: The removal of linebreaks is necessary but it's not very nice
var re = /\r|\n/g;
var normalize = function(str) {
return str.replace(re, String.EMPTY);
}
return normalize(source) === normalize(this.getSource());
// FIXME: The removal of linebreaks is necessary but it's not very nice
var re = /\r|\n/g;
var normalize = function(str) {
return str.replace(re, String.EMPTY);
}
return normalize(source) === normalize(this.getSource());
}
/**
* @returns {String}
*/
Skin.prototype.getConfirmText = function() {
return gettext("You are about to reset the skin {0}.{1}.",
this.prototype, this.name);
return gettext("You are about to reset the skin {0}.{1}.",
this.prototype, this.name);
}
/**
* @returns {String}
*/
Skin.prototype.toString = function() {
return "Skin #" + this._id + ": " + this.prototype + "." + this.name;
return "Skin #" + this._id + ": " + this.prototype + "." + this.name;
}
/**
*
*/
Skin.prototype.status_macro = function() {
return this.isTransient() ? "inherited" : "modified";
return this.isTransient() ? "inherited" : "modified";
}
/**
*
*/
Skin.prototype.content_macro = function() {
return res.write(this.getSource());
return res.write(this.getSource());
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -54,7 +54,7 @@ Skins.prototype.constructor = function(name, parent) {
* @returns {Boolean}
*/
Skins.prototype.getPermission = function(action) {
return res.handlers.layout.getPermission("main");
return res.handlers.layout.getPermission("main");
}
/**
@ -63,99 +63,99 @@ Skins.prototype.getPermission = function(action) {
* @returns {Skins|Skin}
*/
Skins.prototype.getChildElement = function(name) {
if (this.parent) {
var group = path[path.length - 1].name;
var skin = this.getSkin(group, name);
if (skin) {
return skin;
}
if (global[group] || group === "Global") {
return this.getSkin(group, name);
}
}
return new Skins(name, this);
if (this.parent) {
var group = path[path.length - 1].name;
var skin = this.getSkin(group, name);
if (skin) {
return skin;
}
if (global[group] || group === "Global") {
return this.getSkin(group, name);
}
}
return new Skins(name, this);
}
Skins.prototype.onRequest = function() {
if (this.parent) {
res.redirect(res.handlers.layout.skins.href(req.action));
}
return HopObject.prototype.onRequest.call(this);
if (this.parent) {
res.redirect(res.handlers.layout.skins.href(req.action));
}
return HopObject.prototype.onRequest.call(this);
}
Skins.prototype.main_action = function() {
res.data.title = gettext("Basic Skins");
res.data.body = this.renderSkinAsString("$Skins#main");
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Basic Skins");
res.data.body = this.renderSkinAsString("$Skins#main");
res.handlers.site.renderSkin("Site#page");
return;
}
Skins.prototype.create_action = function() {
if (req.postParams.save) {
try {
var prototype = req.postParams.prototype;
var name = stripTags(req.postParams.name);
if (!prototype || !req.postParams.name) {
throw Error(gettext("Please choose a prototype and enter a skin name"));
} else if (name !== req.postParams.name || /\s/.test(name) || NAMEPATTERN.test(name)) {
throw Error(gettext("Please avoid special characters or HTML code in the name field."));
} else if (Skin.getByName(prototype, name)) {
throw Error("Sorry, there is already a skin with that name. Please enter a different one.");
}
var skin = this.getSkin(prototype, name);
skin.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
if (req.postParams.save == 1) {
res.redirect(skin.href("edit"));
} else {
res.redirect(res.handlers.layout.skins.href("modified"));
}
} catch (ex) {
res.message = ex;
app.log(ex);
if (req.postParams.save) {
try {
var prototype = req.postParams.prototype;
var name = stripTags(req.postParams.name);
if (!prototype || !req.postParams.name) {
throw Error(gettext("Please choose a prototype and enter a skin name"));
} else if (name !== req.postParams.name || /\s/.test(name) || NAMEPATTERN.test(name)) {
throw Error(gettext("Please avoid special characters or HTML code in the name field."));
} else if (Skin.getByName(prototype, name)) {
throw Error("Sorry, there is already a skin with that name. Please enter a different one.");
}
}
res.data.title = gettext('Add Skin');
res.data.action = this.href(req.action);
HopObject.confirmConstructor(Skin);
res.data.body = (new Skin).renderSkinAsString("$Skin#edit");
this.renderSkin("$Skins#page");
return;
var skin = this.getSkin(prototype, name);
skin.update(req.postParams);
res.message = gettext("The changes were saved successfully.");
if (req.postParams.save == 1) {
res.redirect(skin.href("edit"));
} else {
res.redirect(res.handlers.layout.skins.href("modified"));
}
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.title = gettext('Add Skin');
res.data.action = this.href(req.action);
HopObject.confirmConstructor(Skin);
res.data.body = (new Skin).renderSkinAsString("$Skin#edit");
this.renderSkin("$Skins#page");
return;
}
Skins.prototype.modified_action = function() {
res.data.title = gettext("Modified Skins");
res.push();
this.renderSkin("$Skins#header");
this.modified.forEach(function() {
this.renderSkin("$Skin#listItem");
});
res.data.body = res.pop();
res.handlers.site.renderSkin("Site#page");
return;
res.data.title = gettext("Modified Skins");
res.push();
this.renderSkin("$Skins#header");
this.modified.forEach(function() {
this.renderSkin("$Skin#listItem");
});
res.data.body = res.pop();
res.handlers.site.renderSkin("Site#page");
return;
}
Skins.prototype.all_action = function() {
if (this.parent) {
res.redirect(res.handlers.layout.skins.href(req.action));
}
res.data.list = this.getOutline();
res.data.title = gettext("All Skins");
res.data.body = this.renderSkinAsString("$Skins#all");
res.handlers.site.renderSkin("Site#page");
return;
if (this.parent) {
res.redirect(res.handlers.layout.skins.href(req.action));
}
res.data.list = this.getOutline();
res.data.title = gettext("All Skins");
res.data.body = this.renderSkinAsString("$Skins#all");
res.handlers.site.renderSkin("Site#page");
return;
}
Skins.prototype.safe_action = function() {
res.data.title = gettext("Modified Skins");
res.push();
this.modified.forEach(function() {
this.renderSkin("$Skin#listItem");
});
res.data.title = "Modified Skins";
res.data.body = res.pop();
this.renderSkin("$Skins#page");
return;
res.data.title = gettext("Modified Skins");
res.push();
this.modified.forEach(function() {
this.renderSkin("$Skin#listItem");
});
res.data.title = "Modified Skins";
res.data.body = res.pop();
this.renderSkin("$Skins#page");
return;
}
/**
@ -165,7 +165,7 @@ Skins.prototype.safe_action = function() {
* @returns {Skin}
*/
Skins.prototype.getSkin = function(group, name) {
return Skin.getByName(group, name) || new Skin(group, name);
return Skin.getByName(group, name) || new Skin(group, name);
}
/**
@ -173,42 +173,42 @@ Skins.prototype.getSkin = function(group, name) {
* @returns {String}
*/
Skins.prototype.getOutline = function() {
var skinfiles, prototype, skin, subskins, names, skins = [];
var options = Skin.getPrototypeOptions();
var skinfiles, prototype, skin, subskins, names, skins = [];
var options = Skin.getPrototypeOptions();
for each (var option in options) {
names = [];
prototype = option.value;
skinfiles = app.getSkinfilesInPath(res.skinpath);
skin = createSkin(skinfiles[prototype][prototype]);
subskins = skin.getSubskinNames();
for each (var subskin in subskins) {
names.push(subskin);
}
names.sort();
skins.push([prototype, names]);
}
for each (var option in options) {
names = [];
prototype = option.value;
skinfiles = app.getSkinfilesInPath(res.skinpath);
skin = createSkin(skinfiles[prototype][prototype]);
subskins = skin.getSubskinNames();
for each (var subskin in subskins) {
names.push(subskin);
}
names.sort();
skins.push([prototype, names]);
}
res.push();
for each (var item in skins) {
prototype = item[0];
skin = item[1];
if (skin && skin.length > 0) {
html.openTag("li");
html.openTag("a", {href: "#" + prototype});
res.write(prototype);
html.closeTag("a");
html.openTag("ul");
for each (var name in skin) {
subskin = this.getSkin(prototype, name);
html.openTag("li");
html.link({href: subskin.href("edit")},
subskin.prototype + "." + subskin.name);
html.closeTag("li");
}
html.closeTag("ul");
html.closeTag("li");
res.push();
for each (var item in skins) {
prototype = item[0];
skin = item[1];
if (skin && skin.length > 0) {
html.openTag("li");
html.openTag("a", {href: "#" + prototype});
res.write(prototype);
html.closeTag("a");
html.openTag("ul");
for each (var name in skin) {
subskin = this.getSkin(prototype, name);
html.openTag("li");
html.link({href: subskin.href("edit")},
subskin.prototype + "." + subskin.name);
html.closeTag("li");
}
}
return res.pop();
html.closeTag("ul");
html.closeTag("li");
}
}
return res.pop();
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -52,89 +52,89 @@ markgettext("stories");
* @returns {Boolean}
*/
Stories.prototype.getPermission = function(action) {
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
if (!this._parent.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "create":
return Site.require(Site.OPEN) && session.user ||
Membership.require(Membership.CONTRIBUTOR) ||
User.require(User.PRIVILEGED);
case "all":
case "top":
case "closed":
return Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
case "all":
case "top":
case "closed":
return Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
}
return false;
}
Stories.prototype.main_action = function() {
var stories = User.getMembership().stories;
res.data.list = renderList(stories, "$Story#listItem",
10, req.queryParams.page);
res.data.pager = renderPager(stories,
this.href(), 10, req.queryParams.page);
res.data.title = gettext("Member Stories");
res.data.body = this.renderSkinAsString("$Stories#main");
this._parent.renderSkin("Site#page");
return;
var stories = User.getMembership().stories;
res.data.list = renderList(stories, "$Story#listItem",
10, req.queryParams.page);
res.data.pager = renderPager(stories,
this.href(), 10, req.queryParams.page);
res.data.title = gettext("Member Stories");
res.data.body = this.renderSkinAsString("$Stories#main");
this._parent.renderSkin("Site#page");
return;
}
Stories.prototype.create_action = function() {
if (req.data.save) {
try {
story = Story.add(req.params);
story.notify(req.action);
JSON.sendPaddedResponse(story._id);
delete session.data.backup;
res.message = gettext("The story was successfully created.");
res.redirect(story.href());
} catch (ex) {
JSON.sendPaddedResponse(null);
res.status = 400;
res.message = ex;
app.log(ex);
}
}
if (req.data.save) {
try {
story = Story.add(req.params);
story.notify(req.action);
JSON.sendPaddedResponse(story._id);
delete session.data.backup;
res.message = gettext("The story was successfully created.");
res.redirect(story.href());
} catch (ex) {
JSON.sendPaddedResponse(null);
res.status = 400;
res.message = ex;
app.log(ex);
}
}
res.data.title = gettext("Add Story");
res.data.action = this.href(req.action);
HopObject.confirmConstructor(Story);
res.data.body = (new Story).renderSkinAsString("Story#edit");
this._parent.renderSkin("Site#page");
return;
res.data.title = gettext("Add Story");
res.data.action = this.href(req.action);
HopObject.confirmConstructor(Story);
res.data.body = (new Story).renderSkinAsString("Story#edit");
this._parent.renderSkin("Site#page");
return;
}
Stories.prototype.closed_action = function() {
res.data.list = renderList(this.closed,
"$Story#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this.closed,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("Closed Stories");
res.data.body = this.renderSkinAsString("$Stories#main");
this._parent.renderSkin("Site#page");
return;
res.data.list = renderList(this.closed,
"$Story#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this.closed,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("Closed Stories");
res.data.body = this.renderSkinAsString("$Stories#main");
this._parent.renderSkin("Site#page");
return;
}
Stories.prototype.all_action = function() {
res.data.list = renderList(this, "$Story#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("All Stories");
res.data.body = this.renderSkinAsString("$Stories#main");
this._parent.renderSkin("Site#page");
return;
res.data.list = renderList(this, "$Story#listItem", 10, req.queryParams.page);
res.data.pager = renderPager(this,
this.href(req.action), 10, req.queryParams.page);
res.data.title = gettext("All Stories");
res.data.body = this.renderSkinAsString("$Stories#main");
this._parent.renderSkin("Site#page");
return;
}
Stories.prototype.top_action = function() {
res.data.title = gettext("Top Stories");
res.data.body = this.renderSkinAsString("$Stories#top");
this._parent.renderSkin("Site#page");
return;
res.data.title = gettext("Top Stories");
res.data.body = this.renderSkinAsString("$Stories#top");
this._parent.renderSkin("Site#page");
return;
}
/**
@ -143,18 +143,18 @@ Stories.prototype.top_action = function() {
* @param {String} type
*/
Stories.prototype.list_macro = function(param, type) {
switch (type) {
case "top":
var counter = 1;
this.top.forEach(function() {
this.renderSkin("$Story#top", {
position: counter
});
counter += 1;
switch (type) {
case "top":
var counter = 1;
this.top.forEach(function() {
this.renderSkin("$Story#top", {
position: counter
});
break;
}
return;
counter += 1;
});
break;
}
return;
}
/**
@ -164,7 +164,7 @@ Stories.prototype.list_macro = function(param, type) {
* @see Site#getTags
*/
Stories.prototype.getTags = function(group) {
return this._parent.getTags("tags", group);
return this._parent.getTags("tags", group);
}
/**
@ -173,5 +173,5 @@ Stories.prototype.getTags = function(group) {
* @returns {String[]}
*/
Stories.prototype.getAdminHeader = function(name) {
return ["#", "Tag", "Items"];
return ["#", "Tag", "Items"];
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,11 +34,11 @@ this.handleMetadata("title");
this.handleMetadata("text");
Story.ALLOWED_MACROS = [
"file",
"image",
"link",
"poll",
"story.link"
"file",
"image",
"link",
"poll",
"story.link"
];
/**
@ -49,31 +49,31 @@ Story.ALLOWED_MACROS = [
* @returns {Story}
*/
Story.add = function(data, site, user) {
HopObject.confirmConstructor(Story);
site || (site = res.handlers.site);
user || (user = session.user);
var story = new Story;
story.name = String.EMPTY;
story.requests = 0;
story.created = story.modified = new Date;
story.site = site;
story.creator = story.modifier = user;
story.update(data);
site.stories.add(story);
return story;
HopObject.confirmConstructor(Story);
site || (site = res.handlers.site);
user || (user = session.user);
var story = new Story;
story.name = String.EMPTY;
story.requests = 0;
story.created = story.modified = new Date;
story.site = site;
story.creator = story.modifier = user;
story.update(data);
site.stories.add(story);
return story;
}
/**
* @function
*/
Story.remove = function() {
if (this.constructor === Story) {
HopObject.remove.call(this.comments);
this.setTags(null);
this.deleteMetadata();
this.remove();
}
return;
if (this.constructor === Story) {
HopObject.remove.call(this.comments);
this.setTags(null);
this.deleteMetadata();
this.remove();
}
return;
}
/**
@ -82,22 +82,22 @@ Story.remove = function() {
* @see defineConstants
*/
Story.getStatus = defineConstants(Story, markgettext("closed"),
markgettext("public"), markgettext("shared"), markgettext("open"));
markgettext("public"), markgettext("shared"), markgettext("open"));
/**
* @function
* @returns {String[]}
* @see defineConstants
*/
Story.getModes = defineConstants(Story, markgettext("hidden"),
markgettext("featured"));
markgettext("featured"));
/**
* @function
* @returns {String[]}
* @see defineConstants
*/
Story.getCommentModes = defineConstants(Story, markgettext("closed"),
/* markgettext("readonly"), markgettext("moderated"), */
markgettext("open"));
/* markgettext("readonly"), markgettext("moderated"), */
markgettext("open"));
/**
* @name Story
@ -124,8 +124,8 @@ Story.getCommentModes = defineConstants(Story, markgettext("closed"),
* @extends HopObject
*/
Story.prototype.constructor = function() {
HopObject.confirmConstructor(this);
return this;
HopObject.confirmConstructor(this);
return this;
}
/**
@ -134,45 +134,45 @@ Story.prototype.constructor = function() {
* @returns {Boolean}
*/
Story.prototype.getPermission = function(action) {
if (!this.site.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
return this.status !== Story.CLOSED ||
this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
case "comment":
return this.site.commentMode === Site.ENABLED &&
(this.commentMode === Story.OPEN ||
this.commentMode === Story.MODERATED);
case "delete":
return this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
case "edit":
case "rotate":
return this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
(this.status === Story.SHARED &&
Membership.require(Membership.CONTRIBUTOR)) ||
(this.status === Story.OPEN &&
Membership.require(Membership.SUBSCRIBER)) ||
User.require(User.PRIVILEGED);
}
return false;
if (!this.site.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
return this.status !== Story.CLOSED ||
this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
case "comment":
return this.site.commentMode === Site.ENABLED &&
(this.commentMode === Story.OPEN ||
this.commentMode === Story.MODERATED);
case "delete":
return this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
User.require(User.PRIVILEGED);
case "edit":
case "rotate":
return this.creator === session.user ||
Membership.require(Membership.MANAGER) ||
(this.status === Story.SHARED &&
Membership.require(Membership.CONTRIBUTOR)) ||
(this.status === Story.OPEN &&
Membership.require(Membership.SUBSCRIBER)) ||
User.require(User.PRIVILEGED);
}
return false;
}
Story.prototype.main_action = function() {
res.data.title = this.getTitle(10);
res.data.body = this.renderSkinAsString("Story#main");
this.site.renderSkin("Site#page");
this.site.log();
this.count();
this.log();
return;
res.data.title = this.getTitle(10);
res.data.body = this.renderSkinAsString("Story#main");
this.site.renderSkin("Site#page");
this.site.log();
this.count();
this.log();
return;
}
/**
@ -181,37 +181,37 @@ Story.prototype.main_action = function() {
* @returns {String}
*/
Story.prototype.getTitle = function(limit) {
var key = this + ":title:" + limit;
if (!res.meta[key]) {
if (this.title) {
res.meta[key] = stripTags(this.title).clip(limit, "...", "\\s");
} else if (this.text) {
var parts = stripTags(this.text).embody(limit, "...", "\\s");
res.meta[key] = parts.head;
res.meta[this + ":text:" + limit] = parts.tail;
}
}
return String(res.meta[key]) || "...";
var key = this + ":title:" + limit;
if (!res.meta[key]) {
if (this.title) {
res.meta[key] = stripTags(this.title).clip(limit, "...", "\\s");
} else if (this.text) {
var parts = stripTags(this.text).embody(limit, "...", "\\s");
res.meta[key] = parts.head;
res.meta[this + ":text:" + limit] = parts.tail;
}
}
return String(res.meta[key]) || "...";
}
Story.prototype.edit_action = function() {
if (req.postParams.save) {
try {
this.update(req.postParams);
delete session.data.backup;
res.message = gettext("The story was successfully updated.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
if (req.postParams.save) {
try {
this.update(req.postParams);
delete session.data.backup;
res.message = gettext("The story was successfully updated.");
res.redirect(this.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.data.action = this.href(req.action);
res.data.title = gettext('Edit Story');
res.data.body = this.renderSkinAsString("Story#edit");
this.site.renderSkin("Site#page");
return;
res.data.action = this.href(req.action);
res.data.title = gettext('Edit Story');
res.data.body = this.renderSkinAsString("Story#edit");
this.site.renderSkin("Site#page");
return;
}
/**
@ -219,88 +219,88 @@ Story.prototype.edit_action = function() {
* @param {Object} data
*/
Story.prototype.update = function(data) {
var site = this.site || res.handlers.site;
var site = this.site || res.handlers.site;
if (!data.title && !data.text) {
throw Error(gettext("Please enter at least something into the “title” or “text” field."));
}
if (data.created) {
try {
this.created = data.created.toDate("yyyy-MM-dd HH:mm", site.getTimeZone());
} catch (ex) {
throw Error(gettext("Cannot parse timestamp {0} as a date.", data.created));
app.log(ex);
}
}
if (!data.title && !data.text) {
throw Error(gettext("Please enter at least something into the “title” or “text” field."));
}
if (data.created) {
try {
this.created = data.created.toDate("yyyy-MM-dd HH:mm", site.getTimeZone());
} catch (ex) {
throw Error(gettext("Cannot parse timestamp {0} as a date.", data.created));
app.log(ex);
}
}
// Get difference to current content before applying changes
var delta = this.getDelta(data);
this.title = data.title ? data.title.trim() : String.EMPTY;
this.text = data.text ? data.text.trim() : String.EMPTY;
this.status = data.status || Story.PUBLIC;
this.mode = data.mode || Story.FEATURED;
this.commentMode = data.commentMode || Story.OPEN;
this.setCustomContent(data);
// Get difference to current content before applying changes
var delta = this.getDelta(data);
this.title = data.title ? data.title.trim() : String.EMPTY;
this.text = data.text ? data.text.trim() : String.EMPTY;
this.status = data.status || Story.PUBLIC;
this.mode = data.mode || Story.FEATURED;
this.commentMode = data.commentMode || Story.OPEN;
this.setCustomContent(data);
// FIXME: To be removed resp. moved to Stories.create_action and
// Story.edit_action if work-around for Helma bug #607 fails
// We need persistence for setting the tags
this.isTransient() && this.persist();
this.setTags(data.tags || data.tag_array);
// FIXME: To be removed resp. moved to Stories.create_action and
// Story.edit_action if work-around for Helma bug #607 fails
// We need persistence for setting the tags
this.isTransient() && this.persist();
this.setTags(data.tags || data.tag_array);
if (delta > 50) {
this.modified = new Date;
if (this.status !== Story.CLOSED) {
site.modified = this.modified;
}
site.callback(this);
// Notification is sent in Stories.create_action()
}
if (delta > 50) {
this.modified = new Date;
if (this.status !== Story.CLOSED) {
site.modified = this.modified;
}
site.callback(this);
// Notification is sent in Stories.create_action()
}
this.clearCache();
this.modifier = session.user;
return;
this.clearCache();
this.modifier = session.user;
return;
}
Story.prototype.rotate_action = function() {
if (this.status === Story.CLOSED) {
this.status = this.cache.status || Story.PUBLIC;
} else if (this.mode === Story.FEATURED) {
this.mode = Story.HIDDEN;
} else {
this.cache.status = this.status;
this.mode = Story.FEATURED;
this.status = Story.CLOSED;
}
return res.redirect(req.data.http_referer || this._parent.href());
if (this.status === Story.CLOSED) {
this.status = this.cache.status || Story.PUBLIC;
} else if (this.mode === Story.FEATURED) {
this.mode = Story.HIDDEN;
} else {
this.cache.status = this.status;
this.mode = Story.FEATURED;
this.status = Story.CLOSED;
}
return res.redirect(req.data.http_referer || this._parent.href());
}
Story.prototype.comment_action = function() {
// Check if user is logged in since we allow linking here for any user
if (!User.require(User.REGULAR)) {
User.setLocation(this.href(req.action) + "#form");
res.message = gettext("Please login first.");
res.redirect(this.site.members.href("login"));
}
if (req.postParams.save) {
try {
var comment = Comment.add(req.postParams, this);
comment.notify(req.action);
delete session.data.backup;
res.message = gettext("The comment was successfully created.");
res.redirect(comment.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.handlers.parent = this;
res.data.action = this.href(req.action);
res.data.title = gettext("Add Comment");
HopObject.confirmConstructor(Comment);
res.data.body = (new Comment).renderSkinAsString("Comment#edit");
this.site.renderSkin("Site#page");
return;
// Check if user is logged in since we allow linking here for any user
if (!User.require(User.REGULAR)) {
User.setLocation(this.href(req.action) + "#form");
res.message = gettext("Please login first.");
res.redirect(this.site.members.href("login"));
}
if (req.postParams.save) {
try {
var comment = Comment.add(req.postParams, this);
comment.notify(req.action);
delete session.data.backup;
res.message = gettext("The comment was successfully created.");
res.redirect(comment.href());
} catch (ex) {
res.message = ex;
app.log(ex);
}
}
res.handlers.parent = this;
res.data.action = this.href(req.action);
res.data.title = gettext("Add Comment");
HopObject.confirmConstructor(Comment);
res.data.body = (new Comment).renderSkinAsString("Comment#edit");
this.site.renderSkin("Site#page");
return;
}
/**
@ -309,20 +309,20 @@ Story.prototype.comment_action = function() {
* @returns {Object}
*/
Story.prototype.getFormValue = function(name) {
if (req.isPost()) {
return req.postParams[name];
}
switch (name) {
case "commentMode":
return this.commentMode || Story.OPEN;
case "mode":
return this.mode || Story.FEATURED;
case "status":
return this.status || Story.PUBLIC;
case "tags":
return this.getTags().join(Tag.DELIMITER);
}
return this[name] || this.getMetadata(name);
if (req.isPost()) {
return req.postParams[name];
}
switch (name) {
case "commentMode":
return this.commentMode || Story.OPEN;
case "mode":
return this.mode || Story.FEATURED;
case "status":
return this.status || Story.PUBLIC;
case "tags":
return this.getTags().join(Tag.DELIMITER);
}
return this[name] || this.getMetadata(name);
}
/**
@ -331,18 +331,18 @@ Story.prototype.getFormValue = function(name) {
* @returns {String[]}
*/
Story.prototype.getFormOptions = function(name) {
switch (name) {
case "commentMode":
return Story.getCommentModes();
case "mode":
return Story.getModes();
case "status":
return Story.getStatus();
case "tags":
// FIXME: This could become a huge select element...
return [];
}
return;
switch (name) {
case "commentMode":
return Story.getCommentModes();
case "mode":
return Story.getModes();
case "status":
return Story.getStatus();
case "tags":
// FIXME: This could become a huge select element...
return [];
}
return;
}
/**
@ -350,13 +350,13 @@ Story.prototype.getFormOptions = function(name) {
* @param {Object} data
*/
Story.prototype.setCustomContent = function(data) {
var metadata = {};
for (var key in data) {
if (this.isCustomContent(key)) {
metadata[key] = data[key];
}
}
return HopObject.prototype.setMetadata.call(this, metadata);
var metadata = {};
for (var key in data) {
if (this.isCustomContent(key)) {
metadata[key] = data[key];
}
}
return HopObject.prototype.setMetadata.call(this, metadata);
}
/**
@ -364,28 +364,28 @@ Story.prototype.setCustomContent = function(data) {
* @param {String} name
*/
Story.prototype.isCustomContent = function(key) {
return this[key] === undefined && key !== 'save';
return this[key] === undefined && key !== 'save';
}
/**
* Increment the request counter
*/
Story.prototype.count = function() {
if (session.user === this.creator) {
return;
}
var story;
var key = "Story#" + this._id;
if (story = app.data.requests[key]) {
story.requests += 1;
} else {
app.data.requests[key] = {
type: this.constructor,
id: this._id,
requests: this.requests + 1
};
}
return;
if (session.user === this.creator) {
return;
}
var story;
var key = "Story#" + this._id;
if (story = app.data.requests[key]) {
story.requests += 1;
} else {
app.data.requests[key] = {
type: this.constructor,
id: this._id,
requests: this.requests + 1
};
}
return;
}
/**
@ -394,27 +394,27 @@ Story.prototype.count = function() {
* @returns {Number}
*/
Story.prototype.getDelta = function(data) {
if (this.isTransient()) {
return Infinity;
}
if (this.isTransient()) {
return Infinity;
}
var deltify = function(s1, s2) {
var len1 = s1 ? String(s1).length : 0;
var len2 = s2 ? String(s2).length : 0;
return Math.abs(len1 - len2);
};
var deltify = function(s1, s2) {
var len1 = s1 ? String(s1).length : 0;
var len2 = s2 ? String(s2).length : 0;
return Math.abs(len1 - len2);
};
var delta = 0;
delta += deltify(data.title, this.title);
delta += deltify(data.text, this.text);
for (var key in data) {
if (this.isCustomContent(key)) {
delta += deltify(data[key], this.getMetadata(key))
}
}
// In-between updates (1 hour) get zero delta
var timex = (new Date - this.modified) > Date.ONEHOUR ? 1 : 0;
return delta * timex;
var delta = 0;
delta += deltify(data.title, this.title);
delta += deltify(data.text, this.text);
for (var key in data) {
if (this.isCustomContent(key)) {
delta += deltify(data[key], this.getMetadata(key))
}
}
// In-between updates (1 hour) get zero delta
var timex = (new Date - this.modified) > Date.ONEHOUR ? 1 : 0;
return delta * timex;
}
/**
@ -423,10 +423,10 @@ Story.prototype.getDelta = function(data) {
* @returns {HopObject}
*/
Story.prototype.getMacroHandler = function(name) {
if (name === "metadata") {
return this.getMetadata();
}
return null;
if (name === "metadata") {
return this.getMetadata();
}
return null;
}
/**
@ -436,17 +436,17 @@ Story.prototype.getMacroHandler = function(name) {
* @param {String} text
*/
Story.prototype.link_macro = function(param, action, text) {
switch (action) {
case "rotate":
if (this.status === Story.CLOSED) {
text = gettext("Publish");
} else if (this.mode === Story.FEATURED) {
text = gettext("Hide");
} else {
text = gettext("Close");
}
}
return HopObject.prototype.link_macro.call(this, param, action, text);
switch (action) {
case "rotate":
if (this.status === Story.CLOSED) {
text = gettext("Publish");
} else if (this.mode === Story.FEATURED) {
text = gettext("Hide");
} else {
text = gettext("Close");
}
}
return HopObject.prototype.link_macro.call(this, param, action, text);
}
/**
@ -454,34 +454,34 @@ Story.prototype.link_macro = function(param, action, text) {
* @param {Object} param
*/
Story.prototype.summary_macro = function(param) {
param.limit || (param.limit = 15);
var keys, summary;
if (arguments.length > 1) {
res.push();
var content;
for (var i=1; i<arguments.length; i+=1) {
if (content = this.getMetadata(arguments[i])) {
res.write(content);
res.write(String.SPACE);
}
param.limit || (param.limit = 15);
var keys, summary;
if (arguments.length > 1) {
res.push();
var content;
for (var i=1; i<arguments.length; i+=1) {
if (content = this.getMetadata(arguments[i])) {
res.write(content);
res.write(String.SPACE);
}
summary = res.pop();
}
if (!summary) {
summary = (this.title || String.EMPTY) + String.SPACE +
(this.text || String.EMPTY);
}
var clipped = stripTags(summary).clip(param.limit, param.clipping, "\\s");
var head = clipped.split(/(\s)/, param.limit * 0.6).join(String.EMPTY);
var tail = clipped.substring(head.length).trim();
head = head.trim();
if (!head && !tail) {
head = "...";
}
html.link({href: this.href()}, head);
res.writeln("\n");
res.write(tail);
return;
}
summary = res.pop();
}
if (!summary) {
summary = (this.title || String.EMPTY) + String.SPACE +
(this.text || String.EMPTY);
}
var clipped = stripTags(summary).clip(param.limit, param.clipping, "\\s");
var head = clipped.split(/(\s)/, param.limit * 0.6).join(String.EMPTY);
var tail = clipped.substring(head.length).trim();
head = head.trim();
if (!head && !tail) {
head = "...";
}
html.link({href: this.href()}, head);
res.writeln("\n");
res.write(tail);
return;
}
/**
@ -490,29 +490,29 @@ Story.prototype.summary_macro = function(param) {
* @param {String} mode
*/
Story.prototype.comments_macro = function(param, mode) {
var story = this.story || this;
if (story.site.commentMode === Site.DISABLED ||
story.commentMode === Site.CLOSED) {
return;
} else if (mode) {
var n = this.comments.size() || 0;
var text = ngettext("{0} comment", "{0} comments", n);
if (mode === "count" || mode === "size") {
res.write(text);
} else if (mode === "link") {
n < 1 ? res.write(text) :
html.link({href: this.href() + "#comments"}, text);
}
} else {
this.prefetchChildren();
this.forEach(function() {
html.openTag("a", {name: this._id});
html.closeTag("a");
this.renderSkin(this.parent.constructor === Story ?
"Comment#main" : "Comment#reply");
});
}
return;
var story = this.story || this;
if (story.site.commentMode === Site.DISABLED ||
story.commentMode === Site.CLOSED) {
return;
} else if (mode) {
var n = this.comments.size() || 0;
var text = ngettext("{0} comment", "{0} comments", n);
if (mode === "count" || mode === "size") {
res.write(text);
} else if (mode === "link") {
n < 1 ? res.write(text) :
html.link({href: this.href() + "#comments"}, text);
}
} else {
this.prefetchChildren();
this.forEach(function() {
html.openTag("a", {name: this._id});
html.closeTag("a");
this.renderSkin(this.parent.constructor === Story ?
"Comment#main" : "Comment#reply");
});
}
return;
}
/**
@ -521,18 +521,18 @@ Story.prototype.comments_macro = function(param, mode) {
* @param {String} mode
*/
Story.prototype.tags_macro = function(param, mode) {
if (mode === "link") {
var tags = [];
this.tags.list().forEach(function(item) {
res.push();
if (item.tag) {
renderLink(param, item.tag.href(), item.tag.name);
tags.push(res.pop());
}
});
return res.write(tags.join(Tag.DELIMITER));
}
return res.write(this.getFormValue("tags"));
if (mode === "link") {
var tags = [];
this.tags.list().forEach(function(item) {
res.push();
if (item.tag) {
renderLink(param, item.tag.href(), item.tag.name);
tags.push(res.pop());
}
});
return res.write(tags.join(Tag.DELIMITER));
}
return res.write(this.getFormValue("tags"));
}
/**
@ -541,35 +541,35 @@ Story.prototype.tags_macro = function(param, mode) {
* @param {Number} limit
*/
Story.prototype.referrers_macro = function(param, limit) {
if (!User.require(User.PRIVILEGED) &&
!Membership.require(Membership.OWNER)) {
return;
}
if (!User.require(User.PRIVILEGED) &&
!Membership.require(Membership.OWNER)) {
return;
}
limit = Math.min(limit || param.limit || 100, 100);
if (limit < 1) {
return;
}
limit = Math.min(limit || param.limit || 100, 100);
if (limit < 1) {
return;
}
var self = this;
var sql = new Sql;
sql.retrieve(Sql.REFERRERS, "Story", this._id);
var self = this;
var sql = new Sql;
sql.retrieve(Sql.REFERRERS, "Story", this._id);
res.push();
var n = 0;
sql.traverse(function() {
if (n < limit && this.requests && this.referrer) {
this.text = encode(this.referrer.head(50));
this.referrer = encode(this.referrer);
self.renderSkin("$Story#referrer", this);
}
n += 1;
});
param.referrers = res.pop();
if (param.referrers) {
this.renderSkin("$Story#referrers", param);
}
return;
res.push();
var n = 0;
sql.traverse(function() {
if (n < limit && this.requests && this.referrer) {
this.text = encode(this.referrer.head(50));
this.referrer = encode(this.referrer);
self.renderSkin("$Story#referrer", this);
}
n += 1;
});
param.referrers = res.pop();
if (param.referrers) {
this.renderSkin("$Story#referrers", param);
}
return;
}
/**
@ -580,31 +580,31 @@ Story.prototype.referrers_macro = function(param, limit) {
* @returns {String}
*/
Story.prototype.format_filter = function(value, param, mode) {
if (value) {
switch (mode) {
case "plain":
return this.url_filter(stripTags(value), param, mode);
if (value) {
switch (mode) {
case "plain":
return this.url_filter(stripTags(value), param, mode);
case "quotes":
return stripTags(value).replace(/(?:\x22|\x27)/g, function(quote) {
return "&#" + quote.charCodeAt(0) + ";";
});
case "quotes":
return stripTags(value).replace(/(?:\x22|\x27)/g, function(quote) {
return "&#" + quote.charCodeAt(0) + ";";
});
case "image":
var image = HopObject.getFromPath(value, "images");
if (image) {
res.push();
image.render_macro(param);
return res.pop();
}
break;
default:
value = this.macro_filter(format(value), param);
return this.url_filter(value, param);
case "image":
var image = HopObject.getFromPath(value, "images");
if (image) {
res.push();
image.render_macro(param);
return res.pop();
}
}
return String.EMTPY;
break;
default:
value = this.macro_filter(format(value), param);
return this.url_filter(value, param);
}
}
return String.EMTPY;
}
/**
@ -613,20 +613,20 @@ Story.prototype.format_filter = function(value, param, mode) {
* @returns {String}
*/
Story.prototype.macro_filter = function(value) {
var skin = value.constructor === String ? createSkin(value) : value;
var skin = value.constructor === String ? createSkin(value) : value;
Story.ALLOWED_MACROS.forEach(function(value, index) {
skin.allowMacro(value);
});
Story.ALLOWED_MACROS.forEach(function(value, index) {
skin.allowMacro(value);
});
var site;
if (this.site !== res.handlers.site) {
site = res.handlers.site;
res.handlers.site = this.site;
}
value = this.renderSkinAsString(skin);
site && (res.handlers.site = site);
return value;
var site;
if (this.site !== res.handlers.site) {
site = res.handlers.site;
res.handlers.site = this.site;
}
value = this.renderSkinAsString(skin);
site && (res.handlers.site = site);
return value;
}
/**
@ -637,38 +637,38 @@ Story.prototype.macro_filter = function(value) {
* @returns {String}
*/
Story.prototype.url_filter = function(value, param, mode) {
param.limit || (param.limit = 50);
// FIXME: The first RegExp has troubles with <a href=http://... (no quotes)
//var re = /(^|\/>|\s+)([\w+-_]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim;
var re = /(^|\/>|\s+)([!fhtpsr]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim
return value.replace(re, function(str, head, url, tail) {
if (url.startsWith("!")) {
return head + url.substring(1) + tail;
param.limit || (param.limit = 50);
// FIXME: The first RegExp has troubles with <a href=http://... (no quotes)
//var re = /(^|\/>|\s+)([\w+-_]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim;
var re = /(^|\/>|\s+)([!fhtpsr]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim
return value.replace(re, function(str, head, url, tail) {
if (url.startsWith("!")) {
return head + url.substring(1) + tail;
}
res.push();
res.write(head);
if (mode === "plain") {
res.write(url.clip(param.limit));
} else {
var text, location = /:\/\/([^\/]*)/.exec(url)[1];
text = location;
if (mode === "extended") {
text = url.replace(/^.+\/([^\/]*)$/, "$1");
}
res.push();
res.write(head);
if (mode === "plain") {
res.write(url.clip(param.limit));
} else {
var text, location = /:\/\/([^\/]*)/.exec(url)[1];
text = location;
if (mode === "extended") {
text = url.replace(/^.+\/([^\/]*)$/, "$1");
}
html.link({href: url, title: url}, text.clip(param.limit));
if (mode === "extended" && text !== location) {
res.write(" <small>(" + location + ")</small>");
}
html.link({href: url, title: url}, text.clip(param.limit));
if (mode === "extended" && text !== location) {
res.write(" <small>(" + location + ")</small>");
}
res.write(tail);
return res.pop();
});
}
res.write(tail);
return res.pop();
});
}
/**
* @returns {String}
*/
Story.prototype.getConfirmText = function() {
return gettext("You are about to delete a story by user {0}.",
this.creator.name);
return gettext("You are about to delete a story by user {0}.",
this.creator.name);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,8 +34,8 @@ markgettext("tag");
* @constant
*/
Tag.MOUNTPOINTS = {
Story: "tags",
Image: "galleries"
Story: "tags",
Image: "galleries"
}
/**
@ -49,12 +49,12 @@ Tag.DELIMITER = ", ";
* @param {String} type
*/
Tag.add = function(name, type, site) {
var tag = new Tag;
tag.name = name;
tag.type = type;
tag.site = site;
site.$tags.add(tag);
return tag;
var tag = new Tag;
tag.name = name;
tag.type = type;
tag.site = site;
site.$tags.add(tag);
return tag;
}
/**
@ -69,8 +69,8 @@ Tag.add = function(name, type, site) {
* @extends HopObject
*/
Tag.prototype.constructor = function() {
HopObject.confirmConstructor(Tag);
return this;
HopObject.confirmConstructor(Tag);
return this;
}
/**
@ -79,88 +79,88 @@ Tag.prototype.constructor = function() {
* @returns {Boolean}
*/
Tag.prototype.getPermission = function(action) {
if (!res.handlers.site.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "rss.xml":
return true;
case "edit":
case "delete":
case "rename":
return User.require(User.PRIVILEGED) ||
Membership.require(Membership.MANAGER);
}
return false;
if (!res.handlers.site.getPermission("main")) {
return false;
}
switch (action) {
case ".":
case "main":
case "rss.xml":
return true;
case "edit":
case "delete":
case "rename":
return User.require(User.PRIVILEGED) ||
Membership.require(Membership.MANAGER);
}
return false;
}
Tag.prototype.main_action = function() {
res.handlers.list = new jala.ListRenderer(this.getTagged());
res.handlers.list.setPageSize(this.site.pageSize);
res.data.title = gettext("Tag: {0}", this.name);
res.data.body = this.renderSkinAsString("$Tag#main");
res.handlers.site.renderSkin("Site#page");
res.handlers.site.log();
return;
res.handlers.list = new jala.ListRenderer(this.getTagged());
res.handlers.list.setPageSize(this.site.pageSize);
res.data.title = gettext("Tag: {0}", this.name);
res.data.body = this.renderSkinAsString("$Tag#main");
res.handlers.site.renderSkin("Site#page");
res.handlers.site.log();
return;
}
Tag.prototype.rss_xml_action = function() {
res.contentType = "text/xml";
res.dependsOn(this.site.modified);
res.digest();
var tagHubs = this.getTagged().list(0, this.site.pageSize);
var stories = [];
for (var i in tagHubs) {
stories.push(tagHubs[i].tagged);
}
res.write(this.site.getXml(stories));
return;
res.contentType = "text/xml";
res.dependsOn(this.site.modified);
res.digest();
var tagHubs = this.getTagged().list(0, this.site.pageSize);
var stories = [];
for (var i in tagHubs) {
stories.push(tagHubs[i].tagged);
}
res.write(this.site.getXml(stories));
return;
}
Tag.prototype.rename_action = function() {
var tag = this;
if (req.data.name) {
// Trim and remove troublesome characters (like ../.. etc.)
// We call getAccessName with a virgin HopObject to allow most names
var name = this.getAccessName.call(new HopObject, File.getName(req.data.name));
tag = this.site.getTags(this.type, Tags.ALL).get(name);
if (!tag) {
tag = Tag.add(name, this.site, this.type);
}
if (tag !== this) {
this.forEach(function() {
this.tag_id = tag._id;
});
this.remove();
res.commit();
}
}
res.redirect(tag.href());
return;
var tag = this;
if (req.data.name) {
// Trim and remove troublesome characters (like ../.. etc.)
// We call getAccessName with a virgin HopObject to allow most names
var name = this.getAccessName.call(new HopObject, File.getName(req.data.name));
tag = this.site.getTags(this.type, Tags.ALL).get(name);
if (!tag) {
tag = Tag.add(name, this.site, this.type);
}
if (tag !== this) {
this.forEach(function() {
this.tag_id = tag._id;
});
this.remove();
res.commit();
}
}
res.redirect(tag.href());
return;
// FIXME: Actually, the method should work like this but it caused a mess:
if (req.data.name) {
var name = this.getAccessName.call(new HopObject, File.getName(req.data.name));
var tag = this.site.getTags(this.type, Tags.ALL).get(name);
if (tag) {
if (tag !== this) {
// move tagged items to tag like above
}
} else {
// rename tag like: this.name = name
// FIXME: Actually, the method should work like this but it caused a mess:
if (req.data.name) {
var name = this.getAccessName.call(new HopObject, File.getName(req.data.name));
var tag = this.site.getTags(this.type, Tags.ALL).get(name);
if (tag) {
if (tag !== this) {
// move tagged items to tag like above
}
}
} else {
// rename tag like: this.name = name
}
}
}
Tag.prototype.delete_action = function() {
var parent = this._parent;
while (this.size() > 0) {
this.get(0).remove();
};
this.remove();
res.redirect(this.site[Tag.MOUNTPOINTS[this.type]].href());
var parent = this._parent;
while (this.size() > 0) {
this.get(0).remove();
};
this.remove();
res.redirect(this.site[Tag.MOUNTPOINTS[this.type]].href());
}
/**
@ -169,14 +169,14 @@ Tag.prototype.delete_action = function() {
* @returns {String}
*/
Tag.prototype.href = function(action) {
res.push();
res.write(this.site[Tag.MOUNTPOINTS[this.type]].href());
res.write(encodeURIComponent(this.name));
res.write("/");
if (action) {
res.write(java.net.URLEncoder.encode(action));
}
return res.pop();
res.push();
res.write(this.site[Tag.MOUNTPOINTS[this.type]].href());
res.write(encodeURIComponent(this.name));
res.write("/");
if (action) {
res.write(java.net.URLEncoder.encode(action));
}
return res.pop();
}
/**
@ -185,26 +185,26 @@ Tag.prototype.href = function(action) {
* @param {String} type
*/
Tag.prototype.permission_macro = function(param, type) {
return this.getPermission(type);
return this.getPermission(type);
}
/**
* @returns {Story[]|Image[]}
*/
Tag.prototype.getTagged = function() {
return this[pluralize(this.type.toLowerCase())];
return this[pluralize(this.type.toLowerCase())];
}
/**
* @returns {String}
*/
Tag.prototype.getTitle = function() {
return this.name;
return this.name;
}
/**
* @returns {String}
*/
Tag.prototype.toString = function() {
return this.type + " tag " + this.name + " of Site " + this.site.alias;
return this.type + " tag " + this.name + " of Site " + this.site.alias;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,18 +34,18 @@
* @returns {TagHub}
*/
TagHub.add = function(name, tagged, user) {
HopObject.confirmConstructor(this);
var hub = new TagHub;
var site = tagged.site || res.handlers.site;
var tag = site.getTags(tagged._prototype, Tags.ALL).get(name);
if (!tag) {
tag = Tag.add(name, tagged._prototype, site);
}
hub.tag = tag;
hub.tagged = tagged;
hub.user = user;
tagged.tags.add(hub);
return hub;
HopObject.confirmConstructor(this);
var hub = new TagHub;
var site = tagged.site || res.handlers.site;
var tag = site.getTags(tagged._prototype, Tags.ALL).get(name);
if (!tag) {
tag = Tag.add(name, tagged._prototype, site);
}
hub.tag = tag;
hub.tagged = tagged;
hub.user = user;
tagged.tags.add(hub);
return hub;
}
/**
@ -60,8 +60,8 @@ TagHub.add = function(name, tagged, user) {
* @extends HopObject
*/
TagHub.prototype.constructor = function() {
HopObject.confirmConstructor(TagHub);
return this;
HopObject.confirmConstructor(TagHub);
return this;
}
/**
@ -70,18 +70,18 @@ TagHub.prototype.constructor = function() {
* @returns {HopObject}
*/
TagHub.prototype.getMacroHandler = function(name) {
switch (name.toLowerCase()) {
case "tagged":
case "story":
case "image":
return this.tagged;
break;
}
switch (name.toLowerCase()) {
case "tagged":
case "story":
case "image":
return this.tagged;
break;
}
}
/**
* @return {String}
*/
TagHub.prototype.toString = function() {
return "Tag " + this.tag.name + " of " + this.tagged.toString();
return "Tag " + this.tag.name + " of " + this.tagged.toString();
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -49,27 +49,27 @@ Tags.ALPHABETICAL = "alphabetical";
* @returns {Boolean}
*/
Tags.prototype.getPermission = function(action) {
return res.handlers.site.getPermission("main");
return res.handlers.site.getPermission("main");
}
Tags.prototype.main_action = function() {
var action = this.getAction();
if (req.data.group) {
this.setGroup(req.data.group)
res.redirect(this.href(action));
}
if (req.data.page) {
this.setPage(req.data.page);
res.redirect(this.href(action));
}
res.data.title = this.getTitle();
res.data.body = this.renderSkinAsString("$Tags#" + req.action);
res.handlers.site.renderSkin("Site#page");
return;
var action = this.getAction();
if (req.data.group) {
this.setGroup(req.data.group)
res.redirect(this.href(action));
}
if (req.data.page) {
this.setPage(req.data.page);
res.redirect(this.href(action));
}
res.data.title = this.getTitle();
res.data.body = this.renderSkinAsString("$Tags#" + req.action);
res.handlers.site.renderSkin("Site#page");
return;
}
Tags.prototype.admin_action = function() {
return this.main_action();
return this.main_action();
}
/**
@ -78,64 +78,64 @@ Tags.prototype.admin_action = function() {
* @returns {HopObject}
*/
Tags.prototype.getChildElement = function(id) {
var child = this[id] || this.get(Tags.ALL).get(id);
return child;
var child = this[id] || this.get(Tags.ALL).get(id);
return child;
}
/**
*
*/
Tags.prototype.alphabet_macro = function() {
if (this.get(Tags.ALL).size() < 50) {
return;
}
if (this.get(Tags.ALL).size() < 50) {
return;
}
var self = this;
var collection = this.get(Tags.ALPHABETICAL);
var prefix = "?group=";
var group = this.getGroup();
var self = this;
var collection = this.get(Tags.ALPHABETICAL);
var prefix = "?group=";
var group = this.getGroup();
var add = function(text, id) {
if (group === id) {
res.write(text);
} else {
html.link({href: self.href(self.getAction()) + prefix + id}, text);
}
res.write(" ");
return;
};
var add = function(text, id) {
if (group === id) {
res.write(text);
} else {
html.link({href: self.href(self.getAction()) + prefix + id}, text);
}
res.write(" ");
return;
};
add("*", Tags.ALL);
collection.forEach(function() {
add(this._id, this._id);
});
if (this.get(Tags.OTHER).size() > 0) {
add("?", Tags.OTHER);
}
return;
add("*", Tags.ALL);
collection.forEach(function() {
add(this._id, this._id);
});
if (this.get(Tags.OTHER).size() > 0) {
add("?", Tags.OTHER);
}
return;
}
/**
*
*/
Tags.prototype.pager_macro = function() {
var page = this.getPage();
var max = this.get(this.getGroup()).size();
var size = this.getPageSize();
var total = Math.ceil(max / size);
if (total < 2) {
return;
}
var prefix = "?page=";
for (var i=1; i<=total; i+=1) {
if (i == page) {
res.write(i);
} else {
html.link({href: this.href(this.getAction()) + prefix + i}, i);
}
res.write(" ");
}
return;
var page = this.getPage();
var max = this.get(this.getGroup()).size();
var size = this.getPageSize();
var total = Math.ceil(max / size);
if (total < 2) {
return;
}
var prefix = "?page=";
for (var i=1; i<=total; i+=1) {
if (i == page) {
res.write(i);
} else {
html.link({href: this.href(this.getAction()) + prefix + i}, i);
}
res.write(" ");
}
return;
}
/**
@ -143,34 +143,34 @@ Tags.prototype.pager_macro = function() {
* @param {Object} param
*/
Tags.prototype.header_macro = function(param) {
var header = this.getHeader();
for each (var title in header) {
this.renderSkin("Tags#header", {title: title});
}
return;
var header = this.getHeader();
for each (var title in header) {
this.renderSkin("Tags#header", {title: title});
}
return;
}
/**
*
*/
Tags.prototype.list_macro = function(param, skin) {
var page = this.getPage();
var size = param.limit ? Math.min(param.limit, 100) : this.getPageSize();
var start = (page - 1) * size;
var collection = this.get(this.getGroup()).list(start, size);
// FIXME: ListRenderer should do this
//var list = new jala.ListRenderer(collection);
//list.render(skin || mgrlistitem);
var index = start + 1;
for each (var item in collection) {
// FIXME: Is there a more elegant solution?
if (item.constructor !== Tag) {
item = item.get(0);
}
item.renderSkin(skin || "$Tag#listItem", {index: index});
index += 1;
}
return;
var page = this.getPage();
var size = param.limit ? Math.min(param.limit, 100) : this.getPageSize();
var start = (page - 1) * size;
var collection = this.get(this.getGroup()).list(start, size);
// FIXME: ListRenderer should do this
//var list = new jala.ListRenderer(collection);
//list.render(skin || mgrlistitem);
var index = start + 1;
for each (var item in collection) {
// FIXME: Is there a more elegant solution?
if (item.constructor !== Tag) {
item = item.get(0);
}
item.renderSkin(skin || "$Tag#listItem", {index: index});
index += 1;
}
return;
}
/**
@ -179,14 +179,14 @@ Tags.prototype.list_macro = function(param, skin) {
* @returns {TagHub[]}
*/
Tags.prototype.get = function(group) {
return this._parent.getTags(this._id, group || this.getGroup());
return this._parent.getTags(this._id, group || this.getGroup());
}
/**
* @returns {String}
*/
Tags.prototype.getGroup = function() {
return decodeURIComponent(session.data[this.href("group")] || Tags.ALL);
return decodeURIComponent(session.data[this.href("group")] || Tags.ALL);
}
/**
@ -194,16 +194,16 @@ Tags.prototype.getGroup = function() {
* @param {String} group
*/
Tags.prototype.setGroup = function(group) {
session.data[this.href("group")] = encodeURIComponent(group);
this.setPage(1);
return;
session.data[this.href("group")] = encodeURIComponent(group);
this.setPage(1);
return;
}
/**
* @returns {Number}
*/
Tags.prototype.getPage = function() {
return session.data[this.href("page")] || 1;
return session.data[this.href("page")] || 1;
}
/**
@ -211,22 +211,22 @@ Tags.prototype.getPage = function() {
* @param {Number} page
*/
Tags.prototype.setPage = function(page) {
session.data[this.href("page")] = page;
return;
session.data[this.href("page")] = page;
return;
}
/**
* @returns {Number}
*/
Tags.prototype.getPageSize = function() {
return 25;
return 25;
}
/**
* @returns {String}
*/
Tags.prototype.getAction = function() {
return (req.action === "main" ? String.EMPTY : req.action);
return (req.action === "main" ? String.EMPTY : req.action);
}
/**
@ -235,8 +235,8 @@ Tags.prototype.getAction = function() {
* @see Images#getAdminHeader
*/
Tags.prototype.getHeader = function() {
if (this._parent.getAdminHeader) {
return this._parent.getAdminHeader(this._id) || [];
}
return [];
if (this._parent.getAdminHeader) {
return this._parent.getAdminHeader(this._id) || [];
}
return [];
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -48,37 +48,37 @@ User.HASHCOOKIE = getProperty("hashCookie", "antvilleHash");
* @returns {User}
*/
User.add = function(data) {
HopObject.confirmConstructor(this);
var user = new User;
var now = new Date;
user.map({
created: now,
email: data.email,
hash: data.hash,
name: data.name,
salt: session.data.token,
status: User.REGULAR,
url: data.url
});
root.users.add(user);
return user;
HopObject.confirmConstructor(this);
var user = new User;
var now = new Date;
user.map({
created: now,
email: data.email,
hash: data.hash,
name: data.name,
salt: session.data.token,
status: User.REGULAR,
url: data.url
});
root.users.add(user);
return user;
}
/**
* FIXME: Still needs a solution whether and how to remove a users sites
*/
User.remove = function() {
return; // FIXME: Disabled until thoroughly tested
if (this.constructor === User) {
HopObject.remove.call(this.comments);
HopObject.remove.call(this.files);
HopObject.remove.call(this.images);
//HopObject.remove.call(this.sites);
HopObject.remove.call(this.stories);
this.deleteMetadata();
this.remove();
}
return;
return; // FIXME: Disabled until thoroughly tested
if (this.constructor === User) {
HopObject.remove.call(this.comments);
HopObject.remove.call(this.files);
HopObject.remove.call(this.images);
//HopObject.remove.call(this.sites);
HopObject.remove.call(this.stories);
this.deleteMetadata();
this.remove();
}
return;
}
/**
@ -87,7 +87,7 @@ User.remove = function() {
* @returns {User}
*/
User.getByName = function(name) {
return root.users.get(name);
return root.users.get(name);
}
/**
@ -96,17 +96,17 @@ User.getByName = function(name) {
* @see defineConstants
*/
User.getStatus = defineConstants(User, markgettext("Blocked"),
markgettext("Regular"), markgettext("Trusted"),
markgettext("Privileged"));
markgettext("Regular"), markgettext("Trusted"),
markgettext("Privileged"));
/**
* @returns {String}
*/
User.getSalt = function() {
var salt = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8);
var random = java.security.SecureRandom.getInstance("SHA1PRNG");
random.nextBytes(salt);
return Packages.sun.misc.BASE64Encoder().encode(salt);
var salt = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 8);
var random = java.security.SecureRandom.getInstance("SHA1PRNG");
random.nextBytes(salt);
return Packages.sun.misc.BASE64Encoder().encode(salt);
}
/**
@ -116,46 +116,46 @@ User.getSalt = function() {
* @returns {User}
*/
User.register = function(data) {
if (!data.name) {
throw Error(gettext("Please enter a username."));
}
if (!data.name) {
throw Error(gettext("Please enter a username."));
}
data.name = data.name.trim();
if (data.name.length > 30) {
throw Error(gettext("Sorry, the username you entered is too long. Please choose a shorter one."));
} else if (data.name !== stripTags(data.name) || NAMEPATTERN.test(data.name)) {
throw Error(gettext("Please avoid special characters or HTML code in the name field."));
} else if (data.name !== root.users.getAccessName(data.name)) {
throw Error(gettext("Sorry, the user name you entered already exists. Please enter a different one."));
}
data.name = data.name.trim();
if (data.name.length > 30) {
throw Error(gettext("Sorry, the username you entered is too long. Please choose a shorter one."));
} else if (data.name !== stripTags(data.name) || NAMEPATTERN.test(data.name)) {
throw Error(gettext("Please avoid special characters or HTML code in the name field."));
} else if (data.name !== root.users.getAccessName(data.name)) {
throw Error(gettext("Sorry, the user name you entered already exists. Please enter a different one."));
}
data.email && (data.email = data.email.trim());
if (!validateEmail(data.email)) {
throw Error(gettext("Please enter a valid e-mail address"));
}
data.email && (data.email = data.email.trim());
if (!validateEmail(data.email)) {
throw Error(gettext("Please enter a valid e-mail address"));
}
if (User.isBlacklisted(data)) {
throw Error("Sequere pecuniam ad meliora.");
}
if (User.isBlacklisted(data)) {
throw Error("Sequere pecuniam ad meliora.");
}
// Create hash from password for JavaScript-disabled browsers
if (!data.hash) {
// Check if passwords match
if (!data.password || !data.passwordConfirm) {
throw Error(gettext("Could not verify your password. Please repeat your input."))
} else if (data.password !== data.passwordConfirm) {
throw Error(gettext("Unfortunately, your passwords did not match. Please repeat your input."));
}
data.hash = (data.password + session.data.token).md5();
}
// Create hash from password for JavaScript-disabled browsers
if (!data.hash) {
// Check if passwords match
if (!data.password || !data.passwordConfirm) {
throw Error(gettext("Could not verify your password. Please repeat your input."))
} else if (data.password !== data.passwordConfirm) {
throw Error(gettext("Unfortunately, your passwords did not match. Please repeat your input."));
}
data.hash = (data.password + session.data.token).md5();
}
var user = User.add(data);
// grant trust and sysadmin-rights if there's no sysadmin 'til now
if (root.admins.size() < 1) {
user.status = User.PRIVILEGED;
}
session.login(user);
return user;
var user = User.add(data);
// grant trust and sysadmin-rights if there's no sysadmin 'til now
if (root.admins.size() < 1) {
user.status = User.PRIVILEGED;
}
session.login(user);
return user;
}
/**
@ -164,72 +164,72 @@ User.register = function(data) {
* @returns {Boolean}
*/
User.isBlacklisted = function(data) {
var url;
var name = encodeURIComponent(data.name);
var email = encodeURIComponent(data.email);
var ip = encodeURIComponent(data.http_remotehost);
var url;
var name = encodeURIComponent(data.name);
var email = encodeURIComponent(data.email);
var ip = encodeURIComponent(data.http_remotehost);
var key = getProperty("botscout.apikey");
if (key) {
url = ["http://botscout.com/test/?multi", "&key=", key, "&mail=", email, "&ip=", ip];
try {
mime = getURL(url.join(String.EMPTY));
if (mime && mime.text && mime.text.startsWith("Y")) {
return true;
}
} catch (ex) {
app.log("Exception while trying to check blacklist URL " + url);
app.log(ex);
}
}
//return false;
// We only get here if botscout.com does not already blacklist the ip or email address
url = ["http://www.stopforumspam.com/api?f=json", "&email=", email];
if (ip.match(/^(?:\d{1,3}\.){3}\d{1,3}$/)) {
url.push("&ip=", ip);
}
try {
var key = getProperty("botscout.apikey");
if (key) {
url = ["http://botscout.com/test/?multi", "&key=", key, "&mail=", email, "&ip=", ip];
try {
mime = getURL(url.join(String.EMPTY));
} catch (ex) {
if (mime && mime.text && mime.text.startsWith("Y")) {
return true;
}
} catch (ex) {
app.log("Exception while trying to check blacklist URL " + url);
app.log(ex);
}
if (mime && mime.text) {
var result = JSON.parse(mime.text);
if (result.success) {
return !!(result.email.appears || (result.ip && result.ip.appears));
}
}
return false;
}
}
//return false;
// We only get here if botscout.com does not already blacklist the ip or email address
url = ["http://www.stopforumspam.com/api?f=json", "&email=", email];
if (ip.match(/^(?:\d{1,3}\.){3}\d{1,3}$/)) {
url.push("&ip=", ip);
}
try {
mime = getURL(url.join(String.EMPTY));
} catch (ex) {
app.log("Exception while trying to check blacklist URL " + url);
app.log(ex);
}
if (mime && mime.text) {
var result = JSON.parse(mime.text);
if (result.success) {
return !!(result.email.appears || (result.ip && result.ip.appears));
}
}
return false;
}
/**
*
*/
User.autoLogin = function() {
if (session.user) {
return;
}
var name = req.cookies[User.COOKIE];
var hash = req.cookies[User.HASHCOOKIE];
if (!name || !hash) {
return;
}
var user = User.getByName(name);
if (!user) {
return;
}
var ip = req.data.http_remotehost.clip(getProperty("cookieLevel", "4"),
String.EMPTY, "\\.");
if ((user.hash + ip).md5() !== hash) {
return;
}
session.login(user);
user.touch();
res.message = gettext('Welcome to {0}, {1}. Have fun!',
res.handlers.site.title, user.name);
return;
if (session.user) {
return;
}
var name = req.cookies[User.COOKIE];
var hash = req.cookies[User.HASHCOOKIE];
if (!name || !hash) {
return;
}
var user = User.getByName(name);
if (!user) {
return;
}
var ip = req.data.http_remotehost.clip(getProperty("cookieLevel", "4"),
String.EMPTY, "\\.");
if ((user.hash + ip).md5() !== hash) {
return;
}
session.login(user);
user.touch();
res.message = gettext('Welcome to {0}, {1}. Have fun!',
res.handlers.site.title, user.name);
return;
}
/**
@ -238,29 +238,29 @@ User.autoLogin = function() {
* @returns {User}
*/
User.login = function(data) {
var user = User.getByName(data.name);
if (!user) {
throw Error(gettext("Unfortunately, your login failed. Maybe a typo?"));
}
var digest = data.digest;
// Calculate digest for JavaScript-disabled browsers
if (!digest) {
app.logger.warn("Received clear text password from " + req.data.http_referer);
digest = ((data.password + user.salt).md5() + session.data.token).md5();
}
// Check if login is correct
if (digest !== user.getDigest(session.data.token)) {
throw Error(gettext("Unfortunately, your login failed. Maybe a typo?"))
}
if (data.remember) {
// Set long running cookies for automatic login
res.setCookie(User.COOKIE, user.name, 365);
var ip = req.data.http_remotehost.clip(getProperty("cookieLevel", "4"), String.EMPTY, "\\.");
res.setCookie(User.HASHCOOKIE, (user.hash + ip).md5(), 365);
}
user.touch();
session.login(user);
return user;
var user = User.getByName(data.name);
if (!user) {
throw Error(gettext("Unfortunately, your login failed. Maybe a typo?"));
}
var digest = data.digest;
// Calculate digest for JavaScript-disabled browsers
if (!digest) {
app.logger.warn("Received clear text password from " + req.data.http_referer);
digest = ((data.password + user.salt).md5() + session.data.token).md5();
}
// Check if login is correct
if (digest !== user.getDigest(session.data.token)) {
throw Error(gettext("Unfortunately, your login failed. Maybe a typo?"))
}
if (data.remember) {
// Set long running cookies for automatic login
res.setCookie(User.COOKIE, user.name, 365);
var ip = req.data.http_remotehost.clip(getProperty("cookieLevel", "4"), String.EMPTY, "\\.");
res.setCookie(User.HASHCOOKIE, (user.hash + ip).md5(), 365);
}
user.touch();
session.login(user);
return user;
}
/**
@ -281,33 +281,33 @@ User.logout = function() {
* @returns {Boolean}
*/
User.require = function(requiredStatus) {
var status = [User.BLOCKED, User.REGULAR, User.TRUSTED, User.PRIVILEGED];
if (requiredStatus && session.user) {
return status.indexOf(session.user.status) >= status.indexOf(requiredStatus);
}
return false;
var status = [User.BLOCKED, User.REGULAR, User.TRUSTED, User.PRIVILEGED];
if (requiredStatus && session.user) {
return status.indexOf(session.user.status) >= status.indexOf(requiredStatus);
}
return false;
}
/**
* @returns {String}
*/
User.getCurrentStatus = function() {
if (session.user) {
return session.user.status;
}
return null;
if (session.user) {
return session.user.status;
}
return null;
}
/**
* @returns {Membership}
*/
User.getMembership = function() {
var membership;
if (session.user) {
membership = Membership.getByName(session.user.name);
}
HopObject.confirmConstructor(Membership);
return membership || new Membership;
var membership;
if (session.user) {
membership = Membership.getByName(session.user.name);
}
HopObject.confirmConstructor(Membership);
return membership || new Membership;
}
/**
@ -315,19 +315,19 @@ User.getMembership = function() {
* @param {String} url
*/
User.setLocation = function(url) {
session.data.location = url || req.data.http_referer;
//app.debug("Pushed location " + session.data.location);
return;
session.data.location = url || req.data.http_referer;
//app.debug("Pushed location " + session.data.location);
return;
}
/**
* @returns {String}
*/
User.getLocation = function() {
var url = session.data.location;
delete session.data.location;
//app.debug("Popped location " + url);
return url;
var url = session.data.location;
delete session.data.location;
//app.debug("Popped location " + url);
return url;
}
/**
@ -336,15 +336,15 @@ User.getLocation = function() {
* @param {String} newName The desired name of the user account.
*/
User.rename = function(currentName, newName) {
var user = User.getByName(currentName);
if (user) {
if (user.name === newName) {
return newName;
}
user.name = root.users.getAccessName(newName);
return user.name;
}
return currentName;
var user = User.getByName(currentName);
if (user) {
if (user.name === newName) {
return newName;
}
user.name = root.users.getAccessName(newName);
return user.name;
}
return currentName;
}
/**
@ -372,8 +372,8 @@ User.rename = function(currentName, newName) {
* @extends HopObject
*/
User.prototype.constructor = function(data) {
HopObject.confirmConstructor(User);
return this;
HopObject.confirmConstructor(User);
return this;
}
/**
@ -387,7 +387,7 @@ User.prototype.onLogout = function() { /* ... */ }
* @returns {Boolean}
*/
User.prototype.getPermission = function(action) {
return User.require(User.PRIVILEGED);
return User.require(User.PRIVILEGED);
}
/**
@ -395,45 +395,45 @@ User.prototype.getPermission = function(action) {
* @param {Object} data
*/
User.prototype.update = function(data) {
if (!data.digest && data.password) {
data.digest = ((data.password + this.salt).md5() +
session.data.token).md5();
}
if (data.digest) {
if (data.digest !== this.getDigest(session.data.token)) {
throw Error(gettext("Oops, your old password is incorrect. Please re-enter it."));
if (!data.digest && data.password) {
data.digest = ((data.password + this.salt).md5() +
session.data.token).md5();
}
if (data.digest) {
if (data.digest !== this.getDigest(session.data.token)) {
throw Error(gettext("Oops, your old password is incorrect. Please re-enter it."));
}
if (!data.hash) {
if (!data.newPassword || !data.newPasswordConfirm) {
throw Error(gettext("Please specify a new password."));
} else if (data.newPassword !== data.newPasswordConfirm) {
throw Error(gettext("Unfortunately, your passwords did not match. Please repeat your input."));
}
if (!data.hash) {
if (!data.newPassword || !data.newPasswordConfirm) {
throw Error(gettext("Please specify a new password."));
} else if (data.newPassword !== data.newPasswordConfirm) {
throw Error(gettext("Unfortunately, your passwords did not match. Please repeat your input."));
}
data.hash = (data.newPassword + session.data.token).md5();
}
this.map({
hash: data.hash,
salt: session.data.token
});
}
if (!(data.email = validateEmail(data.email))) {
throw Error(gettext("Please enter a valid e-mail address"));
}
if (data.url && !(data.url = validateUrl(data.url))) {
throw Error(gettext("Please enter a valid URL"));
}
this.email = data.email;
this.url = data.url;
this.touch();
return this;
data.hash = (data.newPassword + session.data.token).md5();
}
this.map({
hash: data.hash,
salt: session.data.token
});
}
if (!(data.email = validateEmail(data.email))) {
throw Error(gettext("Please enter a valid e-mail address"));
}
if (data.url && !(data.url = validateUrl(data.url))) {
throw Error(gettext("Please enter a valid URL"));
}
this.email = data.email;
this.url = data.url;
this.touch();
return this;
}
/**
*
*/
User.prototype.touch = function() {
this.modified = new Date;
return;
this.modified = new Date;
return;
}
/**
@ -442,8 +442,8 @@ User.prototype.touch = function() {
* @returns {String}
*/
User.prototype.getDigest = function(token) {
token || (token = String.EMPTY);
return (this.hash + token).md5();
token || (token = String.EMPTY);
return (this.hash + token).md5();
}
/**
@ -452,20 +452,20 @@ User.prototype.getDigest = function(token) {
* @returns {Object}
*/
User.prototype.getFormOptions = function(name) {
switch (name) {
case "status":
return User.getStatus();
}
switch (name) {
case "status":
return User.getStatus();
}
}
/**
* Enable <% user.email %> macro for privileged users only
*/
User.prototype.email_macro = function() {
if (User.require(User.PRIVILEGED)) {
res.write(this.email);
}
return;
if (User.require(User.PRIVILEGED)) {
res.write(this.email);
}
return;
}
/**
@ -474,19 +474,19 @@ User.prototype.email_macro = function() {
* @param {String} type
*/
User.prototype.list_macro = function(param, type) {
switch (type) {
case "sites":
var memberships = session.user.list();
memberships.sort(function(a, b) {
return b.site.modified - a.site.modified;
});
memberships.forEach(function(membership) {
var site;
if (site = membership.get("site")) {
site.renderSkin("$Site#listItem");
}
return;
});
}
return;
switch (type) {
case "sites":
var memberships = session.user.list();
memberships.sort(function(a, b) {
return b.site.modified - a.site.modified;
});
memberships.forEach(function(membership) {
var site;
if (site = membership.get("site")) {
site.renderSkin("$Site#listItem");
}
return;
});
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -35,13 +35,13 @@ markgettext("vote");
* @returns {Vote}
*/
Vote.add = function(choice, poll) {
HopObject.confirmConstructor(Vote);
var vote = new Vote;
vote.choice = choice;
vote.creator = session.user;
vote.creator_name = session.user.name;
vote.created = vote.modified = new Date;
poll.votes.add(vote);
HopObject.confirmConstructor(Vote);
var vote = new Vote;
vote.choice = choice;
vote.creator = session.user;
vote.creator_name = session.user.name;
vote.created = vote.modified = new Date;
poll.votes.add(vote);
return vote;
}
@ -57,6 +57,6 @@ Vote.add = function(choice, poll) {
* @extends HopObject
*/
Vote.prototype.constructor = function(choice) {
HopObject.confirmConstructor(this);
return this;
HopObject.confirmConstructor(this);
return this;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -24,5 +24,5 @@
// $URL$
Comment.prototype.replylink_macro = function(param) {
return this.link_macro(param, "comment");
return this.link_macro(param, "comment");
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -27,74 +27,74 @@ relocateProperty(Site, "createtime", "created");
relocateProperty(Site, "modifytime", "modified");
File.prototype.alias_macro = function(param) {
if (param.as === "editor") {
this.input_macro(param, "name");
} else if (param.as === "link") {
param.title = encodeForm(this.description);
this.link_filter(this.name, param, this.href());
} else {
res.write(this.name);
}
return;
if (param.as === "editor") {
this.input_macro(param, "name");
} else if (param.as === "link") {
param.title = encodeForm(this.description);
this.link_filter(this.name, param, this.href());
} else {
res.write(this.name);
}
return;
}
File.prototype.description_macro = function(param) {
if (param.as === "editor") {
this.input_macro(param, "description");
} else {
res.write(this.description);
}
return;
if (param.as === "editor") {
this.input_macro(param, "description");
} else {
res.write(this.description);
}
return;
}
File.prototype.filesize_macro = function(param) {
return this.contentLength_macro(param);
return this.contentLength_macro(param);
}
File.prototype.editlink_macro = function(param) {
return this.link_macro(param, "edit", param.text || "edit");
return this.link_macro(param, "edit", param.text || "edit");
}
File.prototype.deletelink_macro = function(param) {
res.push();
var image;
if (param.image && (image = this.site.images.get(param.image))) {
image.render_macro(param);
} else {
res.write(param.text || "delete");
}
return this.link_macro(param, "delete", res.pop());
res.push();
var image;
if (param.image && (image = this.site.images.get(param.image))) {
image.render_macro(param);
} else {
res.write(param.text || "delete");
}
return this.link_macro(param, "delete", res.pop());
}
File.prototype.viewlink_macro = function(param) {
param.title = encodeForm(this.description);
return this.link_macro(param, ".", param.text || "view")
param.title = encodeForm(this.description);
return this.link_macro(param, ".", param.text || "view")
}
File.prototype.mimetype_macro = function(param) {
return res.write(this.contentType);
return res.write(this.contentType);
}
File.prototype.filetype_macro = function(param) {
if (this.contentType) {
res.write(this.contentType.substring(this.contentType.indexOf("/") + 1));
} else {
var i = this.name.lastIndexOf(".");
if (i > -1) {
res.write(this.name.substring(i+1, this.name.length));
}
}
return;
if (this.contentType) {
res.write(this.contentType.substring(this.contentType.indexOf("/") + 1));
} else {
var i = this.name.lastIndexOf(".");
if (i > -1) {
res.write(this.name.substring(i+1, this.name.length));
}
}
return;
}
File.prototype.clicks_macro = function(param) {
if (!this.requests) {
res.write(param.no || "no downloads");
} else if (this.requests < 2) {
res.write(param.one || "one download");
} else {
res.write(param.more ? this.requests + " " + param.more :
this.requests + " downloads");
}
return;
if (!this.requests) {
res.write(param.no || "no downloads");
} else if (this.requests < 2) {
res.write(param.one || "one download");
} else {
res.write(param.more ? this.requests + " " + param.more :
this.requests + " downloads");
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,194 +26,194 @@
app.addRepository("modules/helma/Color.js");
var disableAction = function(msg) {
res.data.title = msg + " :(";
res.data.body = msg + ". " + "Sorry.";
this.renderSkin("Site#page");
return;
res.data.title = msg + " :(";
res.data.body = msg + ". " + "Sorry.";
this.renderSkin("Site#page");
return;
}
var relocateProperty = function(proto, name, key) {
if (!proto || !name) {
return;
}
key || (key = name);
proto.prototype.__defineGetter__(name, function() {
return this[key];
});
proto.prototype.__defineSetter__(name, function(value) {
this[key] = value;
return;
});
return addPropertyMacro.apply(this, arguments);
if (!proto || !name) {
return;
}
key || (key = name);
proto.prototype.__defineGetter__(name, function() {
return this[key];
});
proto.prototype.__defineSetter__(name, function(value) {
this[key] = value;
return;
});
return addPropertyMacro.apply(this, arguments);
}
var addPropertyMacro = function(proto, name, key) {
// These two are managed by the HopObject prototype already
if (name === "createtime" || name === "modifytime") {
return;
}
key || (key = name);
proto.prototype[name + "_macro"] = function(param) {
if (param.as === "editor") {
this.input_macro(param, key);
} else {
res.write(this[key]);
}
};
return;
// These two are managed by the HopObject prototype already
if (name === "createtime" || name === "modifytime") {
return;
}
key || (key = name);
proto.prototype[name + "_macro"] = function(param) {
if (param.as === "editor") {
this.input_macro(param, key);
} else {
res.write(this[key]);
}
};
return;
}
var formatTimestamp = function() {
return formatDate.apply(this, arguments);
return formatDate.apply(this, arguments);
}
var linkedpath_macro = breadcrumbs_macro;
function link_macro() {
var param = arguments[0];
if (param.to) {
param.url = param.to;
delete param.to;
}
return renderLink.apply(this, arguments);
var param = arguments[0];
if (param.to) {
param.url = param.to;
delete param.to;
}
return renderLink.apply(this, arguments);
}
function logo_macro(param, name) {
return image_macro.call(global, param, "/" + (name || param.name || "smallchaos"));
return image_macro.call(global, param, "/" + (name || param.name || "smallchaos"));
}
function input_macro(param) {
switch (param.type) {
case "button":
break;
switch (param.type) {
case "button":
break;
case "radio":
param.selectedValue = req.data[param.name]; break;
case "radio":
param.selectedValue = req.data[param.name]; break;
default:
param.value = param.name && req.data[param.name] ?
req.data[param.name] : param.value;
}
default:
param.value = param.name && req.data[param.name] ?
req.data[param.name] : param.value;
}
switch (param.type) {
case "textarea" :
html.textArea(param); break;
switch (param.type) {
case "textarea" :
html.textArea(param); break;
case "checkbox" :
html.checkBox(param); break;
case "checkbox" :
html.checkBox(param); break;
case "button" :
// FIXME: this is left for backwards compatibility
html.submit(param); break;
case "button" :
// FIXME: this is left for backwards compatibility
html.submit(param); break;
case "submit" :
html.submit(param); break;
case "submit" :
html.submit(param); break;
case "password" :
html.password(param); break;
case "password" :
html.password(param); break;
case "radio" :
html.radioButton(param); break;
case "radio" :
html.radioButton(param); break;
case "file" :
html.file(param); break;
case "file" :
html.file(param); break;
default :
html.input(param);
}
return;
default :
html.input(param);
}
return;
}
// FIXME: This method deserves some more compatibility pampering
// (eg. itempre/suffix)
function storylist_macro(param) {
var id = param.of ? param.of + "/stories" : "stories";
return list_macro(param, id, param.limit);
var id = param.of ? param.of + "/stories" : "stories";
return list_macro(param, id, param.limit);
}
function sitelist_macro(param) {
param.limit || (param.limit = 10);
return list_macro(param, "updates", Math.min(param.limit, 25));
param.limit || (param.limit = 10);
return list_macro(param, "updates", Math.min(param.limit, 25));
}
// FIXME: This method deserves some more compatibility pampering
// (eg. itempre/suffix, as="thumbnail")
function imagelist_macro(param) {
var id = param.of ? param.of + "/images" : "images";
return list_macro(param, id, param.limit);
var id = param.of ? param.of + "/images" : "images";
return list_macro(param, id, param.limit);
}
// FIXME: This method deserves some more compatibility pampering
// (eg. itempre/suffix, limit)
function topiclist_macro(param) {
var site = param.of ? root.get(param.of) : res.handlers.site;
if (site) {
site.tags.list_macro(param, param.skin);
}
return;
var site = param.of ? root.get(param.of) : res.handlers.site;
if (site) {
site.tags.list_macro(param, param.skin);
}
return;
}
function username_macro(param) {
if (!session.user) {
return;
}
if (session.user.url && param.as === "link") {
html.link({href: session.user.url}, session.user.name);
} else if (session.user.url && param.as === "url") {
res.write(session.user.url);
} else {
res.write(session.user.name);
}
return;
if (!session.user) {
return;
}
if (session.user.url && param.as === "link") {
html.link({href: session.user.url}, session.user.name);
} else if (session.user.url && param.as === "url") {
res.write(session.user.url);
} else {
res.write(session.user.name);
}
return;
}
function spacer_macro(param) {
param.width || (param.width = 2);
param.height || (param.height = 2);
param.border || (param.border = 0);
param.alt = "";
param.name = "/pixel.gif";
return image_macro(param);
param.width || (param.width = 2);
param.height || (param.height = 2);
param.border || (param.border = 0);
param.alt = "";
param.name = "/pixel.gif";
return image_macro(param);
}
function fakemail_macro(param) {
var tldList = ["com", "net", "org", "mil", "edu", "de", "biz", "de", "ch",
"at", "ru", "de", "tv", "com", "st", "br", "fr", "de", "nl", "dk",
"ar", "jp", "eu", "it", "es", "com", "us", "ca", "pl"];
var nOfMails = param.number ? (param.number <= 50 ? param.number : 50) : 20;
for (var i=0;i<nOfMails;i++) {
var tld = tldList[Math.floor(Math.random()*tldList.length)];
var mailName = "";
var serverName = "";
var nameLength = Math.round(Math.random()*7) + 3;
for (var j=0;j<nameLength;j++)
mailName += String.fromCharCode(Math.round(Math.random()*25) + 97);
var serverLength = Math.round(Math.random()*16) + 8;
for (var j=0;j<serverLength;j++)
serverName += String.fromCharCode(Math.round(Math.random()*25) + 97);
var addr = mailName + "@" + serverName + "." + tld;
html.link({href: "mailto:" + addr}, addr);
if (i+1 < nOfMails)
res.write(param.delimiter ? param.delimiter : ", ");
}
"at", "ru", "de", "tv", "com", "st", "br", "fr", "de", "nl", "dk",
"ar", "jp", "eu", "it", "es", "com", "us", "ca", "pl"];
var nOfMails = param.number ? (param.number <= 50 ? param.number : 50) : 20;
for (var i=0;i<nOfMails;i++) {
var tld = tldList[Math.floor(Math.random()*tldList.length)];
var mailName = "";
var serverName = "";
var nameLength = Math.round(Math.random()*7) + 3;
for (var j=0;j<nameLength;j++)
mailName += String.fromCharCode(Math.round(Math.random()*25) + 97);
var serverLength = Math.round(Math.random()*16) + 8;
for (var j=0;j<serverLength;j++)
serverName += String.fromCharCode(Math.round(Math.random()*25) + 97);
var addr = mailName + "@" + serverName + "." + tld;
html.link({href: "mailto:" + addr}, addr);
if (i+1 < nOfMails)
res.write(param.delimiter ? param.delimiter : ", ");
}
return;
}
// FIXME: This cannot be working...
function imageoftheday_macro(param) {
var images = res.handlers.site.images;
delete param.topic;
var img = pool.get(0);
param.name = img.alias;
return image_macro(param);
var images = res.handlers.site.images;
delete param.topic;
var img = pool.get(0);
param.name = img.alias;
return image_macro(param);
}
function support_macro() { /* ... */ }
function renderColorAsString(c) {
return c && c.isHexColor() ? "#" + c : c;
return c && c.isHexColor() ? "#" + c : c;
}
function renderColor(c) {
return res.write(renderColorAsString(c));
return res.write(renderColorAsString(c));
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,243 +26,243 @@
app.addRepository("modules/helma/Aspects.js");
var aspects = {
setTopics: function(args, func, obj) {
// We must clone the request parameters because only req.data is mutable.
// (See req.params, req.postParams etc.)
var param = Object.prototype.clone.call(args[0], {});
var topic = param.topic || param.addToTopic;
if (!param.tags && topic) {
param.tags = [topic];
setTopics: function(args, func, obj) {
// We must clone the request parameters because only req.data is mutable.
// (See req.params, req.postParams etc.)
var param = Object.prototype.clone.call(args[0], {});
var topic = param.topic || param.addToTopic;
if (!param.tags && topic) {
param.tags = [topic];
}
args[0] = param;
return args;
},
fixMacroParams: function(args) {
var param = args[0];
var id = args[1] || param.name || param.id;
var mode = args[2] || param.as;
var url = param.linkto;
!param.skin && (param.skin = param.useskin);
delete(param.name);
delete(param.as);
delete(param.linkto);
return [param, id, mode, url];
},
fixStoryEditorParams: function(args, func, story) {
// IE6 sends the button text instead of the value; thus, we
// need to check for the "editableby" property as well :/
if (req.isPost() && req.postParams.save != 1) { // && req.postParams.editableby) {
if (req.postParams.publish) {
req.postParams.save = 1;
}
args[0] = param;
return args;
},
fixMacroParams: function(args) {
var param = args[0];
var id = args[1] || param.name || param.id;
var mode = args[2] || param.as;
var url = param.linkto;
!param.skin && (param.skin = param.useskin);
delete(param.name);
delete(param.as);
delete(param.linkto);
return [param, id, mode, url];
},
fixStoryEditorParams: function(args, func, story) {
// IE6 sends the button text instead of the value; thus, we
// need to check for the "editableby" property as well :/
if (req.isPost() && req.postParams.save != 1) { // && req.postParams.editableby) {
if (req.postParams.publish) {
req.postParams.save = 1;
}
if (req.postParams.save != 1) {
req.postParams.save = 1;
req.postParams.status = Story.CLOSED;
} else if (req.postParams.editableby) {
var status = [Story.PUBLIC, Story.SHARED, Story.OPEN];
req.postParams.status = status[req.postParams.editableby] || req.postParams.editableBy;
}
req.postParams.mode = (req.postParams.addToFront ?
Story.FEATURED : Story.HIDDEN);
req.postParams.commentMode = (req.postParams.discussions ?
Story.OPEN : Story.CLOSED);
if (req.postParams.save != 1) {
req.postParams.save = 1;
req.postParams.status = Story.CLOSED;
} else if (req.postParams.editableby) {
var status = [Story.PUBLIC, Story.SHARED, Story.OPEN];
req.postParams.status = status[req.postParams.editableby] || req.postParams.editableBy;
}
req.postParams.addToFront = null;
req.postParams.discussions = null;
req.postParams.editableby = null;
req.postParams.publish = null;
return args;
},
req.postParams.mode = (req.postParams.addToFront ?
Story.FEATURED : Story.HIDDEN);
req.postParams.commentMode = (req.postParams.discussions ?
Story.OPEN : Story.CLOSED);
}
req.postParams.addToFront = null;
req.postParams.discussions = null;
req.postParams.editableby = null;
req.postParams.publish = null;
return args;
},
fixPager: function(args, func, obj) {
var archive = res.handlers.day = obj.archive || obj;
res.push();
archive.stories_macro();
res.data.storylist = res.pop();
res.push();
archive.link_macro({}, "previous", gettext("Previous page"));
res.data.prevpage = res.pop();
res.push();
archive.link_macro({}, "next", gettext("Next page"));
res.data.nextpage = res.pop();
return args;
}
fixPager: function(args, func, obj) {
var archive = res.handlers.day = obj.archive || obj;
res.push();
archive.stories_macro();
res.data.storylist = res.pop();
res.push();
archive.link_macro({}, "previous", gettext("Previous page"));
res.data.prevpage = res.pop();
res.push();
archive.link_macro({}, "next", gettext("Next page"));
res.data.nextpage = res.pop();
return args;
}
}
helma.aspects.addAround(global, "image_macro", function(args, func) {
args = aspects.fixMacroParams(args);
var url = args[3];
url && res.push();
func.apply(global, args);
url && res.write(link_filter(res.pop(), {}, url));
return;
args = aspects.fixMacroParams(args);
var url = args[3];
url && res.push();
func.apply(global, args);
url && res.write(link_filter(res.pop(), {}, url));
return;
});
helma.aspects.addAround(global, "poll_macro", function(args, func) {
return func.apply(global, aspects.fixMacroParams(args));
return func.apply(global, aspects.fixMacroParams(args));
});
helma.aspects.addAround(global, "file_macro", function(args, func) {
return func.apply(global, aspects.fixMacroParams(args));
return func.apply(global, aspects.fixMacroParams(args));
});
helma.aspects.addBefore(global, "story_macro", function(args, func) {
args = aspects.fixMacroParams(args);
if (args[0].skin == "display") {
args[0].skin = "content";
}
return args;
args = aspects.fixMacroParams(args);
if (args[0].skin == "display") {
args[0].skin = "content";
}
return args;
});
(function() {
var func;
if (HopObject.prototype.onCodeUpdate) {
// There are HopObject aspects already in the main code
func = HopObject.prototype.onCodeUpdate;
}
HopObject.prototype.onCodeUpdate = function() {
func && func.call(this); // Call the aspects in main code
helma.aspects.addAfter(this, "onRequest", function(args, func, obj) {
res.handlers.members = res.handlers.site.members;
res.handlers.membermgr = res.handlers.site.members;
return args;
});
helma.aspects.addBefore(this, "skin_macro", function(args, func, obj) {
param = args[0];
return [param, args[1] || param.name];
});
helma.aspects.addBefore(this, "link_macro", function(args, func, obj) {
var url, text;
var param = args[0];
var to = param.to;
delete param.to;
// Enabling story.link macros with full URL in parameter:
if (to && to.contains("://")) {
html.link({href: to}, param.text);
url = text = ".."; // Ugly hack to prevent HopObject.link in code from being rendered as well
} else {
// Compatibility for more recent link macros /////???, doing a lot of i18n witchcraft
url = args[1] || ".";
text = args[2];
var action = url.split(/#|\?/)[0];
if (!text) {
action === "." && (action = obj._id);
text = action.capitalize(); //gettext(action.capitalize());
}
}
return [param, to || url, param.text || text, args[3]];
});
}
var func;
if (HopObject.prototype.onCodeUpdate) {
// There are HopObject aspects already in the main code
func = HopObject.prototype.onCodeUpdate;
}
HopObject.prototype.onCodeUpdate = function() {
func && func.call(this); // Call the aspects in main code
helma.aspects.addAfter(this, "onRequest", function(args, func, obj) {
res.handlers.members = res.handlers.site.members;
res.handlers.membermgr = res.handlers.site.members;
return args;
});
helma.aspects.addBefore(this, "skin_macro", function(args, func, obj) {
param = args[0];
return [param, args[1] || param.name];
});
helma.aspects.addBefore(this, "link_macro", function(args, func, obj) {
var url, text;
var param = args[0];
var to = param.to;
delete param.to;
// Enabling story.link macros with full URL in parameter:
if (to && to.contains("://")) {
html.link({href: to}, param.text);
url = text = ".."; // Ugly hack to prevent HopObject.link in code from being rendered as well
} else {
// Compatibility for more recent link macros /////???, doing a lot of i18n witchcraft
url = args[1] || ".";
text = args[2];
var action = url.split(/#|\?/)[0];
if (!text) {
action === "." && (action = obj._id);
text = action.capitalize(); //gettext(action.capitalize());
}
}
return [param, to || url, param.text || text, args[3]];
});
}
}());
(function() {
var func;
if (Archive.prototype.onCodeUpdate) {
func = Archive.prototype.onCodeUpdate;
}
Archive.prototype.onCodeUpdate = function() {
func && func.call(this);
return helma.aspects.addBefore(this, "main_action", aspects.fixPager);
}
var func;
if (Archive.prototype.onCodeUpdate) {
func = Archive.prototype.onCodeUpdate;
}
Archive.prototype.onCodeUpdate = function() {
func && func.call(this);
return helma.aspects.addBefore(this, "main_action", aspects.fixPager);
}
}());
(function() {
var func;
if (Image.prototype.onCodeUpdate) {
func = Image.prototype.onCodeUpdate;
}
Image.prototype.onCodeUpdate = function() {
func && func.call(this);
return helma.aspects.addBefore(this, "update", aspects.setTopics);
}
var func;
if (Image.prototype.onCodeUpdate) {
func = Image.prototype.onCodeUpdate;
}
Image.prototype.onCodeUpdate = function() {
func && func.call(this);
return helma.aspects.addBefore(this, "update", aspects.setTopics);
}
}());
Images.prototype.onCodeUpdate = function() {
return helma.aspects.addAround(this, "getPermission", function(args, func, images) {
var permission = func.apply(images, args);
if (!permission) {
switch (args[0]) {
case "topics":
return true;
}
return helma.aspects.addAround(this, "getPermission", function(args, func, images) {
var permission = func.apply(images, args);
if (!permission) {
switch (args[0]) {
case "topics":
return true;
}
return permission;
});
}
return permission;
});
}
Layout.prototype.onCodeUpdate = function() {
helma.aspects.addAround(this, "getPermission", function(args, func, layout) {
var permission = func.apply(layout, args);
if (!permission) {
switch (args[0]) {
case "convert":
return true;
}
helma.aspects.addAround(this, "getPermission", function(args, func, layout) {
var permission = func.apply(layout, args);
if (!permission) {
switch (args[0]) {
case "convert":
return true;
}
return permission;
});
return helma.aspects.addAround(this, "image_macro", function(args, func, layout) {
args = aspects.fixMacroParams(args);
var url = args[3];
url && res.push();
func.apply(layout, args);
url && link_filter(res.pop(), {}, url);
return;
});
}
return permission;
});
return helma.aspects.addAround(this, "image_macro", function(args, func, layout) {
args = aspects.fixMacroParams(args);
var url = args[3];
url && res.push();
func.apply(layout, args);
url && link_filter(res.pop(), {}, url);
return;
});
}
Members.prototype.onCodeUpdate = function() {
helma.aspects.addAround(this, "getPermission", function(args, func, members) {
var permission = func.apply(members, args);
if (!permission) {
switch(args[0]) {
case "sendpwd":
return true;
}
helma.aspects.addAround(this, "getPermission", function(args, func, members) {
var permission = func.apply(members, args);
if (!permission) {
switch(args[0]) {
case "sendpwd":
return true;
}
return permission;
});
}
return permission;
});
}
(function() {
var func;
if (Site.prototype.onCodeUpdate) {
func = Site.prototype.onCodeUpdate;
}
Site.prototype.onCodeUpdate = function() {
func && func.call(this);
helma.aspects.addAround(this, "getPermission", function(args, func, site) {
var permission = func.apply(site, args);
if (!permission) {
switch(args[0]) {
case "rss":
case "feeds":
case "mostread":
return true;
}
}
return permission;
});
var func;
if (Site.prototype.onCodeUpdate) {
func = Site.prototype.onCodeUpdate;
}
Site.prototype.onCodeUpdate = function() {
func && func.call(this);
helma.aspects.addAround(this, "getPermission", function(args, func, site) {
var permission = func.apply(site, args);
if (!permission) {
switch(args[0]) {
case "rss":
case "feeds":
case "mostread":
return true;
}
}
return permission;
});
return helma.aspects.addBefore(this, "main_action", aspects.fixPager);
}
return helma.aspects.addBefore(this, "main_action", aspects.fixPager);
}
}());
(function() {
var func;
if (Story.prototype.onCodeUpdate) {
func = Story.prototype.onCodeUpdate;
}
Story.prototype.onCodeUpdate = function() {
func && func.call(this);
helma.aspects.addBefore(this, "edit_action", aspects.fixStoryEditorParams);
return helma.aspects.addBefore(this, "update", aspects.setTopics);
}
var func;
if (Story.prototype.onCodeUpdate) {
func = Story.prototype.onCodeUpdate;
}
Story.prototype.onCodeUpdate = function() {
func && func.call(this);
helma.aspects.addBefore(this, "edit_action", aspects.fixStoryEditorParams);
return helma.aspects.addBefore(this, "update", aspects.setTopics);
}
}());
Stories.prototype.onCodeUpdate = function() {
return helma.aspects.addBefore(this, "create_action",
aspects.fixStoryEditorParams);
return helma.aspects.addBefore(this, "create_action",
aspects.fixStoryEditorParams);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -33,58 +33,58 @@ relocateProperty(Image, "alttext", "description");
Image.prototype.code_macro = Image.prototype.macro_macro;
Image.prototype.topicchooser_macro = function() {
return Story.prototype.topicchooser_macro.apply(this, arguments);
return Story.prototype.topicchooser_macro.apply(this, arguments);
}
Image.prototype.gallery_macro = function() {
return Story.prototype.topic_macro.apply(this, arguments);
return Story.prototype.topic_macro.apply(this, arguments);
}
Image.prototype.topic_macro = Image.prototype.gallery_macro;
Image.prototype.show_macro = function(param) {
if (param.as === "thumbnail" && this.thumbnailWidth) {
res.push();
this.thumbnail_macro(param);
this.link_filter(res.pop(), param, this.href());
} else {
this.render_macro(param);
}
return;
if (param.as === "thumbnail" && this.thumbnailWidth) {
res.push();
this.thumbnail_macro(param);
this.link_filter(res.pop(), param, this.href());
} else {
this.render_macro(param);
}
return;
}
Image.prototype.editlink_macro = function(param) {
res.push();
if (param.image && this.parent.images.get(param.image)) {
renderImage(this.parent.images.get(param.image), param);
} else {
res.write(param.text || "edit");
}
return this.link_macro(param, "edit", res.pop());
res.push();
if (param.image && this.parent.images.get(param.image)) {
renderImage(this.parent.images.get(param.image), param);
} else {
res.write(param.text || "edit");
}
return this.link_macro(param, "edit", res.pop());
}
Image.prototype.deletelink_macro = function(param) {
res.push();
if (param.image && this.parent.images.get(param.image)) {
renderImage(this.parent.images.get(param.image), param);
} else {
res.write(param.text || "delete");
}
return this.link_macro(param, "delete", res.pop());
res.push();
if (param.image && this.parent.images.get(param.image)) {
renderImage(this.parent.images.get(param.image), param);
} else {
res.write(param.text || "delete");
}
return this.link_macro(param, "delete", res.pop());
}
Image.prototype.replacelink_macro = function(param) {
return;
return;
}
Image.prototype.getPopupUrl = function() {
res.push();
res.write("javascript: openPopup('");
res.write(this.getUrl());
res.write("',");
res.write(this.width);
res.write(",");
res.write(this.height);
res.write("); return false;");
return res.pop();
res.push();
res.write("javascript: openPopup('");
res.write(this.getUrl());
res.write("',");
res.write(this.width);
res.write(",");
res.write(this.height);
res.write("); return false;");
return res.pop();
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -24,5 +24,5 @@
// $URL$
Images.prototype.topics_action = function() {
return res.redirect(res.handlers.site.href("galleries"));
return res.redirect(res.handlers.site.href("galleries"));
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -24,291 +24,291 @@
// $URL$
Layout.prototype.convert_action = function() {
if (req.isPost() && req.data.save && req.data.file) {
var mime = req.data.file;
var name = mime.normalizeFilename(mime.name);
var prefix = "antville.layout.import.";
var dir = java.io.File.createTempFile(prefix, "");
dir["delete"]();
dir.mkdir();
var file = java.io.File.createTempFile(prefix, ".zip");
mime.writeToFile(file.getParent(), file.getName());
var zip = new helma.Zip(file);
zip.extractAll(dir);
Layout.convert(dir);
zip = new helma.Zip;
zip.add(dir);
zip.close();
//zip.save(java.io.File.createTempFile(prefix, ".converted.zip"));
res.contentType = "application/zip";
res.setHeader("Content-Disposition",
"attachment; filename=" + name.replace(/(\..*)$/, ".converted$1"));
res.writeBinary(zip.getData());
return;
}
if (req.isPost() && req.data.save && req.data.file) {
var mime = req.data.file;
var name = mime.normalizeFilename(mime.name);
var prefix = "antville.layout.import.";
var dir = java.io.File.createTempFile(prefix, "");
dir["delete"]();
dir.mkdir();
var file = java.io.File.createTempFile(prefix, ".zip");
mime.writeToFile(file.getParent(), file.getName());
var zip = new helma.Zip(file);
zip.extractAll(dir);
Layout.convert(dir);
zip = new helma.Zip;
zip.add(dir);
zip.close();
//zip.save(java.io.File.createTempFile(prefix, ".converted.zip"));
res.contentType = "application/zip";
res.setHeader("Content-Disposition",
"attachment; filename=" + name.replace(/(\..*)$/, ".converted$1"));
res.writeBinary(zip.getData());
return;
}
res.data.title = gettext("Convert Layout");
res.data.body = this.renderSkinAsString("$Layout#convert");
this.site.renderSkin("Site#page");
return;
res.data.title = gettext("Convert Layout");
res.data.body = this.renderSkinAsString("$Layout#convert");
this.site.renderSkin("Site#page");
return;
}
Layout.convert = function(fpath) {
function runProcess(cmd, dir) {
var runtime = java.lang.Runtime.getRuntime();
var proc = runtime.exec(cmd, null, new java.io.File(dir.toString()));
proc.waitFor();
var result = new Object();
result.error = proc.exitValue();
return result;
}
function runProcess(cmd, dir) {
var runtime = java.lang.Runtime.getRuntime();
var proc = runtime.exec(cmd, null, new java.io.File(dir.toString()));
proc.waitFor();
var result = new Object();
result.error = proc.exitValue();
return result;
}
// Code copied from global convert.js file in updater app
// ******************************************************
var styles = {
"bgcolor": "background color",
"linkcolor": "link color",
"alinkcolor": "active link color",
"vlinkcolor": "visited link color",
"titlefont": "big font",
"titlesize": "big font size",
"titlecolor": "big font color",
"textfont": "base font",
"textsize": "base font size",
"textcolor": "base font color",
"smallfont": "small font",
"smallsize": "small font size",
"smallcolor": "small font color"
}
// Code copied from global convert.js file in updater app
// ******************************************************
var styles = {
"bgcolor": "background color",
"linkcolor": "link color",
"alinkcolor": "active link color",
"vlinkcolor": "visited link color",
"titlefont": "big font",
"titlesize": "big font size",
"titlecolor": "big font color",
"textfont": "base font",
"textsize": "base font size",
"textcolor": "base font color",
"smallfont": "small font",
"smallsize": "small font size",
"smallcolor": "small font color"
}
var values = function(metadata) {
if (!metadata) {
return;
var values = function(metadata) {
if (!metadata) {
return;
}
var data = eval(metadata);
res.push();
for (var key in styles) {
var name = styles[key];
var value = String(data[key]).toLowerCase();
if (key.endsWith("color") && !helma.Color.COLORNAMES[key] &&
!value.startsWith("#")) {
value = "#" + value;
}
value = value.replace(/([0-9]+) +px/, "$1px");
res.writeln('<% value "' + name + '" "' + value + '" %>');
}
return res.pop();
}
var data = eval(metadata);
res.push();
for (var key in styles) {
var name = styles[key];
var value = String(data[key]).toLowerCase();
if (key.endsWith("color") && !helma.Color.COLORNAMES[key] &&
!value.startsWith("#")) {
value = "#" + value;
}
value = value.replace(/([0-9]+) +px/, "$1px");
res.writeln('<% value "' + name + '" "' + value + '" %>');
var quote = function(str) {
if (str === null) {
return str;
}
return "'" + str.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
}
var clean = function(source) {
if (source) {
// Renaming prototype and skin names in skin macros
var re = /(<%\s*)([^.]+)(\.skin\s+name="?)([^"\s]+)/g;
source = source.replace(re, function() {
var $ = arguments;
var skin = rename($[2].capitalize(), $[4]);
if (skin) {
// THIS LINE DIFFERS FROM THE UPDATER APP!
return $[1] + skin.prototype.toLowerCase() + $[3] +
skin.prototype + "#" + skin.name;
}
return $[0];
});
// Replacing layout.* macros with corresponding value macros
source = source.replace(/(<%\s*)layout\.([^\s]+)/g, function() {
var value = styles[arguments[2]];
if (value) {
return arguments[1] + "value " + quote(value);
}
return arguments[0];
});
return source;
}
}
// ***********************************
// End of code copied from updater app
var rename = function(proto, name) {
var allowed = ["Comment", "Day", "File", "Global", "Image",
"MemberMgr", "Membership", "Site", "Story", "Topic"];
if (allowed.indexOf(proto) < 0) {
return;
}
switch (proto) {
case "Comment":
name === "toplevel" && (name = "main");
break;
case "Day":
proto = "Archive";
break;
case "MemberMgr":
case "Membership":
if (name === "statusloggedin") {
name = "status";
} else if (name === "statusloggedout") {
name = "login";
} else if (proto === "MemberMgr") {
// FIXME: This return causes errors on Ubuntu?!?
//return;
}
return res.pop();
}
break;
var quote = function(str) {
if (str === null) {
return str;
case "Site":
if (name === "searchbox") {
name = "search";
} else if (name === "style") {
name = "stylesheet";
}
return "'" + str.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
}
break;
var clean = function(source) {
if (source) {
// Renaming prototype and skin names in skin macros
var re = /(<%\s*)([^.]+)(\.skin\s+name="?)([^"\s]+)/g;
source = source.replace(re, function() {
var $ = arguments;
var skin = rename($[2].capitalize(), $[4]);
if (skin) {
// THIS LINE DIFFERS FROM THE UPDATER APP!
return $[1] + skin.prototype.toLowerCase() + $[3] +
skin.prototype + "#" + skin.name;
}
return $[0];
});
// Replacing layout.* macros with corresponding value macros
source = source.replace(/(<%\s*)layout\.([^\s]+)/g, function() {
var value = styles[arguments[2]];
if (value) {
return arguments[1] + "value " + quote(value);
}
return arguments[0];
});
return source;
case "Story":
if (name === "dayheader") {
name = "date";
} else if (name === "display") {
name = "content";
} else if (name === "historyview") {
name = "history";
}
}
// ***********************************
// End of code copied from updater app
break;
var rename = function(proto, name) {
var allowed = ["Comment", "Day", "File", "Global", "Image",
"MemberMgr", "Membership", "Site", "Story", "Topic"];
if (allowed.indexOf(proto) < 0) {
return;
}
case "Topic":
proto = "Tag";
break;
}
(proto === "MemberMgr") && (proto = "Membership");
return {
prototype: proto,
name: name
};
}
switch (proto) {
case "Comment":
name === "toplevel" && (name = "main");
break;
case "Day":
proto = "Archive";
break;
case "MemberMgr":
case "Membership":
if (name === "statusloggedin") {
name = "status";
} else if (name === "statusloggedout") {
name = "login";
} else if (proto === "MemberMgr") {
// FIXME: This return causes errors on Ubuntu?!?
//return;
}
break;
case "Site":
if (name === "searchbox") {
name = "search";
} else if (name === "style") {
name = "stylesheet";
}
break;
case "Story":
if (name === "dayheader") {
name = "date";
} else if (name === "display") {
name = "content";
} else if (name === "historyview") {
name = "history";
}
break;
case "Topic":
proto = "Tag";
break;
}
(proto === "MemberMgr") && (proto = "Membership");
return {
prototype: proto,
name: name
};
}
var convert2subskins = function(proto, dir) {
res.push();
for each (var fname in dir.list()) {
var file = new helma.File(dir, fname);
var name = fname.split(".")[0], skin;
if (skin = rename(proto, name)) {
res.writeln("<% #" + skin.name + " %>");
var source = clean(file.readAll());
if (skin.prototype === "Site" && skin.name === "stylesheet") {
source = source.replace(/(\.calHead)/g,
"table.calendar thead, $1");
source = source.replace(/(\.calDay)/g,
"table.calendar th, table.calendar tbody td.day, $1");
source = source.replace(/(\.calSelDay)/g,
"table.calendar tbody td.selected, $1");
source = source.replace(/(\.calFoot)/g,
"table.calendar tfoot td, $1");
}
res.writeln(source);
}
}
var str = res.pop();
if (!str) {
return;
}
var target = new java.io.File(fpath, skin.prototype);
target.mkdirs();
target = new helma.File(target, skin.prototype + ".skin");
target.open({append: true});
target.write(str);
target.close();
}
var convertImage = function(image) {
var result = new HopObject;
result.name = image.alias;
result.width = image.width;
result.height = image.height;
result.created = image.exporttime;
result.modified = image.exporttime;
result.description = image.alltext;
result.fileName = image.alias + "." + image.fileext,
result.contentType = "image/" + image.fileext;
result.contentLength = inventory[result.fileName].getLength();
if (image.thumbnail) {
result.thumbnailName = image.thumbnail.filename + "." + image.fileext;
result.thumbnailWidth = image.thumbnail.width;
result.thumbnailHeight = image.thumbnail.height;
}
return result;
}
var dir = new helma.File(fpath, "images");
for each (var fname in dir.list()) {
var convert2subskins = function(proto, dir) {
res.push();
for each (var fname in dir.list()) {
var file = new helma.File(dir, fname);
file.move(new helma.File(fpath, fname));
}
var inventory = new function() {
var dir = new helma.File(fpath);
var result = {};
for each (var fname in dir.list()) {
var file = new helma.File(dir, fname);
if (!file.isDirectory()) {
// Where does the "image\" prefix come from in files from layouts.antville.org?
var parts = fname.split("\\");
var name = parts[parts.length-1];
if (name !== fname) {
res.debug(file);
res.debug(new helma.File(fpath, name))
file.renameTo(new helma.File(fpath, name));
}
result[name] = file;
}
var name = fname.split(".")[0], skin;
if (skin = rename(proto, name)) {
res.writeln("<% #" + skin.name + " %>");
var source = clean(file.readAll());
if (skin.prototype === "Site" && skin.name === "stylesheet") {
source = source.replace(/(\.calHead)/g,
"table.calendar thead, $1");
source = source.replace(/(\.calDay)/g,
"table.calendar th, table.calendar tbody td.day, $1");
source = source.replace(/(\.calSelDay)/g,
"table.calendar tbody td.selected, $1");
source = source.replace(/(\.calFoot)/g,
"table.calendar tfoot td, $1");
}
res.writeln(source);
}
return result;
}
}
var str = res.pop();
if (!str) {
return;
}
var target = new java.io.File(fpath, skin.prototype);
target.mkdirs();
target = new helma.File(target, skin.prototype + ".skin");
target.open({append: true});
target.write(str);
target.close();
}
var xml = Xml.read(new helma.File(fpath, "preferences.xml"));
var file = new helma.File(fpath, "Site");
file.makeDirectory();
file = new helma.File(file, "Site.skin");
file.open();
res.push();
res.writeln("<% #values %>");
res.write(values(xml.preferences));
file.write(res.pop());
file.close();
var convertImage = function(image) {
var result = new HopObject;
result.name = image.alias;
result.width = image.width;
result.height = image.height;
result.created = image.exporttime;
result.modified = image.exporttime;
result.description = image.alltext;
result.fileName = image.alias + "." + image.fileext,
result.contentType = "image/" + image.fileext;
result.contentLength = inventory[result.fileName].getLength();
if (image.thumbnail) {
result.thumbnailName = image.thumbnail.filename + "." + image.fileext;
result.thumbnailWidth = image.thumbnail.width;
result.thumbnailHeight = image.thumbnail.height;
}
return result;
}
dir = new helma.File(fpath, "skins");
var dir = new helma.File(fpath, "images");
for each (var fname in dir.list()) {
var file = new helma.File(dir, fname);
file.move(new helma.File(fpath, fname));
}
var skin;
for each (var fname in dir.list()) {
var inventory = new function() {
var dir = new helma.File(fpath);
var result = {};
for each (var fname in dir.list()) {
var file = new helma.File(dir, fname);
if (!file.isDirectory()) {
// Where does the "image\" prefix come from in files from layouts.antville.org?
var parts = fname.split("\\");
var name = parts[parts.length-1];
if (name !== fname) {
res.debug(file);
res.debug(new helma.File(fpath, name))
file.renameTo(new helma.File(fpath, name));
}
result[name] = file;
}
}
return result;
}
var xml = Xml.read(new helma.File(fpath, "preferences.xml"));
var file = new helma.File(fpath, "Site");
file.makeDirectory();
file = new helma.File(file, "Site.skin");
file.open();
res.push();
res.writeln("<% #values %>");
res.write(values(xml.preferences));
file.write(res.pop());
file.close();
dir = new helma.File(fpath, "skins");
var skin;
for each (var fname in dir.list()) {
file = new helma.File(dir, fname);
skin = convert2subskins(fname, file);
}
var data = new HopObject;
data.images = new HopObject;
var dir = new helma.File(fpath, "imagedata");
for each (fname in dir.list()) {
if (fname.endsWith(".xml")) {
file = new helma.File(dir, fname);
skin = convert2subskins(fname, file);
}
data.images.add(convertImage(Xml.read(file)));
}
}
var data = new HopObject;
data.images = new HopObject;
data.version = "1.2-compatible";
data.origin = "Antville 1.2 Layout Converter";
data.originated = new Date;
data.originator = session.user;
Xml.write(data, new helma.File(fpath, "data.xml"));
var dir = new helma.File(fpath, "imagedata");
for each (fname in dir.list()) {
if (fname.endsWith(".xml")) {
file = new helma.File(dir, fname);
data.images.add(convertImage(Xml.read(file)));
}
}
data.version = "1.2-compatible";
data.origin = "Antville 1.2 Layout Converter";
data.originated = new Date;
data.originator = session.user;
Xml.write(data, new helma.File(fpath, "data.xml"));
(new helma.File(fpath, "preferences.xml")).remove();
(new helma.File(fpath, "imagedata")).removeDirectory();
(new helma.File(fpath, "skins")).removeDirectory();
return;
(new helma.File(fpath, "preferences.xml")).remove();
(new helma.File(fpath, "imagedata")).removeDirectory();
(new helma.File(fpath, "skins")).removeDirectory();
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -29,74 +29,74 @@ relocateProperty(Layout, "createtime", "created");
relocateProperty(Layout, "modifytime", "modified");
Layout.prototype.__defineGetter__("shareable", function() {
return this.mode === Layout.SHARED;
return this.mode === Layout.SHARED;
});
Layout.prototype.__defineSetter__("shareable", function(value) {
this.mode = !!value ? Layout.SHARED : Layout.DEFAULT;
return;
this.mode = !!value ? Layout.SHARED : Layout.DEFAULT;
return;
});
Layout.prototype.getTitle = function() {
return gettext("Layout");
return gettext("Layout");
}
Layout.prototype.title_macro = function(param) {
if (param.as === "editor") {
this.input_macro(param, "title");
} else if (param.linkto) {
(param.linkto === "main") && (param.linkto = "");
this.link_filter(this.title, param, param.linkto);
} else {
res.write(this.title);
}
return;
if (param.as === "editor") {
this.input_macro(param, "title");
} else if (param.linkto) {
(param.linkto === "main") && (param.linkto = "");
this.link_filter(this.title, param, param.linkto);
} else {
res.write(this.title);
}
return;
}
Layout.prototype.description_macro = function(param) {
if (param.as == "editor") {
this.textarea_macro(param, "description");
} else if (this.description) {
if (param.limit) {
res.write(this.description.clip(param.limit, "...", "\\s"));
} else {
res.write(this.description);
}
}
return;
if (param.as == "editor") {
this.textarea_macro(param, "description");
} else if (this.description) {
if (param.limit) {
res.write(this.description.clip(param.limit, "...", "\\s"));
} else {
res.write(this.description);
}
}
return;
}
Layout.prototype.parent_macro = function(param) {
if (param.as === "editor") {
this.select_macro(param, "parent");
} else if (this.parent) {
res.write(this.parent.title);
}
return;
if (param.as === "editor") {
this.select_macro(param, "parent");
} else if (this.parent) {
res.write(this.parent.title);
}
return;
}
Layout.prototype.shareable_macro = function(param) {
if (param.as == "editor" && !this.site) {
// FIXME: HopObject.createCheckBoxParam() is obsolete
var inputParam = this.createCheckBoxParam("shareable", param);
if (req.data.save && !req.data.shareable)
delete inputParam.checked;
Html.checkBox(inputParam);
} else if (this.shareable)
res.write(param.yes || "yes");
else
res.write(param.no || "no");
return;
if (param.as == "editor" && !this.site) {
// FIXME: HopObject.createCheckBoxParam() is obsolete
var inputParam = this.createCheckBoxParam("shareable", param);
if (req.data.save && !req.data.shareable)
delete inputParam.checked;
Html.checkBox(inputParam);
} else if (this.shareable)
res.write(param.yes || "yes");
else
res.write(param.no || "no");
return;
}
Layout.prototype.testdrivelink_macro = function(param) {
return this.link_macro(param, "test", param.text || "test");
return this.link_macro(param, "test", param.text || "test");
}
Layout.prototype.deletelink_macro = function(param) {
return this.link_macro(param, "delete", param.text || "delete");
return this.link_macro(param, "delete", param.text || "delete");
}
Layout.prototype.activatelink_macro = function(param) {
return this.link_macro(param, "activate", param.text || "activate");
return this.link_macro(param, "activate", param.text || "activate");
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -24,22 +24,22 @@
// $URL$
Members.prototype.sendpwd_action = function() {
res.data.title = gettext("Recover your password");
res.data.body = gettext("Due to security reasons user passwords are not stored in the Antville database any longer. Thus, your password cannot be sent to you, anymore.");
res.data.body += "<p>" + gettext('If you should really have forgotten your password, you can use the <a href="{0}">password reset</a> option.',
this.href("reset")) + "</p>";
this._parent.renderSkin("Site#page");
return;
res.data.title = gettext("Recover your password");
res.data.body = gettext("Due to security reasons user passwords are not stored in the Antville database any longer. Thus, your password cannot be sent to you, anymore.");
res.data.body += "<p>" + gettext('If you should really have forgotten your password, you can use the <a href="{0}">password reset</a> option.',
this.href("reset")) + "</p>";
this._parent.renderSkin("Site#page");
return;
}
Members.prototype.subscribelink_macro = function(param) {
return res.handlers.site.link_macro(param, "subscribe");
return res.handlers.site.link_macro(param, "subscribe");
}
Members.prototype.subscriptionslink_macro = function(param) {
return this.link_macro(param, "subscriptions");
return this.link_macro(param, "subscriptions");
}
Members.prototype.membership_macro = function(param) {
return res.handlers.membership.role;
return res.handlers.membership.role;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -29,45 +29,45 @@ relocateProperty(Membership, "modifytime", "modified");
relocateProperty(Membership, "user", "creator");
Membership.prototype.username_macro = function(param) {
if (param.linkto && (param.linkto !== "edit" ||
this.user !== session.user)) {
html.link({href: this.href(param.linkto)}, this.name);
} else {
res.write(this.name);
}
return;
if (param.linkto && (param.linkto !== "edit" ||
this.user !== session.user)) {
html.link({href: this.href(param.linkto)}, this.name);
} else {
res.write(this.name);
}
return;
}
Membership.prototype.url_macro = function(param) {
var url;
if (url = this.user.url) {
if (param.as === "link") {
delete param.as;
link_filter(url, param, url);
} else {
res.write(url);
}
}
return;
var url;
if (url = this.user.url) {
if (param.as === "link") {
delete param.as;
link_filter(url, param, url);
} else {
res.write(url);
}
}
return;
}
Membership.prototype.level_macro = function(param) {
if (param.as === "editor") {
this.select_macro(param, "role");
} else {
res.write(this.role);
}
return;
if (param.as === "editor") {
this.select_macro(param, "role");
} else {
res.write(this.role);
}
return;
}
Membership.prototype.editlink_macro = function(param) {
return this.link_macro(param, "edit");
return this.link_macro(param, "edit");
}
Membership.prototype.deletelink_macro = function(param) {
return this.link_macro(param, "delete");
return this.link_macro(param, "delete");
}
Membership.prototype.unsubscribelink_macro = function(param) {
return res.handlers.site.link_macro(param, "unsubscribe");
return res.handlers.site.link_macro(param, "unsubscribe");
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -24,84 +24,84 @@
// $URL$
Poll.prototype.choices_macro = function(param) {
var vote;
if (session.user && this.votes.get(session.user.name)) {
vote = this.votes.get(session.user.name).choice;
}
for (var i=0; i<this.size(); i++) {
var choice = this.get(i);
param.name = "choice";
param.title = renderSkinAsString(createSkin(choice.title));
param.value = choice._id;
param.checked = "";
if (choice == vote) {
param.checked = " checked=\"checked\"";
}
res.write(choice.renderSkinAsString("$Choice#main", param));
}
return;
var vote;
if (session.user && this.votes.get(session.user.name)) {
vote = this.votes.get(session.user.name).choice;
}
for (var i=0; i<this.size(); i++) {
var choice = this.get(i);
param.name = "choice";
param.title = renderSkinAsString(createSkin(choice.title));
param.value = choice._id;
param.checked = "";
if (choice == vote) {
param.checked = " checked=\"checked\"";
}
res.write(choice.renderSkinAsString("$Choice#main", param));
}
return;
}
Poll.prototype.total_macro = function(param) {
var n = this.votes.size();
if (n == 0) {
n += " " + (param.no || "votes");
} else if (n == 1) {
n += " " + (param.one || "vote");
} else {
n += " " + (param.more || "votes");
}
return n;
var n = this.votes.size();
if (n == 0) {
n += " " + (param.no || "votes");
} else if (n == 1) {
n += " " + (param.one || "vote");
} else {
n += " " + (param.more || "votes");
}
return n;
}
Poll.prototype.question_macro = function(param) {
if (param.as == "editor") {
this.textarea_macro(param, "question");
} else {
res.write(this.question);
}
return;
if (param.as == "editor") {
this.textarea_macro(param, "question");
} else {
res.write(this.question);
}
return;
}
Poll.prototype.closetime_macro = function(param, format) {
format || (format = param.format);
return this.closed_macro(param, format);
format || (format = param.format);
return this.closed_macro(param, format);
}
Poll.prototype.results_macro = function(param2) {
for (var i=0; i<this.size(); i++) {
var c = this.get(i);
var param = new Object();
param.title = c.title;
param.count = c.size();
param.percent = 0;
if (param.count > 0) {
param.percent = param.count.toPercent(this.votes.size());
param.width = Math.round(param.percent * 2.5);
param.graph = c.renderSkinAsString("graph", param);
if (param.count == 1)
param.text = " " + (param2.one || "vote");
else
param.text = " " + (param2.more || "votes");
} else
param.text = " " + (param2.no || "votes");
c.renderSkin("$Choice#result", param);
}
return;
for (var i=0; i<this.size(); i++) {
var c = this.get(i);
var param = new Object();
param.title = c.title;
param.count = c.size();
param.percent = 0;
if (param.count > 0) {
param.percent = param.count.toPercent(this.votes.size());
param.width = Math.round(param.percent * 2.5);
param.graph = c.renderSkinAsString("graph", param);
if (param.count == 1)
param.text = " " + (param2.one || "vote");
else
param.text = " " + (param2.more || "votes");
} else
param.text = " " + (param2.no || "votes");
c.renderSkin("$Choice#result", param);
}
return;
}
Poll.prototype.editlink_macro = function(param) {
return this.link_macro(param, "edit");
return this.link_macro(param, "edit");
}
Poll.prototype.deletelink_macro = function(param) {
return this.link_macro(param, "delete");
return this.link_macro(param, "delete");
}
Poll.prototype.viewlink_macro = function(param) {
return this.link_macro(param, ".", "view");
return this.link_macro(param, ".", "view");
}
Poll.prototype.closelink_macro = function(param) {
return this.link_macro(param, "rotate");
return this.link_macro(param, "rotate");
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -27,27 +27,27 @@
//Root.VERSION += "-compatible";
Root.prototype.rss_action = function() {
return res.redirect(root.href("rss.xml"));
return res.redirect(root.href("rss.xml"));
}
Root.prototype.url_macro = function(param) {
return this.href_macro(param);
return this.href_macro(param);
}
Root.prototype.sitecounter_macro = function(param) {
if (param.count === "all") {
var size = root.size();
} else {
var size = root.sites.size();
}
if (size < 1) {
res.write(param.no || size);
} else if (size < 2) {
res.write(param.one || size);
} else {
res.write(size + (param.more || String.EMPTY));
}
return;
if (param.count === "all") {
var size = root.size();
} else {
var size = root.sites.size();
}
if (size < 1) {
res.write(param.no || size);
} else if (size < 2) {
res.write(param.one || size);
} else {
res.write(size + (param.more || String.EMPTY));
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -35,291 +35,291 @@ addPropertyMacro(Site, "tagline");
addPropertyMacro(Site, "email");
Site.prototype.__defineGetter__("online", function() {
return this.mode === Site.PUBLIC;
return this.mode === Site.PUBLIC;
});
Site.prototype.__defineSetter__("online", function(value) {
this.mode = Site.PUBLIC;
return;
this.mode = Site.PUBLIC;
return;
});
Site.prototype.__defineGetter__("blocked", function() {
return this.status === Site.BLOCKED;
return this.status === Site.BLOCKED;
});
Site.prototype.__defineGetter__("trusted", function() {
return this.status === Site.TRUSTED;
return this.status === Site.TRUSTED;
});
Site.prototype.__defineGetter__("discussions", function() {
return this.commentsMode === Comment.ONLINE;
return this.commentsMode === Comment.ONLINE;
});
// FIXME: obsolete?
Site.prototype.renderStoryList = function(day) {
res.push();
list_macro(param, "stories");
res.write(res.pop());
return;
res.push();
list_macro(param, "stories");
res.write(res.pop());
return;
}
Site.prototype.rss_action = function() {
if (req.queryParams.show === "all") {
return res.redirect(this.href("rss.xml"))
}
return res.redirect(this.href("stories.xml"));
if (req.queryParams.show === "all") {
return res.redirect(this.href("rss.xml"))
}
return res.redirect(this.href("stories.xml"));
}
//Site.prototype.feeds_action = function() {
// return disableAction.call(this, "Feeds are currently not available");
// return disableAction.call(this, "Feeds are currently not available");
//}
Site.prototype.mostread_action = function() {
return res.redirect(this.stories.href("top"));
return res.redirect(this.stories.href("top"));
}
Site.prototype.link_macro = function(param, url, text) {
param.text || (param.text = text);
if (!param.to) {
param.to = url || ".";
} else if (param.to.contains(":")) {
link_macro.call(global, param, param.to, param.text);
return;
}
var handler;
var parts = param.to.split("/");
var action = parts[0];
switch (action) {
case "mostread":
handler = this.stories;
param.to = "top"; break;
param.text || (param.text = text);
if (!param.to) {
param.to = url || ".";
} else if (param.to.contains(":")) {
link_macro.call(global, param, param.to, param.text);
return;
}
var handler;
var parts = param.to.split("/");
var action = parts[0];
switch (action) {
case "mostread":
handler = this.stories;
param.to = "top"; break;
case "layouts":
action = ".";
handler = this.layout;
param.text = gettext("Layout");
param.to = "."; break;
case "layouts":
action = ".";
handler = this.layout;
param.text = gettext("Layout");
param.to = "."; break;
case "topics":
case "files":
case "images":
case "members":
case "polls":
case "stories":
handler = this[action];
if (handler) {
var node = handler.get(parts[1]);
if (node) {
handler = node;
param.to = parts[2] || "main";
} else {
param.to = parts[1] || "main";
}
case "topics":
case "files":
case "images":
case "members":
case "polls":
case "stories":
handler = this[action];
if (handler) {
var node = handler.get(parts[1]);
if (node) {
handler = node;
param.to = parts[2] || "main";
} else {
param.to = parts[1] || "main";
}
break;
}
break;
default:
handler = this;
}
HopObject.prototype.link_macro.call(handler, param, param.to, param.text);
return;
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");
} else {
var title = this.title;
if (param.linkto) {
if (param.linkto === "main") {
param.linkto = ".";
}
res.write(this.link_filter(title, param, param.linkto));
} else {
res.write(title);
if (param.as === "editor") {
this.input_macro(param, "title");
} else {
var title = this.title;
if (param.linkto) {
if (param.linkto === "main") {
param.linkto = ".";
}
}
return;
res.write(this.link_filter(title, param, param.linkto));
} else {
res.write(title);
}
}
return;
}
Site.prototype.loginstatus_macro = function(param) {
return res.handlers.membership.status_macro();
return res.handlers.membership.status_macro();
}
Site.prototype.navigation_macro = function(param) {
var group;
var navigation = {};
// HopObject.renderSkinAsString() is overridden and will never return an empty skin
// due to the added skin edit controls! Thus, we are using the original methods first,
// and the overriden ones later.
navigation.contributors = this.__renderSkinAsString__("Site#contribnavigation");
navigation.admins = this.__renderSkinAsString__("Site#adminnavigation");
if (!navigation.contributors && !navigation.admins && !res.meta.navigation) {
res.meta.navigation = true;
this.renderSkin("Site#navigation");
} else if ((group = param["for"]) && navigation[group]) {
if (group === "contributors" && this.stories.getPermission("create")) {
this.renderSkin("Site#contribnavigation");
} else if (group === "admins" && this.getPermission("edit")) {
this.renderSkin("Site#adminnavigation");
}
}
return;
var group;
var navigation = {};
// HopObject.renderSkinAsString() is overridden and will never return an empty skin
// due to the added skin edit controls! Thus, we are using the original methods first,
// and the overriden ones later.
navigation.contributors = this.__renderSkinAsString__("Site#contribnavigation");
navigation.admins = this.__renderSkinAsString__("Site#adminnavigation");
if (!navigation.contributors && !navigation.admins && !res.meta.navigation) {
res.meta.navigation = true;
this.renderSkin("Site#navigation");
} else if ((group = param["for"]) && navigation[group]) {
if (group === "contributors" && this.stories.getPermission("create")) {
this.renderSkin("Site#contribnavigation");
} else if (group === "admins" && this.getPermission("edit")) {
this.renderSkin("Site#adminnavigation");
}
}
return;
}
Site.prototype.image_macro = function() {
return global.image_macro.apply(global, arguments);
return global.image_macro.apply(global, arguments);
}
Site.prototype.xmlbutton_macro = function(param) {
param.linkto = this.href("rss.xml");
image_macro(param, "/xmlbutton.gif");
return;
param.linkto = this.href("rss.xml");
image_macro(param, "/xmlbutton.gif");
return;
}
Site.prototype.lastupdate_macro = function(param) {
var value;
if (value = this.modified) {
res.write(formatDate(value, param.format));
}
return;
var value;
if (value = this.modified) {
res.write(formatDate(value, param.format));
}
return;
}
Site.prototype.online_macro = function(param) {
var online = true;
var value = this.mode;
if (value === Site.PRIVATE || value === Site.CLOSED) {
online = false;
}
if (param.as === "editor") {
param.name = "online";
param.value = "true";
if (req.isPost()) {
param.selectedValue = req.postParams.online;
} else {
param.selectedValue = String(online);
}
//res.debug(param.name + ": " + param.value + "/" + param.selectedValue);
return html.checkBox(param);
} else if (online) {
res.write(param.yes || "yes");
} else {
res.write(param.no || "no");
}
return;
var online = true;
var value = this.mode;
if (value === Site.PRIVATE || value === Site.CLOSED) {
online = false;
}
if (param.as === "editor") {
param.name = "online";
param.value = "true";
if (req.isPost()) {
param.selectedValue = req.postParams.online;
} else {
param.selectedValue = String(online);
}
//res.debug(param.name + ": " + param.value + "/" + param.selectedValue);
return html.checkBox(param);
} else if (online) {
res.write(param.yes || "yes");
} else {
res.write(param.no || "no");
}
return;
}
Site.prototype.usermaycontrib_macro = function(param) {
if (param.as === "editor") {
param.name = "usermaycontrib";
param.value = "true";
if (req.isPost()) {
param.selectedValue = req.postParams.usermaycontrib;
} else {
param.selectedValue = String(this.mode === Site.OPEN);
}
return html.checkBox(param);
} else {
res.write(this.mode === Site.OPEN ? "yes" : "no");
}
return;
if (param.as === "editor") {
param.name = "usermaycontrib";
param.value = "true";
if (req.isPost()) {
param.selectedValue = req.postParams.usermaycontrib;
} else {
param.selectedValue = String(this.mode === Site.OPEN);
}
return html.checkBox(param);
} else {
res.write(this.mode === Site.OPEN ? "yes" : "no");
}
return;
}
Site.prototype.hasdiscussions_macro = function(param) {
if (param.as === "editor") {
this.checkbox_macro(param, "commentMode");
} else {
res.write(this.commentsMode === Comment.ONLINE ? "yes" : "no");
}
return;
if (param.as === "editor") {
this.checkbox_macro(param, "commentMode");
} else {
res.write(this.commentsMode === Comment.ONLINE ? "yes" : "no");
}
return;
}
Site.prototype.showarchive_macro = function(param) {
if (param.as === "editor") {
this.checkbox_macro(param, "archiveMode");
} else {
res.write(this.archiveMode === Site.PUBLIC ? "yes" : "no");
}
return;
if (param.as === "editor") {
this.checkbox_macro(param, "archiveMode");
} else {
res.write(this.archiveMode === Site.PUBLIC ? "yes" : "no");
}
return;
}
Site.prototype.enableping_macro = function(param) {
if (param.as === "editor") {
this.checkbox_macro(param, "callbackMode");
} else {
res.write(this.callbackMode === Site.ENABLED ? "yes" : "no");
}
return;
if (param.as === "editor") {
this.checkbox_macro(param, "callbackMode");
} else {
res.write(this.callbackMode === Site.ENABLED ? "yes" : "no");
}
return;
}
Site.prototype.localechooser_macro = function(param) {
return this.select_macro(param, "locale");
return this.select_macro(param, "locale");
}
Site.prototype.timezonechooser_macro = function(param) {
return this.select_macro(param, "timeZone");
return this.select_macro(param, "timeZone");
}
Site.prototype.history_macro = function(param, type) {
param.skin || (param.skin = "Story#history");
var type = isNaN(param.show) ? param.show : "postings";
var limit = Math.min(param.limit || parseInt(param.show) || 10, 50);
delete param.show;
delete param.limit;
return list_macro(param, type, limit);
param.skin || (param.skin = "Story#history");
var type = isNaN(param.show) ? param.show : "postings";
var limit = Math.min(param.limit || parseInt(param.show) || 10, 50);
delete param.show;
delete param.limit;
return list_macro(param, type, limit);
}
Site.prototype.membercounter_macro = function(param) {
return this.members.size();
return this.members.size();
}
Site.prototype.preferences_macro = function(param) {
if (param.as === "editor") {
// FIXME: Site.metadata is now a collection!
var inputParam = this.metadata.createInputParam(param.name, param);
delete inputParam.part;
if (param.cols || param.rows) {
html.textArea(inputParam);
} else {
html.input(inputParam);
}
} else {
res.write(this.getMetadata(param.name));
} return;
if (param.as === "editor") {
// FIXME: Site.metadata is now a collection!
var inputParam = this.metadata.createInputParam(param.name, param);
delete inputParam.part;
if (param.cols || param.rows) {
html.textArea(inputParam);
} else {
html.input(inputParam);
}
} else {
res.write(this.getMetadata(param.name));
} return;
}
Site.prototype.listReferrers_macro = function(param) {
return this.referrers_macro(param);
return this.referrers_macro(param);
}
Site.prototype.searchbox_macro = function(param) {
if (this.getPermission("search")) {
this.renderSkin("Site#search");
}
return;
if (this.getPermission("search")) {
this.renderSkin("Site#search");
}
return;
}
// FIXME: working?
Site.prototype.monthlist_macro = function(param) {
if (!this.stories.size() || this.archiveMode !== Site.PUBLIC) {
return;
}
var collection = this.archive;
var size = Math.min(collection.size(), param.limit || Infinity);
for (var i=0; i<size; i+=1) {
var curr = collection.get(i);
var next = collection.get(i+1);
if (!next || next.groupname.substring(0, 6) <
curr.groupname.substring(0, 6)) {
res.write(param.itemprefix);
html.openLink({href: collection.href() + "/" +
formatDate(curr.groupname.toDate("yyyyMMdd"), "yyyy/MM/dd")});
var ts = curr.groupname.substring(0, 6).toDate("yyyyMM",
this.getTimeZone());
res.write(formatDate(ts, param.format || "MMMM yyyy"));
html.closeLink();
res.write(param.itemsuffix);
}
}
return;
if (!this.stories.size() || this.archiveMode !== Site.PUBLIC) {
return;
}
var collection = this.archive;
var size = Math.min(collection.size(), param.limit || Infinity);
for (var i=0; i<size; i+=1) {
var curr = collection.get(i);
var next = collection.get(i+1);
if (!next || next.groupname.substring(0, 6) <
curr.groupname.substring(0, 6)) {
res.write(param.itemprefix);
html.openLink({href: collection.href() + "/" +
formatDate(curr.groupname.toDate("yyyyMMdd"), "yyyy/MM/dd")});
var ts = curr.groupname.substring(0, 6).toDate("yyyyMM",
this.getTimeZone());
res.write(formatDate(ts, param.format || "MMMM yyyy"));
html.closeLink();
res.write(param.itemsuffix);
}
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -27,370 +27,370 @@ relocateProperty(Story, "createtime", "created");
relocateProperty(Story, "modifytime", "modified");
Story.ALLOWED_MACROS = Story.ALLOWED_MACROS.concat([
"fakemail",
"imageoftheday",
"logo",
"spacer",
"storylist",
"thumbnail",
"fakemail",
"imageoftheday",
"logo",
"spacer",
"storylist",
"thumbnail",
"site.image",
"site.link",
"site.thumbnail",
"site.image",
"site.link",
"site.thumbnail",
"story.image",
"story.thumbnail",
"story.topic",
"story.image",
"story.thumbnail",
"story.topic",
"this.image",
"this.link",
"this.thumbnail",
"this.topic"
"this.image",
"this.link",
"this.thumbnail",
"this.topic"
]);
Story.prototype.backlinks_macro = Story.prototype.referrers_macro;
Story.prototype.allowTextMacros = function(skin) {
return Story.prototype.macro_filter(skin);
return Story.prototype.macro_filter(skin);
}
Story.prototype.commentform_macro = function(param) {
if (this.commentMode === "closed") {
return;
}
if (session.user) {
res.data.action = this.href("comment");
res.handlers.parent = this;
HopObject.confirmConstructor(Comment);
var comment = new Comment;
comment.story = this;
comment.renderSkin("Comment#edit");
} else {
html.link({href: this.site.members.href("login")},
param.text || "Please login to add a comment");
}
return;
if (this.commentMode === "closed") {
return;
}
if (session.user) {
res.data.action = this.href("comment");
res.handlers.parent = this;
HopObject.confirmConstructor(Comment);
var comment = new Comment;
comment.story = this;
comment.renderSkin("Comment#edit");
} else {
html.link({href: this.site.members.href("login")},
param.text || "Please login to add a comment");
}
return;
}
Story.prototype.content_macro = function(param) {
// Clone param and remove non-HTML attributes from param:
var options = Object.clone.call(param, {});
var noAttr = 'as clipping delimiter fallback limit part';
for each (let key in noAttr.split(String.SPACE)) {
delete param[key];
}
// Clone param and remove non-HTML attributes from param:
var options = Object.clone.call(param, {});
var noAttr = 'as clipping delimiter fallback limit part';
for each (let key in noAttr.split(String.SPACE)) {
delete param[key];
}
switch (options.as) {
case "editor":
if (param.cols || param.rows) {
this.textarea_macro(param, options.part);
} else {
this.input_macro(param, options.part);
}
break;
switch (options.as) {
case "editor":
if (param.cols || param.rows) {
this.textarea_macro(param, options.part);
} else {
this.input_macro(param, options.part);
}
break;
case "image":
var part = this.getMetadata(options.part);
part && res.write(this.format_filter(part, param, "image"));
break;
case "image":
var part = this.getMetadata(options.part);
part && res.write(this.format_filter(part, param, "image"));
break;
default:
var part = this.getRenderedContentPart(options.part, options.as);
if (!part && options.fallback) {
part = this.getRenderedContentPart(options.fallback, options.as);
}
if (options.limit) {
part = part.stripTags().head(options.limit,
options.clipping, options.delimiter || String.SPACE);
}
if (options.as === "link") {
res.write(this.link_filter(part || "...", param));
} else {
res.write(part);
}
}
return;
default:
var part = this.getRenderedContentPart(options.part, options.as);
if (!part && options.fallback) {
part = this.getRenderedContentPart(options.fallback, options.as);
}
if (options.limit) {
part = part.stripTags().head(options.limit,
options.clipping, options.delimiter || String.SPACE);
}
if (options.as === "link") {
res.write(this.link_filter(part || "...", param));
} else {
res.write(part);
}
}
return;
}
Story.prototype.getRenderedContentPart = function(name, mode) {
var part = this.getMetadata(name);
if (!part) {
return "";
}
var key = mode ? (name + ":" + mode) : name;
var lastRendered = this.cache["lastRendered_" + key];
if (!lastRendered) {
// FIXME: || lastRendered.getTime() < this.metadata.getLastModified().getTime())
switch (mode) {
case "plaintext":
part = this.format_filter(part, {}, "plain");
break;
var part = this.getMetadata(name);
if (!part) {
return "";
}
var key = mode ? (name + ":" + mode) : name;
var lastRendered = this.cache["lastRendered_" + key];
if (!lastRendered) {
// FIXME: || lastRendered.getTime() < this.metadata.getLastModified().getTime())
switch (mode) {
case "plaintext":
part = this.format_filter(part, {}, "plain");
break;
case "alttext":
part = this.format_filter(part, {}, "quotes");
break;
case "alttext":
part = this.format_filter(part, {}, "quotes");
break;
default:
// Enable caching; some macros (eg. poll, storylist) will set this
// to false to prevent caching of a contentpart containing them.
res.meta.cachePart = true;
part = this.format_filter(part, {});
}
this.cache[key] = part;
if (res.meta.cachePart) {
this.cache["lastRendered_" + key] = new Date();
}
}
return this.cache[key];
default:
// Enable caching; some macros (eg. poll, storylist) will set this
// to false to prevent caching of a contentpart containing them.
res.meta.cachePart = true;
part = this.format_filter(part, {});
}
this.cache[key] = part;
if (res.meta.cachePart) {
this.cache["lastRendered_" + key] = new Date();
}
}
return this.cache[key];
}
Story.prototype.location_macro = function(param) {
switch (this.mode) {
case Story.FEATURED:
res.write("site"); break;
switch (this.mode) {
case Story.FEATURED:
res.write("site"); break;
default:
if (this.tags.size() > 0) {
html.link({href: this.tags.get(0).tag.href()}, "topic");
}
}
return;
default:
if (this.tags.size() > 0) {
html.link({href: this.tags.get(0).tag.href()}, "topic");
}
}
return;
}
Story.prototype.topic_macro = function(param) {
// This method is applied to images as well, thus we check what we got first:
if (this.constructor !== Image && this.status !== Story.PUBLIC) {
return;
}
if (this.tags.size() < 1) {
return;
}
var tag = this.tags.get(0).tag;
if (!tag) {
return;
}
if (!param.as || param.as === "text") {
res.write(tag.name);
} else if (param.as === "link") {
html.link({href: tag.href()}, param.text || tag.name);
} else if (param.as === "image") {
param.imgprefix || (param.imgprefix = "topic_");
var img = HopObject.getFromPath(param.imgprefix + tag.name, "images");
delete param.imgprefix;
delete param.as;
if (img) {
res.push();
img.render_macro(param);
delete param.height;
delete param.width;
delete param.border;
delete param.src;
delete param.alt;
link_filter(res.pop(), param, tag.href());
}
}
return;
// This method is applied to images as well, thus we check what we got first:
if (this.constructor !== Image && this.status !== Story.PUBLIC) {
return;
}
if (this.tags.size() < 1) {
return;
}
var tag = this.tags.get(0).tag;
if (!tag) {
return;
}
if (!param.as || param.as === "text") {
res.write(tag.name);
} else if (param.as === "link") {
html.link({href: tag.href()}, param.text || tag.name);
} else if (param.as === "image") {
param.imgprefix || (param.imgprefix = "topic_");
var img = HopObject.getFromPath(param.imgprefix + tag.name, "images");
delete param.imgprefix;
delete param.as;
if (img) {
res.push();
img.render_macro(param);
delete param.height;
delete param.width;
delete param.border;
delete param.src;
delete param.alt;
link_filter(res.pop(), param, tag.href());
}
}
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 = (this.constructor === Story ? site.stories.tags :
site.images.galleries);
var options = [], topic;
for (var i=0; i<topics.size(); i++) {
topic = topics.get(i);
options.push({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;
var site = this.site || res.handlers.site;
var currentTopic = this.tags.size() > 0 ? this.tags.get(0).tag : null;
var topics = (this.constructor === Story ? site.stories.tags :
site.images.galleries);
var options = [], topic;
for (var i=0; i<topics.size(); i++) {
topic = topics.get(i);
options.push({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.addtofront_macro = function(param) {
if (param.as === "editor") {
// if we're in a submit, use the submitted form value.
// otherwise, render the object's value.
if (req.data.publish || req.data.save) {
if (!req.data.addToFront) {
delete param.checked;
}
} else if (req.action !== "create" && this.mode !== Story.FEATURED) {
delete param.checked;
if (param.as === "editor") {
// if we're in a submit, use the submitted form value.
// otherwise, render the object's value.
if (req.data.publish || req.data.save) {
if (!req.data.addToFront) {
delete param.checked;
}
param.name = "addToFront";
param.value = "1";
delete param.as;
html.checkBox(param);
}
return;
} else if (req.action !== "create" && this.mode !== Story.FEATURED) {
delete param.checked;
}
param.name = "addToFront";
param.value = "1";
delete param.as;
html.checkBox(param);
}
return;
}
Story.prototype.discussions_macro = function(param) {
if (res.handlers.site.commentMode === Site.DISABLED) {
return;
}
if (param.as === "editor") {
if (req.data.publish || req.data.save) {
param.checked = req.data.discussions;
} else if (req.action !== "create") {
param.checked = this.commentMode === Story.OPEN ? "checked" : null;
} else {
param.checked || (param.checked = "checked");
}
delete param.as;
param.name = "discussions";
param.value = "1";
html.checkBox(param);
} else {
res.write(this.commentMode === Story.OPEN ? "yes" : "no");
}
return;
if (res.handlers.site.commentMode === Site.DISABLED) {
return;
}
if (param.as === "editor") {
if (req.data.publish || req.data.save) {
param.checked = req.data.discussions;
} else if (req.action !== "create") {
param.checked = this.commentMode === Story.OPEN ? "checked" : null;
} else {
param.checked || (param.checked = "checked");
}
delete param.as;
param.name = "discussions";
param.value = "1";
html.checkBox(param);
} else {
res.write(this.commentMode === Story.OPEN ? "yes" : "no");
}
return;
}
Story.prototype.editableby_macro = function(param) {
if (param.as == "editor" && (session.user == this.creator || !this.creator)) {
var options = [Story.PUBLIC, Story.SHARED, Story.OPEN];
var labels = ["content managers", "contributors", "subscribers"];
delete param.as;
if (req.data.publish || req.data.save) {
var selValue = req.data.status || null;
} else {
var selValue = this.status;
}
for (var i=0; i<options.length; i+=1) {
html.radioButton({name: "editableby",
value: options[i], selectedValue: selValue});
res.write("&nbsp;");
res.write(labels[i]);
res.write("&nbsp;");
}
} else {
switch (this.status) {
case Story.PUBLIC:
res.write("Content managers of " + path.site.title);
break;
case Story.SHARED:
res.write("Contributors to " + path.site.title);
break;
case Story.OPEN:
res.write("Subscribers of and contributors to " + path.site.title);
break;
}
}
return;
if (param.as == "editor" && (session.user == this.creator || !this.creator)) {
var options = [Story.PUBLIC, Story.SHARED, Story.OPEN];
var labels = ["content managers", "contributors", "subscribers"];
delete param.as;
if (req.data.publish || req.data.save) {
var selValue = req.data.status || null;
} else {
var selValue = this.status;
}
for (var i=0; i<options.length; i+=1) {
html.radioButton({name: "editableby",
value: options[i], selectedValue: selValue});
res.write("&nbsp;");
res.write(labels[i]);
res.write("&nbsp;");
}
} else {
switch (this.status) {
case Story.PUBLIC:
res.write("Content managers of " + path.site.title);
break;
case Story.SHARED:
res.write("Contributors to " + path.site.title);
break;
case Story.OPEN:
res.write("Subscribers of and contributors to " + path.site.title);
break;
}
}
return;
}
Story.prototype.editlink_macro = function(param) {
res.push();
if (param.image && this.site.images.get(param.image)) {
var image = this.site.images.get(param.image);
delete param.image;
image && image.render_macro(param);
} else {
res.write(param.text || "edit");
}
return this.link_macro(param, "edit", res.pop());
res.push();
if (param.image && this.site.images.get(param.image)) {
var image = this.site.images.get(param.image);
delete param.image;
image && image.render_macro(param);
} else {
res.write(param.text || "edit");
}
return this.link_macro(param, "edit", res.pop());
}
Story.prototype.deletelink_macro = function(param) {
res.push();
if (param.image && this.site.images.get(param.image)) {
var image = this.site.images.get(param.image);
delete param.image;
image && image.render_macro(param);
} else {
res.write(param.text || "delete");
}
return this.link_macro(param, "delete", res.pop());
res.push();
if (param.image && this.site.images.get(param.image)) {
var image = this.site.images.get(param.image);
delete param.image;
image && image.render_macro(param);
} else {
res.write(param.text || "delete");
}
return this.link_macro(param, "delete", res.pop());
}
Story.prototype.viewlink_macro = function(param) {
res.push();
if (param.image && this.site.images.get(param.image)) {
var image = this.site.images.get(param.image);
delete param.image;
image && image.render_macro(param);
} else {
res.write(param.text || "view");
}
return this.link_macro(param, ".", res.pop());
res.push();
if (param.image && this.site.images.get(param.image)) {
var image = this.site.images.get(param.image);
delete param.image;
image && image.render_macro(param);
} else {
res.write(param.text || "view");
}
return this.link_macro(param, ".", res.pop());
}
Story.prototype.commentlink_macro = function(param) {
if (this.commentMode === Story.OPEN &&
this.site.commentMode === Site.ENABLED) {
html.link({href: this.href(param.to || "comment")},
param.text || "comment");
}
return;
if (this.commentMode === Story.OPEN &&
this.site.commentMode === Site.ENABLED) {
html.link({href: this.href(param.to || "comment")},
param.text || "comment");
}
return;
}
Story.prototype.onlinelink_macro = function(param) {
return this.link_macro(param, "rotate");
return this.link_macro(param, "rotate");
}
Story.prototype.online_macro = function(param) {
if (this.satus === Story.CLOSED) {
res.write(param.no || "offline");
} else if (this.status === Story.PUBLIC || this.status === Story.HIDDEN) {
res.write(param.yes || "online");
} return;
if (this.satus === Story.CLOSED) {
res.write(param.no || "offline");
} else if (this.status === Story.PUBLIC || this.status === Story.HIDDEN) {
res.write(param.yes || "online");
} return;
}
Story.prototype.createtime_macro = function(param) {
if (param.as === "editor") {
if (this.created) {
param.value = formatDate(this.created, "yyyy-MM-dd HH:mm");
} else {
param.value = formatDate(new Date(), "yyyy-MM-dd HH:mm");
}
param.name = "created";
html.input(param);
} else if (this.created) {
var text = formatDate(this.created, param.format);
if (param.as === "link" && this.status === Story.PUBLIC) {
var group = this.site.archive.get(this.created.format("yyyyMMdd"));
var path = formatDate(group._id.toDate("yyyyMMdd"), "yyyy/MM/dd");
html.link({href: this.site.archive.href() + path}, text);
} else {
res.write(text);
}
}
return;
if (param.as === "editor") {
if (this.created) {
param.value = formatDate(this.created, "yyyy-MM-dd HH:mm");
} else {
param.value = formatDate(new Date(), "yyyy-MM-dd HH:mm");
}
param.name = "created";
html.input(param);
} else if (this.created) {
var text = formatDate(this.created, param.format);
if (param.as === "link" && this.status === Story.PUBLIC) {
var group = this.site.archive.get(this.created.format("yyyyMMdd"));
var path = formatDate(group._id.toDate("yyyyMMdd"), "yyyy/MM/dd");
html.link({href: this.site.archive.href() + path}, text);
} else {
res.write(text);
}
}
return;
}
Story.prototype.commentcounter_macro = function(param) {
if (this.site.commentMode === Site.DISABLED ||
this.commentMode === Story.CLOSED ||
this.commentMode === Story.READONLY) {
return;
}
var commentCnt = this.comments.count();
param.linkto || (param.linkto = "main");
var linkflag = (param.as === "link" && param.as !== "text" ||
!param.as && commentCnt > 0);
if (linkflag) {
html.openTag("a", {href: this.href() + "#comments"});
}
if (commentCnt < 1) {
res.write(param.no || "no comments");
} else if (commentCnt < 2) {
res.write(param.one || "one comment");
} else {
res.write(commentCnt + (param.more || " " + "comments"));
}
if (linkflag) {
html.closeTag("a");
}
return;
if (this.site.commentMode === Site.DISABLED ||
this.commentMode === Story.CLOSED ||
this.commentMode === Story.READONLY) {
return;
}
var commentCnt = this.comments.count();
param.linkto || (param.linkto = "main");
var linkflag = (param.as === "link" && param.as !== "text" ||
!param.as && commentCnt > 0);
if (linkflag) {
html.openTag("a", {href: this.href() + "#comments"});
}
if (commentCnt < 1) {
res.write(param.no || "no comments");
} else if (commentCnt < 2) {
res.write(param.one || "one comment");
} else {
res.write(commentCnt + (param.more || " " + "comments"));
}
if (linkflag) {
html.closeTag("a");
}
return;
}
Story.prototype.reads_macro = function(param) {
res.write(this.requests);
return;
res.write(this.requests);
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -24,15 +24,15 @@
// $URL$
Topics.prototype.main_action = function() {
return res.redirect(this.href());
return res.redirect(this.href());
}
Topics.prototype.getChildElement = function(id) {
return res.redirect(this.href() + id);
return res.redirect(this.href() + id);
}
Topics.prototype.href = function() {
var mountpoint = (this._parent.constructor === Site ||
this._parent.constructor === Root ? "tags" : "galleries");
return this._parent[mountpoint].href();
var mountpoint = (this._parent.constructor === Site ||
this._parent.constructor === Root ? "tags" : "galleries");
return this._parent[mountpoint].href();
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,68 +26,68 @@
disableMacro(User, "password");
User.prototype.__defineGetter__("blocked", function() {
return this.status === User.BLOCKED;
return this.status === User.BLOCKED;
});
User.prototype.__defineSetter__("blocked", function(blocked) {
this.status = blocked ? User.BLOCKED : User.DEFAULT;
this.status = blocked ? User.BLOCKED : User.DEFAULT;
});
User.prototype.__defineGetter__("trusted", function() {
return this.status === User.TRUSTED;
return this.status === User.TRUSTED;
});
User.prototype.__defineSetter__("trusted", function(trusted) {
this.status = trusted ? User.TRUSTED : User.DEFAULT;
this.status = trusted ? User.TRUSTED : User.DEFAULT;
});
User.prototype.__defineGetter__("sysadmin", function() {
return this.status === User.PRIVILEGED;
return this.status === User.PRIVILEGED;
});
User.prototype.__defineSetter__("sysadmin", function(privileged) {
this.status = privileged ? User.PRIVILEGED : User.DEFAULT;
this.status = privileged ? User.PRIVILEGED : User.DEFAULT;
});
User.prototype.status_macro = function(param) {
// This macro is allowed for privileged users only
if (!User.require(User.PRIVILEGED)) {
return;
}
if (param.as === "editor") {
this.select_macro(param, "status");
} else {
res.write(this.status);
}
return;
// This macro is allowed for privileged users only
if (!User.require(User.PRIVILEGED)) {
return;
}
if (param.as === "editor") {
this.select_macro(param, "status");
} else {
res.write(this.status);
}
return;
}
User.prototype.name_macro = function(param) {
if (param.as === "link" && this.url) {
link_filter(this.name, param, this.url);
} else {
res.write(this.name);
}
return;
if (param.as === "link" && this.url) {
link_filter(this.name, param, this.url);
} else {
res.write(this.name);
}
return;
}
User.prototype.url_macro = function(param) {
if (param.as === "editor") {
this.input_macro(param, "url");
} else {
res.write(this.url);
}
return;
if (param.as === "editor") {
this.input_macro(param, "url");
} else {
res.write(this.url);
}
return;
}
User.prototype.email_macro = function(param) {
if (!User.require(User.PRIVILEGED) && this !== session.user) {
return;
}
if (param.as === "editor") {
this.input_macro(param, "email");
} else {
res.write(this.email);
}
return;
if (!User.require(User.PRIVILEGED) && this !== session.user) {
return;
}
if (param.as === "editor") {
this.input_macro(param, "email");
} else {
res.write(this.email);
}
return;
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,301 +34,301 @@ app.addRepository(app.dir + "/../extra/connect/scribe-1.3.0.jar");
// FIXME: Might be good to somehow define the action together with its permissions...
Members.prototype.connect_action = function() {
try {
var connect = Feature.get("connect");
switch (req.data.type) {
case "facebook":
connect.facebook(req);
break;
case "google":
connect.google(req);
break;
case "twitter":
connect.scribe(req.data.type);
break;
}
} catch (ex) {
session.logout();
res.message = String(ex);
res.redirect(res.handlers.members.href("login"));
}
JSON.sendPaddedResponse(this._parent.stories.getPermission("create"));
res.redirect(User.getLocation() || res.handlers.site.href());
return;
try {
var connect = Feature.get("connect");
switch (req.data.type) {
case "facebook":
connect.facebook(req);
break;
case "google":
connect.google(req);
break;
case "twitter":
connect.scribe(req.data.type);
break;
}
} catch (ex) {
session.logout();
res.message = String(ex);
res.redirect(res.handlers.members.href("login"));
}
JSON.sendPaddedResponse(this._parent.stories.getPermission("create"));
res.redirect(User.getLocation() || res.handlers.site.href());
return;
}
Members.prototype.disconnect_action = function() {
switch (req.data.type) {
case "facebook":
case "google":
case "twitter":
res.handlers.membership.creator.deleteMetadata(req.data.type + "_id");
break;
}
res.redirect(req.data.http_referer);
return;
switch (req.data.type) {
case "facebook":
case "google":
case "twitter":
res.handlers.membership.creator.deleteMetadata(req.data.type + "_id");
break;
}
res.redirect(req.data.http_referer);
return;
}
Feature.add("connect", "http://code.google.com/p/antville/wiki/ConnectFeature", {
_getPermission: function(action) {
if (this.constructor === Members) {
switch (action) {
case "connect":
return true;
case "disconnect":
return User.require(User.REGULAR);
}
_getPermission: function(action) {
if (this.constructor === Members) {
switch (action) {
case "connect":
return true;
case "disconnect":
return User.require(User.REGULAR);
}
},
main: function(options) {
var defaultDomain = getProperty("domain.*");
var domain = getProperty("domain." + res.handlers.site.name);
if (defaultDomain && domain && !domain.endsWith(defaultDomain)) {
return;
}
var suffix = options.context ? "_" + options.context : "";
getProperty("connect.facebook.id") && renderSkin("connect#facebook" + suffix);
getProperty("connect.google.id") && renderSkin("connect#google" + suffix);
getProperty("connect.twitter.id") && renderSkin("connect#twitter" + suffix);
},
getUserByConnection: function(type, id) {
var user;
var connections = root.connections.get(id);
if (connections) {
connections.forEach(function(index) {
if (this.name === type + "_id") {
user = this.parent;
}
});
}
return user;
},
scribe: function(type) {
var name = type.titleize();
var appId = getProperty("connect." + type + ".id");
var secret = getProperty("connect." + type + ".key");
if (!secret || req.data.denied) {
throw Error(gettext("Connecting with {0} failed. {1} Please try again.", name,
gettext("You denied the request.")));
}
if (req.isPost()) {
try {
User.login(req.postParams);
} catch (ex) { }
}
var scribe = Packages.org.scribe;
var provider, requestUrl, scope, getValues;
var headers = {};
switch (type) {
case "google":
provider = scribe.builder.api.GoogleApi;
requestUrl = "http://www-opensocial.googleusercontent.com/api/people/@me/@self";
scope = "http://www-opensocial.googleusercontent.com/api/people/";
headers["GData-Version"] = "3.0";
getValues = function(data) {
data = data.entry;
return {
id: data.id,
name: data.displayName,
email: data.email,
url: data.url
}
}
break;
case "twitter":
provider = scribe.builder.api.TwitterApi;
requestUrl = "https://api.twitter.com/1.1/account/verify_credentials.json";
getValues = function(data) {
return {
id: data.id_str,
name: data.screen_name,
email: data.email,
url: data.profileUrl
}
}
break;
}
var url = res.handlers.members.href(req.action) + "?type=" + type;
var service = new scribe.builder.ServiceBuilder()
.provider(provider)
.apiKey(appId)
.apiSecret(secret)
.callback(url);
if (scope) {
service.scope(scope);
}
var oauth = service.build();
var verifier = req.data.oauth_verifier;
if (!verifier) {
// Because the service provider will redirect back to this URL the
// request token needs to be stored in the session object
session.data.requestToken = oauth.getRequestToken();
res.redirect(oauth.getAuthorizationUrl(session.data.requestToken));
}
try {
var accessToken = oauth.getAccessToken(session.data.requestToken,
new scribe.model.Verifier(verifier));
} catch (ex) {
throw Error(gettext("Connecting with {0} failed. {1} Please try again.", name,
gettext("Something went wrong.")));
}
var request = new scribe.model.OAuthRequest(scribe.model.Verb.GET, requestUrl);
oauth.signRequest(accessToken, request);
for (let name in headers) {
request.addHeader(name, headers[name]);
}
var response = request.send();
var data = getValues(JSON.parse(response.getBody()));
var user = this.getUserByConnection(type, data.id);
if (!user) {
if (!session.user) {
var name = root.users.getAccessName(data.name);
user = User.register({
name: name,
hash: session.data.requestToken.getToken(),
email: data.email || root.replyTo,
url: data.url
});
session.login(user);
} else {
user = session.user;
}
user.setMetadata(type + "_id", data.id);
} else if (user !== session.user) {
user.touch();
session.login(user);
}
return;
}
},
facebook: function(req) {
var appId = getProperty("connect.facebook.id");
var secret = getProperty("connect.facebook.key");
if (!secret || req.data.error) {
throw Error(gettext("Could not connect with Facebook. ({0})", -1));
}
if (req.isPost()) {
try {
User.login(req.postParams);
} catch (ex) { }
}
var url = res.handlers.members.href(req.action) + "?type=facebook";
var code = req.data.code;
if (!code) {
res.redirect("https://www.facebook.com/dialog/oauth?client_id=" + appId +
"&scope=email&redirect_uri=" + url);
return;
}
var mime = getURL("https://graph.facebook.com/oauth/access_token?client_id=" + appId +
"&redirect_uri=" + url + "&client_secret=" + secret + "&code=" + code);
if (!mime || !mime.text) {
throw Error(gettext("Could not connect with Facebook. ({0})", -3));
}
var token = mime.text;
mime = getURL("https://graph.facebook.com/me?" + token);
if (!mime) {
throw Error(gettext("Could not connect with Facebook. ({0})", -4));
}
var content = Packages.org.apache.commons.io.IOUtils.toString(mime.inputStream);
if (!content) {
throw Error(gettext("Could not connect with Facebook. ({0})", -5));
}
var data = JSON.parse(content);
var user = this.getUserByConnection("facebook", data.id);
if (!user) {
if (!session.user) {
var name = root.users.getAccessName(data.name);
user = User.register({
name: name,
hash: token,
email: data.email,
url: data.link,
});
session.login(user);
} else {
user = session.user;
}
user.setMetadata("facebook_id", data.id);
} else if (user !== session.user) {
user.touch();
session.login(user);
}
main: function(options) {
var defaultDomain = getProperty("domain.*");
var domain = getProperty("domain." + res.handlers.site.name);
if (defaultDomain && domain && !domain.endsWith(defaultDomain)) {
return;
},
}
var suffix = options.context ? "_" + options.context : "";
getProperty("connect.facebook.id") && renderSkin("connect#facebook" + suffix);
getProperty("connect.google.id") && renderSkin("connect#google" + suffix);
getProperty("connect.twitter.id") && renderSkin("connect#twitter" + suffix);
},
google: function(req) {
if (req.isPost()) {
try {
User.login(req.postParams);
} catch (ex) { }
getUserByConnection: function(type, id) {
var user;
var connections = root.connections.get(id);
if (connections) {
connections.forEach(function(index) {
if (this.name === type + "_id") {
user = this.parent;
}
});
}
return user;
},
scribe: function(type) {
var name = type.titleize();
var appId = getProperty("connect." + type + ".id");
var secret = getProperty("connect." + type + ".key");
if (!secret || req.data.denied) {
throw Error(gettext("Connecting with {0} failed. {1} Please try again.", name,
gettext("You denied the request.")));
}
if (req.isPost()) {
try {
User.login(req.postParams);
} catch (ex) { }
}
var scribe = Packages.org.scribe;
var provider, requestUrl, scope, getValues;
var headers = {};
switch (type) {
case "google":
provider = scribe.builder.api.GoogleApi;
requestUrl = "http://www-opensocial.googleusercontent.com/api/people/@me/@self";
scope = "http://www-opensocial.googleusercontent.com/api/people/";
headers["GData-Version"] = "3.0";
getValues = function(data) {
data = data.entry;
return {
id: data.id,
name: data.displayName,
email: data.email,
url: data.url
}
}
break;
var url = root.members.href('connect') + "?type=google";
case "twitter":
provider = scribe.builder.api.TwitterApi;
requestUrl = "https://api.twitter.com/1.1/account/verify_credentials.json";
getValues = function(data) {
return {
id: data.id_str,
name: data.screen_name,
email: data.email,
url: data.profileUrl
}
}
break;
}
if (req.data.code) {
var http = new helma.Http();
http.setMethod("POST");
http.setContent("code=" + encodeURIComponent(req.data.code) +
"&client_id=" + encodeURIComponent(getProperty("connect.google.id")) +
"&client_secret=" + encodeURIComponent(getProperty("connect.google.key")) +
"&redirect_uri=" + encodeURIComponent(url) + "&grant_type=authorization_code");
var response = http.getUrl("https://accounts.google.com/o/oauth2/token");
var data = JSON.parse(response.content);
var token = data.access_token;
var mime = getURL("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" +
encodeURIComponent(data.access_token));
var data = JSON.parse(Packages.org.apache.commons.io.IOUtils.toString(mime.inputStream));
var user = this.getUserByConnection("google", data.id);
if (!user) {
if (!session.user) {
var name = root.users.getAccessName(data.name);
user = User.register({
name: name,
hash: token,
email: data.email,
url: data.link
});
session.login(user);
} else {
user = session.user;
}
user.setMetadata("google_id", data.id);
} else if (user !== session.user) {
user.touch();
session.login(user);
}
var url = res.handlers.members.href(req.action) + "?type=" + type;
var service = new scribe.builder.ServiceBuilder()
.provider(provider)
.apiKey(appId)
.apiSecret(secret)
.callback(url);
if (scope) {
service.scope(scope);
}
var oauth = service.build();
var verifier = req.data.oauth_verifier;
if (!verifier) {
// Because the service provider will redirect back to this URL the
// request token needs to be stored in the session object
session.data.requestToken = oauth.getRequestToken();
res.redirect(oauth.getAuthorizationUrl(session.data.requestToken));
}
try {
var accessToken = oauth.getAccessToken(session.data.requestToken,
new scribe.model.Verifier(verifier));
} catch (ex) {
throw Error(gettext("Connecting with {0} failed. {1} Please try again.", name,
gettext("Something went wrong.")));
}
var request = new scribe.model.OAuthRequest(scribe.model.Verb.GET, requestUrl);
oauth.signRequest(accessToken, request);
for (let name in headers) {
request.addHeader(name, headers[name]);
}
var response = request.send();
var data = getValues(JSON.parse(response.getBody()));
var user = this.getUserByConnection(type, data.id);
if (!user) {
if (!session.user) {
var name = root.users.getAccessName(data.name);
user = User.register({
name: name,
hash: session.data.requestToken.getToken(),
email: data.email || root.replyTo,
url: data.url
});
session.login(user);
} else {
res.redirect("https://accounts.google.com/o/oauth2/auth?" +
"client_id=" + encodeURIComponent(getProperty("connect.google.id")) +
"&redirect_uri=" + encodeURIComponent(url) +
"&scope=" + encodeURIComponent("https://www.googleapis.com/auth/userinfo.profile") +
"+" + encodeURIComponent("https://www.googleapis.com/auth/userinfo.email") +
"&response_type=code");
user = session.user;
}
}
user.setMetadata(type + "_id", data.id);
} else if (user !== session.user) {
user.touch();
session.login(user);
}
return;
},
facebook: function(req) {
var appId = getProperty("connect.facebook.id");
var secret = getProperty("connect.facebook.key");
if (!secret || req.data.error) {
throw Error(gettext("Could not connect with Facebook. ({0})", -1));
}
if (req.isPost()) {
try {
User.login(req.postParams);
} catch (ex) { }
}
var url = res.handlers.members.href(req.action) + "?type=facebook";
var code = req.data.code;
if (!code) {
res.redirect("https://www.facebook.com/dialog/oauth?client_id=" + appId +
"&scope=email&redirect_uri=" + url);
return;
}
var mime = getURL("https://graph.facebook.com/oauth/access_token?client_id=" + appId +
"&redirect_uri=" + url + "&client_secret=" + secret + "&code=" + code);
if (!mime || !mime.text) {
throw Error(gettext("Could not connect with Facebook. ({0})", -3));
}
var token = mime.text;
mime = getURL("https://graph.facebook.com/me?" + token);
if (!mime) {
throw Error(gettext("Could not connect with Facebook. ({0})", -4));
}
var content = Packages.org.apache.commons.io.IOUtils.toString(mime.inputStream);
if (!content) {
throw Error(gettext("Could not connect with Facebook. ({0})", -5));
}
var data = JSON.parse(content);
var user = this.getUserByConnection("facebook", data.id);
if (!user) {
if (!session.user) {
var name = root.users.getAccessName(data.name);
user = User.register({
name: name,
hash: token,
email: data.email,
url: data.link,
});
session.login(user);
} else {
user = session.user;
}
user.setMetadata("facebook_id", data.id);
} else if (user !== session.user) {
user.touch();
session.login(user);
}
return;
},
google: function(req) {
if (req.isPost()) {
try {
User.login(req.postParams);
} catch (ex) { }
}
var url = root.members.href('connect') + "?type=google";
if (req.data.code) {
var http = new helma.Http();
http.setMethod("POST");
http.setContent("code=" + encodeURIComponent(req.data.code) +
"&client_id=" + encodeURIComponent(getProperty("connect.google.id")) +
"&client_secret=" + encodeURIComponent(getProperty("connect.google.key")) +
"&redirect_uri=" + encodeURIComponent(url) + "&grant_type=authorization_code");
var response = http.getUrl("https://accounts.google.com/o/oauth2/token");
var data = JSON.parse(response.content);
var token = data.access_token;
var mime = getURL("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" +
encodeURIComponent(data.access_token));
var data = JSON.parse(Packages.org.apache.commons.io.IOUtils.toString(mime.inputStream));
var user = this.getUserByConnection("google", data.id);
if (!user) {
if (!session.user) {
var name = root.users.getAccessName(data.name);
user = User.register({
name: name,
hash: token,
email: data.email,
url: data.link
});
session.login(user);
} else {
user = session.user;
}
user.setMetadata("google_id", data.id);
} else if (user !== session.user) {
user.touch();
session.login(user);
}
} else {
res.redirect("https://accounts.google.com/o/oauth2/auth?" +
"client_id=" + encodeURIComponent(getProperty("connect.google.id")) +
"&redirect_uri=" + encodeURIComponent(url) +
"&scope=" + encodeURIComponent("https://www.googleapis.com/auth/userinfo.profile") +
"+" + encodeURIComponent("https://www.googleapis.com/auth/userinfo.email") +
"&response_type=code");
}
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -28,33 +28,33 @@
*/
Root.prototype.proxy_action = function() {
var url = req.data.url;
if (!url) {
return;
}
var url = req.data.url;
if (!url) {
return;
}
var http = new helma.Http;
var data = http.getUrl(url);
var http = new helma.Http;
var data = http.getUrl(url);
if (!data.content) {
throw Error("Failed to retrieve URL.");
}
if (!data.content) {
throw Error("Failed to retrieve URL.");
}
var callback = req.data.callback;
if (callback) {
res.contentType = "text/javascript";
res.write(JSON.pad(data.content, callback));
} else {
res.write(data.content);
}
return;
var callback = req.data.callback;
if (callback) {
res.contentType = "text/javascript";
res.write(JSON.pad(data.content, callback));
} else {
res.write(data.content);
}
return;
}
Feature.add("proxy", "http://code.google.com/p/antville/wiki/ProxyFeature", {
_getPermission: function(action) {
if (this._prototype in {Root: 1} &&
action === "proxy" && User.require(User.TRUSTED)) {
return true;
}
}
_getPermission: function(action) {
if (this._prototype in {Root: 1} &&
action === "proxy" && User.require(User.TRUSTED)) {
return true;
}
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -29,35 +29,35 @@
*/
Feature.add("recaptcha", "http://code.google.com/p/antville/wiki/RecaptchaFeature", new function() {
var key = getProperty("recaptcha.key");
var key = getProperty("recaptcha.key");
return {
main: function() {
if (key && !session.user) {
renderSkin("recaptcha", {id: getProperty("recaptcha.id")});
}
return;
},
verify: function(data) {
if (session.user) {
return;
}
var http = new helma.Http;
http.setTimeout(200);
http.setReadTimeout(300);
http.setMethod("POST");
http.setContent({
privatekey: key,
remoteip: req.data.http_remotehost,
challenge: data.recaptcha_challenge_field,
response: data.recaptcha_response_field
});
var request = http.getUrl("http://www.google.com/recaptcha/api/verify");
if (request.code === 200 && !request.content.startsWith("true")) {
throw Error(gettext("Please enter the correct words in the CAPTCHA box."));
}
return;
return {
main: function() {
if (key && !session.user) {
renderSkin("recaptcha", {id: getProperty("recaptcha.id")});
}
}
return;
},
verify: function(data) {
if (session.user) {
return;
}
var http = new helma.Http;
http.setTimeout(200);
http.setReadTimeout(300);
http.setMethod("POST");
http.setContent({
privatekey: key,
remoteip: req.data.http_remotehost,
challenge: data.recaptcha_challenge_field,
response: data.recaptcha_response_field
});
var request = http.getUrl("http://www.google.com/recaptcha/api/verify");
if (request.code === 200 && !request.content.startsWith("true")) {
throw Error(gettext("Please enter the correct words in the CAPTCHA box."));
}
return;
}
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -29,307 +29,307 @@ app.data.status = "idle";
var server = Packages.helma.main.Server.getServer();
var status = function(type) {
if (type) {
app.data.status = type;
return;
} else {
return app.data.status;
}
if (type) {
app.data.status = type;
return;
} else {
return app.data.status;
}
}
var antville = function() {
return new Packages.helma.framework.core.ApplicationBean(server.
getApplication("antville"));
return new Packages.helma.framework.core.ApplicationBean(server.
getApplication("antville"));
}
var db = function() {
app.data.db || (app.data.db = new Packages.helma.scripting.rhino.extensions.
DatabaseObject(antville().getDbSource("antville")));
return app.data.db;
app.data.db || (app.data.db = new Packages.helma.scripting.rhino.extensions.
DatabaseObject(antville().getDbSource("antville")));
return app.data.db;
}
var ResultWrapper = function(result) {
var columns = [];
this.values = {};
var columns = [];
this.values = {};
for (var i=1; i<=result.getColumnCount(); i+=1) {
columns.push(result.getColumnName(i));
}
for (var i=1; i<=result.getColumnCount(); i+=1) {
columns.push(result.getColumnName(i));
}
this.update = function() {
for each (var key in columns) {
this.values[key] = result.getColumnItem(key);
}
return;
}
this.update = function() {
for each (var key in columns) {
this.values[key] = result.getColumnItem(key);
}
return;
}
return this;
return this;
}
var version = function() {
try {
var rootSite = antville().__app__.getDataRoot();
var metadata = eval(rootSite.metadata_source);
return metadata.version || "";
} catch (ex) {
return "";
}
try {
var rootSite = antville().__app__.getDataRoot();
var metadata = eval(rootSite.metadata_source);
return metadata.version || "";
} catch (ex) {
return "";
}
}
var init = function() {
var currentVersion = version();
if (status() === "running") {
msg("Updater is already running");
return false;
} else if (getProperty("version.to") == currentVersion) {
msg("Antville installation is already up-to-date");
status("finished");
return false;
} else if (getProperty("version.from") != currentVersion) {
msg("Updater cannot upgrade version " + currentVersion);
status("failed")
return false;
} else {
status("running");
}
var currentVersion = version();
if (status() === "running") {
msg("Updater is already running");
return false;
} else if (getProperty("version.to") == currentVersion) {
msg("Antville installation is already up-to-date");
status("finished");
return false;
} else if (getProperty("version.from") != currentVersion) {
msg("Updater cannot upgrade version " + currentVersion);
status("failed")
return false;
} else {
status("running");
}
return true;
}
var finalize = function() {
var rootSite = antville().__app__.getDataRoot();
var metadata = eval(rootSite.metadata_source);
metadata.version = getProperty("version.to");
rootSite.metadata_source = metadata.toSource();
status("finished");
return;
var rootSite = antville().__app__.getDataRoot();
var metadata = eval(rootSite.metadata_source);
metadata.version = getProperty("version.to");
rootSite.metadata_source = metadata.toSource();
status("finished");
return;
}
var out = function() {
var str;
if (app.data.out.length() > 0) {
str = app.data.out.toString();
app.data.out.setLength(0);
}
res.write({
status: status(),
log: str
}.toSource());
return;
var str;
if (app.data.out.length() > 0) {
str = app.data.out.toString();
app.data.out.setLength(0);
}
res.write({
status: status(),
log: str
}.toSource());
return;
}
var log = function(str) {
app.log(str);
return;
app.log(str);
return;
}
var msg = function(str1 /* , str2, str2, ... */) {
var str = "";
for (var i=0; i<arguments.length; i+=1) {
str += String(arguments[i]) + " ";
}
if (str !== undefined) {
var now = "[" + new Date + "] ";
//app.data.out.insert(0, now + encodeForm(str) + "\n");
app.data.out.append(now + encodeForm(str) + "\n");
log(str);
}
return;
var str = "";
for (var i=0; i<arguments.length; i+=1) {
str += String(arguments[i]) + " ";
}
if (str !== undefined) {
var now = "[" + new Date + "] ";
//app.data.out.insert(0, now + encodeForm(str) + "\n");
app.data.out.append(now + encodeForm(str) + "\n");
log(str);
}
return;
}
var error = function(exception) {
var error = exception || db().getLastError();
if (error) {
msg(error);
status("failed");
res.abort();
}
return;
var error = exception || db().getLastError();
if (error) {
msg(error);
status("failed");
res.abort();
}
return;
}
var quote = function(str) {
if (str === null) {
return str;
}
return "'" + str.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
if (str === null) {
return str;
}
return "'" + str.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
}
var query = function(type) {
var param = {};
for (var i=1; i<arguments.length; i+=1) {
param["value" + i] = arguments[i];
}
return renderSkinAsString("convert#" + type, param).replace(/\n|\r/g, " ");
var param = {};
for (var i=1; i<arguments.length; i+=1) {
param["value" + i] = arguments[i];
}
return renderSkinAsString("convert#" + type, param).replace(/\n|\r/g, " ");
}
var clean = function(str) {
if (!str) {
return;
}
return str.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
if (!str) {
return;
}
return str.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "");
}
var update = function(tableName) {
msg("Updating table " + tableName);
var sql = renderSkinAsString("convert#" + tableName);
sql.split(/\n|\r|\n\r/).forEach(function(line) {
if (!line) {
return;
} else if (line.indexOf("#!") === 0) {
convert(line.substr(2));
} else {
execute(line);
}
msg("Updating table " + tableName);
var sql = renderSkinAsString("convert#" + tableName);
sql.split(/\n|\r|\n\r/).forEach(function(line) {
if (!line) {
return;
});
return;
} else if (line.indexOf("#!") === 0) {
convert(line.substr(2));
} else {
execute(line);
}
return;
});
return;
var parts = sql.split("#!");
execute(parts[0]);
if (parts[1]) {
var index = parts[1].indexOf("\n");
convert(parts[1].substr(0, index));
execute(parts[1].substr(index));
}
return;
var parts = sql.split("#!");
execute(parts[0]);
if (parts[1]) {
var index = parts[1].indexOf("\n");
convert(parts[1].substr(0, index));
execute(parts[1].substr(index));
}
return;
}
var id = function() {
app.data.id || (app.data.id = 0);
return (app.data.id += 1);
app.data.id || (app.data.id = 0);
return (app.data.id += 1);
}
var count = function(sql) {
var count = 0;
sql = "select count(*) from " + sql;
log(sql);
result = db().executeRetrieval(sql);
if (result.next()) {
count = result.getColumnItem("count(*)");
msg("Converting " + count + " records");
}
result.release();
return count;
var count = 0;
sql = "select count(*) from " + sql;
log(sql);
result = db().executeRetrieval(sql);
if (result.next()) {
count = result.getColumnItem("count(*)");
msg("Converting " + count + " records");
}
result.release();
return count;
}
var value = function(obj) {
if (obj === null) {
return obj;
}
if (obj === undefined) {
obj = String(obj);
}
switch (obj.constructor) {
case Number:
return obj;
case String:
return quote(obj);
case Date:
return "from_unixtime(" + (obj.getTime() / 1000) + ")";
case HopObject:
case Object:
return quote(obj.toSource());
}
return quote(String(obj));
if (obj === null) {
return obj;
}
if (obj === undefined) {
obj = String(obj);
}
switch (obj.constructor) {
case Number:
return obj;
case String:
return quote(obj);
case Date:
return "from_unixtime(" + (obj.getTime() / 1000) + ")";
case HopObject:
case Object:
return quote(obj.toSource());
}
return quote(String(obj));
}
var stringf = function(str /*, value1, ..., valueN */) {
var values = Array.prototype.slice.call(arguments, 1);
if (values.length > 0) {
var callback;
if (typeof values[values.length - 1] === "function") {
callback = values.pop();
}
if (typeof values[0] === "object") {
values = values[0];
}
str = str.replace(/\$(\w*)/g, function(str, key) {
return callback ? callback(values[key]) : values[key];
});
}
return str;
var values = Array.prototype.slice.call(arguments, 1);
if (values.length > 0) {
var callback;
if (typeof values[values.length - 1] === "function") {
callback = values.pop();
}
if (typeof values[0] === "object") {
values = values[0];
}
str = str.replace(/\$(\w*)/g, function(str, key) {
return callback ? callback(values[key]) : values[key];
});
}
return str;
}
var retrieve = function(sql /*, value1, ..., valueN */) {
// Add callback for global value() method to stringf() arguments
Array.prototype.push.call(arguments, value);
app.data.query = stringf.apply(null, arguments);
return;
// Add callback for global value() method to stringf() arguments
Array.prototype.push.call(arguments, value);
app.data.query = stringf.apply(null, arguments);
return;
}
var traverse = function(callback, noOffset, idName) {
if (!app.data.query || !callback) {
return;
}
var STEP = 5000, start = Date.now();
var sql, rows, offset = 0;
while (true) {
start = Date.now();
if (noOffset) {
sql = app.data.query.replace(/\$min/, offset);
sql = sql.replace(/\$max/, offset += noOffset);
msg(sql);
} else {
sql = app.data.query + " limit " + STEP;
sql += " offset " + offset;
offset += STEP;
msg(sql);
}
result = db().executeRetrieval(sql);
error();
msg("Select statement took " + (Date.now() - start) + " millis");
// FIXME: The hasMoreRows() method does not work as expected
rows = result.next();
if (!rows) {
result.release();
break;
}
do {
var wrapper = new ResultWrapper(result);
wrapper.update(result);
callback.call(wrapper.values, result);
} while (rows = result.next());
if (!app.data.query || !callback) {
return;
}
var STEP = 5000, start = Date.now();
var sql, rows, offset = 0;
while (true) {
start = Date.now();
if (noOffset) {
sql = app.data.query.replace(/\$min/, offset);
sql = sql.replace(/\$max/, offset += noOffset);
msg(sql);
} else {
sql = app.data.query + " limit " + STEP;
sql += " offset " + offset;
offset += STEP;
msg(sql);
}
result = db().executeRetrieval(sql);
error();
msg("Select statement took " + (Date.now() - start) + " millis");
// FIXME: The hasMoreRows() method does not work as expected
rows = result.next();
if (!rows) {
result.release();
msg("Update took " + (Date.now() - start) + " millis");
}
return;
break;
}
do {
var wrapper = new ResultWrapper(result);
wrapper.update(result);
callback.call(wrapper.values, result);
} while (rows = result.next());
result.release();
msg("Update took " + (Date.now() - start) + " millis");
}
return;
}
var execute = function(sql /*, value1, ..., valueN */) {
// Add callback for global value() method to stringf() arguments
Array.prototype.push.call(arguments, value);
sql = stringf.apply(null, arguments);
log(sql.contains("\n") ? sql.substr(0, sql.indexOf("\n")) + " ..." : sql);
try {
db().executeCommand(sql);
error();
} catch (ex) {
error(ex);
}
return;
// Add callback for global value() method to stringf() arguments
Array.prototype.push.call(arguments, value);
sql = stringf.apply(null, arguments);
log(sql.contains("\n") ? sql.substr(0, sql.indexOf("\n")) + " ..." : sql);
try {
db().executeCommand(sql);
error();
} catch (ex) {
error(ex);
}
return;
}
var archive = function() {
var staticDir = new helma.File(app.dir + "/../static");
for each (var siteName in staticDir.list()) {
var site = siteName !== "www" ? root.get(siteName) : root;
if (!site) {
continue;
var staticDir = new helma.File(app.dir + "/../static");
for each (var siteName in staticDir.list()) {
var site = siteName !== "www" ? root.get(siteName) : root;
if (!site) {
continue;
}
var dir = new helma.File(staticDir, siteName + "/layouts");
for each (var layoutName in dir.list()) {
if (layoutName.startsWith(".")) {
continue;
}
var dir = new helma.File(staticDir, siteName + "/layouts");
for each (var layoutName in dir.list()) {
if (layoutName.startsWith(".")) {
continue;
}
var layout = new Layout(site);
for each (var image in dir.listRecursive(/\.(jpg|gif|png)$/)) {
var name = image.split("/").pop().split(".")[0];
retrieve(query("archive", name, layoutName, siteName));
traverse(function() {
var img = new Image(this);
log(img);
});
}
var layout = new Layout(site);
for each (var image in dir.listRecursive(/\.(jpg|gif|png)$/)) {
var name = image.split("/").pop().split(".")[0];
retrieve(query("archive", name, layoutName, siteName));
traverse(function() {
var img = new Image(this);
log(img);
});
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -30,86 +30,86 @@ app.addRepository("modules/helma/Color.js");
app.addRepository("modules/helma/File.js");
Root.prototype.updater_action = function() {
// Disabled for safety reasons
return;
// Disabled for safety reasons
return;
app.invokeAsync(global, function() {
if (init()) {
//update("size"); // DEBUG
//update("legacy");
update("tag");
update("tag_hub");
update("AV_ACCESSLOG");
update("AV_CHOICE");
update("AV_FILE");
update("AV_IMAGE");
update("AV_LAYOUT");
update("AV_MEMBERSHIP");
update("AV_POLL");
update("AV_SITE");
update("AV_SKIN");
update("AV_TEXT");
update("AV_USER");
update("AV_VOTE");
update("AV_SYSLOG"); // This table has to go last!
convert("folders");
convert("root");
finalize();
}
return;
}, [], -1);
this.renderSkin("~Root");
return;
app.invokeAsync(global, function() {
if (init()) {
//update("size"); // DEBUG
//update("legacy");
update("tag");
update("tag_hub");
update("AV_ACCESSLOG");
update("AV_CHOICE");
update("AV_FILE");
update("AV_IMAGE");
update("AV_LAYOUT");
update("AV_MEMBERSHIP");
update("AV_POLL");
update("AV_SITE");
update("AV_SKIN");
update("AV_TEXT");
update("AV_USER");
update("AV_VOTE");
update("AV_SYSLOG"); // This table has to go last!
convert("folders");
convert("root");
finalize();
}
return;
}, [], -1);
this.renderSkin("~Root");
return;
}
Root.prototype.out_action = function() {
res.contentType = "text/plain";
return out();
res.contentType = "text/plain";
return out();
}
Root.prototype.nonames_action = function() {
app.invokeAsync(global, function() {
["image", "file"].forEach(function(table) {
retrieve("select * from " + table + " where name = ''");
traverse(function() {
this.name = Date.now() + "-" + this.id;
var metadata = eval(this.metadata);
var extension = metadata.contentType.split("/").pop();
metadata.fileName = this.name + "." + extension;
metadata.thumbnailName = this.name + "_small." + extension;
this.metadata = metadata;
execute("update " + table + " set name = $name, metadata = " +
"$metadata where id = $id", this);
});
app.invokeAsync(global, function() {
["image", "file"].forEach(function(table) {
retrieve("select * from " + table + " where name = ''");
traverse(function() {
this.name = Date.now() + "-" + this.id;
var metadata = eval(this.metadata);
var extension = metadata.contentType.split("/").pop();
metadata.fileName = this.name + "." + extension;
metadata.thumbnailName = this.name + "_small." + extension;
this.metadata = metadata;
execute("update " + table + " set name = $name, metadata = " +
"$metadata where id = $id", this);
});
status("finished");
}, [], -1);
this.renderSkin("~Root");
return;
});
status("finished");
}, [], -1);
this.renderSkin("~Root");
return;
}
Root.prototype.galleries_action = function() {
var oldDatabase = "antville_1_1";
app.invokeAsync(global, function() {
execute("alter table tag_hub add column `tagged_id_old` int(11) default NULL");
execute("alter table tag_hub add column `tagged_type_old` enum('Story','Image') default NULL");
execute("update tag_hub set tagged_type_old = tagged_type, tagged_id_old = tagged_id;");
retrieve(stringf("select tag_hub.*, IMAGE_ALIAS as name, " +
"IMAGE_F_SITE as site from tag_hub left join $0.AV_IMAGE on " +
"IMAGE_ID = tagged_id where tagged_id in " +
"(select IMAGE_ID from $0.AV_IMAGE where IMAGE_TOPIC is not " +
"null and IMAGE_F_IMAGE_PARENT is null)", oldDatabase));
traverse(function() {
execute("update tag_hub set tagged_type = 'Image', tagged_id = " +
"(select id from image where name = $name and site_id = " +
"$site and parent_type = 'Site') where id = $id", this);
});
status("finished");
}, [], -1);
this.renderSkin("~Root");
return;
var oldDatabase = "antville_1_1";
app.invokeAsync(global, function() {
execute("alter table tag_hub add column `tagged_id_old` int(11) default NULL");
execute("alter table tag_hub add column `tagged_type_old` enum('Story','Image') default NULL");
execute("update tag_hub set tagged_type_old = tagged_type, tagged_id_old = tagged_id;");
retrieve(stringf("select tag_hub.*, IMAGE_ALIAS as name, " +
"IMAGE_F_SITE as site from tag_hub left join $0.AV_IMAGE on " +
"IMAGE_ID = tagged_id where tagged_id in " +
"(select IMAGE_ID from $0.AV_IMAGE where IMAGE_TOPIC is not " +
"null and IMAGE_F_IMAGE_PARENT is null)", oldDatabase));
traverse(function() {
execute("update tag_hub set tagged_type = 'Image', tagged_id = " +
"(select id from image where name = $name and site_id = " +
"$site and parent_type = 'Site') where id = $id", this);
});
status("finished");
}, [], -1);
this.renderSkin("~Root");
return;
}
Root.prototype.patch = function(code) {
eval(code);
eval(code);
}

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,48 +26,48 @@
// Apply with enabled updater repository via ant patch -Dpatch.id=20080913
root.forEach(function() {
var site = this;
if (site.layout) {
res.handlers.layout = site.layout;
res.skinpath = site.layout.getSkinPath();
var site = this;
if (site.layout) {
res.handlers.layout = site.layout;
res.skinpath = site.layout.getSkinPath();
// Fixing the corrupted <% site#history" %> macros
var skin = site.layout.skins.getSkin("Site", "page");
// Fixing the corrupted <% site#history" %> macros
var skin = site.layout.skins.getSkin("Site", "page");
var source = skin.getSource();
var newSource = source.replace(/<%(\s+site#(history|searchbox)"[^%]*%>)/g, function() {
var replacement = "<% // " + arguments[1];
app.log(arguments[0] + " ==> " + replacement);
return replacement;
});
if (newSource !== source) {
var delta = source.length - newSource.length;
//if (Math.abs(delta) > 5) res.debug("!!! Delta in " + site + ": " + delta);
skin.setSource(newSource);
}
// Fixing the macro handlers in skins shared between Story and Comment
["history", "rss", "result"].forEach(function(name) {
var skin = site.layout.skins.getSkin("Story", name);
var source = skin.getSource();
var newSource = source.replace(/<%(\s+site#(history|searchbox)"[^%]*%>)/g, function() {
var replacement = "<% // " + arguments[1];
app.log(arguments[0] + " ==> " + replacement);
return replacement;
});
if (newSource !== source) {
var delta = source.length - newSource.length;
//if (Math.abs(delta) > 5) res.debug("!!! Delta in " + site + ": " + delta);
skin.setSource(newSource);
if (!source) {
// FIXME: What the heck is going on here?
app.log("????? " + site.name + ": " + skin);
return;
}
// Fixing the macro handlers in skins shared between Story and Comment
["history", "rss", "result"].forEach(function(name) {
var skin = site.layout.skins.getSkin("Story", name);
var source = skin.getSource();
if (!source) {
// FIXME: What the heck is going on here?
app.log("????? " + site.name + ": " + skin);
return;
}
var newSource = source.replace(/(<%\s+)story\./g, function() {
var replacement = arguments[1] + "this.";
app.log(arguments[0] + " ==> " + replacement);
return replacement;
});
var delta = source.length - newSource.length;
if (delta !== 0) {
//if (Math.abs(delta) > 5) app.log("!!! Delta in " + site + " skin Story:" + name + ": " + delta);
skin.setSource(newSource);
}
var newSource = source.replace(/(<%\s+)story\./g, function() {
var replacement = arguments[1] + "this.";
app.log(arguments[0] + " ==> " + replacement);
return replacement;
});
var delta = source.length - newSource.length;
if (delta !== 0) {
//if (Math.abs(delta) > 5) app.log("!!! Delta in " + site + " skin Story:" + name + ": " + delta);
skin.setSource(newSource);
}
});
} else {
app.log("Creating missing layout for site " + site.name);
site.layout = new Layout(site);
}
app.log("Creating missing layout for site " + site.name);
site.layout = new Layout(site);
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,22 +26,22 @@
// Apply with enabled updater repository via ant patch -Dpatch.id=20081211
root.forEach(function() {
var site = this;
if (site.layout) {
res.handlers.layout = site.layout;
res.skinpath = site.layout.getSkinPath();
var site = this;
if (site.layout) {
res.handlers.layout = site.layout;
res.skinpath = site.layout.getSkinPath();
// Fixing the <% if <% comment.created %> %> macro
var skin = site.layout.skins.getSkin("Comment", "edit");
var source = skin.getSource();
var re = /(<%\s+if\s+<%\s+comment\.creat)ed(\s+%>\s+is\s+null)/g;
var newSource = source.replace(re, function() {
var replacement = arguments[1] + "or" + arguments[2];
app.log(arguments[0] + " ==> " + replacement);
return replacement;
});
if (newSource !== source) {
skin.setSource(newSource);
}
}
// Fixing the <% if <% comment.created %> %> macro
var skin = site.layout.skins.getSkin("Comment", "edit");
var source = skin.getSource();
var re = /(<%\s+if\s+<%\s+comment\.creat)ed(\s+%>\s+is\s+null)/g;
var newSource = source.replace(re, function() {
var replacement = arguments[1] + "or" + arguments[2];
app.log(arguments[0] + " ==> " + replacement);
return replacement;
});
if (newSource !== source) {
skin.setSource(newSource);
}
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -30,8 +30,8 @@ var template;
// Add deleted mode to site table
sql.execute("alter table antville.site change column mode mode \
enum('deleted','closed','restricted','public','open') \
character set latin1 collate latin1_general_ci default 'closed'");
enum('deleted','closed','restricted','public','open') \
character set latin1 collate latin1_general_ci default 'closed'");
// Rename user table to conform to standard SQL / Postgre specification
sql.execute("alter table antville.user rename to account");

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -30,15 +30,15 @@ var sql = new Sql;
// Correct Image.contentLength property for some images
sql.retrieve("select id from image");
sql.traverse(function() {
var image = Image.getById(this.id);
try {
var contentLength = image.getFile().getLength();
app.log("Processing " + image + ": " + image.contentLength);
if (contentLength && image.contentLength !== contentLength) {
app.log("Updating content length to " + contentLength);
image.contentLength = contentLength;
res.commit();
}
} catch (x) { }
var image = Image.getById(this.id);
try {
var contentLength = image.getFile().getLength();
app.log("Processing " + image + ": " + image.contentLength);
if (contentLength && image.contentLength !== contentLength) {
app.log("Updating content length to " + contentLength);
image.contentLength = contentLength;
res.commit();
}
} catch (x) { }
});
app.log("Done.");

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -34,25 +34,25 @@ var template;
// Afterwards user permissions should be restored:
// mysql -e "grant select, insert, update, delete on antville.* to 'antville'@'localhost'"
if (app.getDbSource("antville").isMySQL()) {
template = "alter table $0 modify column $1 varchar(20) default null";
sql.execute(template, "account", "status");
sql.execute(template, "content", "comment_mode");
sql.execute(template, "content", "mode");
sql.execute(template, "content", "parent_type");
sql.execute(template, "content", "prototype");
sql.execute(template, "content", "status");
sql.execute(template, "file", "prototype");
sql.execute(template, "file", "parent_type");
sql.execute(template, "image", "prototype");
sql.execute(template, "image", "parent_type");
sql.execute(template, "layout", "mode");
sql.execute(template, "log", "context_type");
sql.execute(template, "membership", "role");
sql.execute(template, "poll", "status");
sql.execute(template, "site", "status");
sql.execute(template, "site", "mode");
sql.execute(template, "tag", "type");
sql.execute(template, "tag_hub", "tagged_type");
template = "alter table $0 modify column $1 varchar(20) default null";
sql.execute(template, "account", "status");
sql.execute(template, "content", "comment_mode");
sql.execute(template, "content", "mode");
sql.execute(template, "content", "parent_type");
sql.execute(template, "content", "prototype");
sql.execute(template, "content", "status");
sql.execute(template, "file", "prototype");
sql.execute(template, "file", "parent_type");
sql.execute(template, "image", "prototype");
sql.execute(template, "image", "parent_type");
sql.execute(template, "layout", "mode");
sql.execute(template, "log", "context_type");
sql.execute(template, "membership", "role");
sql.execute(template, "poll", "status");
sql.execute(template, "site", "status");
sql.execute(template, "site", "mode");
sql.execute(template, "tag", "type");
sql.execute(template, "tag_hub", "tagged_type");
}
// Convert membership roles to lowercase
@ -64,7 +64,7 @@ sql.execute(template, 'owner', 'Owner');
// Convert notification modes to lowercase
root.forEach(function() {
if (this.notificationMode !== null) {
this.notificationMode = this.notificationMode.toLowerCase()
}
if (this.notificationMode !== null) {
this.notificationMode = this.notificationMode.toLowerCase()
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,20 +26,20 @@
// Apply with enabled updater repository via ant patch -Dpatch.id=20101209
root.forEach(function() {
var site = this;
var locale = site.locale;
// Update locales to new format
if (locale.contains("_")) {
site.locale = locale.substr(0, locale.lastIndexOf("_"));
}
// Update time zones to new format
var timeZone = site.timeZone;
switch (timeZone) {
case "CET":
site.timeZone = "Europe/Vienna";
break;
case "GMT":
site.timeZone = "Europe/London";
break;
}
var site = this;
var locale = site.locale;
// Update locales to new format
if (locale.contains("_")) {
site.locale = locale.substr(0, locale.lastIndexOf("_"));
}
// Update time zones to new format
var timeZone = site.timeZone;
switch (timeZone) {
case "CET":
site.timeZone = "Europe/Vienna";
break;
case "GMT":
site.timeZone = "Europe/London";
break;
}
});

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,7 +26,7 @@
// Apply with enabled updater repository via ant patch -Dpatch.id=20110209
if (!String(Root.VERSION).startsWith("1.2")) {
throw Error("This patch needs to be applied to version 1.2 of the Antville codebase.");
throw Error("This patch needs to be applied to version 1.2 of the Antville codebase.");
}
app.addRepository("modules/helma/Database.js");

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -26,7 +26,7 @@
// Apply with enabled updater repository via ant patch -Dpatch.id=20110210
if (Root.VERSION.minor < 1.3) {
throw Error("Please update the Antville codebase to version 1.3 first.");
throw Error("Please update the Antville codebase to version 1.3 first.");
}
app.addRepository("modules/helma/Database.js");
@ -34,40 +34,40 @@ app.addRepository("modules/helma/Database.js");
var sql = new Sql;
function convertMetadata(prototype, table) {
table || (table = prototype.name.toLowerCase());
table || (table = prototype.name.toLowerCase());
var start = 0;
var max, end;
var start = 0;
var max, end;
sql.retrieve("select max(id) as count from $0", table);
sql.traverse(function() {
max = this.count;
});
sql.retrieve("select max(id) as count from $0", table);
sql.traverse(function() {
max = this.count;
});
while (start < max) {
end = start + 1000;
sql.retrieve("select id, metadata from $0 where id >= $1 and id < $2", table, start, end);
sql.traverse(function() {
try {
var newMetadata;
var parent = prototype.getById(this.id);
var metadata = eval(this.metadata);
for (let name in metadata) {
let value = metadata[name];
parent.setMetadata(name, value);
}
} catch (ex) {
app.log("***** Original or converted metadata might not be kosher for " +
prototype.name + " #" + this.id);
app.log(ex.rhinoException);
}
});
res.commit();
start = end;
app.log(java.lang.String.format("Processed %.0f of %.0f %s objects", start, max, prototype.name));
}
while (start < max) {
end = start + 1000;
sql.retrieve("select id, metadata from $0 where id >= $1 and id < $2", table, start, end);
sql.traverse(function() {
try {
var newMetadata;
var parent = prototype.getById(this.id);
var metadata = eval(this.metadata);
for (let name in metadata) {
let value = metadata[name];
parent.setMetadata(name, value);
}
} catch (ex) {
app.log("***** Original or converted metadata might not be kosher for " +
prototype.name + " #" + this.id);
app.log(ex.rhinoException);
}
});
res.commit();
start = end;
app.log(java.lang.String.format("Processed %.0f of %.0f %s objects", start, max, prototype.name));
}
return;
return;
}
convertMetadata(File);

View file

@ -10,7 +10,7 @@
// 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
// 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,
@ -28,9 +28,9 @@
var sql = new Sql();
var sql2 = new Sql();
for each (let table in ["file", "image", "tag"]) {
sql.retrieve("select * from $0 where name like '%?%';", table);
sql.traverse(function() {
var name = "-".repeat(this.name.count("?"));
sql2.execute("update $0 set name = '$1' where id = $2", table, name, this.id);
});
sql.retrieve("select * from $0 where name like '%?%';", table);
sql.traverse(function() {
var name = "-".repeat(this.name.count("?"));
sql2.execute("update $0 set name = '$1' where id = $2", table, name, this.id);
});
}

View file

@ -10,7 +10,7 @@
// 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
// 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,

View file

@ -1,82 +1,82 @@
$(function() {
setLayoutMode();
// Extend jQuery with selectText() method.
$.fn.selectText = function() {
var element = this.get(0);
if (document.body.createTextRange) { // ms
var range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (window.getSelection) { // moz, opera, webkit
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
}
// Go back one step in history when clicking on links with the cancel class.
$("a.cancel").click(function(event) {
event.preventDefault();
history.back();
});
setLayoutMode();
// Select the macro code when clicking on elements with the macro-code class.
$('.macro-code').click(function(event) {
$(this).selectText();
});
// Extend jQuery with selectText() method.
$.fn.selectText = function() {
var element = this.get(0);
if (document.body.createTextRange) { // ms
var range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (window.getSelection) { // moz, opera, webkit
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
}
// Group related <option> elements by inserting additional <optgroup> elements.
var groups = [],
element = $("form#prefs #timeZone");
element.find("option").each(function(index, item) {
var zone = $(item),
parts = zone.html().split("/"), // E.g. Europe/Vienna
group = parts[0];
// Go back one step in history when clicking on links with the cancel class.
$("a.cancel").click(function(event) {
event.preventDefault();
history.back();
});
if ($.inArray(group, groups) < 0) {
groups.push(group);
}
});
groups.sort();
$.each(groups, function(index, group) {
var key = group + "/"; // E.g. Europe/
element.find("option:contains(" + key + ")")
.wrapAll($("<optgroup>").attr("label", group))
.each(function(index, item) {
$(item).html($(item).html().replace(key, ""));
});
});
// Select the macro code when clicking on elements with the macro-code class.
$('.macro-code').click(function(event) {
$(this).selectText();
});
// Group related <option> elements by inserting additional <optgroup> elements.
var groups = [],
element = $("form#prefs #timeZone");
element.find("option").each(function(index, item) {
var zone = $(item),
parts = zone.html().split("/"), // E.g. Europe/Vienna
group = parts[0];
if ($.inArray(group, groups) < 0) {
groups.push(group);
}
});
groups.sort();
$.each(groups, function(index, group) {
var key = group + "/"; // E.g. Europe/
element.find("option:contains(" + key + ")")
.wrapAll($("<optgroup>").attr("label", group))
.each(function(index, item) {
$(item).html($(item).html().replace(key, ""));
});
});
});
function setLayoutMode(mode) {
if (mode === false || $('.skin-control').length < 0) {
$('.skin-control').remove();
return;
}
/*$('body').prepend($('<div>').attr('class', 'layout-sandbox')
.append($('<div>')
.append($('<button>')
.html('Exit Sandbox')
.click(function() {
location.replace($('a[href$="sandbox"]').attr('href'));
}))));*/
$('.skin').each(function() {
var skinButton = $('<div class="skin-control"><a class="skin-edit-link">');
skinButton.find('a').attr({
href: $(this).data('href'),
title: 'Click to edit ' + $(this).data('name') + ' skin'
}).mouseover(function() {
$(this).parents('.skin').eq(0).addClass('active');
}).mouseout(function() {
$(this).parents('.skin').eq(0).removeClass('active');
}).html('Ⓢ');
$(this).append(skinButton);
});
if (mode === false || $('.skin-control').length < 0) {
$('.skin-control').remove();
return;
}
/*$('body').prepend($('<div>').attr('class', 'layout-sandbox')
.append($('<div>')
.append($('<button>')
.html('Exit Sandbox')
.click(function() {
location.replace($('a[href$="sandbox"]').attr('href'));
}))));*/
$('.skin').each(function() {
var skinButton = $('<div class="skin-control"><a class="skin-edit-link">');
skinButton.find('a').attr({
href: $(this).data('href'),
title: 'Click to edit ' + $(this).data('name') + ' skin'
}).mouseover(function() {
$(this).parents('.skin').eq(0).addClass('active');
}).mouseout(function() {
$(this).parents('.skin').eq(0).removeClass('active');
}).html('Ⓢ');
$(this).append(skinButton);
});
}
/**
@ -285,75 +285,75 @@ Antville = {};
Antville.prefix = "Antville_";
Antville.encode = function(str) {
var chars = ["&", "<", ">", '"'];
for (var i in chars) {
var c = chars[i];
var re = new RegExp(c, "g");
str = str.replace(re, "&#" + c.charCodeAt() + ";");
}
return str;
var chars = ["&", "<", ">", '"'];
for (var i in chars) {
var c = chars[i];
var re = new RegExp(c, "g");
str = str.replace(re, "&#" + c.charCodeAt() + ";");
}
return str;
}
Antville.decode = function(str) {
return str.replace(/&amp;/g, "&");
return str.replace(/&amp;/g, "&");
}
Antville.Referrer = function(url, text, count) {
this.url = url;
this.text = text;
this.count = count;
this.compose = function(key, prefix) {
var query = new Antville.Query(this.url);
if (query[key]) {
if (prefix == null)
prefix = "";
return prefix + Antville.encode(query[key]);
}
return this.text;
}
return this;
this.url = url;
this.text = text;
this.count = count;
this.compose = function(key, prefix) {
var query = new Antville.Query(this.url);
if (query[key]) {
if (prefix == null)
prefix = "";
return prefix + Antville.encode(query[key]);
}
return this.text;
}
return this;
}
Antville.Query = function(str) {
if (str == undefined)
var str = location.search.substring(1);
else if (str.indexOf("?") > -1)
var str = str.split("?")[1];
if (str == "")
return this;
var parts = Antville.decode(decodeURIComponent(str)).split("&");
for (var i in parts) {
var pair = parts[i].split("=");
var key = pair[0];
if (key) {
key = key.replace(/\+/g, " ");
var value = pair[1];
if (value)
value = value.replace(/\+/g, " ");
this[key] = value;
}
}
return this;
if (str == undefined)
var str = location.search.substring(1);
else if (str.indexOf("?") > -1)
var str = str.split("?")[1];
if (str == "")
return this;
var parts = Antville.decode(decodeURIComponent(str)).split("&");
for (var i in parts) {
var pair = parts[i].split("=");
var key = pair[0];
if (key) {
key = key.replace(/\+/g, " ");
var value = pair[1];
if (value)
value = value.replace(/\+/g, " ");
this[key] = value;
}
}
return this;
}
Antville.Filter = function(def, key) {
this.key = key;
if (def == null)
this.items = [];
else if (def instanceof Array)
this.items = def;
else
this.items = def.replace(/\r/g, "\n").split("\n");
this.test = function(str) {
if (!str)
return false;
str = str.replace(/&amp;/g, "&");
for (var n in this.items) {
var re = new RegExp(this.items[n], "i");
if (re.test(str))
return true;
}
this.key = key;
if (def == null)
this.items = [];
else if (def instanceof Array)
this.items = def;
else
this.items = def.replace(/\r/g, "\n").split("\n");
this.test = function(str) {
if (!str)
return false;
}
return this;
str = str.replace(/&amp;/g, "&");
for (var n in this.items) {
var re = new RegExp(this.items[n], "i");
if (re.test(str))
return true;
}
return false;
}
return this;
}

View file

@ -1,14 +1,14 @@
var tests = ["example"];
var setup = function() {
return;
return;
}
var cleanup = function() {
return;
return;
}
var example = function() {
assertEqual(1, 1);
return;
assertEqual(1, 1);
return;
}

View file

@ -3,72 +3,72 @@ var tests = ["set", "get", "remove"];
var user;
var setup = function() {
user = User.getById(1);
return;
user = User.getById(1);
return;
}
var cleanup = function() {
return;
return;
}
var set = function() {
assertThrows(function() {
user.setMetadata(null, 1);
});
user.setMetadata("array", [1,2,3]);
user.setMetadata("boolean", false);
user.setMetadata("date", new Date("1 Feb 2345, 06:07:08"));
user.setMetadata("float", 3.141);
user.setMetadata("function", function add(a,b,c) {return a+b+c});
user.setMetadata("integer", 123);
user.setMetadata("NaN", NaN);
user.setMetadata("null", null);
user.setMetadata("object", {a:1,b:2,c:3});
user.setMetadata("regexp", /^abc$/g);
user.setMetadata("string", "123");
user.setMetadata("undefined", undefined);
user.setMetadata({foo: "bar", bar: "foo"});
res.commit();
return;
assertThrows(function() {
user.setMetadata(null, 1);
});
user.setMetadata("array", [1,2,3]);
user.setMetadata("boolean", false);
user.setMetadata("date", new Date("1 Feb 2345, 06:07:08"));
user.setMetadata("float", 3.141);
user.setMetadata("function", function add(a,b,c) {return a+b+c});
user.setMetadata("integer", 123);
user.setMetadata("NaN", NaN);
user.setMetadata("null", null);
user.setMetadata("object", {a:1,b:2,c:3});
user.setMetadata("regexp", /^abc$/g);
user.setMetadata("string", "123");
user.setMetadata("undefined", undefined);
user.setMetadata({foo: "bar", bar: "foo"});
res.commit();
return;
}
var get = function() {
assertEqual(user.getMetadata("array").pop(), 3);
assertTrue(!user.getMetadata("boolean"));
assertEqual(user.getMetadata("date").getSeconds(), 8);
assertEqual(user.getMetadata("float"), 3.141);
assertEqual(user.getMetadata("function")(1,2,3), 6);
assertEqual(user.getMetadata("integer"), 123);
assertNaN(user.getMetadata("NaN"));
assertEqual(user.getMetadata("null"), null);
assertEqual(user.getMetadata("object").b, 2);
assertMatch("abc", user.getMetadata("regexp"));
assertEqual(user.getMetadata("string"), "123");
assertEqual(user.getMetadata("undefined"), null);
assertEqual(user.getMetadata("foo"), "bar");
assertEqual(user.getMetadata("bar"), "foo");
return;
assertEqual(user.getMetadata("array").pop(), 3);
assertTrue(!user.getMetadata("boolean"));
assertEqual(user.getMetadata("date").getSeconds(), 8);
assertEqual(user.getMetadata("float"), 3.141);
assertEqual(user.getMetadata("function")(1,2,3), 6);
assertEqual(user.getMetadata("integer"), 123);
assertNaN(user.getMetadata("NaN"));
assertEqual(user.getMetadata("null"), null);
assertEqual(user.getMetadata("object").b, 2);
assertMatch("abc", user.getMetadata("regexp"));
assertEqual(user.getMetadata("string"), "123");
assertEqual(user.getMetadata("undefined"), null);
assertEqual(user.getMetadata("foo"), "bar");
assertEqual(user.getMetadata("bar"), "foo");
return;
}
var remove = function() {
user.deleteMetadata("array");
res.commit();
assertNull(user.getMetadata("array"));
user.setMetadata({"boolean": null, date: null});
res.commit();
assertNull(user.getMetadata("boolean"));
assertNull(user.getMetadata("date"));
user.deleteMetadata("float", "function");
res.commit();
assertNull(user.getMetadata("float"));
assertNull(user.getMetadata("function"));
user.deleteMetadata();
res.commit();
assertNull(user.getMetadata("integer"));
assertNull(user.getMetadata("object"));
assertNull(user.getMetadata("regexp"));
assertNull(user.getMetadata("string"));
assertNull(user.getMetadata("foo"));
assertNull(user.getMetadata("bar"));
return;
user.deleteMetadata("array");
res.commit();
assertNull(user.getMetadata("array"));
user.setMetadata({"boolean": null, date: null});
res.commit();
assertNull(user.getMetadata("boolean"));
assertNull(user.getMetadata("date"));
user.deleteMetadata("float", "function");
res.commit();
assertNull(user.getMetadata("float"));
assertNull(user.getMetadata("function"));
user.deleteMetadata();
res.commit();
assertNull(user.getMetadata("integer"));
assertNull(user.getMetadata("object"));
assertNull(user.getMetadata("regexp"));
assertNull(user.getMetadata("string"));
assertNull(user.getMetadata("foo"));
assertNull(user.getMetadata("bar"));
return;
}