Julien Desrosiers

A freelance Web developer based in Sherbrooke, Québec, Canada.

Build an Automator script to upload images to your server

// November 19, 2011

Image uploader script

The problem

I always need to send people screenshots. For this, i used to use LittleSnapper to publish the screenshots on my server (at http://s.juliendesrosiers.ca/*) for other people to see them.

It worked great, but for the sake of learning bash, and because i love to make my own things, i made a small Automator script to accomplish this simple task.

The script

filename=$(basename $1)
public_url="http://s.juliendesrosiers.ca/$filename"
scp $1 tannant:/home/deploy/apps/s_juliendesrosiers_ca/$filename
/usr/local/bin/growlnotify -m "Uploaded: $public_url"
echo $public_url | pbcopy

Explanations (and things to modify)

The first line takes the base name of the file’s name (for example, instead of /home/user/julien/myfile.jpg, it would be myfile.jpg only)

filename=$(basename $1)

Create a variable that will hold the full publicly accessible path, with the file name. Change s.juliendesrosiers.ca for your own web address.

public_url="http://s.juliendesrosiers.ca/$filename"

scp will copy the file from its local location (in your computer) into your remote server (in my case, “tannant” is simply an ssh shortcut for this host, but in your case, you’re likely to replace this for something like “youruser@yourhost.com”). You’ll also want to modify the remote path (/home/deploy/etc…) to reflect the directory structure of your own server.

scp $1 tannant:/home/deploy/apps/s_juliendesrosiers_ca/$filename

The following line will notify you that your upload worked successfully. For this line, you’ll need to install Growl, along with it’s command line utility “growlnotify”. With homebrew, it’s only one brew install growlnotify away.

/usr/local/bin/growlnotify -m "Uploaded: $public_url"

Last but not least, we put the newly-uploaded image’s public address into the clipboard.

echo $public_url | pbcopy

Now the Automator part

  1. Open Automator
  2. File > New > Application
  3. In the actions library, choose “Execute a shell script”, and drag it into the right panel.
  4. In the “input data” select at the right, choose “as arguments”, or something like this (i have the french version).
  5. In the big text field, paste your big (modified to your needs) command.
  6. Save. On your desktop, or in /Applications, or whatever.

Usage

Upload an image

Just drag your images or screenshots over to the Upload Automator script’s icon to upload them to your server and wait for it to return your public URL.

Note

Please note that if you want people to see your uploaded files on your server, you must serve them with a Web server (Apache, nginx, etc). This is outside of the scope of this post.

YegorDyachkov.com

// September 18, 2011

yegordyachkov.com

The renowned cellist Yegor Dyachkov came to us asking for a CMS for his new website. So we created a simple, Sinatra-based (programmed in Ruby), CMS that makes it possible for him to manage all of his site’s content.

The excellent graphic designer Susan Scott created the mockups for Julie to integrate into the website, using HTML5 and CSS3 code.

The result is an elegant website that features the music of a master cellist. We really hope you will enjoy this piece.

Open source

From this project i abstracted and open sourced a small Sinatra module (https://github.com/juliend2/ck_image_upload) to handle the image upload in CKeditor for the Sinatra back-end. I also created a jQuery plugin (https://github.com/juliend2/julienMP3Player) for the MP3 player.

More infos about julienMP3Player here.

Run Gollum on Pow

// July 20, 2011

Ever wanted your own Github-style wiki on your own mac server? Read on…

Gollum is the Git-powered wiki that is used in the Github’s wiki system. This tutorial will show you how to run it on Pow’s zero-configuration server on your mac.

Step 1: Install gollum on Ruby 1.9.2 (tried 1.8.6 with no luck)

gem install gollum

Step 2: Create a blank repository where you want to store your wiki pages. I put it in ~/Sites/wiki so i wrote:

cd ~/Sites/wiki
git init 

Step 3: in ~/Sites/wiki/ , create a config.ru file with this content in it :

require "gollum/frontend/app"

Precious::App.set(:gollum_path, File.dirname(__FILE__))
Precious::App.set(:wiki_options, {})
run Precious::App

(thanks to this thread)

Step 4: Install the “Pow” webserver:

curl get.pow.cx | sh

Step 5:

cd ~/.pow
ln -s ~/Sites/wiki

Step 6: Gollum lets you edit wiki pages with textile, markdown, Rdoc, and many others. If you want to edit your entries with Textile, you’ll need to install the RedCloth gem, like this:

gem install RedCloth

Step 7: Now, the fact that your rack app is in the wiki folder makes your app available through wiki.dev on the machine that is hosting it. BUT, if you’re like me and you need to access it from another computer in your network, then you need to get the IP address of your mac that is hosting the wiki, and add an entry like this in the /etc/hosts file on every machine that wants to access the wiki (in my case, the macmini that is hosting the wiki has 192.168.2.12):

192.168.2.12       wiki.dev

That’s it! You can now visit http://wiki.dev in your browser.

JulienMP3Player: an MP3 Player jQuery plugin (Yes, in JavaScript!)

// April 2, 2011

These days i’m creating a website for a musician. And he needed an MP3 player for his website. So my first thought was to use an open source MP3 in flash . But since i need to extend it, i looked at the AS2 code and i thought about the possibility to use JavaScript instead (i prefer JS to AS). It turns out there is already a library that lets you play and control sounds via JavaScript, by using a swf file (for maximum compatibility). It’s called SoundManager2, and it rocks. But since i needed something that could play multiple songs one after the other and that can be easily dropped via jQuery in a non-obstrusive way, i created a jQuery plugin that leverages SoundManager2, and i called it julienMP3Player.

Here’s a Demo: juliendesrosiers.com/demo/julienMP3Player/. Download/Fork it on GitHub: github.com/juliend2/julienMP3Player.

Auto-Generating CRUDs in Sinatra, for fun and profit

// March 21, 2011

I’m currently building yet another CMS, this time with Sinatra. And i was having a lot of code duplication in my controllers where i created the usual CRUD (Create Read Update Delete) actions.

Here’s how it works: I have this base class (abridged for this post) for all my controllers, named “Joiedmin”.

class AdminController < Sinatra::Base

  def self.crud(route_prefix, singular_name)

    self.class_eval <<EVAL
      get '#{route_prefix}' do
        @#{singular_name.pluralize} = #{singular_name.pluralize.classify}.all
        haml :index
      end

      get '#{route_prefix}new' do
        @#{singular_name} = #{singular_name.pluralize.classify}.new
        haml :new
      end

      post '#{route_prefix}new' do
        @#{singular_name} = #{singular_name.pluralize.classify}.new(params[:#{singular_name}])
        if @#{singular_name}.save
          redirect '/admin#{route_prefix}#{singular_name.pluralize}'
        else
          haml :new
        end
      end

      get '#{route_prefix}edit/:id' do
        @#{singular_name} = #{singular_name.pluralize.classify}.find params[:id]
        haml :edit
      end

      put '#{route_prefix}edit/:id' do
        @#{singular_name} = #{singular_name.pluralize.classify}.find params[:id]
        if @#{singular_name}.update_attributes(params[:#{singular_name}])
          redirect '/admin#{route_prefix}#{singular_name.pluralize}'
        else
          haml :edit
        end
      end

      delete '#{route_prefix}delete/:id' do
        #{singular_name.pluralize.classify}.find(params[:id]).destroy
        redirect '/admin#{route_prefix}#{singular_name.pluralize}'
      end
EVAL
  end

end

(Note that for the “pluralize” and “classify” methods to work, you’ll need to include “activesupport” in your Gemfile.)

And in each of my controller’s classes, all i have to do is just calling the crud method like so:

class Acclaims < Joiedmin::AdminController
  crud '/', 'acclaim'
  # more controller stuff...    
end

I found the class_eval trick in this thread: http://stackoverflow.com/questions/973728/self-class-eval-def-def.

Fixing the “bundled mysql.rb driver has been removed from Rails 2.2″ error

// December 25, 2010

I’m migrating dumpyourtime.com to my new VPS at Linode and i had a hard time getting this rails (2.3.8) app to work on my setup (REE, Passenger 3/Apache2, MySQL, Ubuntu 10.04) because of the mysql gem.

I was getting this error on my apache error.log file: “!!! The bundled mysql.rb driver has been removed from Rails 2.2. Please install the mysql gem and try again: gem install mysql.“ . I googled that error and most of the advices were to install the mysql gem with the --with-mysql-config option pointing to the mysql_config path. That didn’t work for me though.

But what did work for me was to vendor the mysql gem and then append the path of this newly-vendored mysql gem to the config.load_paths, like this:

Rails::Initializer.run do |config|
  config.load_paths <<  "#{RAILS_ROOT}/vendor/gems/mysql-2.8.1/lib/"
  ...
end

But it feels kind of wrong. So feel free to write a comment if there is a better way to handle this kind of problem!

Edit: added the vendoring step

KahnawakeVoices.com

// November 19, 2010

kahnawakevoices.com

KahnwawakeVoices.com is a project commissioned by Studio XX for the Mohawk community of Kahnawake. There is a custom CMS which is coded with Ruby on Rails. The front-end is in HTML, CSS (by Julie Desforges), some Flash and a bit of JavaScript.

It’s made in collaboration with Datcha Web for the design part.

Saving hours with Anemone and Nokogiri

// November 8, 2010

Today, i’ve been working on a WordPress site that needed to be moved to another server and also another domain. This site had quite a few (absolute) internal links in its content — that had URLs like http://oldsite.com — and i needed to replace these URLs with http://newsite.com instead. Exact same url structure. Just the domain name to change. It could have been pretty tedious and boring to go over all these pages and check their source to make sure it did not contain any reference to oldsite.com. But in my extreme proactive lazyness, i found a solution to make this task a lot more fun and reusable. I used Anemone and Nokogiri Ruby gems. Here is the code:

require 'rubygems'
require 'anemone'
require 'nokogiri'

Anemone.crawl("http://www.newsite.com/") do |anemone|
  anemone.on_every_page do |page|
    if page.doc
      page.doc.css('a').each do |link|
        if link.attributes['href'].to_s =~ /oldsite\.com/
          puts "#{link.attributes['href']} in #{page.url}"
        end
      end
    end
  end
end

What this script does is this: Anemone is crawling all the pages in newsite.com. For each page, i use Nokogiri to look for its links. And i loop into each of these links to get the ones that contains occurrences of “oldsite.com” in them.

By running this script for a couple of minutes, i got this output:

http://www.oldsite.com/the-link in http://www.newsite.com
http://www.oldsite.com/wp-content/uploads/2010/09/dude1.jpg in http://www.newsite.com/the-guy

Then, all i had to do is go over the WordPress admin, www.newsite.com/wp-admin and replace all the old domain in the URLs.

Done!

Announcing my first jQuery plugin: JulienRSSWidget

// October 22, 2010

Recently, i created a jQuery plugin to easily grab and display RSS feeds in your website.

You can see it in action here.

You can download/fork it here.

Let me know what you think!

howto bootstrap your own server at home (with a dynamic IP)

// October 14, 2010

Warning: running a server of any kind at home is a security risk. Security problems are sometimes found in server software, and these can be exploited to gain access to or damage your files. Your computer must be kept absolutely up to date with Software Update or the equivalent for your operating system if you intend to run a web server on it. This doesn’t eliminate the risk — it only minimizes it. You run a server at home entirely at your own risk. If you do choose to run a server at home, I recommend finding an old PC (or like me an old MacMini) on the curb and setting it up as your home server, reducing the danger to your own computer. I’m not responsible for any damage you may encounter by following this guide. I’m just a crazy hacker with too much time on my hands. NOT A SECURITY EXPERT.

As you may know, hosting Ruby on Rails applications can take quite a bit of system resources. And it also helps to have root privileges on the machine that’s hosting your app. Since i have some time at hand and a willingness to save money, i’ve setup my spare MacMini to host DumpYourTime.com and also MontrealHackers.com. It works well. And since i switched from a 512mb CloudServer at Rackspace, i want to note that the performances are better on my own server. I can handle almost 2 times more requests per seconds. And of course, this cheap power comes with some drawbacks: vulnerability to power and network outage, to name a few. But since i’m not hosting any critical information or service, i can live with that. Here’s a guide on how to do this at home.

Requirements

Setup your router (2wire, from Bell)

  1. Go to http://192.168.2.1/ in your browser
  2. Go to this tab (http://grab.by/6RFi). in english it says something like Your Home Network.
  3. You should see a list of all the computers in your network. Find the one that will serve your web sites (by logging into this computer and looking at the output of ifconfig in the terminal) and click on this link (http://grab.by/6RFv) next to it. To modify the parameters of what applications can serve requests on this computer.
  4. Next to Select the computer, make sure it’s the right IP that is selected. And next to Modify the parameters [...] (http://grab.by/6RFC), check the DMZPlus option (the last one). Click Terminer (or Finish). This step will basically let connections on every ports to go on the machine that you’ve selected. (For some reasons it didn’t work when i tried to just permit HTTP individually.) So make sure you…

Protect your Computer!

  1. Activate your firewall on your machine to only permit the SSH and HTTP ones. (see http://www.macobserver.com/tmo/article/snow_leopard_enabling_the_built-in_firewall/)
  2. Make sure you activate only the services that you absolutely need in the Sharing preferences of your server (inside Apple menu > System Preferences.), like the Web Sharing (HTTP) and Remote Login (SSH) .
  3. Install and setup Fail2ban.
  4. Subscribe to the Apache security mailing list to get the latest security updates (and fixes) for Apache.
  5. Keep you system up to date. Religiously (at least like every week) check if there is any update that you can install via Software Updates.

Setup your Domain in ZoneEdit.com

  1. login to zoneedit.com
  2. Click Add Zones
  3. Enter your Domain Name, example : montrealhackers.com A confirmation page will tell you this (NOTE: your nameservers are likely to be different than mine):

    IMPORTANT: Before your "montrealhackers.com" site is live
    you must contact your registrar (the people from whom
    you purchased this domain name) and tell them to change its
    nameservers to:
    
    Nameserver 1: ns13.zoneedit.com (66.223.40.121)
    Nameserver 2: ns9.zoneedit.com (66.240.231.42)
    
    Current DNS information:
    
    .    nameserver = A.ROOT-SERVERS.NET.
    .    nameserver = B.ROOT-SERVERS.NET.
    .    nameserver = C.ROOT-SERVERS.NET.
    .    nameserver = D.ROOT-SERVERS.NET.
    .    nameserver = E.ROOT-SERVERS.NET.
    .    nameserver = F.ROOT-SERVERS.NET.
    .    nameserver = G.ROOT-SERVERS.NET.
    .    nameserver = H.ROOT-SERVERS.NET.
    .    nameserver = I.ROOT-SERVERS.NET.
    .    nameserver = J.ROOT-SERVERS.NET.
    .    nameserver = K.ROOT-SERVERS.NET.
    .    nameserver = L.ROOT-SERVERS.NET.
    .    nameserver = M.ROOT-SERVERS.NET.
    
    Current registrar information:
    
    Domain Name: MONTREALHACKERS.COM
    Registrar: NEW DREAM NETWORK, LLC
    Whois Server: whois.dreamhost.com
    Referral URL: http://www.dreamhost.com
    Name Server: DNS1.STABLETRANSIT.COM
    Name Server: DNS2.STABLETRANSIT.COM
    Status: ok
    Updated Date: 03-sep-2010
    
    Please Note: We are not a domain name registrar.
    All domain names must be registered with an accredited registrar
    before you will be able to use our DNS servers!
    
    NOTE: Even after you change the nameservers it takes
    72 hours for your site to go live. This is a limitation of
    the Internet/TLD registry, not our service.
    
  4. Just click “Start editing Zone”
  5. Click on IP Addresses.
  6. in the Name field, enter “www”, and in the “Numeric IP” field, enter the IP of your machine. (find out your IP address by going to http://whatismyipaddress.com/) It will then show you a page like this:

    Are you sure you would like to add the following IP Addresses?
    Both "www.montrealhackers.com" and "montrealhackers.com" will have the IP 65.92.140.67.
    
    Only "www.montrealhackers.com" will have the IP 65.92.140.67, and please leave "montrealhackers.com" the way it is.
    (not recommended)
    
  7. Click Yes for the first question, because i want to have both montrealhackers.com AND www.montrealhackers.com to redirect to my server’s IP address. Now you should see your two names redirecting to your IP Address.
  8. On your server machine, add this to your crontab:

    @hourly       /opt/local/bin/wget -O - --http-user=xxxxxxxxxx --http-passwd=xxxxxxxxx 'http://dynamic.zoneedit.com/auth/dynamic.html?host=www.montrealhackers.com'
    @hourly       /opt/local/bin/wget -O - --http-user=xxxxxxxxxx --http-passwd=xxxxxxxxx 'http://dynamic.zoneedit.com/auth/dynamic.html?host=montrealhackers.com'
    

    (You might need to change your path to the wget command. Find it by looking at the output of “which wget” in the terminal) Basically it just makes a GET request to the zoneedit server every hours to update them with your IP address. If it did not change, nothing happens. If it did change, it’s updated on their end so when they receive requests to your domain, they redirect to your new IP address.

  9. You’ll have to wait a couple of hours before modifying your nameservers on your registrar’s control panel for the zoneedit ones.

That's about it.