Interesting proposition: how do you report 1.2k crashes at once?
Tag: Howto
Maintaining Maintenance
Sometimes well-intentioned features have unintended side effects. Case in point: WordPress’ maintenance mode. Whenever you update plugins WP will automatically enter maintenance mode, which displays a nice message to your visitors that the site will be back online shortly. It will automatically go out of maintenance once the updates are done.
Well, sometimes unexpected things happen: you are stuck in maintenance mode. WP will effectively lock you out … even the admin section will not be accessible. *ugh* This is the moment you start panicking … luckily if you wait 10 minutes or delete the .maintenance file manually you’ll be able to access your site again. *phew*
Just went though that whole cycle. m(
JetPack vs. Antispam Bee
Seems like Jetpack discussions and Antispam Bee don’t go well together: upon submitting a comment you get a “Invalid security token” error. Well … bye, bye Jetpack discussions.
Convert any file VLC can play to mp3
I just felt the need for a script that could extract the audio track of a video, transcode it and save it as an mp3 file … 2 hours later I was finished (get the Gist). 😀 It uses VLC to do hard work. 😉
Thanks to Kris Hom for the inspiration. 🙂
Update 2014-03-01:
- Check whether VLC is installed
- Should also work on Linux now
- Increase default bit rate to 192kbit/s
- Fixed bug where the file/playlist would repeat endlessly
Update 2014-11-05:
- Also look for VLC in “~/Application/”
Update 2016-03-05
- Added a ffmpeg version
Default Values for Boolean Options in Ruby
Let’s say you read settings from a YAML file and have some sort of settings object. Then you check if certain options are set with custom values or you have to set default/fall-back values on them. If you are dealing with Boolean options you have to be careful … as I had to find out myself.
Initially you would probably do something like the following to set a default value on a Boolean option:
settings[:some_option] ||= true # set default value if nothing set
Do you see the problem? What happens if the option was deliberately set to
false
? You would overwrite it because both cases
nil
(i.e. nothing set) and
false
would evaluate to
false
in the context of the
||=
operator and you would in both cases assign the right hand value (and overriding an explicit user choice in one case) … *ouch*.
So the correct solution is something like the following:
settings[:some_option] = true if settings[:some_option].nil?
Just be careful … 😀
Render Rails assets to string
If you ever needed a way to render a Rails assets to a string, Hongli Lai from Phusion describes how. 🙂
I prepared a Gist wrapping it into a nice helper. 😀
module ApplicationHelper # thanks to http://blog.phusion.nl/2011/08/14/rendering-rails-3-1-assets-to-string/ # you may need to change the owner of the tmp/cache/* directories to the web servers user # e.g. for Debian systems: `chown -R www-data:www-data tmp/cache/*` def render_asset(asset) Conferator::Application.assets.find_asset(asset).body.html_safe end end
File.basename Tricks
Just realized Ruby’s File.basename can also filter out (arbitrary) file extensions. 😀
File.basename("foo/bar/baz.html", ".*") #=> "baz"
Sortable Columns Across Tables
If you follow Railscast 228 you get sortable table columns for your model. But what if you don’t want to expose the name of the actual database columns or more interesting if you want to sort across tables? Here is how I do it.
In your controller add order
or reorder
if you already have an order clause in one of the used scopes (default_scope
counts too).
class AttendeesController < ApplicationController def index @attendances = @conference.attendances.reorder(sort_query).page(params[:page]) end # ... end
As I’m using this mechanism in different controllers I added the common functionality to the application_controller.rb file.
class ApplicationController < ActionController::Base helper_method :navigation_params, :sort_column, :sort_direction protected # supports only attendances for now ALLOWED_SORT_COLUMNS = { "fee_payed" => "fee_payed", "fee_payed_on" => "fee_payed_on", "name" => "users.last_name, users.first_name", "payment_confirmation_sent_at" => "payment_confirmation_sent_at", "registered_at" => "registered_at", "registration_confirmation_sent_at" => "registration_confirmation_sent_at", "town" => "users.town" } # use this in views def sort_column ALLOWED_SORT_COLUMNS.keys.include?(params[:sort]) ? params[:sort] : "name" end def sort_direction %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc" end def navigation_params { direction: params[:direction], page: params[:page], sort: params[:sort] } end def sort_query sort_query_column.split(',').map{ |column| column + ' ' + sort_direction }.join(', ') end # use this in controllers def sort_query_column ALLOWED_SORT_COLUMNS[sort_column] end end
This will use the ALLOWED_SORT_COLUMNS
hash to map between user visible and actual database sort columns. Adding sort_query
also allows us to sort by multiple columns at once. navigation_params
is a shortcut I use when generating URLs (e.g. in link_to
) and I want to preserve pagination, sorting, filters/searches, etc. across pages.
def link_to_sortable(column, title = nil) title ||= column.titleize sort_icon = column == sort_column ? content_tag(:i, nil, class: (sort_direction == "asc" ? "icon-chevron-down" : "icon-chevron-up")) : "" direction = column == sort_column && sort_direction == "asc" ? "desc" : "asc" link_to (title+" "+sort_icon).html_safe, params.merge(sort: column, direction: direction, page: nil) end
Note that sort_icon
assumes you are using Bootstrap.
Now we can have sortable columns in our views:
<%= link_to_sortable "name" %> ...
How to to set up Gitlab on Debian
Update: This howto is outdated. GitLab has changed a lot since it was written and a lot of it is not applicable anymore (e.g. since GitLab 5.0 it doesn’t depend on Gitolite any more and only needs one system user to be setup). So you are probably better off using the official installation guide. 🙂
If you want to install Gitlab on Debian you can easily follow their installation steps for Ubuntu. But be careful there are a few gotchas nobody is talking about.
The following steps will assume you are root.
Preparations
First make sure you have all the latest updates installed.
aptitude update aptitude full-upgrade
Then we have to install a few packages.
aptitude install git-core wget curl gcc checkinstall libxml2-dev libxslt-dev sqlite3 libsqlite3-dev libcurl4-openssl-dev libc6-dev libssl-dev libmysql++-dev make build-essential zlib1g-dev libicu-dev redis-server sudo
Install Ruby
If you have not installed ruby you might want to consider using RVM.
Install it with
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
It will be installed into /usr/local/rvm.
Ask it for the requirements for installing MRI and install them.
rvm requirements
aptitude install build-essentials ...
Install ruby and make it the default.
rvm install 1.9.3 rvm --default use 1.9.3
You should install a minimum set of gems. Add “passenger” if you are running Apache as your web server or “thin” if you are using Nginx.
gem install bundler
Install Gitolite
First of all we want to create a dedicated user for Gitolite and Gitlab. This will also be the user the Rails processes will be running in (this is important later).
adduser \ --system \ --shell /bin/sh \ --gecos 'Git Version Control' \ --group \ --disabled-password \ --home /home/git \ git
Configure git for the new user.
sudo -u git -H git config --global user.email "git@your-server.tld" sudo -u git -H git config --global user.name "Gitlab Admin"
Generate the ssh key for the git user. It will be saved in /home/git/.ssh/id_rsa. We will run Gitlab as the git user so it will use this key to authenticate against Gitolite.
sudo -u git -H ssh-keygen -t rsa -b 2048
Copy the public part of the key for later use when we setup Gitolite.
sudo -u git -H cp /home/git/.ssh/id_rsa.pub /home/git/rails.pub
After that we install Gitolite. In contrast to the Gitlab documentation I installed it from the Debian repositories.
aptitude install gitolite
It will not be fully installed as it will tell you something like:
No adminkey given – not initializing gitolite in /var/lib/gitolite.
So we do this by using dpkg-reconfigure and using our previously prepared account.
When prompted, answer as follows:
- Gitolite user: git
- repositories directory: /home/git
- admin key: /home/git/rails.pub
dpkg-reconfigure gitolite
Now you should have Gitolite set up in the /home/git directory. But we will still have to tweak it a little.
Edit /home/git/.gitolite.rc and find the line that reads “REPO_UMASK = 0077;” and change it to “REPO_UMASK = 0007;” (i.e. three zeros).
You now need to change the directory privileges on the /repositories directory so Gitlab can use them
sudo chmod -R g+rwX /home/git/repositories/ sudo chown -R git:git /home/git/repositories/
Gitolite should be ready now.
You can test it by cloning the admin repository:
sudo -u git -H git clone git@localhost:gitolite-admin /tmp/gitolite-admin rm -rf /tmp/gitolite-admin
Install Gitlab
Install a few prerequisites.
aptitude install python-dev python-pip redis-server libicu-dev sudo pip install pygments
Clone Gitlab
git clone git://github.com/gitlabhq/gitlabhq.git gitlab cd gitlab
We create a gemset for Gitlab to not pollute the global gemset. To automate this we will use a .rmvrc inside the Gitlab directory. RVM will make sure it will be loaded automatically whenever you enter the directory.
echo "rvm use 1.9.3@gitlab --create" > .rvmrc
cd into directory to make rvm use the .rvmrc and accept with “y”.
cd .. && cd gitlab
Check your current gemset with
rvm current
It should show something like “ruby-1.9.3-p0@gitlab”.
Now you might need to update Gitlab’s Gemfile (e.g. add the mysql2 gem for MySQL databases).
Now install the gems necessary for running Gitlab.
bundle install --deployment
You may need to run “bundle install –no-deployment” to pick up changes to the Gemfile and rerun the previous command.
Edit config/gitlab.yml to configure Gitlab. If you have followed this howto you should only need to update the “email” section and the “host” option in the “git_host” section.
You might want to edit config/application.rb and update the time zone and locale configurations.
Edit config/database.yml and set up your database configuration.
Now set up and initialize your database.
bundle exec rake db:setup RAILS_ENV=production bundle exec rake db:seed_fu RAILS_ENV=production
Install with Passenger + Apache
(todo)
Install with Thin + Nginx
(todo)
Result
😀