Updating an existing VersionEye project via API

The VersionEye API enables you to create a project via the API. You just need to send your project file via POST to this endpoint “/v1/projects.json” and VersionEye creates a new project for that and returns a JSON with the used libraries and the information if they are outdated.

There is already an AddOn for the Symfony Deverloper Toolbar:

https://github.com/mattsches/VersionEyeBundle

versioneyebundle_screenshot

And 1 for the Zend Dev. Toolbar:

https://github.com/Ocramius/VersionEyeModule

This modules are sending your composer.json file to the VersionEye server. Unfortunately the first version created with every post a new project at VersionEye. That is not the desired behavior. We added a new Endpoint to the API, which enables the API developer to update an existing project.

The process now looks like this. The first time you upload the composer.json file via POST to this resource: “/v1/projects.json“. In the response you get back an “project_key” for the project at VersionEye. Next time you send the composer.json file via POST to this new resource: “/v1/projects/{project_key}.json“.

Screen Shot 2013-03-18 at 4.06.24 PM

The new Endpoint “/v1/projects/{project_key}.json” doesn’t create a new project. It only updates an existing project. Please use this in future to update an existing project.

Git tagging

Note for me, how to tag with git. Because I always forget it!

git tag -a v1.4 -m 'version 1.4'
git tag 

The first line creates a tag with the annotation (-a) v1.4 and the message (-m) “version 1.4”. And this line pushes the tag to origin master.

git push --tags

 

Parsing a CSV in Ruby

Parsing is CSV file in Ruby is very easy. Check out this code:

require "csv"
csv_file_path = "ABSOLUTE_PATH_TO_YOUR_CSV_FILE"
file = File.open(csv_file_path, "r:ISO-8859-1")
csv = CSV.parse file

That’s it. This is how you get the first row:

csv.first

This is how you get the first column of the first row:

csv.first.first

And this is how you iterate over all rows:

csv.each do |row|
  p row
end

Easy! Right?

Subscribe to your Software Libraries via RSS

On the weekend we finished the RSS feature for VersionEye. You can now subscribe to your Libraries via RSS. On your profile page, directly next to your favorite packages, you will see an RSS icon.

Screen Shot 2013-02-18 at 8.45.27 AM

Just click on it and in future you will get the new version notifications through your favorite RSS Reader. I am using RSS Toaster.

Screen Shot 2013-02-17 at 3.39.52 PM

And the cool thing is you are now able to get the notifications on your smart phone.

Screen Shot 2013-02-17 at 4.29.25 PM

Or your preferred tablet.

Screen Shot 2013-02-17 at 4.31.22 PM

Let me know if you have questions.

How to get a list of all licenses for your Software Project

Through the new VersionEye API you can get a list of all licenses for your software project. VersionEye now supports 7 different package managers. In this example I will use a Ruby Gemfile to demonstrate how easy it is to get the license list.

First of all you need to signup at VersionEye to get your API KEY. It’s free and takes less than 30 seconds. With your API KEY you can take advantage of the VersionEye API.

The “/api/v1/projects.json” resource supports file uploads via the API.

Screen Shot 2013-02-16 at 3.39.11 PM

Just send your Gemfile via POST to this resource and receive a JSON object as response with all the dependencies in the file.

Screen Shot 2013-02-16 at 3.39.35 PM

In the JSON response you will receive an “project_key”. This project key is unique per user. You can use it to fetch all licenses for the project. Just send a GET request to “/api/v1/projects/PROJECT_KEY/licenses.json?api_key=API_KEY” and you will receive the license list as JSON.

Screen Shot 2013-02-16 at 3.40.14 PM

That’s it. You need only 2 Requests to get the licenses list. Let me know how you like it.

VersionEye now supports custom repositories for Composer

Yesterday night I pushed a new version online. Up to know we supported only simple composer.json files like this here:

{
  "require": {
    "symfony/symfony": "2.0.7",
    "symfony/doctrine-bundle" : "*",
    "symfony/process" : "2.0.*",
    "symfony/browser-kit" : "!= 2.0.6",
    "symfony/security-bundle" : ">=2.0.7",
    "symfony/locale" : "<=2.0.7",
    "symfony/yaml": "<2.0.8",
    "symfony/http-kernel": ">2.0.6",
    "twig/twig" : ">=1.9.1,<2.0.0",
    "doctrine/common" : ">2.2 , <2.4",
    "symfony/console" : ">=2.0.0, <2.0.10, !=2.0.6"
  }
}

If you refered to a package that is not on packagist.org than we displayed it as unknown. But since yesterday VersionEye supports custom repositories. Here is an example:

{
  "name": "till/wtfdate",
  "description": "A WIP library to provide a somewhat API-compatible replacement for Zend_Date.",
  "license": "BSD-2-Clause",
  "repositories": [
   {
     "type": "package",
     "package": {
       "name": "zendframework/zendframework1-dl",
       "version": "1.12.1",
       "dist": {
         "url": "https://packages.zendframework.com/releases/ZendFramework-1.12.1/ZendFramework-1.12.1-minimal.zip",
         "type": "zip"
       }
     }
   }
 ],
 "autoload": {
   "classmap": [ "src/", "tests/Wtf"]
 },
 "require-dev": {
   "zendframework/zendframework1-dl": "1.12.1"
 }
}

VersionEye now recognises the custom repository and doesn’t display zendframework1-dl as unknown dependency. It displays it as known dependency and as up-to-date.

Screen Shot 2013-02-14 at 10.10.03 PM

Let me know how it works for you. I looking forward to your feedback.

http://www.versioneye.com

VersionEye – Continuous Updating

This week I went to the PHP User Group in Berlin. The room was full with people. I guess round about 30 PHP Devs. Martin Holzhauer did an awesome talk about PHP Application Architecture. And Volker Dusch did an awesome talk about PHPUnit. I really enjoyed both talks.

I did a talk about VersionEye and Continuous Updating. My slides are on SlideShare. Check it out:

Your Feedback is appreciated.

Ruby on Rails + MySQL on CloudControl

CloudControl is a pretty cool StartUp from Berlin. It is a PaaS Solution like Heroku.  CloudControl is hosting on AWS in Ireland. They are more flexible than Heroku. Beside the number of web processes you can choose how much RAM each instance should have. This is a cool features what you don’t get on Heroku. And you can have different environments on CloudControl for 1 single app. Check out their page: https://www.cloudcontrol.com/

Cloud-Control-logo-centered

I want to show here how you get started with your Ruby on Rails on CloudControl. First of all you have to sign up at CloudControl:  https://console.cloudcontrolled.com/

I assume you are familiar with GIT, Ruby and Linux/Mac OS X. First of all you have to install the CloudControl command line tool.

$ sudo easy_install pip
$ sudo pip install cctrl

The command line tool will be installed via pip, the python package manager. the CloudControl command line tool works similar to the Heroku command line tool. Let’s add your public SSH Key:

cctrluser key.add

In that way you don’t have to enter every time your credentials.

As next switch to the app root directory of your Rails App you want to deploy on CloudControl. Create an app on CloudControl:

cctrlapp APP_NAME create ruby

And now push your code to CloudControl:

cctrlapp APP_NAME push

The command above pushes your code but it doesn’t deploy it. Use this command to make a deployment:

cctrlapp APP_NAME deploy

Now check your app on :

http[s]://APP_NAME.cloudcontrolled.com

It is very likely that it is not running 🙂 No problem. You have to make some small changes to your Rails App. First of all, if you create an app on CloudControl it is without any database. That is a big difference to Heroku. Of course you can add a MySQL or Postgres DB as AddOn. Let’s add a MySQL:

cctrlapp APP_NAME/default addon.add mysqls.free

Don’t forget to add the “mysql2” GEM to your Gemfile. This is the driver for MySQL.

Now you have to customise your database.yml like this:

production:
  adapter: mysql2
  encoding: utf8
  database: <%= "'#{ ENV['MYSQLS_DATABASE'] }'" %>
  host: <%= "'#{ ENV['MYSQLS_HOSTNAME'] }'" %>
  port: <%= ENV["MYSQLS_PORT"] %>
  username: <%= "'#{ ENV['MYSQLS_USERNAME'] }'" %>
  password: <%= "'#{ ENV['MYSQLS_PASSWORD'] }'" %>
  pool: 100
  timeout: 5000

All right. One more step. You have to have a “Procfile” in the root of your Rails App with this content:

web: bundle exec rails s -p $PORT

That’s it. Now try again:

cctrlapp APP_NAME push
cctrlapp APP_NAME deploy

And check the URL :

http[s]://APP_NAME.cloudcontrolled.com

For me it worked quiet well. Let me know how it works for you.

Getting a list of all Licenses in a Project

In a regular project you are using a handfull Software Libraries. Every Library in your project can use a different license. To get a list of all licenses which are used in your project can be difficult. You can double check the license for every single library in your project manually. But that is time intensive and a pain in the ass!

VersionEye is offering a quick solution for that. You can get the license list in less than 1 minute. After your login you are in “My Projects”. Click the link “Add New Project” in the left nav bar, to create a new project.

Screen Shot 2013-02-04 at 5.40.07 PM

Simply upload a project file. A pom.xml, Gemfile, composer.json, package.json, dependency.gradle or another supported file with your dependencies. After the upload you will see a tab with all the dependencies.

Screen Shot 2013-02-04 at 5.40.53 PM

Simply click on the “License” tab to see all licenses in this project. And here it is.

Screen Shot 2013-02-04 at 5.41.17 PM

In this example most Libraries are using the MIT License. Some of them are under “Ruby” license and for 1 Library VersionEye was not able to detect a license.

It’s that simple. Let me know if you have questions to this.

Language Statistics : Java and Ruby are leading

VersionEye is tracking Open Source Software Libraries in the Internet. VersionEye is not interested in SourceCode. VersionEye is only interested in ready releases. In Artefacts that are “done” and you can reuse in your projects. The Graph down shows the amount of projects per language.

Software Libraries per Language

 

These numbers are collected from more than 50 different repository servers in the Internet, i.e. repository servers such as RubyGems.org, pypi.python.org, packagist.org and more than 40 Maven repository servers. SCM tools such as GitHub or BitBucket are not included.

This numbers contain only Software Library projects. Desktop Tools written Java and hosted on SourceForge are not included.

The following graph shows the growth of the repositories over time.

Screen Shot 2013-01-29 at 7.05.35 PM

VersionEye started to crawle Repositories in April. That’s why we can not go further back in time. But the last couple months are already enough to show the growth speed of the repositories. If RubyGems is continuing to grow this fast, than soon it will be number 1.

You can check out the daily updated graphs at VersionEye: https://www.versioneye.com/statistics

FridayAtSix Talkshow at VersionEye Office in Berlin

Last Friday my company VersionEye hosted the FridayAtSix Talkshow in Berlin. FridayAtSix is a Talkshow about the tech. StartUp scene in Berlin. It happens 1 or 2 times a month. And always at a different location. Usually at the office of a cool tech StartUp. Last Friday the cool tech StartUp was VersionEye 🙂

You can check out the whole talkshow on YouTube:

And on SoundCloud:

I am getting interviewed in the 2nd round. I talk about the B2D (Business to Developers) market.

Here on my private travel blog there is a more detailed article about the event: http://robs-blog.com/2013/01/29/fridayatsix-at-versioneye/

ObjectC Libs at VersionEye

Just added some ObjectC Libraries to the VersionEye index. The most important ones.

http://www.versioneye.com/package/github–AFNetworking–AFNetworking
http://www.versioneye.com/package/github–aerogear–aerogear-ios
http://www.versioneye.com/package/github–jdg–MBProgressHUD
http://www.versioneye.com/package/github–RestKit–RestKit
http://www.versioneye.com/package/github–magicalpanda–MagicalRecord
http://www.versioneye.com/package/github–johnezang–JSONKit
http://www.versioneye.com/package/github–TheRealKerni–HockeyKit
http://www.versioneye.com/package/github–robbiehanson–CocoaLumberjack
http://www.versioneye.com/package/github–steipete–SDURLCache
http://www.versioneye.com/package/github–mattt–TTTAttributedLabel
http://www.versioneye.com/package/github–soffes–sstoolkit
http://www.versioneye.com/package/github–square–SocketRocket

Let me know if you miss something on the list.

PHP User Group FFM

Yesterday night I went to the PHP User Group in Frankfurt am Main. It was at the CoWorking space “Die Zentrale“. Here is their Twitter channel: https://twitter.com/phpugffm.

Marco Pivetta did a great talk about Proxies. Marco is contributing to several famous projects in the PHP world. For example doctrine2, zf2 and Symfony. In his talk he explained the Proxy pattern in general and showed different uses cases for them. For example Lazy Loading, AOP or just hiding optimisation and init code. Very interesting stuff. Most of this topics I know already from the Java World. PHP is getting more serious. It becomes more Java like. Not sure if I like that.

I did a talk about VersionEye and Continuous Updating. I showed very quickly how the software development changed in the past 10 years and what is missing, from my point of view. The feedback to VersionEye was very good and productive. I got new ideas and motivation to continue with the project. Many Thanks for that.

phpugffm-2013-01-18

The PHP UG FFM is a bunch of funny guys. Very open minded and always ready to try out new things. I will come back.

Many thanks to DMR Solutions. The company is specialised into the LAMP stack. They build cool stuff on top of PHP, JavaScript and MySQL. DMR payed the food last night. Many Thanks for that.

Die Zentrale FFM

Die Zentrale” in Frankfurt is a pretty cool CoWorking Space. They just openend 2 weeks ago. I have been yesterday for the whole day. It is a silent place where you can work.

DieZentrale

The best feature here is the internet connection. They have a 128 MBit/s Internet connection. Yes! I am not kidding you. And they have this super fast internet connection, because internet access is cheap in Germany. The pay only 70 EUR / month for that.

If I would live in Frankfurt I would hang out here every day 🙂

 

Capistrano + Rails + Unicorn + NGinx + RVM

Capistrano is a ruby based deployment tool which executes commands in parallel on multiple remote machines, via the SSH protocol. With Capistrano you can deploy your application on N server with one single command from your dev machine. You don’t need to login via SSH to your server.

Screen Shot 2013-01-15 at 8.15.33 PM

If you don’t deploy your app on Heroku or CloudControl, if you have dedicated servers or you are using AWS, than Capistrano is the way to go.

Before you start with Capistrano, you have to implement SSH with authentification keys instead of password. In that way you can just login to your server with a simple “ssh user@server” without password. That is possible if your public ssh certificates are on the server. In that way the server “knows” you.

First you need to add the Gem to your Gemfile.

gem 'capistrano'
gem 'rvm-capistrano'

I am adding here “rvm-capistraon”, too. Because I am working with RVM on my dev machine and on the server. Now you have to run bundler.

bundle install

As next step you have to capify your rails project. Just run:

capify .

That will create some files in your project.

[add] writing './Capfile'
[add] writing './config/deploy.rb'
[done] capified!

Your Capfile is loading the deploy.rb script. The Capfile should look like this:

load 'deploy'
# Uncomment if you are using Rails' asset pipeline
# load 'deploy/assets'
load 'config/deploy'

The magic happens in the deploy.rb file. The full documentation to this script you will find here: https://github.com/capistrano/capistrano. It basically executes a couple of commands on your server. It fetches the current code from your GIT server, runs bundler, rake db:migrate, precompiles your assets and runs the ruby app server.

Here is my deploy.rb with some additional comments.


# Automatically precompile assets
load "deploy/assets"

# Execute "bundle install" after deploy, but only when really needed
require "bundler/capistrano"

# RVM integration
require "rvm/capistrano"

# Name of the application in scm (GIT)
set :application, "your_app"
set :repository, "git@github.com:your_company/your_project/project.git"

# Source Control Management
set :scm, :git

set :deploy_to, "/var/www/#{application}"

# server there the web server is running (nginx)
role :web, "192.168.0.12"

# server there the app server is running (unicorn)
role :app, "192.168.0.12"

# server there the db is running
# This is where Rails migrations will run
role :db, "192.168.0.12", :primary => true

set :rails_env, :production

# user on the server
set :user, "project_user"
set :use_sudo, false

# Target ruby version
set :rvm_ruby_string, '1.9.3'

# System-wide RVM installation
set :rvm_type, :system

# Apply default RVM version for the current account
after "deploy:setup", "deploy:set_rvm_version"

namespace :deploy do

  task :set_rvm_version, :roles => :app, :except => { :no_release => true } do
    run "source /etc/profile.d/rvm.sh && rvm use #{rvm_ruby_string} --default"
  end

  task :start, :roles => :app, :except => { :no_release => true } do
    run "/etc/init.d/unicorn start"
  end

  task :stop, :roles => :app, :except => { :no_release => true } do
    run "/etc/init.d/unicorn stop"
  end

  task :restart, :roles => :app, :except => { :no_release => true } do
    run "/etc/init.d/unicorn restart"
  end

  # Precompile assets
  namespace :assets do
    task :precompile, :roles => :web, :except => { :no_release => true } do
      run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
    end
  end

end

The script for starting and stoping unicorn you can find here: https://robert-reiz.com/2012/02/29/running-unicorn-as-a-service-on-debian-linux/.

On the Linux server you should install a couple things before you deploy:

apt-get install make
apt-get install g++
gem update --system
gem install bundler

Now you can deploy with:

cap deploy

And this command shows you all possible Capistrano tasks:

cap -T

Let me know if you have questions.

Ruby on Rails + ElasticSearch

This is a tutorial how to use ElasticSearch with Ruby on Rails. ElasticSearch is a distributed RESTful Search Engine build on top of Apache Lucene.

Sure! You can use your SQL database for search. But that is usually slow and you will not get very good search results. With ElasticSearch you can deliver a fuzzy search. Let’s say you have a record “Hibernate” in the database. If somebody is doing a search for “hibernate” you will get a match with a simple SQL query. But what if your customers input looks like this:

  • hibernate 3.2
  • hibernate.jar
  • hibernate.jar 3.5

In this cases you will have 0 results with a simple SQL query. With ElasticSearch you would still have results. Depending on your configuration. So let’s start!

ES

Just download the current version from here: http://www.elasticsearch.org/download/. Unpack it and run the ES server with this command:

./bin/elasticsearch -f

The ES server is now running on localhost:9200. If you type in “http://localhost:9200/_search” into your browser you should get some basic results.

I assume that you know already Ruby on Rails and ActiveRecord. Of course there is a GEM to interact with ElasticSearch. Checkout the Tire GEM. That is a pretty good wrapper for ElastisSearch. Just add it to your Gemfile.

gem 'tire', '0.5.4'

and run:

bundle update

In your application.rb you need to require the new package:

require 'tire'

And in environment.rb you need to init the package:


begin
  Tire.configure do
    logger STDERR
    url Settings.elasticsearch_url
  end
rescue => e
  p "Wrong configuration: #{e}"
end

On the GitHub Page there is a description how to integrate Tire into your model. But honestly I don’t like that very much. That just blows up the model class. I prefer a clear separation between my models and the interaction with ElasticSearch.

The model I wanted to map and to make searchable with ElastiSearch is “product.rb”. It is located in “app/models/”. I created another directory called “app/elastics/”. And here I placed a new file “product_elastic.rb”, which is mapping my Product class to ElasticSearch and is responsible for the interaction with the ES server.

The first thing you have to do is to create a mapping. You have to map your properties from your model to ElasticSearch. This is how I did my first mapping:


def self.create_index_with_mappings
  Tire.index Settings.elasticsearch_product_index do
    create :mappings => {
      :product => {
        :properties => {
          :_id => { :type => 'string', :analyzer => 'keyword', :include_in_all => false },
          :name => {:type => 'string', :analyzer => 'snowball', :boost => 100},
          :description => { :type => 'string', :analyzer => 'snowball' },
          :description_manual => { :type => 'string', :analyzer => 'snowball' },
          :language => { :type => 'string', :analyzer => 'keyword'}
        }
      }
    }
  end
 end

The analyzers are documented on the ElasticSearch homepage: http://www.elasticsearch.org/guide/. Here is the magic happening 😉

Than I wrote 2 more methods (clean_all and reset) to delete the “product” index at ES and to create the mappings.


def self.clean_all
  Tire.index( Settings.elasticsearch_product_index ).delete
end

def self.reset
  self.clean_all
  self.create_index_with_mappings
end

Don’t call the reset method in production 😉 With this 3 methods you can delete old mapping and create a new one. You can now run the rails console and try out the methods. That should all work fine.

If creating the mapping was successful, the next step is to index the data in the database. To index a model, the model itself must offer a method which returns their values as JSON. I added a “to_indexex_json” method to the Product class:


def to_indexed_json
 {
   :_id => self.id.to_s,
   :_type => "product",
   :name => self.name,
   :description => self.description ? self.description : "" ,
   :description_manual => self.description_manual ? self.description_manual : "" ,
   :language => self.language,
   :group_id => self.group_id ? self.group_id : "",
   :prod_key => self.prod_key,
 }
 end

The first 2 attributes are required by Tire, to link the response from ES with your model. And here is the method in “product_elastic.rb” to index one record.


def self.index( product )
  Tire.index Settings.elasticsearch_product_index do
    store product.to_indexed_json
    product.update_attribute(:reindex, false)
  end
rescue => e
  p "ERROR in index(product) Message: #{e.message}"
  p "ERROR in index(product) backtrace: #{e.backtrace}"
end

And this here is the method to index all products from the DB:


def self.index_all
  Product.all.each do |product|
    ProductElastic.index product
  end
  self.refresh
end

def self.refresh
  Tire.index( Settings.elasticsearch_product_index ).refresh
end

Easy! Right? You can try the methods in the rails console. All right. You can now create mappings and index data. The only thing which is missing now is the search method. There is a lot to say about the search. I really recommend that you take your time and read the documentation about the search at the Tire homepage and the ES homepage. But here is one example.


def self.search(q, page_count = 1)
  if (q.nil? || q.empty?)
    raise ArgumentError, "query is empty! This is not allowed"
  end

  page_count = 1 if page_count.nil? || page_count.to_i < 1
  results_per_page = 30
  from = results_per_page * (page_count.to_i - 1)

  q = "*" if !q || q.empty?

  s = Tire.search( Settings.elasticsearch_product_index,
   load: true,
   from: from,
   per_page: results_per_page,
   size: results_per_page) do |search|

    search.sort { by [{:_score => 'desc'}] }

    search.query do |query|
      query.string "name:" + q
    end

  end

  s.results
end

The method above is with paging. You can easily use it with the “will_paginate” GEM.

There is much more to say about the mapping and the search. But this is the part there you have to invest time to figure it out, to deliver the search results you want. You will find a pretty good documentation on the ElasticSearch homepage: http://www.elasticsearch.org/guide/. And the core committer from the Tire project always responded in less than 24 hours to my tickets. The project support is very good.

Together with Timo I integrated ElasticSearch into VersionEye. Since them the search is much faster and the results are better. Even if there is no perfect match you will get results.

Kindle Paperwhite

Last week I got a late christmas gift.

Kindle Paperwhite

The brand new Kindle Paperwhite.

IMG_2893

It doesn’t have a color display. But that is a good thing, because that means that the battery lifetime is epic! 8 weeks! And because it doesn’t have a glamor display you can read on it comfortable on sunny days outdoors.

IMG_2886

The iPad is on sunny days outdoors not usable. Because of the shiny glamor display turns into mirror 🙂 This is not the case with a Kindle device. And it has some cool features. If you read a book, you can see a list of all people appearing in the book. That is useful.

IMG_2885

The device is even smaller than the iPad mini. It fits easily into your jacket pocket.

IMG_2895

One new feature at this device is the background light. The old kindle didn’t had background light and in dark rooms it was very hard to read them. This generation has a build in background light you can turn on and off.

And beside books, there are a couple magazines and newspapers available, too. For example “New York Times” or “Frankfurter Allgemeine Zeitung”.

I like it pretty much, because:

  1. It’s small & light 
  2. 8 weeks battery life time
  3. No shiny glamor display. It’s very good readable outdoors on sunny days
  4. No disturbing apps (Email, Messanger and so on).
  5. Background light
  6. Multitouch

And it is not very expensive. $119 is a fair price.

Why old school radio is bad for productivity

Are you a radio listener? I am! I listen radio every day at work. Just because I don’t want create my own playlist and I want to listen to new music. During work I like to listen to Jazz and to electronic music. Something what runs in the background and doesn’t disturb me.

But the old school radio stations are very disturbing. I am talking about radio stations you receive with old analog radios like this here.

radio

There are 3 reasons why old school radio stations are disturbing and bad for productivity.

  1. Commercials
  2. News
  3. DJs talking bullshit

When I turn on the Radio I want to listen to music. I am not interested in News! If I want to know what happens in the world, I go to Twitter or CNN. And of course I am not interested in commercial. Nobody is interested in commercial! And I am not interested in hearing the same joke 20 times a day from 2 different DJs.

I am sure you know this situation. You turn on the radio. You listen to 1 or 2 good songs. And than the DJ starts to talk. And he/she is telling you something you are not interested in. And then you listen again to 1 or 2 songs until they play some stupid commercials. And then again 1 or 2 songs until they tell you some news you know already. Their strategy is to disturb you after every 2nd song. I call that a bad user experience.

@BigFM. I am not interested in the fact the DJ Susanka is pregnant! Because I don’t know her! It’s not my fault that she is pregnant. And sharing this information with me every day doesn’t make my life better!

Old school radio is just annoying and bad for productivity! But there is hope. There is a new generation of radio stations out there. Radio and music apps without

  1. Commercial
  2. News
  3. DJs talking bullshit

I completely stopped listening old school radio! Instead of that I am listening to SoundCloud, Pandora and Spotify.

SoundCloud is just awesome! You can listen to music for hours, for free, without any annoying commercial, news and DJs talking bullshit. The people who are uploading the music are paying a small amount. That means the DJs are paying. For you as a listener it’s completely free!

soundcloud_logo

Another cool service is Pandora. At Pandora you can create your own stations. You just type in a song or a band you like and Pandora will play similar kind of music. Every song Pandora is playing for you, you can like or dislike. In that way Pandora learns your taste. From time to time they play a small commercial. But you can buy the premium account for $40 / year, and than it is completely commercial free. And yes! I am paying for the premium account. I would even pay more for the service. Because it’s is awesome!

pandora

SoundCloud and Pandora are my 2 favorites. But there are more music services out there. And I wish them all the best. I think that is the feature of music / radio.

What about you? You know any cool music services you want to share here?