coding (67)


Space Editor 0.8.7

New for this release:

Correctly handles stations (old versions converted them to large ships…oops!)

now only displaces entities when you clone them, export / import does not displace items… so be careful of collisions!

Download from github

 




Space Editor 0.8.6

I was going to leave this until tomorrow…but I got excited.

v0.8.6 adds support for mirroring blocks.

So you can go from this:

SpaceEngineers_2013-10-29-22-50-32-373_FinalScreen

to this:

SpaceEngineers_2013-10-29-22-51-27-585_FinalScreen

With a couple of clicks.

Get it here:

download from github




Space Editor 0.8.5

Yet another new release, this one has:

An all new layout (most functions now available via right click)
Ability to edit any of the positional information
Auto update feature

Untitled

Download from github




Space Editor Open Sourced

As promised: https://github.com/Tall-Paul/SpaceEditor

Nothing new in the code itself, hoping to have character placement and position editing by tomorrow.

Enjoy.




Space Editor 0.8.2 released

Another day another release….

Capture

I noticed this morning that I’m not handling the player character very well. If you’re piloting a ship when you save, then load that save into SpaceEditor, then save… it loses the player character, and corrupts the save. Not very useful. So, my longterm goal (ie: in the next day or so) is to properly handle the player character, and let you pick a ship to control, or dump him (you) in the depths of space as you see fit. For now however, this release just refuses to load a save if you’re piloting a ship.

Also, I’ve made the treeview a bit nicer (changed the entity IDs to useful names like ‘Big Ship’ etc) and added a ‘delete’ button (by popular request).

Enjoy!




SpaceEditor Released

(I’ve since released a newer version of this software, which you can find here)

Just a quick post about a project I’ve been working on over the weekend: SpaceEditor.

Capture

This is a basic savegame editor for the really rather excellent ‘Space Engineers’ (which you can find on steam here: http://store.steampowered.com/app/244850/?snr=1_7_15__13)

The game itself is a bit basic at the moment, it’s still in ‘early Alpha’ stage, so there’s not actually a great deal to do other than build ships and crash them into things. One thing that’s conspicuously missing at the moment is the ability to save / load your creations. You can save a whole ‘world’, but extracting your design from that world just isn’t enabled…yet.

That’s what this tool is aimed at. The current feature set is:

Load a save game (you need to browse to the ‘SANDBOX_0_0_0_.sbs file in your savegame folder)
Export any ships from that game into files (Make sure you have a ship entity selected in the tree before you press this!)
Import ship files back into a save game
clone a ship within the world (again, you have to have a ship entity selected!)

And it lets you do stuff like this:

SpaceEngineers_2013-10-27-11-10-33-550_FinalScreen

I’ll be open sourcing the project as soon as I’ve tidied it up, but for now you can grab the executable here:

*UPDATE* check here for the latest version: http://www.tall-paul.co.uk/category/coding/space-editor/

WARNING: this should be considered even more pre-alpha than the game itself. If it completely mangles that ship you just spent 3 days building, don’t say I didn’t warn you. Because I did. Just now.

Edit: New version released, this should be much quicker at loading…. I’ve updated the download link.




Category based shipping in magento

One of the things that’s always annoyed me about Magento is the dearth of decent, free shipping modules available for the system. Out of the box you can do a reasonable amount with regards shipping, setting a flat rate or using one of the built in shipping methods…but if you want to do anything fancy (and in my experience, people always do) then you need to pay out for one of the many customisable shipping modules available.

It’s been nearly a year since I last looked at Magento, but a recent freelance project has meant me getting back into it and as the client has some very specific shipping requirements, I thought I’d write my own shipping module. I spent a few hours fiddling with config files, before rememebering why Magento always annoyed me so much (hint, it’s the config files) and used the rather brilliant magento module generator to get me started.

Here’s what I wanted from a shipping module:

  • Different shipping rates for individual products
  • Different shipping rates to different countries
  • Easy assigning of shipping rates to products

So, to tackle these problems I came up with a module that uses Shipping rules defined through categories. This means you can setup your rules, and then use the standard product / category concept in Magento to assign your shipping rates.

Once you install the module (see below for a download) each category gets a new attribute under its ‘general’ tab, named ‘Shipping’. That’s where you enter your rules. Rules are extremely simple, and consist of a series of lines, each of which is made up of ‘country code’ = ‘price’

here’s an example of one ruleset:

Capture

This translates to ‘If the delivery address is in the UK, free shipping. If it’s in the European union, shipping is 3.00, for the rest of the world it’s 5.00’.

You can have as many lines as you want (they’re processed top to bottom) and if you have multiple items in your basket that produce different shipping rates, the most expensive rate is picked (there’s no option to sum the rates together yet, I might add that in at some point).

You can add these rules to your actual, published product categories or do what I’ve done for this client and set up a seperate tree of ‘Shipping categories’ like so:

Capture

So there you go. Bit basic, but does what I needed it to do.

Here’s the download link (upload the ‘app’ folder from the archive into the root of your magento installation):




DIY security keypad

After my couple of hours of tinkering with python yesterday (see here) I started pondering how to expand on what I’d done.  Some sort of keypad would be handy, so I could just tap in a code and disable my cameras…. and then I’d need something to run the code on and connect the keypad to….Oh, and some way of indicating whether the cameras are currently enabled or disabled would be nice.

Luckily, I still had my trusty raspberry pi sat around doing nothing, so that solved the platform issue quite nicely.  The debian install for the pi already comes with python, so it was trivial to get my code up and running…. now I just needed a keypad.  I did look at something like this:

£10 from amazon might seem like a bargain, but I already had a spare usb keyboard sat around.  If only I could use that.  Well, that’s where some hacking came in handy:

2013-05-28 19.31.43

 

 

Somewhat astonishingly, the numpad bit of the keyboard still worked after my delicate surgery (I got lucky and happened to have a keyboard that responded well to being cut in half.  your mileage may vary).  So now we have a platform for the code to run on, and a number pad to enable or disable the cameras…it would be nice if we could determine whether the cameras are enabled or disabled though.  Handily, we can!  Pretty much every keyboard has a selection of LEDs on it to indicate the status of the ‘locking’ keys (caps lock, num lock and scroll lock) and my hastily hacked up masterpiece was no exception.  And it turns out it’s fairly straightforward to control these lights in python (although you do need to have root privileges to do so.  Why?  because linux that’s why) .

So, with a bit more googling and some slapping together of code here’s how it all works.

The pi is set to login automatically on boot (using the info here) and starts the python script (source below).  The script then queries motion for the current status, and sets the scroll lock LED accordingly, before waiting for the user to enter a passcode.  If the passcode is incorrect the lights on the keyboard flash on and off, before returning the user to the ‘enter passcode’ bit again.

Here’s a couple of images of the ‘mounted’ number pad (sellotape is brilliant!):

cameras off / cameras on.

 

2013-05-28 21.04.36 2013-05-28 21.04.43

As well as some tidying up, I want to do some more work on the python script (I’d quite like it to poll the cameras while waiting for input, and flash the capslock key as a ‘heartbeat’ indicator) but here’s what the code looks like so far:

 

#!/usr/bin/python
import getpass
import requests
import os
import fcntl
import time
import pwd
import grp

KDSETLED = 0x4B32
SCR_LED  = 0x01
NUM_LED  = 0x02
CAP_LED  = 0x04

def get_status():
        response = requests.get(url= host+"/1/detection/status")
        if response.status_code == 200:
                if "PAUSE" in response.text:
                        return 0
                else:
                        return 1
        else:
                return -1

def toggle_status(current_status):
        if current_status == -1:
                return
        if current_status == 0:
                path = "/detection/start"
                out = " started"
        else:
                path = "/detection/pause"
                out = " stopped"
        for x in range(1,camCount+1):
                response = requests.get(url= host+"/"+str(x)+path)
                if response.status_code == 200:
                        print "Camera "+str(x)+out
                else:
                        print "Error with camera "+str(x)

camCount = 2
password = "PASSWORD"
host = "http://HOST:PORT"
console_fd = os.open('/dev/console', os.O_NOCTTY)
enabled = SCR_LED | NUM_LED
disabled = NUM_LED
error = CAP_LED
all_off = 0
all_on = SCR_LED | NUM_LED | CAP_LED

while True:
        os.system('cls' if os.name=='nt' else 'clear')
        status = get_status()
        if status == 0:
                print "Motion detection disabled"
                fcntl.ioctl(console_fd, KDSETLED, disabled)
        else:
                if status == 1:
                        print "Motion detection enabled"
                        fcntl.ioctl(console_fd, KDSETLED, enabled)

                else:
                        print "Error determining status"
                        fcntl.ioctl(console_fd, KDSETLED, error)
        input = getpass.getpass("Enter the passcode: ")
        if input == password:
                toggle_status(status)
        else:
                fcntl.ioctl(console_fd, KDSETLED, all_on)
                time.sleep(2)
                fcntl.ioctl(console_fd, KDSETLED, all_off)
                time.sleep(2)



New project: Node.js application framework

So I decided to learn a new language / architecture last weekend and since Node.js has been getting a lot of attention lately I thought I might as well go with that.

I’ve put maybe 6 hours into it so far, and you can see the fruits of my labour over at github: https://github.com/Tall-Paul/node-framework

I don’t have it up and running anywhere yet, and there’s still some work to do but so far I have:

  • A routing system that takes a json config file and routes requests to ‘handlers’
  • A packaging system that allows related code to be grouped together
  • An ORM based on sequelize that lets you easily define database backed models for data
  • Automatic Ajax loading of models.

You can see an example of this in the ‘blog’ package that comes with the framework.

Currently there’s a model (/packages/blog/models/post.js) that looks like this:

module.exports = function(sequelize, DataTypes) {
  return sequelize.define("Post", {
    title: DataTypes.STRING,
    content: DataTypes.TEXT,
    author: DataTypes.STRING,
    slug: DataTypes.STRING,
    category: DataTypes.INTEGER,
  })
}
A custom handler / route that currently just takes any request of the form /blog/foo/bar.html and returns the first blog entry (this obviously needs work so it translates the request into the correct blog post) and finally a simple template that looks like this:
<html>
<head>
{{{js_includes}}}
{{{framework_get_object("blog_post",post_id,"post")}}}
</head>
<body>
<div id="post_id"></div>
<div id="post_title"></div>
<div id="post_content"></div>
</body>
</html>
It may not look much, but that template is doing some pretty funky stuff behind the scenes, it embeds some javascript on the page that trundles off and gets the blog post you asked for (post_id in that function call is a template variable that’s set by the handler, but it doesn’t have to be… you can get any content you want with a similar call) and then puts the data from the object into the page in the divs you specify.  Pretty neat (if I do say so myself).  Remember that Ajax stuff is built for you by the framework, just by defining a model of ‘post’ in the package ‘blog’ we automatically get the ability to load instances of that model via ajax.
This is clearly still a work in progress, and doesn’t actually ‘do’ very much yet… but by the weekend I hope to have automagic ajax searching of data in place and then I’m going to think about moving this site over to the new framework, possibly hosted on Engine Yard (depending on how pricey that turns out to be).  So check back soon for a demo of the framework in action.
Also, if anyone can think of a better name for this than ‘node.js web framework’ drop me a line



Accessing RPC/Encoded Web services in Servicemix / Fuse ESB

If there’s one issue I’ve found with ServiceMix, it’s that it tends to enthusiastically embrace a certain way of doing things while letting other methods fall to the wayside.  A prominent example of this is when constructing code to access web services.  By default, Servicemix uses Apache CXF as its web service layer.  CXF is a thoroughly modern framework for constructing web service clients and services, but because it’s so modern it doesn’t support some of the older web services definitions.  A particular example is ‘RPC/Encoded’ web services. If you’re not sure what an RPC/Encoded web service is, but you’ve run into the dreaded ‘rpc encoded wsdls are not supported in jaxws’ error message that is reported when you try to use CXF in this case, there’s a good (if rather dry) explanation of the various types of web services here but all you really need to know is that most people moved away from RPC/Encoded services a while ago, and most modern frameworks are dropping support for this style.  This is all well and good, but what should you do if you need to access a piece of 3rd party software using this style of web service?  CXF doesn’t support it at all, and servicemix doesn’t offer an alternative web framework that does support it.  If you google this issue, you find a load of posts form mailing groups and forums discussing it, but none offering a real solution.

Well, as with most things relating to servicemix there’s a couple of ways of approaching this.

The first, and most time consuming is to simply construct XML Requests and / or responses yourself and then slot your data in before sending it off to the remote endpoint using CXF.  SoapUI is useful here to work out what your XML should look like, and you can use the camel-freemarker component to add in your data and make requests.  For responses, you need some way of parsing the xml that comes back and extracting the relevant data.  If you only have a few requests / responses to make, this is probably a good method.  Once you start adding more requests / responses though it very quickly becomes unwieldy and time consuming to write the parsers and request xml templates for this.

So, what’s the better way of doing this?  Well, before CXF came along there was another Java based web services framework called Axis.  And, fortunately for us, Axis does support RCP/Encoded web services.  However, there are some issues with getting Axis support into servicemix.  Firstly, it’s not supported at all.  There’s no nice FuseSource provided packages available and, because Axis makes use of some of the same wiring as CXF, having Axis present in your OSGI environment can cause all kinds of issues with packages using Axis dependencies instead of CXF dependencies.

Luckily for you, I’ve already done the work to get this working, and All you need to do is copy the methodology below for a nice working RCP/Encoded client API.

For ease of use, I’ve split my project into two separate areas.  A ‘generator’ bundle, which produces our Axis API code, and an ‘API’ bundle which makes use of that code.

Here’s the POM.xml for the Generator bundle:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.tall-paul</groupId>
 <artifactId>my-rpc-generator</artifactId>
 <packaging>pom</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>${project.artifactId}</name>
 <properties>
 <camel-version>2.9.0</camel-version>
 <activemq-camel-version>5.5.1</activemq-camel-version>
 <servicemix-version>2011.02</servicemix-version>
 <maven-bundle-plugin-version>2.3.4</maven-bundle-plugin-version>
 <build-plugins-plugin-version>2.5</build-plugins-plugin-version>
 <build-helper-plugin-version>1.7</build-helper-plugin-version>
 <maven-resources-plugin-version>2.5</maven-resources-plugin-version>
 <maven-compiler-plugin-version>2.3.2</maven-compiler-plugin-version>
 <osgi-import-package>*,org.apache.camel.osgi</osgi-import-package>
 <osgi-export-package/>
 </properties>
 <dependencies>
 <dependency>
 <groupId>org.apache.axis</groupId>
 <artifactId>axis</artifactId>
 <version>1.4</version>
 </dependency>
 <dependency>
 <groupId>org.apache.axis</groupId>
 <artifactId>axis-jaxrpc</artifactId>
 <version>1.4</version>
 </dependency>
 <dependency>
 <groupId>org.apache.axis</groupId>
 <artifactId>axis-saaj</artifactId>
 <version>1.4</version>
 </dependency>
 <dependency>
 <groupId>axis</groupId>
 <artifactId>axis-wsdl4j</artifactId>
 <version>1.5.1</version>
 </dependency>
 <dependency>
 <groupId>commons-discovery</groupId>
 <artifactId>commons-discovery</artifactId>
 <version>0.4</version>
 </dependency>
 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.14</version>
 </dependency>
 </dependencies>
 <build>
 <pluginManagement>
 <plugins>
 <!-- used to generate the MANIFEST-FILE of a bundle -->
 <plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <configuration>
 <source>1.5</source>
 <target>1.5</target>
 </configuration>
 </plugin>
 <plugin>
 <groupId>org.codehaus.mojo</groupId>
 <artifactId>axistools-maven-plugin</artifactId>
 <configuration>
 <sourceDirectory>src/main/resources/</sourceDirectory>
 <packageSpace>my.package.namespace</packageSpace>
 <testCases>false</testCases>
 <serverSide>true</serverSide>
 <subPackageByFileName>false</subPackageByFileName>
 </configuration>
 <executions>
 <execution>
 <goals>
 <goal>wsdl2java</goal>
 </goals>
 </execution>
 </executions>
 </plugin>
 </plugins>
 </pluginManagement>
 </build>
</project>

There’s a couple of things you’ll need to change here for your project.  As well as the usual maven artifactID etc, you’ll need to change the ‘packageSpace’ element to reflect what package you want the generated code to fall under.  Your RPC/Encoded wsdl needs to go in your src/main/resources directory.  Do a maven build, and you should find a load of generated code in your target directory (yay!).  Now we have to actually do something with that code.  Here, I copy the generated code into my ‘Api’ project, the pom for which looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.tall-paul</groupId>
  <artifactId>my-rpc-api</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>bundle</packaging>
  <name>my-rpc-api</name>
  <description>My RPC Api</description>
  <properties>
    <camel-version>2.9.0</camel-version>
    <activemq-camel-version>5.5.1</activemq-camel-version>
    <servicemix-version>2011.02</servicemix-version>
    <maven-bundle-plugin-version>2.3.4</maven-bundle-plugin-version>
    <build-plugins-plugin-version>2.5</build-plugins-plugin-version>
    <build-helper-plugin-version>1.7</build-helper-plugin-version>
    <maven-resources-plugin-version>2.5</maven-resources-plugin-version>
    <maven-compiler-plugin-version>2.3.2</maven-compiler-plugin-version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.axis</groupId>
      <artifactId>axis</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.axis</groupId>
      <artifactId>axis-jaxrpc</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.axis</groupId>
      <artifactId>axis-saaj</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>javax.xml</groupId>
      <artifactId>jaxrpc-api-osgi</artifactId>
      <version>1.1-b01</version>
    </dependency>
    <dependency>
      <groupId>axis</groupId>
      <artifactId>axis-wsdl4j</artifactId>
      <version>1.5.1</version>
    </dependency>
    <dependency>
      <groupId>commons-discovery</groupId>
      <artifactId>commons-discovery</artifactId>
      <version>0.4</version>
    </dependency>
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.0.2</version>
    </dependency>
    <dependency>
      <groupId>javax.xml</groupId>
      <artifactId>jaxrpc-api</artifactId>
      <version>1.1</version>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.14</version>
    </dependency>   
  </dependencies>
  <build>
    <defaultGoal>install</defaultGoal>
    <plugins>
      <plugin>
        <groupId>org.apache.felix</groupId>
        <artifactId>maven-bundle-plugin</artifactId>
        <version>${maven-bundle-plugin-version}</version>
        <extensions>true</extensions>
        <configuration>
          <instructions>
            <Bundle-SymbolicName>TESTING</Bundle-SymbolicName>
            <Export-Package>my-package-namespace,javax.xml.rpc</Export-Package>
            <Embed-Dependency>
							axis;scope=compile|runtime,
							axis-jaxrpc;scope=compile|runtime,
							axis-saaj;scope=compile|runtime,
							jaxrpc-api-osgi;
							scope=compile|runtime,
							axis-wsdl4j;scope=compile|runtime,
							commons-discovery;scope=compile|runtime,
							jaxrpc-api;scope=compile|runtime,
							log4j;scope=compile|runtime,
							commons-logging;scope=compile|runtime
						</Embed-Dependency>
            <Embed-Transitive>true</Embed-Transitive>
            <Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath>
            <Import-Package>
							*;resolution:=optional,
							com.sun.jdmk.comm;resolution:=optional,
							com.sun.jimi.core;resolution:=optional,
							com.sun.net.ssl;resolution:=optional,
							com.sun.net.ssl.internal.ssl;resolution:=optional,
							org.apache.bsf;resolution:=optional,
							org.apache.log;resolution:=optional,
							sun.awt.image.codec;resolution:=optional,
							sun.security.provider;resolution:=optional,
							org.exolab.castor.xml;resolution:=optional,
							org.apache.camel.osgi,
							</Import-Package>
          </instructions>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-compiler-plugin-version}</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

 

The real magic here is the ‘Embed-Depency’ element, which ensures the Jars referenced here are downloaded and bundled into our project, rather than being imported from the OSGI container at runtime.

And that’s pretty much it, you can now use the generated axis code in much the same way as similar CXF code.