Posted
02 Dec 2009 @ 13:30

Categories
,

Comments
None

Author
Alex

'Merge All Windows' AppleScript

A friend reminded me of how nice it would be to merge all the windows in Safari back together using LaunchBar (or QuickSilver for that matter). So I wrote a quick AppleScript to accomplish the task;

on gui_scripting_status()
    tell application "System Events"
        set ui_enabled to UI elements enabled
    end tell
    if ui_enabled is false then
        tell application "System Preferences"
            activate
                set current pane to pane id "com.apple.preference.universalaccess"
                    display dialog "The GUI scripting architecture of Mac OS X is currently disabled." & return & return & "To activate GUI Scripting select the checkbox \"Enable access for assistive devices\" in the Universal Access preference pane." with icon 1 buttons {"Okay"} default button 1
        end tell
    end if
    return ui_enabled
end gui_scripting_status

on click_menu(app_name, menu_name, menu_item)
    try
        tell application app_name
            activate
        end tell
        tell application "System Events"
            click menu item menu_item of menu menu_name of menu bar 1 of process app_name
        end tell
        return true
    on error error_message
        return false
    end try
end click_menu

if gui_scripting_status() then
    click_menu("Safari", "Window", "Merge All Windows")
end if

The ‘gui_scripting_status()’ routine is taken and modified from code that can be found here: http://www.macosxautomation.com/applescript/uiscripting/index.html.

Check back soon.

Posted
03 May 2009 @ 18:31

Categories
,

Comments
2 Comments

Author
Alex

Clearing Out Old Sessions

Rails

A while ago I started setting up my websites to use ActiveRecord as a session store, this means that the session information for all the visitors to my website is placed in a table in my database. It may or may not be the best way to store sessions but it’s certainly faster than the filesystem and my VPS doesn’t really have the memory capacity for an ‘in memory’ store.

Anyway, one day I decided to perform some DB maintenance, check tables where okay etc, upon logging into the DB I noticed that my sessions table had grown quite large, almost 125,000 records, little did I realize that the sessions are persisted forever in the DB.

I didn’t think it was the best idea to keep all the session data so wrote the following script and put it in ‘lib/tasks/session.rake’;

namespace :session do
    desc "Prune old session data"
    task :prune => :environment do
        sql = ActiveRecord::Base.connection()
        sql.execute "SET autocommit=0"
        sql.begin_db_transaction
            response = sql.execute("DELETE FROM sessions WHERE `updated_at` < DATE_SUB(CURDATE(), INTERVAL 1 DAY)");
        sql.commit_db_transaction
    end
end

This gave me a ‘session:prune’ rake task. The task removes all sessions older than 1 day from the sessions table. I then added a CRON job for in the following format;

0 0 * * * cd /home/user/railsapp && rake RAILS_ENV=production session:prune > /dev/null 2>&1

The job above basically calls the ‘session:prune’ rake task at midnight every night.

The code in the task in MySQL specific but without a model representing the session table I couldn’t (or at least couldn’t think of a way) to make the code any more ruby-fied. In the event that you do have, or decide to create a session model the following code may work in your task (warning: untested);

Session.destroy_all("created_at" < (Time.now - 1.day))

Hope the above snippet solves at least one of your ActiveRecord session woes.

Check back soon.

Posted
03 May 2009 @ 17:50

Categories
,

Comments
None

Author
Alex

Clearing Out The rFlickr Cache

rFlickr

Assuming you’ve followed the Caching Your Photographs tutorial at some point, you’ll probably have had a lot of fun either deleting the cache every time you upload a new photo or you’ve written your own automated method by now. For those of you that haven’t written your own method of dumping the cache yet, here’s how I do it.

First of all, I created a ‘lib/actions’ folder in the root of my rails project. Inside this folder I created the file ‘photography_action.rb’ with the following contents;

class PhotographyAction
    def self.clear_cache
        ActionController::Base.new.expire_fragment(%r{photography.cache})
    end
end

The above fragment naming assumes that your photos are on a page called ‘photography’ if they are elsewhere, change the fragment to expire that page instead.

Fairly simple I think you’ll agree, you may also be asking yourself ‘why the extra file?’, the main reason for the new file is so that the cache clearing can be executed from a new rake task that doesn’t remove all your cached pages or from an admin page on the website.

You’ll also need to update your ‘config.load_paths’ in ‘environment.rb’. After updating, mine looks like this;

config.load_paths += %W( #{RAILS_ROOT}/app/sweepers #{RAILS_ROOT}/lib/actions )

Inside some action in some, preferably protected, controller somewhere, add the following (redirecting to anywhere you fancy);

PhotographyAction.clear_cache
redirect_to :action => 'index'

Now for the rake task. Inside the directory ‘lib/tasks’ (create it if it doesn’t exists) create the file ‘photography.rake’ then put the following code inside the file;

namespace :photo do
    namespace :cache do
        desc "Clear out photography cache"
        task :clear => :environment do
            PhotographyAction.clear_cache
        end
    end
end

You should then be able to run;

rake photo:cache:clear

From the base of your project in order to clear the cache.

Bear in mind, the code above is literally just a convenient way of clearing out the fragment cache so new photos show up on your photo page, it does not delete photos, nor does it perform a refresh automatically, although, you could add it to a CRON job.

When I get chance, I intend to automate this process and build it into rFlickr along with a new, improved, caching mechanism. I’m sure the above will tide you over for now though.

Check back soon.

Posted
12 Oct 2008 @ 14:31

Categories
,

Comments
2 Comments

Author
Alex

Calculating Work Days In Java

In work this week I came across a couple of problems in which I needed to performs some calculations involving dates and a number of “work days” rather than just normal numbers of days. My first few attempts filed miserably, so I did some Googling to see if I could find anyone else that had come across the same problem and of course, there were plenty of people.

The code I eventually used I found shoehorned into the middle of a coding help forum and, with a little bit of tweaking, it calculated the number of whole work days in between two dates. The code is as follows;

public static int calculateDuration(Date startDate, Date endDate)
{
    Calendar startCal = Calendar.getInstance();
    startCal.setTime(startDate);

    Calendar endCal = Calendar.getInstance();
    endCal.setTime(endDate);

    int workDays = 0;

    if (startCal.getTimeInMillis() > endCal.getTimeInMillis())
    {
        startCal.setTime(endDate);
        endCal.setTime(startDate);
    }

    do
    {
        startCal.add(Calendar.DAY_OF_MONTH, 1);
        if (startCal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && startCal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY)
        {
            workDays++;
        }
    }
    while (startCal.getTimeInMillis() <= endCal.getTimeInMillis());

    return workDays;
}

This code solved my first problem, however I couldn’t find any code to solve my second problem, how to calculate a final date from a start date and a specified number of work days, to do the calculation I came up with the following code;

public static Date calculateEndDate(Date startDate, int duration)
{    
    Calendar startCal = Calendar.getInstance();

    startCal.setTime(startDate);
    
    for (int i = 1; i < duration; i++)
    {
        startCal.add(Calendar.DAY_OF_MONTH, 1);
        while (startCal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || startCal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY)
        {
            startCal.add(Calendar.DAY_OF_MONTH, 1);
        }
    }

    return startCal.getTime();
}

Hope this code works as well for you as it did for me.

Check back soon.

Update: Improved the calculating code with the suggestion from Anass (below) and made some more accuracy & business logic improvements to the ‘calculateDuration’ method. Enjoy.

Posted
12 Oct 2008 @ 14:00

Categories
,

Comments
None

Author
Alex

Flickr BBCode

phpBB is one of the most widely used forum systems on the internet and Flickr is one of the most popular photo sharing websites, unfortunately there is still no concrete way to integrate the two of them. As a temporary solution I came up with the following piece of BBCode to allow for the easy display of Flickr images in phpBB forums.

First, you will need to navigate to the “Admin Control Panel” of phpBB then to the “Posting” section. From here navigate to the screen that allows you to add custom BBCode.

In the “Usage” section paste the following code (‘\’s denote a continuation of the current line, don’t include them);

[flickr=<a href="{URL1}" title="{TEXT1}"><img src="{URL2}" width="{NUMBER1}" \
height="{NUMBER2}" alt="{TEXT2}" /></a>][/flickr]

In the “HTML” section paste;

<a href="{URL1}" title="{TEXT1}"><img src="{URL2}" width="{NUMBER1}" \
height="{NUMBER2}" alt="{TEXT2}" /></a><br /><a href="{URL1}">{TEXT2}</a>

Then in the “Help” section paste:

Flickr: [flickr=<Flickr, Medium Size, Copy & Paste HTML>][/flickr]

And that’s it, you can use the tag by navigating to one of your photo’s Flickr “All Sizes → Medium” page (e.g. http://www.flickr.com/photos/digitalpardoe/2900618617/sizes/m/), copying the code in the “1. Copy and paste this HTML into your webpage:” box. And inserting it after the “=” in the Flickr BBCode tag, e.g;

[flickr=<a href="http://www.flickr.com/photos/digitalpardoe/2900618617/" \
title="Isolation by digital:pardoe, on Flickr"> \
<img src="http://farm4.static.flickr.com/3095/2900618617_26bc8abc12.jpg" \
width="500" height="334" alt="Isolation" /></a>][/flickr]

Check back soon.

Posted
30 May 2008 @ 23:03

Categories
,

Comments
8 Comments

Author
Alex

Caching Your Photographs

rFlickr

If you have at some point followed my now fairly ancient rFlickr tutorial you may have noticed that your photo page loads quite slowly, and that my photo page loads fairly quickly. To get my page to load as quickly as it does required a small custom caching method and a willingness on my part to sacrifice some bandwidth. Here’s how I did it.

This tutorial assumes that you have already worked through the previously mentioned rFlickr tutorial and have something similar to it set up. It also assumes that you have some knowledge of Rails, not that my knowledge was particularly wide ranging at the point I wrote this caching method.

First of all, you will need a table in your database to store the information about your photographs, I suggest the structure illustrated in the migration below;

class CreatePhotos < ActiveRecord::Migration
    def self.up
        create_table :photos, :id => false do |t|
            t.column "flickr_id", :string, :limit => 25, :null => false
            t.column "title", :string, :limit => 250
            t.column "description", :text
            t.column "url", :string, :limit => 250
        end
    
        add_index :photos, :flickr_id
    end
  
    def self.down
        drop_table :photos
    end
end

Once you have created this table you will need to create some folders to store the cached images, I created the following folders and will be using them throughout this tutorial;

#{RAILS_ROOT}/public/images/flickr_cache/small/
#{RAILS_ROOT}/public/images/flickr_cache/large/

Then generate the model for this photos table;

$ cd /your/rails/application
$ ./script/generate model Photo

Your view from the first tutorial can remain almost the same (details at the end of the post), however, to see the greatest speed improvement I suggest caching it, i.e;

<% cache do %>
... Your view code here. ...
<% end %>

Then modify your view method in your photography controller to read something like;

def view
    unless read_fragment({})
        check_cache
        @photos = Photo.find(:all)
    end
end

The above code will make sure that a cached photography page doesn’t already exist, if it doesn’t, then and only then will it check that the photograph cache is up to date and query the database.

We have not yet created a ‘check_cache’ method, this method is the core method to make the photography page load much, much faster, even when the photography page’s cache does not exist. The method should be placed as the last method in your photography controller, the code is as follows;

private
def check_cache
    if ENV['RAILS_ENV'] == 'production'
        flickr = Flickr.new(RAILS_ROOT + "/config/flickr.cache", FLICKR_API_KEY, FLICKR_SHARED_SECRET)
        @photos = flickr.people.getPublicPhotos(flickr.people.findByUsername(FLICKR_USERNAME))
      
        @db_photos = Array.new
        Photo.find(:all).each { |p| @db_photos.push(p.flickr_id) }

        for photo in @photos.reverse
            if !@db_photos.include?(photo.id)
       
                db_photo = Photo.new
                db_photo.flickr_id = photo.id.to_i
                db_photo.title = photo.flickr.photos.getInfo(photo.id).title
                db_photo.description = photo.flickr.photos.getInfo(photo.id).description
                db_photo.url = photo.flickr.photos.getInfo(photo.id).urls.values[0]
          
                db_photo.save
          
                open(File.expand_path("#{RAILS_ROOT}/public/images/flickr_cache/small/" + photo.id + ".jpg"),"w").write(open(photo.url('s')).read)
                open(File.expand_path("#{RAILS_ROOT}/public/images/flickr_cache/large/" + photo.id + ".jpg"),"w").write(open(photo.url).read)
            end
        end
    end
end

The following code will only run if you are in production mode (and probably test mode too). It will then load the necessary information from Flickr using the methods outlined in the rFlickr tutorial post. The method then iterates through the collection of photos from Flickr in reverse, so they appear in the same order in the database as the order they appear on Flickr.

It will then check if the photo already exists in the database, if it does not it will store a copy of the photograph’s information in the database and download previews of the images from Flickr to your server, previews of images can then be loaded from your server rather than Flickr’s slow servers .

To take advantage of the cache you will also need to modify your view to access the thumbnails from your newly created local repository rather than from Flickr’s servers, i.e;

<% for photo in @photos.reverse %>
    <%= image_tag("/images/flickr_cache/small/" + photo.flickr_id + ".jpg", :alt => photo.title) %>
<% end %>

Hope this goes some way to helping you improve the speed of your website.

Check back soon.

Update: As I have just been reminded in the comments, I forgot a piece of code to make this tutorial work correctly. You should put the line;

require 'open-uri'

Either in the bottom of you ‘environment.rb’ file or just under the ‘class’ line in the controller that is responsible for your photography page.

Update (3rd May 09): The code in the ‘check_cache’ method has been updated slightly, it now makes less round trips to the database, should speed things up if your DB server is in a different location to your application server. Also, any redirection problems you may have faced before should be solved by the new rFlickr ruby gem that has support for ‘farm’ URLs built in.

Posted
15 Nov 2007 @ 13:08

Categories
,

Comments
14 Comments

Author
Alex

Setting Hard Drive Icons In OS X

Another day and I’m finally getting around to writing another tutorial. This time I thought I concentrate on something I’ve had quite a lot of emails about, ’you’ve given me the icons, how do I go about using them’. I suppose it’s quite an important thing, if your supplying people with something, to tell them how to use it. (Warning: this is a Mac only tutorial).

In previous version of Mac OS X, before Leopard you could get away with applying HD icons though copy and paste alone, and from that point on everything would work fine. Unfortunately, one of the first things I noticed about applying HD icons in Leopard is that copy and paste gives bad results, especially for the scaled down versions of the icon in the new Finder sidebar.

I eventually found the correct way to apply the icons, it involves a little bit of Terminal usage but don’t be afraid. (I have a sneaking suspicion you may also need the Apple Developer Tools installed, these should have been included on your Leopard DVD). I believe this tutorial also applies to setting HD icons on previous versions of Mac OS X.

The first command we will execute in the Terminal copies the icon resource (.icns file) to the correct place on the target HD. You will need to fill in the paths in a way suitable for your system but you can do this by dragging and dropping onto the terminal window.

sudo cp -f /Path_to_Icon/icon_file.icns /Path_to_Drive_Root/.VolumeIcon.icns

Not too difficult was it. The next line will tell the HD to accept a thrid-party icon.

sudo SetFile -a C /Path_to_Drive_Root

The final line will restart the Finder so you can see the changes.

killall Finder

And that’s it. You should see your new icon in the Finder and the correct scaled down version in the Finder sidebar.

Hope you get it working. Check back soon.

Update: After many emails I have written a small utility called Set Icon that automates this process, if you are not feeling confident with the Terminal commands you can download it here.

Update: I’ve just got my hands on a copy of Snow Leopard and the above instructions still seem to work correctly, happy icon changing.

Posted
28 Jul 2007 @ 21:51

Categories
,

Comments
4 Comments

Author
Alex

Using rFlickr

rFlickr

I said it was coming and here it is, my little tutorial on how to use the rFlickr Ruby on Rails gem to create a photograph section like the one on my own website. The first thing to note is that pretty much all of the options available in the Flickr API (here) are available for use in rFlickr due to the fact it is all based around XML. There is a laborious process of configuration to go through, however, to make everything work, but once this is done you should have no problems.

Firstly install the rFlickr gem, I should at this juncture note the fact I am primarily a UNIX user so will aim these instructions at other UNIX users, mainly because I don’t know the specifics for Rails installations on Windows. So lets dive in (‘$’ denotes the terminal prompt and ‘\’ denotes line continues below):

$ sudo gem install rflickr --include-dependencies

The second thing you will need to do is make sure you have a Flickr account with some photos on it then pay a visit to http://www.flickr.com/services/api/keys/ and sign yourself up for an API key, once you have generated the key make a note of the key itself and the ‘secret’ that you are given, you will be needing these quite a bit.

The next thing to do is to basically follow the tutorial here, albeit with a few modifications, I have re-written the tutorial in full below.

$ cd /your/rails/application
$ ./script/console

To make differences clear the Rails console prompt will be shown as ‘>>’, don’t forget to replace the x’s with your information.

>> require 'flickr'
>> API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
>> SHARED_SECRET = "xxxxxxxxxxxxxxxx"
>> flickr = Flickr.new("/tmp/flickr.cache", API_KEY, SHARED_SECRET)
>> flickr.auth.token
=> nil

The above just sets up your rFlickr object and makes sure that you don’t already have a key.

>> flickr.auth.getFrob

This returns a value that you will need to save somewhere.

>> flickr.auth.login_link
=> "http://some.link.flickr.com"

Click or copy the link you are given into a browser and authorize the API for usage, don’t worry, we’re almost there.

>> flickr.auth.getToken('that_frob_number_we_saved')
>> flickr.auth.cache_token
>> exit

Right, this is as far as the tutorial online goes, but there are some other useful steps we need to take to make everything more useable, mainly the moving of the token as the ‘/tmp’ directory may get cleared by our host.

$ cp /tmp/flickr.cache /your/rails/application/config/flickr.cache
$ rm /tmp/flickr.cache

Now we can get onto the actual programming and leave the authentication business behind.

We’re going to need a controller to use, for the purposes of this tutorial I will use a controller named ‘Photography’, it should save me some time as that’s what mine is called, the page to be rendered will be called ‘view’.

In the file ‘photography_controller.rb’ we will need the following information, rename as necessary to your application.

class PhotographyController < ApplicationController
    API_KEY = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    SHARED_SECRET = "xxxxxxxxxxxxxxxx"

    def index
        view
        render :action => 'view'
    end
  
    def view
        flickr = Flickr.new(RAILS_ROOT + "/config/flickr.cache", \
            API_KEY, SHARED_SECRET)
        @photos = flickr.people.getPublicPhotos( \
            flickr.people.findByUsername("YOUR_FLICKR_NAME"))
    end
end

Then in the ‘views.rhtml’ that you will have created in your ‘views’ folder (or at least, are creating now) paste the following code.

<% for photo in @photos %>
    <a href="<%= photo.flickr.photos.getInfo(photo.id).urls.values %>" \
        ><img src="<%= photo.url('s') %>" /></a>
<% end %>

And that’s it, your basically done, all the thumbnails will link directly to your Flickr page, easy wasn’t it? The main problem occurs when you load your newly created page, it’s very, very slow, due to the speed of the Flickr API (I think). In order to improve the situation I would recommend using either page or fragment caching, but that will be covered in a future tutorial.

Hopefully this will have given you a few pointers in using the rFlickr gem, read through the Flickr API for more inspiration if you are feeling adventurous. Check back soon.

Update: If you are having problems with Rails 2.0, take a look at this fix.

Update: I have written a new tutorial on caching your photos page, that should speed it up a lot, assuming you are having problems.

Posted
17 Nov 2006 @ 16:26

Categories
, ,

Comments
None

Author
Alex

TextMate, Java & Compiling [Updated]

TextMate Bundle

For those of you that do not already know TextMate is a brilliant text editor for Mac OS X, including syntax highlighting and the most useful snippets system I have ever come across. If your a budding coder and want to try it out visit: macromates.com, and download a copy.

This post illustrates some of the bundle items I have either modified or added to TextMate to make it easier to use for Java development. If you use TextMate already then hopefully you will know how to use the bundle editor if you don’t then there is some good documentation available here.

In the code snippets below a ‘\’ at the end of a line indicates the code continues but is illustrated on the line below.

1. Compile, but no run.

echo "<h2>Compiling $TM_FILENAME</h2>"
cd "$TM_DIRECTORY"
javac -encoding UTF8 "$TM_FILENAME" &> >("${TM_RUBY:-ruby}" \
    -rtm_parser -eTextMate.parse_errors)

2. Run in terminal.

osascript <<EOF
    tell application "Terminal"
        activate
        try
            close front window
        end try
        do script "cd '$TM_DIRECTORY'; java '${TM_FILENAME%.java}'"
    end tell
EOF

3. Compile and run in TextMate.

echo "<h2>Compiling $TM_FILENAME</h2>"
cd "$TM_DIRECTORY"
javac -encoding UTF8 "$TM_FILENAME" &> >("${TM_RUBY:-ruby}" \
    -rtm_parser -eTextMate.parse_errors)
if (($? >= 1)); then exit; fi

{ java -Dfile.encoding=utf-8 "${TM_FILENAME%.java}"
  echo -e "\nProgram exited with status $?."; }|pre

4. Compile and run in terminal.

echo "<h2>Compiling $TM_FILENAME</h2>"
cd "$TM_DIRECTORY"
javac -encoding UTF8 "$TM_FILENAME" &> >("${TM_RUBY:-ruby}" \
    -rtm_parser -eTextMate.parse_errors)
if (($? >= 1)); then exit; fi

osascript <<EOF
    tell application "Terminal"
        activate
        try
            close front window
        end try
        do script "cd '$TM_DIRECTORY'; java '${TM_FILENAME%.java}'"
    end tell
EOF

5. Compile and run package item. This also relies on you setting a CLASSPATH variable in you .bashrc, and will only work for packages one deep, still useful if you are just starting out with Java.

echo "<h2>Compiling $TM_FILENAME</h2>"
cd "$TM_DIRECTORY"
javac -encoding UTF8 "$TM_FILENAME" &> >("${TM_RUBY:-ruby}" \
    -rtm_parser -eTextMate.parse_errors)
if (($? >= 1)); then exit; fi

export CURRENT_DIR=`pwd | sed -n 's/.*\///p'`

{ java -Dfile.encoding=utf-8 $CURRENT_DIR."${TM_FILENAME%.java}"
echo -e "\nProgram exited with status $?."; }|pre

This post was just an illustration of how to make compilation in TextMate for Java more useable, in the next post I will be adding some new snippets, the ones that are missing from the original TextMate bundle.

Update: I have now (finally) expanded on this post, you can read about more changes here.

Posted
27 Aug 2006 @ 22:22

Categories
,

Comments
None

Author
Alex

Rich Text File (RTF) Into NSTextView, Cocoa & Obj-C

I was searching for an example of how to do this for ages and came up with nothing. All the pros out there will probably say it is easy and give shorter ways of doing this but for noobs and people not in the know I wrote this little snippet. This is especially useful for creating easy to maintain change logs or for adding simple read-me and help files to your application.

First of all you will need to create a NIB file with some sort of controller class in it. In the controller class create an outlet of type ‘NSTextView’, for this example I will call it ‘controller_Out_TextView’. Then
generate the files for this controller so they appear in your Xcode project.

Secondly, create a window and add an NSTextView to it from the palette, connect the NSTextView to the outlet in the controller.

You will then need to create your rich text file with the necessary text in it, make sure it is added to your project and will be copied to the application bundle. For this example the text file will be called (rather originally) ‘file.rhtml’.

Finally add the following code to the ‘controller_name.m’ file between the ‘@implementation’ and ‘@end’, or in your ‘awakeFromNib’ method, if you already have one.

- (void)awakeFromNib
{
    NSBundle * myMainBundle = [NSBundle mainBundle];
    NSString * rtfFilePath = \
            [myMainBundle pathForResource:@"file" ofType:@"rtf"];
    [controller_Out_TextView readRTFDFromFile:rtfFilePath];
}

Compile and run, hoepfully all of your text will be displayed, good hey.