Block commit to SVN when Redmine issue is not specified

Redmine allows to reference commits to issues by using keyword refs followed by # and number of the issue. If you want to block user commit to SVN without specifying Redmine issue you can use similar pre-commit hook on SVN. The hook is for Windows version.


@ECHO OFF

REM *************************************************************
REM * this sets the arguments supplied by Subversion *
REM *************************************************************
SET REPOS=%1
SET TXN=%2

REM *************************************************************
REM * define directory paths *
REM * you *must* add any paths for command line tools you plan *
REM * since SVN does not include the Windows %PATH% environment *
REM * variable for security reasons. *
REM * *
REM * DIR - the current hooks directory *
REM * PATH - a user set path of where executables are located *
REM * *
REM *************************************************************
SET DIR=%REPOS%hooks

REM *************************************************************
REM * make sure to add the path to the SendEmail executable *
REM *************************************************************
SET PATH=%PATH%;%DIR%

REM *************************************************************
REM * get comment search for "refs #" *
REM *************************************************************
svnlook log -t "%TXN%" "%REPOS%" | findstr /c:"refs #" > NUL
IF %errorlevel% NEQ 0 GOTO Error

GOTO Success

:Error
ECHO. 1>&2
ECHO Your commit has been blocked because you didn't 1>&2
ECHO specify Redmine issue with refs keyword. 1>&2
ECHO Please write a log message (eg. refs #123) and 1>&2
ECHO then try committing again. -- Thank you Roman 1>&2
EXIT 1

:Success

Hide images from the Plone’s Tabular View

It is easily possible to hide images from the navigation port-let using control panel, but I did not find similar option for the Tabular View when a folder contents is displayed.
So here is the solution I have applied.

  1. Login to Zope Management interface
  2. Go to /…/portal_skins/plone_content and create a custom version of folder_tabular_view
  3. In the customized version of the folder_tabular_view locate “class python:test(oddrow, ‘even’, ‘odd’)” and change it to “class python:test(oddrow, ‘even tr-‘ + item_type_class, ‘odd tr-‘ + item_type_class)
  4. After these changes TR tag of the folder contents table will have an additional CSS class which we can use to hide unwanted content types
  5. Save the changes and edit customized CSS file called ploneCustom.css
  6. Add “.tr-contenttype-image { display: none; }” to hide rows with image content types

HtmlDecode inside SQLCLR without System.Web reference

I grabbed code from the WebUtility class which is available in System.Net of the .NET Framework 4.0. Can be compiled inside .NET 2.0.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace System.Net
{
public static class WebUtility
{
private static class HtmlEntities
{
private static string[] _entitiesList = new string[]
{
""-quot",
"&-amp",
"'-apos",
"<-lt>-gt",
"u00a0-nbsp",
"¡-iexcl",
"¢-cent",
"£-pound",
"¤-curren",
"¥-yen",
"¦-brvbar",
"§-sect",
"¨-uml",
"©-copy",
"ª-ordf",
"«-laquo",
"¬-not",
"­-shy",
"®-reg",
"¯-macr",
"°-deg",
"±-plusmn",
"²-sup2",
"³-sup3",
"´-acute",
"µ-micro",
"¶-para",
"·-middot",
"¸-cedil",
"¹-sup1",
"º-ordm",
"»-raquo",
"¼-frac14",
"½-frac12",
"¾-frac34",
"¿-iquest",
"À-Agrave",
"Á-Aacute",
"Â-Acirc",
"Ã-Atilde",
"Ä-Auml",
"Å-Aring",
"Æ-AElig",
"Ç-Ccedil",
"È-Egrave",
"É-Eacute",
"Ê-Ecirc",
"Ë-Euml",
"Ì-Igrave",
"Í-Iacute",
"Î-Icirc",
"Ï-Iuml",
"Ð-ETH",
"Ñ-Ntilde",
"Ò-Ograve",
"Ó-Oacute",
"Ô-Ocirc",
"Õ-Otilde",
"Ö-Ouml",
"×-times",
"Ø-Oslash",
"Ù-Ugrave",
"Ú-Uacute",
"Û-Ucirc",
"Ü-Uuml",
"Ý-Yacute",
"Þ-THORN",
"ß-szlig",
"à-agrave",
"á-aacute",
"â-acirc",
"ã-atilde",
"ä-auml",
"å-aring",
"æ-aelig",
"ç-ccedil",
"è-egrave",
"é-eacute",
"ê-ecirc",
"ë-euml",
"ì-igrave",
"í-iacute",
"î-icirc",
"ï-iuml",
"ð-eth",
"ñ-ntilde",
"ò-ograve",
"ó-oacute",
"ô-ocirc",
"õ-otilde",
"ö-ouml",
"÷-divide",
"ø-oslash",
"ù-ugrave",
"ú-uacute",
"û-ucirc",
"ü-uuml",
"ý-yacute",
"þ-thorn",
"ÿ-yuml",
"Œ-OElig",
"œ-oelig",
"Š-Scaron",
"š-scaron",
"Ÿ-Yuml",
"ƒ-fnof",
"ˆ-circ",
"˜-tilde",
"Α-Alpha",
"Β-Beta",
"Γ-Gamma",
"Δ-Delta",
"Ε-Epsilon",
"Ζ-Zeta",
"Η-Eta",
"Θ-Theta",
"Ι-Iota",
"Κ-Kappa",
"Λ-Lambda",
"Μ-Mu",
"Ν-Nu",
"Ξ-Xi",
"Ο-Omicron",
"Π-Pi",
"Ρ-Rho",
"Σ-Sigma",
"Τ-Tau",
"Υ-Upsilon",
"Φ-Phi",
"Χ-Chi",
"Ψ-Psi",
"Ω-Omega",
"α-alpha",
"β-beta",
"γ-gamma",
"δ-delta",
"ε-epsilon",
"ζ-zeta",
"η-eta",
"θ-theta",
"ι-iota",
"κ-kappa",
"λ-lambda",
"μ-mu",
"ν-nu",
"ξ-xi",
"ο-omicron",
"π-pi",
"ρ-rho",
"ς-sigmaf",
"σ-sigma",
"τ-tau",
"υ-upsilon",
"φ-phi",
"χ-chi",
"ψ-psi",
"ω-omega",
"ϑ-thetasym",
"ϒ-upsih",
"ϖ-piv",
"u2002-ensp",
"u2003-emsp",
"u2009-thinsp",
"‌-zwnj",
"‍-zwj",
"‎-lrm",
"‏-rlm",
"–-ndash",
"—-mdash",
"‘-lsquo",
"’-rsquo",
"‚-sbquo",
"“-ldquo",
"”-rdquo",
"„-bdquo",
"†-dagger",
"‡-Dagger",
"•-bull",
"…-hellip",
"‰-permil",
"′-prime",
"″-Prime",
"‹-lsaquo",
"›-rsaquo",
"‾-oline",
"⁄-frasl",
"€-euro",
"ℑ-image",
"℘-weierp",
"ℜ-real",
"™-trade",
"ℵ-alefsym",
"←-larr",
"↑-uarr",
"→-rarr",
"↓-darr",
"↔-harr",
"↵-crarr",
"⇐-lArr",
"⇑-uArr",
"⇒-rArr",
"⇓-dArr",
"⇔-hArr",
"∀-forall",
"∂-part",
"∃-exist",
"∅-empty",
"∇-nabla",
"∈-isin",
"∉-notin",
"∋-ni",
"∏-prod",
"∑-sum",
"−-minus",
"∗-lowast",
"√-radic",
"∝-prop",
"∞-infin",
"∠-ang",
"∧-and",
"∨-or",
"∩-cap",
"∪-cup",
"∫-int",
"∴-there4",
"∼-sim",
"≅-cong",
"≈-asymp",
"≠-ne",
"≡-equiv",
"≤-le",
"≥-ge",
"⊂-sub",
"⊃-sup",
"⊄-nsub",
"⊆-sube",
"⊇-supe",
"⊕-oplus",
"⊗-otimes",
"⊥-perp",
"⋅-sdot",
"⌈-lceil",
"⌉-rceil",
"⌊-lfloor",
"⌋-rfloor",
"〈-lang",
"〉-rang",
"◊-loz",
"♠-spades",
"♣-clubs",
"♥-hearts",
"♦-diams"
};
private static Dictionary _lookupTable = WebUtility.HtmlEntities.GenerateLookupTable();
private static Dictionary GenerateLookupTable()
{
Dictionary dictionary = new Dictionary(StringComparer.Ordinal);
string[] entitiesList = WebUtility.HtmlEntities._entitiesList;
for (int i = 0; i < entitiesList.Length; i++)
{
string text = entitiesList[i];
dictionary.Add(text.Substring(2), text[0]);
}
return dictionary;
}
public static char Lookup(string entity)
{
char result;
WebUtility.HtmlEntities._lookupTable.TryGetValue(entity, out result);
return result;
}
}
private static char[] _htmlEntityEndingChars = new char[]
{
';',
'&'
};
public static string HtmlDecode(string value)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
if (value.IndexOf('&') < 0)
{
return value;
}
StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
WebUtility.HtmlDecode(value, stringWriter);
return stringWriter.ToString();
}
public static void HtmlDecode(string value, TextWriter output)
{
if (value == null)
{
return;
}
if (output == null)
{
throw new ArgumentNullException("output");
}
if (value.IndexOf('&') < 0)
{
output.Write(value);
return;
}
int length = value.Length;
int i = 0;
while (i < length)
{
char c = value[i];
if (c != '&')
{
goto IL_110;
}
int num = value.IndexOfAny(WebUtility._htmlEntityEndingChars, i + 1);
if (num <= 0 || value[num] != ';')
{
goto IL_110;
}
string text = value.Substring(i + 1, num - i - 1);
if (text.Length > 1 && text[0] == '#')
{
ushort num2;
if (text[1] == 'x' || text[1] == 'X')
{
ushort.TryParse(text.Substring(2), NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out num2);
}
else
{
ushort.TryParse(text.Substring(1), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out num2);
}
if (num2 != 0)
{
c = (char)num2;
i = num;
goto IL_110;
}
goto IL_110;
}
else
{
i = num;
char c2 = WebUtility.HtmlEntities.Lookup(text);
if (c2 != '')
{
c = c2;
goto IL_110;
}
output.Write('&');
output.Write(text);
output.Write(';');
}
IL_117:
i++;
continue;
IL_110:
output.Write(c);
goto IL_117;
}
}
}
}

OpenOffice service init.d script for CentOS

This script will start soffice headless listening on port 8100. You can use it eg. with JODConverter.

#!/bin/bash
# openoffice.org headless server script
#
# chkconfig: 2345 80 30
# description: headless openoffice server script
# processname: openoffice
#
OOo_HOME=/usr/bin
SOFFICE_PATH=$OOo_HOME/soffice
PIDFILE=/var/run/openoffice-server.pid

set -e

case "$1" in
start)
if [ -f $PIDFILE ]; then
echo "OpenOffice headless server has already started."
sleep 5
exit
fi
echo "Starting OpenOffice headless server"
$SOFFICE_PATH -nologo -nodefault -norestore -nocrashreport -nolockcheck -headless -nofirststartwizard -accept="socket,host=localhost,port=8100;urp" & > /dev/null 2>&1
touch $PIDFILE
;;
stop)
if [ -f $PIDFILE ]; then
echo "Stopping OpenOffice headless server."
killall -9 soffice && killall -9 soffice.bin
rm -f $PIDFILE
exit
fi
echo "Openoffice headless server is not running."
exit
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0

Hosting ClickOnce application on Amazon S3

When hosting ClickOnce applications on Amazon S3 you might notice download problems on some versions of Internet Explorer. Although other browsers does not have problems downloading ClickOnce .application file, Internet Explorer complains with “The requested site is either unavailable or cannot be found.”.

The problem is most probably in the Content-Type of the .application file. It is set to application/binary, but should be application/x-ms-application. To fix it, you have to connect to S3 Management Console and fix the Content-Type under file Properties.