Programmatically adding PHP generated TypoScript to the backend configuration

Today I’ve struggled with adding PHP generated TypoScript configuration to the backend. There doesn’t seem to be an API for this, unfortunately, so I had to dig a little bit into the TYPO3 source.

Turns out that t3lib_befunc#getPagesTSconfig, which is responsible for retrieving TypoScript configuration for the backend, makes use of the following global variable as the “default TypoScript configuration”:

$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultPageTSconfig']

So, being short of a proper API, I ended up simply appending my generated configuration to the defaultPageTSconfig string (in my ext_localconf.php file).

Is there a better way to achieve the same thing? If so, let me know :)

ArgumentError: Could not parse PKey: no start line

After updating my net-ssh gem to 2.6.x I started getting this error message from Capistrano:

ArgumentError: Could not parse PKey: no start line

The private key in question was completely fine though, given that it had been working in several other applications, including openssh itself, for quite some time. There seem to be some weird issues with net-ssh 2.6.x and Capistrano at the moment, and so I simply downgraded to v2.5.2 and everything worked fine once again:

gem uninstall net-ssh
gem install net-ssh -v 2.5.2

Keep deploying :)

InstantiationException when creating Akka Actor

This post might help you if you get an exception such as the following when creating an Akka Actor with actorOf(Props[SomeActor]):

[ERROR] 15:32:44.249 :: akka://…/user/foo :: akka.actor.ActorCell :: error while creating actor
    java.lang.InstantiationException: package.of.SomeActor
    at java.lang.Class.newInstance0(Class.java:340)

The reason I got this error was simply because I didn’t have a constructor with zero arguments, that is, my Actor’s class signature looked like this:

class SomeActor(val attrs:Map[String, String] = Map()) extends Actor

I assumed that, since map has a default value, it would work just like a no-argument constructor, but that was foolish, of course. Akka invokes java.lang.Class.newInstance, which in turn calls java.lang.Class.newInstance0, which (as far as I know) is a special case of newInstance for constructors with no arguments. Given that this special case is not applicable for our Actor class, an exception is thrown.

I worked around this problem like this:

class SomeActor(val attrs:Map[String, String] = Map()) extends Actor {
    def this() = this(Map())
}

Why is my Akka Actor getting “deadLetters” as sender?

That is a question that kept my busy for almost an hour… I had an Actor defined like this (simplified, of course):

trait Foo { self: Actor =>
    []
}

class Bar extends Actor with Foo {
    []
    def receive = {
        case x => sender ! x
    }
}

Weirdly enough, when I was sending messages to that actor, the responses always came from the deadLetters Actor belonging to my actor system. The reason for this behavior was the fact that I used self as the name for the Foo trait’s self-type, because “There is already an implicit val self defined in Actor which refers to an actor’s own ActorRef”, and if you override that, well, it breaks.

Therefore, if I change my trait to read something like this

trait Foo { actor: Actor =>
    []
}

everything works as expected.

How to emulate a slow internet connection on Mac OS X

I found this note-to-self which explains how to do bandwidth and latency emulation on Mac OS X system wide, that is, independent of Chrome, Firefox, Safari or whatever browser you may be using.

It can be done using a “network pipe”, and it is relatively easy to find several detailed articles about its usage once you know the name. One of these articles is this one, which, apart from explaining the basic usage of network pipes, also lets us know that there is a GUI tool called “Network Link Conditioner” bundled with Xcode 4.2 for this very purpose.

Now go and optimize your app/website for low bandwidth conditions :)

Searching your Git history for a string or regular expression

Git seems to always have the feature I need, but often I’m not able to find it right away. While searching for a commit where a certain constant had been removed, I stumbled upon the deprecated git-diff-grep, which, in its readme, led me to the solution I could have easily found by just reading the, you know, manual (i.e. man git-log) :)

-S<string>
    Look for differences that introduce or remove an instance of
    <string>.Note that this is different than the string simply
    appearing in diff output; see the pickaxe entry in gitdiffcore(7)
    for more details.

-G<regex>
    Look for differences whose added or removed line matches the given
    <regex>.

Knowing that, you can simply do the following:

$ git log -S"WHERE_DID_IT_GO"
$ git log -G"WHERE_DID.*"

If you want to see the commit’s diff as well, just supply the -p option.

Cisco VPN Client on Mac OS X 10.6+ – You don’t need it!

My university provides us with VPN access, and the only supported way to connect to it is the Cisco VPN Client, which doesn’t work on any 64-bit Mac OS system though. If you still try to use it, you will most certainly be presented the following error:

Error 51 – unable to communicate with the subsystem

The Cisco VPN Client support is discontinued for good reason, though. As of Mac OS X 10.6, there is a built-in IPSec VPN feature, so you really don’t need any third party software anymore. And here’s how you use it:

  1. Open System Preferences > Network
    • You may need to click the “Unlock” button to make changes
  2. Click the plus sign above the lock button
    1. Select VPN in the Interface dropdown
    2. Choose Cisco IPSec as the VPN Type.
    3. Give it a descriptive “Service Name”
    4. Click “Create”

Now you’ve created a new VPN connection, but you still need to configure it. If you know all the necessary configuration parameters just go ahead an configure away. More probably though, you have a .pcf file which contains all the configuration. But don’t worry. First of all, open the .pcf configuration file in your favorite text editor. It should at least contain the following configuration parameters:

  • Host
  • GroupName
  • enc_GroupPwd

You’ll also need to know your username and password for the IPSec VPN. Enter the configuration value for “Host” into the “Server Address” field, and you username below it. Mac OS automatically prompts you for your password when connecting to the VPN.

Now click the Authentication Settings... button. Enter the “GroupName” found in the .pcf file into the “Group Name” field. Unfortunately you can’t directly copy the “enc_GroupPwd” into the “Shared Secret” field because it is “encrypted”. However, certain ways and means exist for getting the clear group password. Enter it into the “Shared Secret” field, and you’re done.

If I explained everything correctly, you should now be able to click the “Connect” button, to stop worrying about VPN configuration stuff and finally get back to work :)

Whenever Gem and Capistrano – Specifying the cronjob user

If you are using Capistrano in a project that relies on the Whenever gem to manage your crontab, it will update the crontab of the user that you use for your Capistrano deploys. So if, for example, you’d deploy with the user capistrano and your app runs under the user www-data, you could run into all sorts of trouble, e.g. permissions in case your cronjob creates new files.

Specifying the user under whom the cronjob command should be executed is relatively easy though. This mailing list entry tells us that we should add --user your_user as a parameter to the whenever command. The problem with that is that you don’t execute the command yourself, but the whenever gem’s Capistrano recipe does. So all we need to do is change the whenever_update_flags variable to meet our wishes. First the original line, and after that our modification:

# Old
_cset(:whenever_update_flags) { "–update-crontab #{fetch :whenever_identifier} –set #{fetch :whenever_variables}" }

# New
_cset(:whenever_update_flags) { "–update-crontab #{fetch :whenever_identifier} –set #{fetch :whenever_variables} –user www-data" }

You probably don’t want to change the whenever gem directly, so placing that line anywhere in the deploy.rb file should work just fine.

Multiple unapply methods for pattern matching in Scala

TLDR: Take my directly to the solution.

I found this nice trick on the Scala forums. Lets imagine we have a case class such as the following:

case class Foo(a:String, b:String, c:String = null, d:String = null)

This case class, as you probably know, can now be “pattern matched” like this:

Foo("foo", "bar", "baz", "wobble") match {
    case Foo("foo", b, _, _) => b
    case _ => "What?"
}

But what if, most of the time, you only need the first two arguments, and the others are mostly irrelevant for your pattern matching. You wouldn’t want to write Foo(a, _, _ ,_) all the time, right? One possibility would be to write the unapply(x:Foo) method yourself:

class Foo(val a:String, val b:String, val c:String = null, val d:String = null)

object Foo {
    def unapply(x:Foo): Option[(String, String)] = Some(x.a, x.b)
}

new Foo("foo", "bar", "baz", "wobble") match {
    case Foo("foo", b) => b
    case _ => "What?"
}

But what if you would like to use both unapply methods at some point? In that case you have to define multiple objects with different unapply methods, because unfortunately, unlike apply, unapply can’t be overloaded (because it always takes the the same argument).

So here is my approach to multiple unapply methods:

case class Foo(val a:String, val b:String, val c:String = null, val d:String = null)

object Foo_ {
    def unapply(x:Foo): Option[(String, String)] = Some(x.a, x.b)
}

new Foo("foo", "bar", "baz", "wobble") match {
    case Foo_("foo", b) => b
    case Foo(a, _, _, d) => (a, d)
    case _ => "What?"
}

While it isn’t exactly awesome because you have to introduce a new object Foo_, I like it better than always having to write out all 4 (or more) parameters.

If you have a better approach to this problem, please let me know :)

Teamspeak 3 installation script for Debian/Ubuntu

I installed a Teamspeak server today, and because I had a little time and wanted to brush up my bash scripting skills anyway, I coded a Teamspeak 3 server installation script that should work on most Debian systems (such as Ubuntu). Because of possible legal issues I didn’t include the download of the installation files itself in the script, so you’ll have to download those yourself (use either “Server amd64″ or “Server x86″ depending on your system).

After downloading the installation archive (don’t extract), you can execute the following to install your very own Teamspeak 3 server:

wget https://raw.github.com/gist/3730343/39db4465b5f7f97213f015bedb888e74c7db8526/install_teamspeak.sh && \
    chmod +x install_teamspeak.sh && \
    ./install_teamspeak.sh <insert path to installation archive here>

If you’d like to take a look at the script, don’t let me keep you. If you run into any problems, please leave me a comment :)