skip main content

Posts Tagged ‘howto’

Fixing the trailing slash in Nginx

posted by Duncan at 10:16 am on July 5th, 2010

The solution as usual is super simple. The problem I was having was that when you didn’t put a trailing slash on a url, it would not handle it and throw a 404. I saw lots of fixes with complex re-write rules, but it turns out that a simple fix for me was to add this to my .conf file:

# http://wiki.nginx.org/NginxHttpCoreModule#server_name_in_redirect
server_name_in_redirect off;

So your *.conf would look like this

server {
  listen  80;
  server_name  localhost;
  ...
  server_name_in_redirect off;
  ...
}

Installing Nokogiri on CentOS5

posted by Duncan at 10:45 am on November 13th, 2008

Nokogiri is an HTML, XML, SAX, and Reader parser with XPath and CSS selector support. It claims to be a drop in replacement for Hpricot, and it claims to be faster. I think the latter has been addressed but the drop-in bit, well. You see, the Hpricot’s gem had always in the past, just installed, but with Nokogiri I had dependency problems. Turns out I needed a few extra libs that were not installed on my machine. Here’s how I got things going again:

# It seems you need the latest version of rubygems
sudo gem update --system
# and some RPM's
sudo yum install libxml libxml-devel libxslt libxslt-devel
# now the gem should install ok
sudo gem install nokogiri

Installing daemontools on CentOS5 x86_64

posted by Duncan at 9:43 pm on November 4th, 2008

[UPDATE] It turns out you need to apply the patch below on any recent Linux distribution, not just 64 bit architectures, if that helps anyone.

More head scratching, web searching, friend asking, and huzzah, finally solved. How to actually install daemonstools on my SliceHost CentOS5 slice. The catch for me was that it wouldn’t compile because ‘it required a patch‘. Who’d of known? So here’s my notes:

$ sudo mkdir -p /package
$ sudo chmod 1755 /package/
$ cd /package/
$ sudo wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
$ sudo tar xzf daemontools-0.76.tar.gz
$ sudo wget http://www.qmail.org/moni.csi.hu/pub/glibc-2.3.1/daemontools-0.76.errno.patch
$ cd admin/daemontools-0.76
$ sudo patch -p1 < ../../daemontools-0.76.errno.patch
$ sudo rm ../../daemontools-0.76.errno.patch ../../daemontools-0.76.tar.gz
$ sudo ./package/install
...
...
Adding svscanboot to inittab...
init should start svscan now.

Installing Python’s Twisted on CentOS5 x86_64

posted by Duncan at 10:43 am on October 26th, 2008

I had to do a bit of searching to find the correct way to install Twisted on a 64 bit CentOS 5 machine, like the one I have via virtual hosting with SliceHost. But once I had the answers it was very actually very simple, so this should save you the same headache.

I was having an import problem with Twisted’s subpackages, and was also initially having a problem building the lib from source. The first problem was caused by the fact that 64 bit CentOS installs things in both /usr/lib and /usr/lib64 which confuses Twisted, as it expects things in the same directory. The final problems was due to me trying to compile Twisted without the python-devel lib and the Twisted Zope Interfaces which is a dependancy.

So to install, run these commands:

$ sudo yum install python-devel python-crypto pyOpenSSL zope
$ mkdir src;cd src
$ wget http://tmrc.mit.edu/mirror/twisted/Twisted/8.1/Twisted-8.1.0.tar.bz2
$ tar jxvf Twisted-8.1.0.tar.bz2
$ cd Twisted-8.1.0
$ sudo python setup.py install --install-lib /usr/lib64/python2.4

Bingo, and you should now be able to test with:

$ python
...
>>> import twisted
>>> import twisted.web

The lines above should give you no output.

Installing MySQL gem on CentOS

posted by Duncan at 10:20 am on October 13th, 2008

Old news, but you’d be surprised how many times the same:

Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.
...

error brings everything to a halt. Well on Centos the way to install the MySQL gem is:

$ sudo yum install mysql mysql-devel gcc
...
 
# 32 bit machine
$ sudo gem install mysql -- \
> --with-mysql-include=/usr/bin/mysql \
> --with-mysql-lib=/usr/lib/mysql
 
# or 64 bit like they are on SliceHost
$ sudo gem install mysql -- \
> --with-mysql-include=/usr/bin/mysql \
> --with-mysql-lib=/usr/lib64/mysq
 
Building native extensions.  This could take a while...
Successfully installed mysql-2.7
1 gem installed
...

Setting the timezone on CentOS

posted by Duncan at 12:51 pm on October 1st, 2008

I forget this pretty much all the time, even though it’s a fairly simple operation. There are loads of timezone data files stored in:

/usr/share/zoneinfo

So for my CentOS install, to set my machine to London time, I use:

#
# this is not correct for me
#
$ date
Wed Oct  1 07:43:58 CDT 2008
#
# to fix it
#
$ sudo rm /etc/localtime
$ sudo ln -s /usr/share/zoneinfo/Europe/London /etc/localtime
#
# now check it's ok
#
$ date
Wed Oct  1 12:42:33 GMT 2008

I imagine this works on Redhat and Fedora as well, but I can’t be sure on other Linux distros.

Twammer, sending stuff from Twitter to Yammer

posted by Duncan at 8:12 pm on September 28th, 2008

I use Twitter. I don’t really post much, but I do like to dip in and hear what my friends are doing. Yammer is like a private Twitter for companies. We have just had a network set up for the BBC, which is interesting. Again, I like the idea of posting what I am doing and dipping into what other people are doing around the organisation.

So you can see my problem, I’m doubling up here a bit. When I post something to Twitter, and I think it would be relevant for work too, I don’t want to have to open a different interface and post it again. Now there are services like ping.fm which will sync every site you belong to, but I what to decide what gets posted at work and what doesn’t in this instance. The simple answer is to build something that looks at my Twitter feed and if it sees anything new, then posts it off to Yammer. My friend Mr Humfrey does that very thing. I wanted more than this though, I wanted to filter, plus I wanted to make it easy to use, so I have written this very simple app that does the job:

  1. Read my Twitter feed every n minutes for changes
  2. Keep messages with my chosen keyword
  3. Remove keyword, and send off to Yammer

Twammer usage:

# Display help
./twammer -h
 
# check Twitter messages with last 5 mins (default)
# filter by #bbc but don't send anything to Yammer
./twammer -t 47983 -u user -p pass -f bbc -q
 
# check Twitter messages within last 10 mins
# send anything to Yammer. Show output
./twammer -t 47983 -u user -p pass -d 10 -v

This is designed to be run as a cron job. You must also make sure you run it at the same interval as the –delay in the app. Here’s what my crontab looks like:

0,5,10,15,20,25,30,35,40,45,50,55 * * * * /home/duncan/bin/twammer -t 47983 -u user -p pass -f bbc > /dev/null

[UPDATE] Changed to using the correct API instead of scraping the RSS

Shuffling an Array in Ruby

posted by Duncan at 12:40 pm on November 10th, 2006

[UPDATE] Someone called NoKarma and perraultd have posted even nicer versions on the Code Snippets site, thanks!

class Array
  def shuffle
    sort_by { rand }
  end
 
  def shuffle!
    self.replace shuffle
  end
end

I had a situation when I need to shuffle the contents of an array to randomize the stuff inside. After hunting and hacking the final solution appeared to be:

class Array
  def shuffle!
    size.downto(1) { |n| push delete_at(rand(n)) }
    self
  end
end

So you just enhance the Array Class and give it a new funky method shuffle! so you can do stuff like:

a = [1,2,3,4,5,6,7,8,9]
a.shuffle!
=> [5, 2, 8, 7, 3, 1, 6, 4, 9]

Just how cool is Ruby.

Another tag cloud script for Ruby on Rails

posted by Duncan at 9:09 am on July 6th, 2006

Or any other Ruby program really. I know there are attempts already out there but none that really suited my purposes. I needed a simple way of creating that tag-cloud-look for many situations. I needed a tag cloud by size or by colour and I didn’t want it to do everything, just provide me with the style attributes I needed to get the job done. Below is an example of what gets returned by default:

font-size:16px;color:rgb(70,70,70);

Here’s the code; it comes with no warranty.

With all these tags cloud scripts you really only need 3 parameters:

  1. The total counts of items – For example you have 10 tags each that has been used numerous times. The total counts would be all of the uses added together
  2. The minimum count of items in a batch – Using the example above this would be a count of the uses for the tag that has been used least
  3. The maximum count of items in a batch – Using the example above this would be a count of the uses for the tag that has been used most

Below is the actual script and then below that I have stuck a quick example of how you could use it.

def font_size_for_tag_cloud( total, lowest, highest, options={} )
  return nil if total.nil? or highest.nil? or lowest.nil?
  #
  # options
  maxf = options.delete( :max_font_size ) || 14
  minf = options.delete( :min_font_size ) || 11
  maxc = options.delete( :max_color ) || [ 0, 0, 0 ]
  minc = options.delete( :min_color ) || [ 156, 156, 156 ]
  hide_sizes = options.delete( :hide_sizes )
  hide_colours = options.delete( :hide_colours )
  #
  # function to work out rgb values
  def rgb_color( a, b, i, x)
    return nil if i <= 1 or x <= 1
    if a & b
      a-(Math.log(i)*(a-b)/Math.log(x)).floor
    else
      (Math.log(i)*(b-a)/Math.log(x)+a).floor
    end
  end
  #
  # work out colours
  c = []
  (0..2).each { |i| c && rgb_color( minc[i], maxc[i], total, highest ) || nil }
  colors = c.compact.empty? ? minc.join(',') : c.join(',')
  #
  # work out the font size
  spread = highest.to_f - lowest.to_f
  spread = 1.to_f if spread <= 0
  fontspread = maxf.to_f - minf.to_f
  fontstep = spread / fontspread
  size = ( minf + ( total.to_f / fontstep ) ).to_i
  size = maxf if size > maxf
  #
  # display the results
  size_txt = "font-size:#{ size.to_s }px;" unless hide_sizes
  color_txt = "color:rgb(#{ colors });" unless hide_colours
  return [ size_txt, color_txt ].join
end

and now a quick example of it’s use in a rails view. This code assumes the db find call looks something like this:

@foo = Foo.find( :all,
  :select => '*, COUNT(DISTINCT(i.id)) AS item_cnt',
  :joins => 'AS f INNER JOIN bars AS b ON f.id=b.foo_id',
  :group => 'b.id',
  :order => 'item_cnt DESC',
  :limit => 50
)

Below just loop through your db results and calls font_size_for_tag_cloud for each item, passing in the required parameters. There are a few options available but if you leave them out you should still see something useful.

<ul>
<% for f in @foo -%>
<%= content_tag( 'li', f.some_label, :style => font_size_for_tag_cloud( f.bars.size, 
  f.first.count_items, 
  f.last.count_items,  
) ) %>
<% end -%>
</ul>

That’s it! I guess I should turn it into a plugin but hey, there’s to much reading to be done on ActiveResource at the moment heyhey!


back to the top