Monthly Archives: December 2013

ht_chromecast_nt_130724_16x9_992

Google Chromecast in a South African context

I had my Google Chromecast delivered from a local supplier last night, and thought that I would write a quick post on my experiences so far.

Seeing as though I have already had a large number of requests as to where I got it, I will answer that question first. I bought it from Takealot.com on the following URL http://www.takealot.com/tv-audio-video/google-chromecast-hdmi-streaming-media-player,29924636

Right, so the first thing that you need to do is plug the chromecast into a free HDMI port on your TV. Great. Easy enough. The box comes with an external power adapter as well as a USB adapter to power the device, but the external power plug is a US plug. Oops. Useless. USB power it is then! I would have liked to use the external power, simply for the fact that the TV does not have to be on for me to queue up online videos to the device, but alas, unless you are willing to screw around with clumsy power adapters and transformers, forget about it. The USB cable plugged into one of the TV USB slots and powered up the device without issue.

You are presented with a beautiful wallpaper and a device name, with the instruction to go and finish setup by connecting to your new Chromecast with an Android device or a laptop.

I tried to complete setup immediately with my Samsung Galaxy S4, having to download the Chromecast app from the Play store beforehand, which failed. I then tried to set up using my laptop computer, and was told by Google that I was using an unsupported OS (Linux), but I could try anyway. That failed too. Hum…

I then had a bit of an idea, and checked that uPnP was enabled on my (admittedly very old) wifi router, and enabled that. It would have been nice if that little caveat was covered in the intro screen, but it wasn’t. I use MAC address filtering to limit wifi access at home to specific devices, and one thing that I really did appreciate is that the Chromecast device displayed its MAC address on the setup page by default.

The setup, once started, becomes somewhat fiddly. My S4 has decided that a wifi connection is unworthy if it cannot reach the internet, and this was a big problem in completing the setup. I resorted to my laptop again, and managed to get through the steps after having to (confusingly) change wifi networks mid way to properly configure the device.

The device will not connect properly to anything but a 2.4GHz wifi network, so keep that in mind too.

I did have to do each of the steps a couple of times in order for the device to recognise my network and install itself properly, but once that was done, it was pretty plain sailing thereafter.

I immediately was able to stream a YouTube video to the TV in full HD without a glitch. The coolest part was that in the Chrome browser, I installed the Chromecast extension and was able to share not only a specific browser tab to the TV, but also my entire screen. There was some noticeable lag (about 500ms) when playing Kerbal Space Program via the network, but for a very graphics intensive app, and on a not-so-great wifi router, it was rather impressive (and still completely playable).

The apps that Google use to sell you the Chromecast (Netflix, Hulu etc.) are great, but not available in South Africa. Sure, I know that you can get a Netflix account (illegally) by spoofing a DNS service to make it look like you are in the US or UK, but the Chromecast has a trick up its sleeve. Google DNS services are hard coded into the device, so, even with a service like that, you would still need some trickery to get it right.

On the other hand, however, DStv BoxOffice works beautifully via a Chrome browser window, and you are able to enjoy the entire Online catalogue at R30 a movie, even if you are not a subscriber! To me, that is well worth the purchase price, as you are not entitled to pay a subscription, and you can rent when you want to. It is way cheaper for a family to grab a BoxOffice movie in this manner than it is to go to the cinema!

Overall, I think that the device is well worth getting (if you don’t already have an XBMC device or similar), although the price could come down a little in my opinion. There is a LOT of potential here, and I do think that we are only seeing the beginnings of something here for TV viewing.

The ultimate best awesome crazy cool killer feature of this device, though completely undocumented, is for people that do a lot of presentations. If you are a regular speaker, you will know that fiddling with projectors and screens on your laptop can quickly become a nightmare. I would suggest getting one of these things to pop into your laptop bag, and carry around with you. When you need to give a talk, simply plug it in and cast your presentation, saving a lot of time and stress!

I don’t normally do reviews like this, so I don’t really know how to end it off, but, yeah, get one of these things, they are OK tending towards good. In the future, depending on the climate, they may be awesome.

 

How to truncate multiple MongoDB collections in a Database

MongoDB has a drop() command that you can use to delete everything in a certain collection, but this also, unfortunately, will drop your indexes and other things too. What I wanted was a way that I could “truncate” the collection (borrowing from MySQL) and retain the indexes etc too.

The following snippet will do that, plus it has a built in “Oops, I changed my mind” safety check in case you need to cancel the collection truncate command.

var dbName = 'myDB';
db.getSiblingDB(dbName).getCollectionNames().forEach(function(collName) {
    // Drop all collections except system ones (indexes/profile)
    if (!collName.startsWith("system.")) {
        // Safety net
        print("WARNING: going to drop ["+dbName+"."+collName+"] in 5s .. hit Ctrl-C if you've changed your mind!");
        sleep(5000);
        db[collName].drop();
    }
})

This would be best saved as a UDF in your mongo shell, and probably made to take a parameter for the db too…

Spring data Neo4j using Java based config

There are very few examples in the wild on using Spring’s Java config methods to configure and start a Neo4j Graph Database service to use in your application. This post will serve as a primer to get you started on your Neo4j application and hopefully save you some bootstrap time as well!

The first thing that we need to do is make sure that you have a running Neo4j server up and ready for action, as well as a new Spring project that you can start with.

In your project POM XML file, you need to add in a few dependencies to work with Neo4j. In this example, I have used Neo4j-1.9.5-community (Spring Data Neo4j for Neo4j-2.x was not available at the time of writing). I have used Spring Framework 3.2.3-RELEASE as the Spring version, and Sping-data-Neo4j-2.3.2-RELEASE.

<dependencies>
		<!-- Spring and Transactions -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>

		<!-- Logging with SLF4J & LogBack  // clipped... -->
                <!-- JavaConfig needs this library -->
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>

		<!-- Test Artifacts // clipped -->
                <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
                <dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.0-api</artifactId>
			<version>1.0.1.Final</version>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.0.0.GA</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-neo4j-aspects</artifactId>
            <version>${spring-data-neo4j.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.hibernate.javax.persistence</groupId>
                    <artifactId>hibernate-jpa-2.0-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-neo4j-rest</artifactId>
			<version>${spring-data-neo4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.mojo</groupId>
			<artifactId>aspectj-maven-plugin</artifactId>
			<version>1.2</version>
			<type>maven-plugin</type>
		</dependency>
	</dependencies>

NOTE: I have clipped some of the less relevant bits for testing and standard Spring dependencies, but if you would like a full POM example, please just let me know!

The next big thing is that you now need to define your graphDatabaseService as a bean that you can then use via the @Autowired annotation in the rest of your code.

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
import org.springframework.data.neo4j.aspects.config.Neo4jAspectConfiguration;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;

@Configuration
@Import(Neo4jAspectConfiguration.class)
@EnableTransactionManagement
@EnableNeo4jRepositories("com.company.your.repos")
@EnableSpringConfigured
public class AppConfig extends Neo4jConfiguration {

	@Bean
	public GraphDatabaseService graphDatabaseService() {
                // if you want to use Neo4j as a REST service
		//return new SpringRestGraphDatabase("http://localhost:7474/db/data/");
                // Use Neo4j as Odin intended (as an embedded service)
		GraphDatabaseService service = new GraphDatabaseFactory().newEmbeddedDatabase("/tmp/graphdb");
		return service;
	}

Great! You are just about done! Now create a simple entity with the @NodeEntity annotation and save some data to it! You now have a working graph application!

This is really easy once you know how, sometimes, though, getting to know how is hard!

If you enjoyed this post, or found it useful, please leave a comment and I will start a new series on Neo4j in Java/Spring!

CORS in Python Bottle Framework

I was hacking up a quick mobile web app and needed to do an AJAX (jQuery based) POST and PUT to a simple Python Bottle REST server. Turn out that the AJAX POST was sending HTTP OPTIONS before the POST and the server was rejecting it with a 405. This, I find out, was due to a Cross Origin scripting issue and needed a solution.

Easiest way that I could come up with to fix the CORS (Cross Origin Resource Sharing) problem, was to write a simple bottle.py decorator that would enable me to do cross origin posts easily.

Firstly, the JQuery AJAX looked something like this on the client side:

$.ajax({
                            url: "http://host:port/save",
                            type: "POST",
                            data: JSON.stringify( { "mydata" : "Some stuff" } ),
                            contentType: "application/json",
                            success: function(data){
                                $("#result").html('got datal: ' + data);
                            },
                            error:function(error){
                                $("#result").html('There was an error while submitting: ' + error.message);
                            }
                    });

and the Python code looks like this:

# the decorator
def enable_cors(fn):
    def _enable_cors(*args, **kwargs):
        # set CORS headers
        response.headers['Access-Control-Allow-Origin'] = '*'
        response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
        response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'

        if bottle.request.method != 'OPTIONS':
            # actual request; reply with the actual response
            return fn(*args, **kwargs)

    return _enable_cors

You can then add the decorator to whatever of your @route methods that you need to enable CORS for with the simple @enable_cors annotation

@route('/save/', method=['OPTIONS', 'POST'])
@enable_cors
def save():
    # Rest of your code here...

Note that in the method I have set a list of the allowed methods, which include HTTP OPTIONS…

That is it! Javascript folks will tell you to rather do a $.post query, but I do prefer this method (I am more of a server side type of dude…)

There are, other ways to achieve this, but in my opinion, this is simplest and most elegant.