ruby, Ruby on Rails

A formal introduction to gaevents

This post serves a general introduction to gaevents, a Ruby gem to send user events to google analytics.

You can find the gem here:
https://rubygems.org/gems/gaevents

and the code:
https://github.com/singhshivam/gaevents/

What is gaevents?
In a nutshell, gaevents is a Ruby gem that enables sending user events to Google Analytics in batches from a Ruby/Rails application.

What unique problem does it solve?
Traditionally, Google analytics defines events as:

Events are user interactions with content that can be tracked independently from a web page or a screen load.

However, in a complex application, users might trigger delayed events which are equally important for the analytics.

Delayed Events:

To understand delayed events, let’s take the example of Netflix. Netflix allows users to create subscriptions which are then billed monthly or annually depending on the plan. When the user has first created the subscription, they interacted with the application, i.e. navigated a few pages, clicked buttons and submitted forms. These interactions fit perfectly with GA’s definition of “events” and are therefore easy to track. However, depending on your requirement, you might also want to track all subsequent charges that were made on the user’s card. These charges are automatically generated by the system and are not dependent on the user interaction. Such events are referred here as delayed events.

Depending on your application there can be many such system generated events which are equally important for the analytics but don’t fit the textbook definition of events. Gaevents provides a clean way to track these events. The gem also supports batch events update out-of-box!

How does it work?
You can use gaevents to send out the events as and when they occur, however here, we will focus on sending batch updates with the help of redis.

In your application, whenever an event is triggered, capture it in a redis queue. Something like:

redis.set("analytical_events", [
   {:event => “event_1”, :user => user1},
   {:event => “event_2”, :user => user2},
   {:event => “event_3”, :user => user3}
]).to_json

You can create a worker job (using DelayedJob or Resque) which will look for these events at a given interval of time:

events = JSON.parse(redis.get("analytical_events"))

Create GAEvents::Event for the collected events:

gaevents = []
events.each { |event|
   gaevents << GAEvents::Event.new({
          :cid => event[:user].cid,
          :t => event[:user].tid,
          :ec => "gauser",
          :ea => event[:event],
          :uid => event[:user].id,
          :tid => event[:user].tid
   })
}

Please refer Measurement Protocol Parameter Reference for the list of all parameters and their accepted values.

Once all the events are collected you can send them in one shot:

res = GAEvents.track(gaevents)

gaevents is focused on solving one unique problem and aims at solving it well.

Please feel free to share your thoughts in the comments below. Do check out the github repository. Any contribution or suggestion is welcome.

Cheers!

Advertisements
Standard
ruby

Recover your iPod playlist within seconds

I had to leave for Goa the other day and I was packing my bare essentials when I came across my age old forgotten iPod. Finding it out of blue was a bliss and I decided to take it along. I put it on charge and it was ready to rock.

2015-08-30I never realized what wonder old playlists can do. Listening to those old tracks I felt as if I was transported back to those good old carefree college days. After returning from Goa I decided to export those tracks to my computer, however there was an issue. We all know for some reason Apple renames music files and rearrange them in random folders. This makes it impossible to figure out which file corresponds which track.

Here take a look:

ipod files list

These are all random filenames. However to my relief these files were not encrypted and their ID3 tags were still intact. That meant all I needed to do was rename these files and I was good to go.

However given the size of my playlist (6.5 GB) there was no option to do this manually. So I wrote a little script that could help me out.

Selection_006

My script goes through these files, collecting their ID3 tags, maintaining a hash and finally copying these files over user provided destination to respective folders based on album name and the file itself is renamed on track title. Running the script restored back my playlist within 105 seconds. Here’s the benchmark:

0.160000 7.470000 7.630000 (105.228952)

And this is how my playlist looks now on my file system:

Selection_007 Selection_008

Here is the source code:

Feel free to star, fork, follow or contribute on GitHub. 🙂

Standard
Project Euler, ruby

Project Euler in Ruby

I recently started solving project Euler. I am using Ruby to solve these problems. My aim is to get results in optimum time. I try refraining myself from using brute force however I have used them couple of places where the sample data was limited and it did not make any considerable difference in performance.

Leonhard_Euler_2

In the process I also tried implementing a few mathematical algorithms like – Fermat’s Factorization and Quadratic Sieve wherever necessary. Its a great experience solving these problems. Given the nature of these problems it demands you to be intelligent in your approach. Many times its quite tempting to use brute force and I did that too (ended up restarting my crashed laptop).

And boy! its fascinatingly addictive. I’ve been digging wiki for countless algorithms, analyzing their pros and cons and selecting them accordingly for my solution – and not to mention coding them.

As Project Euler discourages posting answers online, I won’t be posting answers however I will be sharing my solutions. In the end of each solution I have posted Ruby Benchmark score calculated on my system.

Here’s the link to my GitHub repository:
https://github.com/meshivam/Project-Euler-in-Ruby

Its a work in progress, so feel free to fork it, star it and collaborate to make it better.

Cheers! 🙂

Standard
Ruby on Rails

FTPS (TLS/SSL) In Ruby

FTPS is an extension to the commonly used FTP that adds support for the Transport Layer Security (TLS) and the Secure Sockets Layer (SSL) cryptographic protocols.

While FTPS using clients like FileZilla, we generally prefix our host with ‘ftpes://’:
ftpes://ftp.example.com

Net::SSH is the most popular ruby library for ssh and ftp purpose. It however is not so helpful when it comes to FTPS. We will use Net::FTPFXP RubyGem instead.

Installing Net::FTPFXP is simple. Run:
gem install ftpfxp

Now to establish the connection, do the following:
require 'net/ftptls'
ftp = Net::FTPTLS.new()
ftp.passive = true
ftp.connect('host.com', port_number)
ftp.login('Username', 'Password')
ftp.list
ftp.close

Port number by default is 21.

Standard