Tag: howto

March 04th 2010

Round image corners with php

Tags: howto php code Written by Dave Barker

I needed to round the corners of a banner image dynamically in PHP and I couldn’t find any explanations. Anyway it turns out the easiest way is to make an image of a rounded corner, like this rounded-corner.png and then stamp it on all 4 corners. You have to rotate it each time of course.Anyway here’s a snipplet of code to give you an idea:

<?php
$banner = '/path/to/banner-image.png';
$corner = '/path/to/rounded-corner.png';

// Load up the images
$banner = open_image($banner);
$corner = open_image($corner);

// Round the corner
imagecopy($banner, $corner, 0, 0, 0, 0, imagesx($corner), imagesy($corner));
$corner = imagerotate($corner, 90, 0);
imagecopy($banner, $corner, 0, imagesy($banner) - imagesy($corner), 0, 0, imagesx($corner), imagesy($corner));
$corner = imagerotate($corner, 90, 0);
imagecopy($banner, $corner, imagesx($banner) - imagesy($corner), imagesy($banner) - imagesy($corner), 0, 0, imagesx($corner), imagesy($corner));
$corner = imagerotate($corner, 90, 0);
imagecopy($banner, $corner, imagesx($banner) - imagesy($corner), 0, 0, 0, imagesx($corner), imagesy($corner));

// Output the image
header("Content-type: image/gif");
imagegif($banner);

// Tidy up
imagedestroy($banner);
imagedestroy($corner);
?>

August 02nd 2009

Mac emacs control option keybindings

Tags: howto mac emacs Written by Dave Barker

If you recently upgraded to Emacs 23 from Carbon Emacs on your Mac you might have found all the control keys are bound wrong. Anyway it’s easy to fix, add these lines to your .emacs and restart Emacs.

; Setup the Mac keys
(setq mac-option-key-is-meta nil)
(setq mac-command-key-is-meta t)
(setq mac-option-modifier nil)
(setq mac-command-modifier 'meta)
(global-set-key (kbd "<kp-delete>") 'delete-char)

May 14th 2011

Embedded development setup with Macbook

Tags: python howto embedded Written by Dave Barker

I’ve been put onto an interesting project recently, doing some embedded Python development for a Telit GM862-GPS unit. Being new to this type of thing it took me a while to get a development environment set up that I was happy with. In an effort to share what I’ve learned, here’s my setup:

(To be clear I’m using the Roundsolutions development starter kit for the Telit GM862-GPS with my Macbook pro.)

Roundsolutions dev board

First of all I had to install the usb-serial driver (PL2303_1.2.1r2.dmg) to get the serial port working. Once that’s installed and it’s connected the serial device /dev/tty.usbserial appeared for use.

Next I followed this guide and connected to the device using the GNU Screen command that’s included with Snowleopard. This command worked nicely: screen -S telit -T vt100 /dev/tty.usbserial 115200,crtcts,-parity,-cstopb

Typing AT returned OK and I knew I was in business!

I soon found that deploying code over serial manually was pretty tedious, it’s easy to mess up the AT commands. I wrote this script to automate the process, making deployment as easy as telit-send-python.py telit example.py.

The next issue I hit was that my code was sometimes being crapped up during transfer. I eventually figured out I was using the wrong line terminators for my files, Unix style just uses \n where as the Telit module demands \n\r (DOS style). To convert my files in Emacs I used the buffer-file-coding-system command, so M-x set buffer-file-coding-system undecided dos.

Next I realised backspace wasn’t being transmitted properly across Screen, there’s an option in the Advanced section of Terminal preferences “Delete sends Cntrl-H” which resolved it for me. Unfortunately I found it messed up my normal SSH sessions, a better solution is to have this fixed in GNU Screen, add these lines to your ~/.screenrc:

bindkey -d ^? stuff ^H
bindkey -d ^@ stuff ^H

Another annoyance with Screen was that I wasn’t able to scroll up like normal in my Terminal windows. Luckily fixing that was pretty easy, I added this to my ~/.screenrc : termcapinfo xterm* ti@:te@

Messing with SMS at commands I realised that the body of a SMS needs to be terminated with 0x1a, it bit tricky to type but there’s a solution, Screen’s “digraph” feature. To send 0x1a here’s what I did: C-a C-v 0x1a.

So the next thing I really wanted to was to get the Telit version of Python running locally, allowing me to test things interactively at a ‘REPL’. The units run a modified version of Python 1.5.2 and unfortunately I had no luck compiling or installing a version that old under Snowleopard. My solution in the end was to install the Windows version TelitPy1.5.2+_V4.1.exe using Wine. I then set up a little shell-script shortcut to launch it easily. (It installs to ~/.wine/drive_c/Program\ Files/Python/python.exe )

Now I’ve got a pretty sweet set up, but having the PCB dangling off the side of my Macbook in Starbucks isn’t really an option. So I plugged it into my Linux server at home and then I can SSH in and deploy code / interact with the Terminal. (Using Emacs’ tramp feature I can edit the code directly over SSH too.)

Only thing worth noting is that the naming convention for serial devices seems different in Linux. Also I found that sometimes the LANG environment variable ended up corrupting the binary transfer. Here’s the Screen command I ended up using: unset LANG && screen -S telit -T vt100 /dev/ttyUSB0 115200,crtcts,-parity,-cstopb.

Read the Stty man page for details about those serial options at the end.

I also sometimes needed to check what Screen’s really sending out, helpful for debugging problems with transmitting binary data. It’s not hard though, just start a Screen session and run this command inside it: stty raw; cat > binary-file-name.

(Just make sure to exit using the C-a :quit screen command rather, most special keys will be sent directly through into your file.)

Finaly while I’m waiting for the Python debugging board to arrive I needed to have some way of getting output through to the serial port. Otherwise it’s hard to know if your code even ran at all. Turns out it’s not too hard, here’s a (noddy) example:

import SER, MOD, MDM, GPS, sys

# Set the baud rate
SER.set_speed('115200', '8N1')

# Send stout and stderr over serial
# http://forum.sparkfun.com/viewtopic.php?t=6289
class SerWriter:
  def write(self, s):
    SER.send(s + '\r')
sys.stdout = sys.stderr = SerWriter()

# You get the idea...
print "Lovely stuff"

Thanks for reading, I’d be interested to hear how any tips you’ve got in the comments. Also if anyone knows a better support forum / community than the Roundsolutions one let me know.

Cheers, Dave.

Edit: I’ve just discovered Sparkfun’s evaluation board. The board looks a lot nicer, it’s cheaper and Sparkfun actually list prices and stock. I’ve just been browsing their forum and it’s way friendlier too, I would definitely go with Sparkfun over Roundsolutions if you get the choice.

Edit 2: I’ve had all sorts of problems uploading Python scripts larger than about 7kb to the Telit module. In the end I updated my script to send files in chunks with enough delay for the module to catch up. I also had problems deleting large files until I removed the quotes around a file name. Much much more details on this forum post.

Edit 3: I’ve just been shown this great guide about Telit Python development, well worth reading.

November 18th 2010

Syncing Google calendar with Facebook birthdays and events

Tags: howto project python Written by Dave Barker

Hi everyone,

I recently tried to get Facebook birthdays and events to show up in my Google calendar. Everything I tried was broken, I just couldn’t find something that worked properly.

Anyway I’ve made my own solution, it’s available here: http://apps.facebook.com/calenderp

You have to click two install buttons (one with Facebook and one with Google) and then your calendar will be synced. It gets timezones right, has been translated into 3 languages so far and is starting to build up a fair following of users.

If you’re interested in the technical side of things I’ve shared the source on GitHub https://github.com/kzar/CalenDerp. It uses Python, Google appengine, Facebook’s graph API and the Google calendar API to sync everything.

Anyway let me know if you have feedback!

Cheers, Dave.

Edit: Also I’m looking for translators, get in touch if you can translate about 20 phrases into your language for me.

December 11th 2010

Blocking Spotify's P2P Connections

Tags: howto Written by Dave Barker

It turns out Spotify uses P2P technology so that it can reduce the load on it’s servers. Great, except that uses a fair amount of bandwidth and sometimes that’s not OK.

The client always falls back on their central servers, so we could just block P2P. Problem is that we’re given no manual option to disable, (or limit) P2P sharing. Worse still, the client spawns connections to other users within a massive range of ports making them tricky to block.

I just spent the last few hours looking at this because my bandwidth quota has been destroyed, I’ve got a few ideas and some of them have worked.

Desktop Firewall

I know, I know, I hate these Desktop firewalls as well. I never thought I’d see the day when I wanted to use one. On the other hand it does make dealing with programs like Spotify much easier. On my Macbook I was able to install The Little Snitch and set it up to block the Spotify process from connecting to anything except .spotify.com .

Little snitch settings to block Spotifys P2P connections

It actually turned out to work pretty well and it was the easiest / quickest solution. It’s not helpful if you’re using more than one computer though and I still don’t like the idea of relying on programs like these.

Edit: On the Windows 2000 box Tiny Personal Firewall was the best firewall I could find, it’s lacking compared to The Little Snitch for Mac though.

Socks Proxy

Spotify gives the option to send connections through a proxy server. This gave me an idea, what if we setup a proxy server that only allowed connections to .spotify.com and then forced Spotify to use it. (Of course the proxy server would be useless for web-browsing or any other purpose.)

This took me a while to get working properly, in the end I setup the Dante proxy server on one of my Debian servers. Here’s my /etc/danted.conf, it’s probably wrong and insecure so don’t count on it. (10.10.10.0/24 is my internal subnet and eth1 happens to be the box’s primary ethernet adapter. You will probably have to change those settings.)

Spotify socks proxy settings.

After the proxy is set up you need to tell Spotify to use it (I had to restart Spotify before it kicked in). But now we’re set, we’ve thrown all the bathwater out and the baby’s fine. This method has a lot of benefits too. It’s a centralized solution and doesn’t require any other software for the clients.

Edit: Spotify ignored my proxy settings for P2P traffic! It sends all the good stuff through the proxy though, I then had to block any other traffic with a desktop firewall myself :(

Hidden option

If I made Spotify I would have probably added a secret option somewhere to disable P2P connections. It would be tricky to test the app without it and surely Spotify’s office would be brought to a standstill otherwise?! Let’s find the option, I’ve got two ideas where it might be.

Spotify command line switches

Spotify seems to support command line switches, although they are undocumented there might be some interesting functionality hidden away and who knows maybe we can turn off sharing?

{
  "autologin_username" : "daveinadub",
  "listen_port" : 12517,
  "cache_size" : 1024,
  "proxy" : "10.10.10.99:8080@socks4",
  "proxy_mode" : 2,
  "proxy_pass" : "REDACTED",
  "g_sett_high_bitrate" : 1,
  "flash_version" : 9,
  "realtime_clock_delta" : 0
}

My final thought is editing the settings manually. Spotify has a settings file, it seems to be a simple JSON format so if we knew the names of hidden options we could change the settings there. Who knows maybe 'p2p': 0 is all that’s standing in the way?!

Either way, I have no idea where this elusive option is. Get searching and report back!

Mess up the cache

Well Spotify has a cache of files, presumably for use with the P2P sharing. If we could clear that cache or somehow disable it perhaps this could break P2P sharing? The Spotify client only lets you reduce the cache size to a minimum of 1 Gigabyte but interestingly I’ve noticed the setting is stored in the settings file. (Look at that sample above, ‘“cache_size”: 1024’). Perhaps this could be set to 0 manually? I don’t have time to test that idea but let me know if it works for you.

Edit: I’ve just given it a try, I found that setting cache_size to 1 was lowest it would accept. It reduced my cache down to 90megs initially and since then it’s been dropping slowly. I’m not sure if it will ever get as low as 1meg though. This idea might be counterproductive if it means we need to download more often, I’m also not sure if it’s reduced the P2P traffic or not. Another downside with this train of thought is it would be very easy for the Spotify team to just make the minimum number 1024 in a future update.

Alternative Client

I just had another thought, instead of forcing the official Spotify client to conform we could just use an alternative client. There seems to be a range of alternative clients available. I haven’t tried any of them yet but it looks like an promising approach.

Cheers Dave.

December 03rd 2008

Parsing a number from a string in PHP

Tags: php code howto Written by Dave Barker

Another quick PHP snippet, a function that returns the first integer found in the string given:

// Take a string and return the first number found
function parse_int($string) {
  ereg("([0-9]+)", $string, $results);
  if (is_array($results))
    return (int)$results[0];
  else
    return NULL;
}

October 06th 2010

Fixing Spotify uxtheme.dll error on Windows 2000

Tags: windows howto Written by Dave Barker

Spotify’s recent update broke it for use on Windows 2000, it causes this error:

Cannot find 'UxTheme.dll'. Please, re-install this application

Anyway I’ve figured out a solution, no guarantees but this works for me. I’ve cross-compiled the Wine implementation of the DLL for Windows. (I followed the instructions here.)

Long story short download this zip and extract it into c:\winnt\system32 .

Hope that helps. Cheers, Dave.

Edit: Great this seems to be working for other people too.

Edit 2: The latest version (0.4.10) of Spotify has broken Windows 2000 support again. This time the client disappears immediately on launch with no errors or messages. Luckily though the Spotify team have figured out the problem and are fixing it in the next version, here’s the message Magnus left on the support forum:

Magnus Spotify fix explanation

Edit 3: There’s a preview version available that fixes the new problem.

June 23rd 2009

Meld darwinport problem

Tags: mac howto Written by Dave Barker

If you are having problem getting the darwinport of meld running on your mac try these two commands before running the program again.

sudo launchctl load -w /Library/LaunchDaemons/org.freedesktop.dbus-system.plist
sudo launchctl load -w /Library/LaunchAgents/org.freedesktop.dbus-session.plist

The error I was getting before was this:

Xlib: extension "RANDR" missing on display "/tmp/launch-RsRIqw/:0".
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that org.freedesktop.dbus-session.plist is loaded!
Traceback (most recent call last):
File "/opt/local/bin/meld", line 109, in <module>
meldapp.main()
File "/opt/local/lib/meld/meldapp.py", line 855, in main
app = MeldApp()
File "/opt/local/lib/meld/meldapp.py", line 528, in __init__
self.prefs = MeldPreferences()
File "/opt/local/lib/meld/meldapp.py", line 465, in __init__
prefs.Preferences.__init__(self, "/apps/meld", self.defaults)
File "/opt/local/lib/meld/prefs.py", line 91, in __init__
self._gconf.add_dir(rootkey, gconf.CLIENT_PRELOAD_NONE)
glib.GError: Failed to contact configuration server; some possible causes are that you need to enable TCP/IP networking for ORBit, or you have stale NFS locks due to a system crash. See http://projects.gnome.org/gconf/ for information. (Details - 1: Failed to get connection to session: Not enough memory)
</module>

January 26th 2011

Fixing an autoload 'uninitialized constant' NameError

Tags: ruby howto Written by Dave Barker

I ran into a spot of bother getting some Ruby code to work, I kept getting a uninitialized constant NameError on the line declaring the very class I’ve autoloaded the file to declare! I got this problem running Ruby 1.9.2p0

Anyway adding this to the top of the file that autoloaded the file giving the error fixed it for me:

$LOAD_PATH.unshift './'

Cheers, Dave.

November 13th 2009

Changing Magento path

Tags: howto linux Written by Dave Barker

If the Magento path changes everything breaks, here’s how to fix it:

Run this query in your Magento database:

update core_config_data set value='http://new-url.com/' where value='http://old-url.com/example/';

and delete your cache

rm -r magento/var/cache/*

April 07th 2010

Clean parameter based Nginx re-writes with map

Tags: nginx howto linux Written by Dave Barker

When switching to my new blog I needed to re-write all the old Wordpress URLs to point to the appropriate place. Problem is rewrites don’t using arguments so I was stuck.

Luckily Curly060 and Seph in #nginx gave me some ideas and we ended up with this:

# Put this outside of server stanza
map $arg_cat $category {
  6 /blog/topic/security;
  11    /blog/topic/mac;
  8.*   /blog/topic/lisp;
  9.*   /blog/topic/code;
  3     /blog/topic/linux;
  14    /blog/topic/thoughts;
  10    /blog/topic/php;
  7     /blog/topic/security;
  12    /blog/topic/emacs;
  5     /blog/topic/projects;
  9     /blog/topic/code;
  13    /blog/topic/python;
  1     /blog;
  8     /blog/topic/lisp;
}

# Put this with other re-writes
if ($category) {
  rewrite ^ $category;
}

If you want to do a permanent redirect you have to clear all the arguments to stop the browser being caught in a redirect loop. The last stanza would now look something like this:

if ($category) {
  set $args "";
  rewrite ^ $category permanent;
}

July 10th 2009

web.py tutorial + sqlite

Tags: python web.py howto Written by Dave Barker

If you want to follow the web.py tutorial using sqlite here’s how:

Line for your python to connect to DB

db = web.database(dbn='sqlite', db='testdb')

To create the database type sqlite3 testdb and input this SQL:

CREATE TABLE todo (id integer primary key, title text, created date, done boolean default 'f');
CREATE TRIGGER insert_todo_created after insert on todo
begin
update todo set created = datetime('now')
where rowid = new.rowid;
end;

Now create an entry with this SQL

insert into todo (title) values ('Learn web.py');

Finally quit sqlite3 when your ready by typing .quit

November 17th 2008

SLIME connection dropping when using UTF characters

Tags: lisp howto emacs Written by Dave Barker

I ran into a problem today where my Slime connection would suddenly drop if I loaded a file that contained UTF characters.

Luckily the #lisp bods saved the day, here’s how you fix it:

  1. Add (setq slime-net-coding-system 'utf-8-unix) to your .emacs
  2. Add the :coding-system "utf-8-unix" keyword parameter to your (swank:create-server) call

There’s more information available here.

Cheers, Dave.

October 08th 2008

Setting up a Lisp web development environment

Tags: lisp howto emacs Written by Dave Barker

Here’s a guide to take a fresh Debian stable (etch) install and turn it into a viable Lisp web development environment. (Including Emacs22, SBCL, Slime, Hunchentoot, Apache2 all working together from boot)

Please note because this is aimed at a totally fresh Debian stable install you are going to need to be selective with the commands if it’s not a fresh install or if you are using a different version of Debian.

All the commands assume you are logged in as root on your soon-to-be web server.

Installation Steps

# Install Emacs 22
echo deb http://hype.sourceforge.jp/f etch backports >> /etc/apt/sources.list
wget http://hype.sourceforge.jp/A7F20B7E.gpg -O- | apt-key add -
apt-get update
apt-get install emacs22

# Install the other required packages
apt-get install darcs cvs subversion curl git-core cogito sbcl make gcc build-essential detachtty

# Grab clbuild
cd /usr/src
darcs get http://common-lisp.net/project/clbuild/clbuild
cd clbuild && chmod +x clbuild

# Install the different bits and bobs with clbuild
./clbuild update sbcl
./clbuild compile-implementation sbcl
echo cl-unicode get_darcs http://common-lisp.net/~loliveira/ediware/cl-unicode >> projects
echo metabang-bind get_darcs http://common-lisp.net/project/metabang-bind >> projects
echo stefil get_darcs http://common-lisp.net/project/stefil/darcs/stefil >> projects
echo cffi get_darcs http://common-lisp.net/project/cffi/darcs/cffi >> projects
./clbuild build cl-unicode cl-ppcre hunchentoot vecto cl-who slime metabang-bind iterate stefil babel cffi

# Make a lisp image
./clbuild dumpcore --installed

# Setup lisp to start on boot
cd /etc/init.d
wget http://www.kzar.co.uk/lisp-install/lisp-boot
chmod a+x lisp-boot
cd /etc/rc2.d
ln -s ../init.d/lisp-boot S98lispboot
mkdir /var/run/lisp

# Add the lisp user for lisp to run as
adduser lisp-user
touch /var/log/detachtty.log
touch /var/log/lisp-app-dribble
chown lisp-user:lisp-user /var/log/detachtty.log
chown lisp-user:lisp-user -R /var/run/lisp
chown lisp-user:lisp-user /var/log/lisp-app-dribble

# Make it so lisp will start the webserver and swank server each time
cd /usr/src/clbuild/
mkdir /var/lisp && cd /var/lisp
wget http://www.kzar.co.uk/lisp-install/server.lisp
mkdir images && cd images
wget http://www.lisperati.com/lisplogo_alien_128.png
chmod g+w -R /var/lisp
chown -R lisp-user:lisp-user /var/lisp

# Grab Apache2 and set it up with modlisp
apt-get install apache2 cl-modlisp libapache-mod-lisp apache2-threaded-dev
cd /etc/apache2/sites-available/
rm default && wget http://www.kzar.co.uk/lisp-install/default
cd /etc/apache2/mods-enabled
wget http://www.kzar.co.uk/lisp-install/lisp.load
wget http://www.kzar.co.uk/lisp-install/lisp.conf
cd /usr/lib/apache2/modules
wget http://www.kzar.co.uk/lisp-install/mod_lisp2.so

# Get rid of the old SBCL that comes with Debain (Thanks Todd)
apt-get remove sbcl
echo SBCL_HOME=/usr/src/clbuild/target/lib/sbcl >> /etc/profile
ln -s /usr/src/clbuild/target/bin/sbcl /usr/bin/sbcl
ln -s /usr/src/clbuild/target/lib/sbcl /usr/local/lib/sbcl
cd /usr/src/clbuild/target/lib/sbcl && rm -r site-system
ln -s /usr/lib/sbcl/* .

# Start it all running
/etc/init.d/apache2 restart
/etc/init.d/lisp-boot start

# Set up emacs (Do as the user who will use emacs)
cd ~ && wget http://www.kzar.co.uk/lisp-install/.emacs

Usage

  • Browse to http://SERVERNAME/lisp to view your website.
  • Type emacs /var/lisp/server.lisp to start editing the little example page.
  • Type M-x slime-connect RET RET in Emacs to connect to the running Lisp REPL

Notes

  • Add your user to the lisp-user group to edit the files
  • Make sure you have downloaded the .emacs for your user so slime-connect works properly

Leave a comment if you hit a problem and I’ll try and help - Dave.

Edit: Thanks to Todd for some good feedback, I have added an additional stanza of commands that helps get rid of Debian’s old SBCL version and let’s the nice new one still use some of the Debian installed cl package. (That’s the hope anyway, let me know if it worked for you / if there’s a better way to do that part)

April 15th 2010

Installing Compojure

Tags: compojure clojure howto Written by Dave Barker

The Clojure webframework Compojure is dead easy to install and get running but I got stuck. Anyway it’s working now and here are the steps I took:

Install Leiningen (as root)

cd /usr/local/bin/
wget http://github.com/technomancy/leiningen/raw/stable/bin/lein
chmod a+x lein

Setup Leningen and install Compojure (as user)

lein self-install

git clone git://github.com/weavejester/compojure.git
cd compojure
lein deps
lein jar
cp compojure.jar ~/.swank-clojure/
cp libs/* ~/.swank-clojure/

(~/.swank-clojure/ is inside my classpath because I use Emacs, replace that with the correct directory for your installation.)

Now a trial program straight from the Compojure homepage

(use 'compojure.core 'ring.adapter.jetty)

(defroutes main-routes
  (GET "/" []
    "<h1>Hello World</h1>")
  (ANY "*" []
    {:status 404, :body "<h1>Page not found</h1>"}))

(run-jetty main-routes {:port 8080})

Now browse to http://localhost:8080 and it should say “Hello World”.

Cheers, Dave.

March 08th 2010

Flash, Google Chrome and Debian Linux

Tags: linux howto Written by Dave Barker

Here’s how to get flash working on Chrome under Debian:

su -
cd /opt/google/chrome
wget http://download.macromedia.com/pub/labs/flashplayer10/flashplayer10_1_p3_linux_022310.tar.gz
tar xvzf flashplayer10_1_p3_linux_022310.tar.gz
mkdir plugins
mv libflashplayer.so plugins/
rm flashplayer10_1_p3_linux_022310.tar.gz

Then just restart Chrome :)

May 09th 2011

Stop Rails trying to parse the POST / PUT request body

Tags: rails ruby howto Written by Dave Barker

Rails 3 has a nice feature where it will parse the body of PUT and POST requests depending on the Content-type given. So for example if I POST XML to Rails it will all be decoded for me and put into the params hash.

Well it’s a nice feature until you try to switch it off, it’s a nightmare to disable! I managed it in the end, here’s what I did.

Created a piece of ‘rack middleware’ that overwrites the Content-Type for given paths:

# lib/no_parse.rb
class NoParse
  def initialize(app, options={})
    @app = app
    @urls = options[:urls]
  end

  def call(env)
    env['CONTENT_TYPE'] = 'text/plain' if @urls.include? env['PATH_INFO']
    @app.call(env)
  end
end

Included it:

#config/application.rb
require_relative '../lib/no_parse'

Added it into the ‘stack’:

#config/initializers/no_parse.rb

# (Change the :urls to specify which paths use NoParse.)
Rails.configuration.middleware.insert_before('ActionDispatch::ParamsParser',
                                             'NoParse', :urls => ['/example-path'])

Make sure you restart rails and you should be good to go. If it’s not working make sure the rake middleware command is listing the NoParse class above ActionDispatch::ParamsParser.

Cheers, Dave.

January 07th 2009

"Connection reset by peer" errors with cl-couch

Tags: couchdb lisp howto Written by Dave Barker

I was getting a lot of “Connection reset by peer” errors on my website, originally I thought it was Hunchentoot or couchDB but it turned out that c-couch was the problem.

To get things working comment out the :content parameter from the call to drakma:http-request inside (defun http-request … )

I’m not sure what those lines do or how they are broken but commenting them out solved the problem for me.

EDIT: The answer is those lines let you update data… whoops. Anyway I figured it out, here’s a patch that fixes the problem properly.

Cheers, Dave.

November 15th 2008

Installing Weblocks

Tags: weblocks lisp howto Written by Dave Barker

I managed to get Weblocks installed today, it’s been a bit of a struggle but with a lot of help from these guys I got there.

If you are having troubles have a look at these posts:

  1. [clbuild-devel] Problem installing Weblocks
  2. [Weblocks] Problem installing Weblocks
  3. [clbuild-devel] Problem installing Weblocks
  4. [cl-markdown-devel] [clbuild-devel] Problem installing Weblocks
  5. [clbuild-devel] [cl-markdown-devel] Problem installing Weblocks

I’m writing up what you need to do to get it installed and I’m about to actually give it a go now so I will post some more shortly. Cheers, Dave.

December 02nd 2008

How to strip Unicode and UTF using PHP

Tags: code php howto Written by Dave Barker

I have been working on a PHP contract recently and I needed to strip out anything non-asci.

Here’s a little function I wrote that takes a string and returns it minus all the crazy symbols:

// Function to strip out all non asci characters
function strip_utf($string) {
  for ($i = 0; $i < strlen ($string); $i++)
    if (ord($string[$i]) > 127)
      $string[$i] = " ";
  return $string;
}

Hope it helps, Dave.

October 01st 2010

Web.py checkboxes

Tags: web.py python howto code Written by Dave Barker

Checkboxes are a bit tricky with web.py, here’s how to get them working:

import web
from web import form

example_form = form.Form(
    form.Checkbox("lovelycheckbox", description="lovelycheckbox", class_="standard", value="something.. Anything!"),
    form.Button("Update checkbox", type="submit", description="Send"),
    )

class grabresults:
    def GET(self):
        f = example_form()
        return f.render()
    def POST(self):
        f = example_form()
        theresult = f['lovelycheckbox'].checked

OK, so that’s a dumb (and untested) example, but it gives you an idea. The ‘theresult’ variable is going to be true or false depending on if the ‘thelovelycheckbox’ was ticked or not.

Things to note:

  1. The checkbox has to be given a value, it’s a bug with web.py.
  2. To get the result you use .checked instead of the normal .value

Cheers, Dave.

July 04th 2009

Using dired-do-query-replace-regexp to rename read-only files

Tags: howto emacs Written by Dave Barker

If you use dired-do-query-replace-regexp to replace things in read-only files the bell will sound and the batch replace will stop. Here’s a quick workaround, cheers to bojohan in #emacs for helping me with this:

M-x set-variable RET inhibit-read-only RET t RET

Then do your replace again and finally set the variable back to nil again!

January 18th 2008

Virgin Media Broadband Installation on Linux

Tags: thoughts howto linux Written by Dave Barker

Just a quick warning to any Linux users who are getting Virgin Media broadband installed.

The welcome website you put your details into when the connection is first hooked up actually checks if you are using Windows / Mac or not. If not you will get this error:

"Incompatible OS or Browser

To set up Virgin Broadband, your computer needs to use a recent version of Windows or Apple Mac OSX and have a compatible Internet Browser. It looks like your computer does not meet these requirements.

For further information please consult your set-up guide or give us a call on 0906 212 1111*.

* Calls cost 25p per minute, with a 10p connection fee from Virgin Media landlines. If you're calling from a mobile phone, or another network, the charge may vary."

Anyway the solution is easy, install tamper data and Under the “Tamper Data - Options” you can update the User-Agent to Internet explorer or Safari etc. which the website allows.

It’s a stupid check anyway really as to the computer it’s just an ethernet connection so why it would only work on certain operating systems is beyond me!

July 04th 2009

Tramp ssh constant login problem

Tags: emacs mac howto Written by Dave Barker

I was having a problem on my macbook that I had to login every time I wanted to save or open a new file through Tramp. The weird thing was that tab completion only required me to login once.

Anyway I got to the bottom of it, just add this to your .emacs:

(setq tramp-default-method "ssh")

April 18th 2010

How to setup a simple Compojure project

Tags: compojure clojure howto code Written by Dave Barker

If you read my last Compojure post you will soon discover (like me) that you need to put in a little bit more work to get a practical setup. Thanks goes to arbscht in #compojure for showing me all of this.

So first up you need to create a new Leiningen project. Luckily there’s an in-built command to help.

lein new example
cd example

Now you should be able to see the skeleton of your new project. Next you need to setup the project.clj file, it’s used to set the name and dependencies for the project.

You will need to add a description, adjust the version and add the required dependencies for a Compojure based website. Here’s what an example:

(defproject example "0.0.1"
  :description "Test website to learn Compojure"
  :dependencies [[org.clojure/clojure "1.1.0"]
                 [org.clojure/clojure-contrib "1.1.0"]
                 [compojure "0.4.0-SNAPSHOT"]
                 [hiccup "0.2.3"]
                 [ring/ring-jetty-adapter "0.2.0"]
                 [leiningen/lein-swank "1.2.0-SNAPSHOT"]])

Now inside ./src/example/ we need to create a server.clj we can use to setup the webserver, here’s mine:

(ns example.server
  (:use compojure.core
        ring.adapter.jetty))
(defroutes main-routes
  (GET "/" []
    "<h1>Hello World</h1>")
  (GET "/test/:name" req
       (test-page (:name (:params req))))
  (ANY "*" []
    {:status 404, :body "<h1>Page not found</h1>"}))

(defn start []
  (run-jetty #'main-routes {:port 8080 :join? false}))

(defn test-page [name]
  (str "<b>Hello" name "</b>"))

Three interesting things to note with that example:

  1. The call to run-jetty has been put inside a function. That way when the file is included the server doesn’t automatically start. Inconvenient but it lets us :reload the file as much as we need.
  2. run-jetty is passed #’main-routes instead of just main-routes, that is useful so that any changes to our routes are put in effect as soon as the (defroutes main-routes …) s-exp is re-evaled.
  3. The page /test/* is going to display “Hello *” as an example of how to capture “parameters” from the user. Try just passing req instead of (:name (:params req)) to see what else is available to you.

Now we are ready to give this a go, make sure you’re in the root of your project and type

lein deps
lein swank

To start a Clojure process for your project that also runs a Swank server. Then you just need to open Emacs and do the following:

M-x slime-connect ret ret
(use 'example.server)
(example.server/start)

Now browse to http://localhost:8080 and you should see a hello world page. Browse to http://localhost:8080/test/Dave and it should say “Hello Dave”. Finally change your server.clj to say “Hello new world” and re-eval the (defroutes …). The change should take effect as soon as you refresh your browser!

Cheers, Dave.