// November 19, 2011

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

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.
// September 18, 2011

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.
// 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.
// 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.
// 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.
// 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
// November 19, 2010

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.
// 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!
// 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!
// 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
- A Computer: is a MacMini that has Snow Leopard on it. I use Apache with Passenger to host the Rails applications.
- The Internet: I use Bell (I’m in Quebec, Canada) as my Internet provider. So i have a dynamic IP (as opposed to Static IP. Static IP is not available with my ISP. Thus the workaround that i’ll explain to host your site with a Dynamic IP). Note that if you’re using Videotron, you can’t serve anything on port 80 (the port that HTTP is using).
- A ZoneEdit.com account: or any other Dynamic DNS, like Dyndns will do. But i like ZoneEdit because it’s cheaper and it just works. You need this because you ISP is giving you a different IP address once in a while and you don’t want your sites to be down because your domain is no longer pointing to the correct IP. If you had your own static IP (in fact, i think you would need 2 static IPs to setup a DNS server) you wouldn’t need that.
Setup your router (2wire, from Bell)
- Go to http://192.168.2.1/ in your browser
- Go to this tab (http://grab.by/6RFi). in english it says something like Your Home Network.
- 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.
- 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!
- 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/)
- 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) .
- Install and setup Fail2ban.
- Subscribe to the Apache security mailing list to get the latest security updates (and fixes) for Apache.
- 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
- login to zoneedit.com
- Click Add Zones
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.
- Just click “Start editing Zone”
- Click on IP Addresses.
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)
- 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.
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.
- 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.