Rocu.de

Love, caffeine and omlette

Month: April 2013

How to append a footer to all your emails in Rails

In Germany and many other countries as a company you are required to add a legal footer to your emails.

Of course you could just add the legal snippet into the footer of each of your emails.

Or you can create a partial and include it.

But theres a better way.

Writing the test

So let's start with a test.

require 'spec_helper'

class FakeMailer < ActionMailer::Base  
  def any_email
    mail(from: 'a@example.com', to: 'b@example.com', subject: "Hello", body: 'A body')
  end
end

describe 'Email Signature' do  
  it 'appends a signature to every email' do
    signature_divider = "-- n"

    email = FakeMailer.any_email.deliver
    email.body.to_s.should match(signature_divider)
  end
end  

This fails of course. I did match on the signature divider which contains of 2 dashes, a space and a newline. This is a old convention from the Newsnet and can be automatically parsed by many email clients.

The implementation

An elegant way of solving this is to implement an mail interceptor.

An interceptor catches mails that are send and can modify their content.

class EmailSignature  
  def self.delivering_email(message)
    message.body = String(message.body) + footer
  end

  def self.footer
    "-- n" +  "Insert your footer here"
  end
end  
Mail.register_interceptor(EmailSignature)  

The interceptor in our case appends the footer to the body of the message. It needs to be registered with

Mail.register_interceptor

Conclusion

This is a very simple way to add a footer to all your text emails.

It does not take into account HTML emails and email's with multiple parts. (Though it's no black magic to modify the code.)

Backup a local directory to a FTP server

I had to backup a local directory to a FTP server.

My first impulse was to use Rsync but I was out of luck. Rsync doesn't work over FTP since it is a protocol of it's own.

That's when I stumbled over lftp:

LFTP is a sophisticated ftp/http client, and a file transfer program supporting a number of network protocols. Like BASH, it has job control and uses the readline library for input. It has bookmarks, a built-in mirror command, and can transfer several files in parallel.

In order to use lftp you have to install it using the package manager of your choice.

brew install lftp

Now you create a simple script. We use the mirror command here in order to sync a local directory onto the server.

SERVER="your.ftp.server"
USERNAME="user"
PASSWORD="pass123"

LOCAL_DIR="/source/dir"
REMOTE_DIR="/target/dir"

lftp -c "set ftp:list-options -a;
open ftp://$USERNAME:$PASSWORD@$SERVER;
lcd $LOCAL_DIR;
cd $REMOTE_DIR;
mirror --reverse"

The script uses your credentials to log in to the ftp server. The it starts to mirror your local directory to the directory on the server. The flag "reverse" is appended to the mirror command because per default lftp mirrors the content from the server into your local directory.

The mysterious line

lftp -c "set ftp:list-options -a;

is necessary if you want to transfer hidden files as well and your FTP server does not list them per default.

Conclusion

Often FTP backup space is one of the cheapest ways to back up a server, that's when lftp comes really handy. It is way slower then Rsync - but works fine in most situations.

I am glad I have lftp in my toolchain now.

How to prevent a cron job from running multiple times

Sometimes a cron job might run slower, than you anticipated and many instances of it stack up.

You can increase the time interval during starts of the cron job - this can lead to problems in the future however.

Fortunately there's a easy and clean fix.

Just replace your cronjob with this:

/usr/bin/flock -n /var/lock/<foobar> <long-running-task>

Whenever your cron job is started a lock file will be created and no other instance can start.

Conclusion

This a simple remedy for colliding cron job's. I use it frequently.

© 2017 Rocu.de

Theme by Anders NorenUp ↑