17 November 2009

FOODOPI - coming soon to a nation near you!

IP news from France. My translation probably isn't perfect. There are other things to worry about, too.

Watching the evilly smug faces of recording industry executives following France's recent adoption of Hadopi, restaurant owners have decided they deserved a slice of the IP pie, too. Watch out for the new law to be introduced later this year: FOODOPI!

Restaurant managers, owners, and chefs who have dedicated years of their talent, skill, and secret sauce to creating irresistible mouthwatering dishes have watched in dismay as food pirates illegally copy their ideas, recreating such classics as Ratatouille, Chicken Curry with Rice, and Spaghetti Bolognese with impunity in their own homes.

This is all going to change and the impoverished actors of the restauration industry will finally see their hard work rewarded and protected. The new FOODOPI law, if adopted, will allow restaurant industry executives name individuals suspected of recipe pirating and, after three warnings, those individuals will be prohibited from cooking for a length of time varying from six months to ten years.

Although the lack of judicial review during the prohibition process has raised concerns among civil liberties groups, a spokesperson for a French restaurateur's association observed "the justice system is already overstretched and it makes no sense to burden it even further. This law is a huge win for the public, ensuring continued innovation in the food service industry. It would be a disservice to the public and a drain on limited taxpayer resources to push this through the courts."

A spokesperson for a US-based organisation conducting cutting-edge research on genetic improvement of popular crops said while they would vigourously defend their IP in France under this new law, "currently we have no intention of prosecuting the most widespread violation of our intellectual property: the use of sodium chloride as a food additive for flavour enhancement". [A lawyer friend has advised me that this patent may not be applicable in France anyway as the use of "table salt" (to use pirate jargon) is a popular custom in this country, dating back centuries - ed.]

While the details of the new system have yet to be worked out, a leaked document obtained by this site indicates some of the strategies being considered -

  • Government-mandated cooking equipment for all new domestic kitchen installations with remote sensing equipment for ambient atmospheric analysis, allowing FOODOPI investigators detect potential violations of food industry IP by comparing chemicals and food traces in the air with a database of protected recipes.
  • Food retailers will report purchases to a central database that will apply sophisticated pattern-matching algorithms to identify individuals who may be planning IP violations. As an example, the document describes a hypothetical shopper in the process of acquiring 500g basmati rice, 8 chicken thighs, unflavoured yoghurt, turmeric, ginger, and garlic. The proposed pattern-matching software would flag this shopper as a potential pirate about to prepare Chicken Curry with Rice for 4.
  • Repeat offenders would ultimately have all kitchen equipment confiscated and perhaps have a camera installed in their homes to deter future violations

The document also noted some concerns of IP holders, including the threat of violations by picknickers and people using obsolete or camping equipment, where monitoring systems are less feasible.

Put that in your pipe and smoke it.

30 September 2009

mass file rename using mv and sed

I wanted to re-organise my config/locale directory because translation files for the same stuff were too far from each other. I had


It was too much of a pain to switch quickly between en/foo.yml and fr/foo.yml. So now I have


except it's not four files, it's dozens. So I needed a mass-rename shell script to rename many files at once:

for file in $*
mv "$file" `echo "$file" | sed ${PATTERN}`

It combines mv and sed to rename files based on patterns in their names. Invoke thus:

cd config/locales/en
mvsed s/yml/en.yml/g *.yml

Repeat for each language, and then just move all the yml files up to the parent directory, and you're done. You can use this for lots of renaming operations, and as you will have noticed, you don't need to be a sed guru to figure out basic patterns. This script works with bash on my macos 10.5; I imagine it will work with little alteration on the sensible non-MSDOS shell you're using.

Acknowledgements to linuxforums.org / dnielsen78 for the inspiration for this script, and to everyone else who wrote this first.

08 July 2009

Don't misunderestimate your children

I was reading a Wallace and Gromit story to my (now 5-year-old) son, and he energetically pointed out

son Look, a grandfather clock!
me Yes, that's a grandfather clock. It's about to fall on top of Wallace!
Wallace That's just the thing, my lad, we'll have to turn back the clock ...
son What's "turn back the clock" ?
me Well, suppose something happened yesterday that you weren't happy about, so you decide to <blah blah long-winded explanation of expression with digression into the role of metaphor in language>
son Oh, you mean he builds a time machine?

Duh. I should have realised time travel is a standard part of every 5-year-old's vocabulary.

28 March 2009

Chart in Javascript


a chart made with javascript

Or several little charts in a row, like this:

several bar charts in a row


  • Really easy to use
  • mouse move highlights bar under mouse
  • pops up tooltip with information for the bar under the mouse
  • All colours are configurable
  • Scales data automatically to height of canvas



var data = [
[ "week 1", "1000" ],
[ "week 2", "2000" ],
[ "week 3", "3000" ]

Declare a canvas element:




Then, draw your data


It couldn't be simpler!


(function() {
  function max(data) {
    var max = 0;
        max = data[i][1];
    return max;

  function coords(event, element, f) {
    var y = p.y - offset.top;
    var x = p.x - offset.left;
    f(y, x);

    if (!canvas || !canvas.getContext) {

    var cx = canvas.getContext('2d');

    this.draw = function(data) {
      cx.clearRect(0, 0, canvas.width, canvas.height);
      var thick = canvas.width / data.length;
      var scale = canvas.height / max(data);

      function highlightBars(index) {
        cx.lineWidth = 1;

            cx.strokeStyle = hilite;
          } else {
            cx.strokeStyle = bg;

      cx.fillStyle = bg;
      cx.fillRect(0, 0, canvas.width, canvas.height);

      cx.fillStyle = fg;

        if (!isNaN(h)) {


      canvas.onmouseout = function(event) {

      canvas.onmousemove = function(event) {
          if (index < 0) {
            index = 0;

          var bar = data[index];
          if (bar) {


26 March 2009

Spidering Internal Pages


So far, so good.







Open Coffee Club Paris: For Sale

Open Coffee Club, Paris, 26 March 2009




20 March 2009

Scaling Testing


Updating the security budget














17 March 2009

Jamendo & Magnatune





10 March 2009

Ban Censorship Now!





03 March 2009

Blogger: break "convert line breaks"




  br { display: none; }
  br.forReal { display:inline; }


  <br class='forReal'/>

So I can make a table thusly*:


Which looks like

foo bar
toto titi



23 February 2009

Exceptions In Java [Must Read]

Exceptions were a big improvement over the old-fashioned C way of returning error codes, but then the debate raged over Checked vs Unchecked Exceptions, vs "Huh? Checked? Whazza?". Java offers all three varieties so you can never hope to port exceptional experience from one project to the next, because there are at least as many correct ways to do things as there are gurus. However, at least now there's a step in the right direction; with Björn Andersson's Java Exception Explanator a lot more of this makes sense. Check it out. Here's a teaser:

AccessControlException : You have lost control of Microsoft Access. If you cannot regain control or stop the program in some other way, you should cut the power to your computer as fast as possible.

ps. thanks reddit

Don't Forget To Flush

So, instead of being asleep like an honest citizen at 2 o'clock in the morning, here I am trying to make hibernate save my collection of Strings.

(I would hate not to be a developer: who else deals with Collections of Strings, I wonder?)

The mapping is perfect, straight from the documentation, to tricky stuff, no funny cases:

    <set name="categories" table="resources_categories">
      <key column="resource"/>
      <element column="category" type="string"/>

Except, when I populate my category list, and try getSession().save(newResource) ... it doesn't save my Strings!

After a little more googling than I would have hoped, I bumped into this - http://forum.hibernate.org/viewtopic.php?t=951848&blah blah... where the hibernate team says you have to flush in this case. You don't have to flush to save most other things, but if it's a Collection of Strings, you have to flush.

So this works:


- no changes to the mapping required.

22 February 2009

Another Smug Mac User





  1. Hit Start -> Run
  5. close the "cmd" window

31 January 2009

Homer vs The Bible







26 January 2009

How to draw an ellipse






 * determines whether a point p,q is inside an ellipse
 * specified by (x,y,a,b)
 * returns 1 if inside, 0 if outside
 * @param x x-coordinate of centre of ellipse
 * @param y y-coordinate of centre of ellipse
 * @param a horizonatal radius
 * @param b vertical radius
 * @param p x-coordinate of point to consider
 * @param q y-coordinate of point to consider
  var dx = (p - x) / a;
  var dy = (q - y) / b;
  var distance = dx * dx + dy * dy;
  return (distance < 1.0) ? 1 : 0;

To calculate the insideness of a square area, use this:

 * @param p x-coordinate of point to consider
 * @param q y-coordinate of point to consider
  var total = i1 + i2 + i3 + i4;
    return total / 4.0;

  side = side / 2;


20 January 2009



From the site:


PariSharing is the meeting of those dreams.




How Do You Find Me?










import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ExternalSearchHelper {

  public String getSearchTerm(HttpServletRequest req) {
    String referrer = req.getHeader("Referer");
      return "";

    return (String) google(referrer)[0];

  public boolean isSearching(HttpServletRequest req) {
    return StringUtils.isNotBlank(getSearchTerm(req)); 

  public static Object[] google(String referrer) {
    Object[] result = new Object[2];
      return result;

    Matcher m2 = itsGoogle2.matcher(referrer);
    if (m2.matches()) {
      return result;

    Matcher m = itsGoogle.matcher(referrer);
    if (m.matches()) {
      result[1] = 0;

    return result;

  private static String decode(String s) {
    return URLDecoder.decode(s);

15 January 2009

On the Latest Intellij


  • Git support, at last!
  • Better javascript syntax highlighting
Anyway, bravo, jetbrains.