Programming

There are a lot of PHP Frameworks around. Altough it mostly makes sense to use one of those, they feel clumsy and overfilled with sometimes hundreds of files.

Luckily, I found a very simple MVC Framework which only does the basics of MVC and is simple enough so you can adjust and improve it easily to all your needs.

It’s simply called Nathan-MVC, you can find it over at github. There is also a slightly outdated blog series about each part available. The blog covers the concepts but the code from github should be used since there were some reasonable additions since the blog posts were written.

Together with my one-file-solution for data access (EntityDataAccess), you get a fairly manageable and easily extendable solution for website building in PHP.

I’ve started working with Elasticsearch and since I know Lucene internals quite well, I want to have a look at the files that Elasticsearch generates.

There’s a tool called Luke (Lucene Index Toolbox) to do that. There are multiple repositories with Luke:

  1. Original (abandoned?)
  2. Dmitry Kan Fork
  3. Ľuboš Koščo Fork

But since Elasticsearch uses it’s own codecs, it’s not possible to directly open the index with one of these Lukes.

To overcome this, the codecs need to be added to Luke.

I found an easy tutorial for this on Ross Simpsons blog.

Here’s a copy of the how-to:
1. Clone Dmitry’s Mavenized fork:

$ git clone https://github.com/DmitryKey/luke/

2. Add a dependency on your required version of Elasticsearch to the Luke project’s pom file:



    org.elasticsearch
    elasticsearch
    1.3.0

3. Compile the Luke jar file (creates target/luke-with-deps.jar):

$ mvn package

4. Unpack Luke’s list of known postings formats to a temporary file:

$ unzip target/luke-with-deps.jar META-INF/services/org.apache.lucene.codecs.PostingsFormat -d ./tmp/
Archive:  target/luke-with-deps.jar
  inflating: ./tmp/META-INF/services/org.apache.lucene.codecs.PostingsFormat

5. Add the ElasticSearch postings formats to the temp file:

$ echo "org.elasticsearch.index.codec.postingsformat.BloomFilterPostingsFormat" \
    >> ./tmp/META-INF/services/org.apache.lucene.codecs.PostingsFormat
$ echo "org.elasticsearch.index.codec.postingsformat.Elasticsearch090PostingsFormat" \
    >> ./tmp/META-INF/services/org.apache.lucene.codecs.PostingsFormat
$ echo "org.elasticsearch.search.suggest.completion.Completion090PostingsFormat" \
    >> ./tmp/META-INF/services/org.apache.lucene.codecs.PostingsFormat\

6. Repack the modified file back into the jar:

$ jar -uf target/luke-with-deps.jar -C tmp/ META-INF/services/org.apache.lucene.codecs.PostingsFormat

7. Run Luke

$ ./luke.sh

That’s it.
And for all the lazy people out there, here’s the prepared Luke 4.9.0 with dependencies for Elasticsearch 1.3.0 (luke-with-deps-es-4.9.0).

Following code will remove all non-printable characters from a string.

 StringBuilder cleanString = new StringBuilder();
 foreach (char character in inputString)
 {
     if (Char.IsControl(character))
     {
         if (Char.IsWhiteSpace(character))
         {
             cleanString.Append(" ");
         }
         continue;
     }
     cleanString.Append(character);
 }

I’m using Selenium for some browser-controlling stuff and mostly use Chrome with the ChromeDriver. But in Version 2.x, ChromeDriver only takes screenshots for the visible area of the screen.

So I created a Script in C# which scrolls around the page, taking screenshots and then stitches it all together.

The code should be easy to port into other languages.

// Get the Total Size of the Document
int totalWidth = (int)EvalScript("return document.width");
int totalHeight = (int)EvalScript("return document.height");

// Get the Size of the Viewport
int viewportWidth = (int)EvalScript("return document.body.clientWidth");
int viewportHeight = (int)EvalScript("return document.body.clientHeight");

// Split the Screen in multiple Rectangles
List rectangles = new List();
// Loop until the Total Height is reached
for (int i = 0; i < totalHeight; i += viewportHeight)
{
	int newHeight = viewportHeight;
	// Fix if the Height of the Element is too big
	if (i + viewportHeight > totalHeight)
	{
		newHeight = totalHeight - i;
	}
	// Loop until the Total Width is reached
	for (int ii = 0; ii < totalWidth; ii += viewportWidth)
	{
		int newWidth = viewportWidth;
		// Fix if the Width of the Element is too big
		if (ii + viewportWidth > totalWidth)
		{
			newWidth = totalWidth - ii;
		}

		// Create and add the Rectangle
		Rectangle currRect = new Rectangle(ii, i, newWidth, newHeight);
		rectangles.Add(currRect);
	}
}

// Build the Image
var stitchedImage = new Bitmap(totalWidth, totalHeight);
// Get all Screenshots and stitch them together
Rectangle previous = Rectangle.Empty;
foreach (var rectangle in rectangles)
{
	// Calculate the Scrolling (if needed)
	if (previous != Rectangle.Empty)
	{
		int xDiff = rectangle.Right - previous.Right;
		int yDiff = rectangle.Bottom - previous.Bottom;
		// Scroll
		RunScript(String.Format("window.scrollBy({0}, {1})", xDiff, yDiff));
		System.Threading.Thread.Sleep(200);
	}

	// Take Screenshot
	var screenshot = ((ITakesScreenshot)_driver).GetScreenshot();

	// Build an Image out of the Screenshot
	Image screenshotImage;
	using (MemoryStream memStream = new MemoryStream(screenshot.AsByteArray))
	{
		screenshotImage = Image.FromStream(memStream);
	}

	// Calculate the Source Rectangle
	Rectangle sourceRectangle = new Rectangle(viewportWidth - rectangle.Width, viewportHeight - rectangle.Height, rectangle.Width, rectangle.Height);

	// Copy the Image
	using (Graphics g = Graphics.FromImage(stitchedImage))
	{
		g.DrawImage(screenshotImage, rectangle, sourceRectangle, GraphicsUnit.Pixel);
	}

	// Set the Previous Rectangle
	previous = rectangle;
}
// The full Screenshot is now in the Variable "stitchedImage"

The EvalScript just executes the Javascript and returns the Value, so it should look like:

public override T EvalScript(string script)
{
	IJavaScriptExecutor js = (IJavaScriptExecutor)_driver;
	return (T)js.ExecuteScript(script);
}

Facebook provides a Like Box to show on your Website, what’s going on on your facebook page.

A nice way to show this box is by a simple tab on the left or right which (on mouseover) slides in this box.

Here’s an easy script to implement this on your page.

Following steps are needed to implement this:

1. Upload the Images for the Facebook Text-Logo
Image Left
Image Right

2. Add the jQuery Script to your page

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

3. Add the CSS Styles

<style type='text/css'>
/*<![CDATA[*/
#fbplikebox {
	display: block;
	padding: 0;
	z-index: 99999;
	position: fixed;
}
.fbplbadgeright {
	background-color:#3B5998;
	display: block;
	height: 150px;
	top: 50%;
	margin-top: -75px;
	position: absolute;
	left: -47px;
	width: 47px;
	background-image: url('fbtext_right.png');
	background-repeat: no-repeat;
	overflow: hidden;
	-webkit-border-top-left-radius: 8px;
	-webkit-border-bottom-left-radius: 8px;
	-moz-border-radius-topleft: 8px;
	-moz-border-radius-bottomleft: 8px;
	border-top-left-radius: 8px;
	border-bottom-left-radius: 8px;
}
.fbplbadgeleft {
	background-color:#3B5998;
	display: block;
	height: 150px;
	top: 50%;
	margin-top: -75px;
	position: absolute;
	right: -47px;
	width: 47px;
	background-image: url('fbtext_left.png');
	background-repeat: no-repeat;
	overflow: hidden;
	-webkit-border-top-right-radius: 8px;
	-webkit-border-bottom-right-radius: 8px;
	-moz-border-radius-topright: 8px;
	-moz-border-radius-bottomright: 8px;
	border-top-right-radius: 8px;
	border-bottom-right-radius: 8px;
}
/*]]>*/
</style>

4. Add the Javascript

<script type='text/javascript'>
/*<![CDATA[*/
    (function(w2b){
        w2b(document).ready(function(){
			var fromRight = false;
			var topPosition = 50;
			var logoPosition = 150;
			var elementWidth = 292;
            var $dur = 'medium';
			
			// Set the Tab Position
			$("#fbplikeboxlogo").css("top", logoPosition);
			
			if (fromRight) {
				$("#fbplikeboxlogo").addClass("fbplbadgeright");
				w2b('#fbplikebox').css({right: -elementWidth, 'top' : topPosition })
				w2b('#fbplikebox').hover(function () {
					w2b(this).stop().animate({
						right: 0
					}, $dur);
				}, function () {
					w2b(this).stop().animate({
						right: -elementWidth
					}, $dur);
				});
			} else {
				$("#fbplikeboxlogo").addClass("fbplbadgeleft");
				w2b('#fbplikebox').css({left: -elementWidth, 'top' : topPosition })
				w2b('#fbplikebox').hover(function () {
					w2b(this).stop().animate({
						left: 0
					}, $dur);
				}, function () {
					w2b(this).stop().animate({
						left: -elementWidth
					}, $dur);
				});
			}
			w2b('#fbplikebox').show();
        });
    })(jQuery);
/*]]>*/
</script>

5. Add the Content

<div id='fbplikebox' style='display:none;'>
    <div id='fbplikeboxlogo'></div> 
	<iframe src="http://www.facebook.com/plugins/likebox.php?href=https%3A%2F%2Fwww.facebook.com%2FFacebookDevelopers&amp;width=292&amp;height=590&amp;colorscheme=light&amp;show_faces=true&amp;header=true&amp;stream=true&amp;show_border=true" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:292px; height:590px; background:#FFFFFF;" allowTransparency="true"></iframe>
</div>

There you go, that is all. Here’s a working examle:
facebookslide

There are some configuration variables at the top of the javascript:

Name Function
fromRight Defines if the tab is on the left or on the right
topPosition The space from the top of the page before the box starts
logoPosition The space from the top where the tab appears
elementWidth The width of the facebook box

Sometimes, you want to get the XPath of an element. Here are two working solutions, one in pure XSLT and one in C#.
Both of them return XPath in the form of: /html[1]/body[1]/div[1]/div[2]/div[3]/div[1]/p[2]/img[1]

C#

/// <summary>
/// Gets the X-Path to a given Node
/// </summary>
/// <param name="node">The Node to get the X-Path from</param>
/// <returns>The X-Path of the Node</returns>
public string GetXPathToNode(XmlNode node)
{
	if (node.NodeType == XmlNodeType.Attribute)
	{
		// attributes have an OwnerElement, not a ParentNode; also they have             
		// to be matched by name, not found by position             
		return String.Format("{0}/@{1}", GetXPathToNode(((XmlAttribute)node).OwnerElement), node.Name);
	}
	if (node.ParentNode == null)
	{
		// the only node with no parent is the root node, which has no path
		return "";
	}

	// Get the Index
	int indexInParent = 1;
	XmlNode siblingNode = node.PreviousSibling;
	// Loop thru all Siblings
	while (siblingNode != null)
	{
		// Increase the Index if the Sibling has the same Name
		if (siblingNode.Name == node.Name)
		{
			indexInParent++;
		}
		siblingNode = siblingNode.PreviousSibling;
	}

	// the path to a node is the path to its parent, plus "/node()[n]", where n is its position among its siblings.         
	return String.Format("{0}/{1}[{2}]", GetXPathToNode(node.ParentNode), node.Name, indexInParent);
}

XSLT

  <xsl:template name="GeneratePath">
	<xsl:param name="node" select="." />
	<xsl:message terminate="no">
	  <xsl:copy-of select="$node"/>
	</xsl:message>
	<xsl:apply-templates select="$node" mode="StartGeneratePath" />
  </xsl:template>

  <xsl:template match="*" mode="StartGeneratePath">
	<xsl:call-template name="genPath" />
  </xsl:template>
  
  <xsl:template name="genPath">
	<xsl:param name="prevPath"/>
	<xsl:variable name="currPath" select="concat('/',name(),'[',count(preceding-sibling::*[name() = name(current())])+1,']',$prevPath)"/>
	<xsl:for-each select="parent::*">
	  <xsl:call-template name="genPath">
		<xsl:with-param name="prevPath" select="$currPath"/>
	  </xsl:call-template>
	</xsl:for-each>
	<xsl:if test="not(parent::*)">
	  <xsl:value-of select="$currPath"/>
	</xsl:if>
  </xsl:template>

XSLT-Usage

<xsl:variable name="path">
  <xsl:call-template name="GeneratePath">
	<xsl:with-param name="node" select="./div[@class='eintrag2']//img[1]"/>
  </xsl:call-template>
</xsl:variable>

This error has greeted me several times before in the past when working with Msysgit on Windows. It alway appears for no apparent reason; sometimes from one boot to the next, and sometimes it suddenly starts happening while the system is running. Once the error is there, it stays consistently at the very least until the next reboot. Sometimes it only happens for specific commands like “git log”, sometimes it seems to affect every cygwin command.
Continue reading Msysgit couldn’t reserve space for cygwin’s heap

Yesterday, I listened to an episode of the .NET Rocks podcast featuring Scott Hanselman and Chris Sells talking about HTML and JavaScript in today’s modern web. While the episode is essentially hysterically funny and I quite like Hanselman and his (at times) extremely helpful blog posts, there is a lot in this particular episode that rubbed me the wrong way and I somehow need to get this off my chest.
Continue reading Why “Browser OS” is a stupid idea