officialfm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,26 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+ *.gem
21
+ .yardopts
22
+ .yardoc
23
+ .bundle
24
+ Gemfile.lock
25
+
26
+ ## PROJECT::SPECIFIC
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Amos Wenger
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # official.fm
2
+
3
+ Unofficial Ruby wrapper for the [official.fm Simple API](http://official.fm/developers).
4
+
5
+ ## Installation
6
+
7
+ sudo gem install officialfm
8
+
9
+ ## Get your API key
10
+
11
+ Be sure and get your API key: [http://official.fm/developers/manage](http://official.fm/developers/manage)
12
+
13
+ ## Usage
14
+
15
+ ### Instantiate a client
16
+
17
+ officialfm = OfficialFM::Client.new(:api_key => 'your_api_key')
18
+
19
+ #### Examples
20
+
21
+ officialfm.user('chab')
22
+ puts user.name
23
+
24
+ officialfm.tracks('Dare', {:limit => 10, :embed => false}).each |track| do
25
+ puts "#{track.name} by #{track.artist_string}"
26
+ end
27
+
28
+ For a complete example of web-app using Sinatra in conjunction with
29
+ this gem, see [ofmtweet](https://github.com/nddrylliog/ofmtweet).
30
+
31
+ ## Additions to the original API
32
+
33
+ ### playlist.tracks
34
+
35
+ For the time being, the structure of playlists in the JSON response of the official.fm
36
+ server is:
37
+
38
+ {
39
+ "tracks_count":4,
40
+ "tracks_list":"57854,40057,11290,12818",
41
+ }
42
+
43
+ It'd be more convenient to have something like:
44
+
45
+ {
46
+ "tracks": [ 57854, 40057, 11290, 12818 ],
47
+ }
48
+
49
+ But until it's fixed, this gem emulates it, so you can still write pretty code like:
50
+
51
+ officialfm.playlists('R&B', :limit => 1)[0].tracks.do |track|
52
+ puts " * #{officialfm.track(track).title}"
53
+ end
54
+
55
+ ### playlist.running\_time
56
+
57
+ The original API has a `length` attribute in playlists, but unfortunately
58
+ we can't use it from the Ruby side with Hashie, because it's already the number
59
+ of fields of the hash (as I understand it).
60
+
61
+ It can still be accessed with `playlist["length"]` but since it's not pretty,
62
+ the gem allows you to access it like this:
63
+
64
+ puts "#{playlist.running_time}s of pure bliss"
65
+
66
+ ## Note on Patches/Pull Requests
67
+
68
+ * Fork the project.
69
+ * Make your feature addition or bug fix.
70
+ * Add tests for it. This is important so I don't break it in a
71
+ future version unintentionally.
72
+ * Commit, do not mess with rakefile, version, or history.
73
+ (if you want to have your own version, that is fine but
74
+ bump version in a commit by itself I can ignore when I pull)
75
+ * Send me a pull request. Bonus points for topic branches.
76
+
77
+ ## Copyright
78
+
79
+ Copyright (c) 2011 Amos Wenger. See LICENSE for details.
80
+
81
+ Based on [@pengwynn's Gowalla API wrapper](https://github.com/pengwynn/gowalla)
82
+
83
+ A huge load of thanks to pengwynn for releasing it open-source! It was wonderful
84
+ to work from his extra-clean codebase.
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rake'
2
+ require "shoulda/tasks"
3
+ require "rake/testtask"
4
+ require 'bundler'
5
+
6
+ Bundler::GemHelper.install_tasks
7
+
8
+ Rake::TestTask.new(:test) do |test|
9
+ test.ruby_opts = ["-rubygems"] if defined? Gem
10
+ test.libs << "lib" << "test"
11
+ test.pattern = "test/**/*_test.rb"
12
+ end
13
+
14
+ task :default => :test
data/changelog.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 0.0.1 March 23, 2011
4
+ * Initial version
5
+ * Supports tracks, users, playlists
6
+ * Improved playlist support: tracks, running_time
@@ -0,0 +1,57 @@
1
+ require 'forwardable'
2
+
3
+ # Note: this gem only supports the Simple API, since the Advanced API
4
+ # is still in development
5
+
6
+ module OfficialFM
7
+ class Client
8
+ extend Forwardable
9
+
10
+ include Users
11
+ include Tracks
12
+ include Playlists
13
+
14
+ attr_reader :api_key
15
+
16
+ def_delegators :web_server
17
+
18
+ def initialize(options={})
19
+ @api_key = options[:api_key] || OfficialFM.api_key
20
+ # Note: Although the default of the API is to return XML, I think
21
+ # json is more appropriate in the Ruby world
22
+
23
+ # Note: I really don't understand how js_callback_function works,
24
+ # so I'm not exposing it here. (Is it for AJAX client-side requests?)
25
+ @format = options[:format] || :json
26
+ connection
27
+ end
28
+
29
+ # Raw HTTP connection, either Faraday::Connection
30
+ #
31
+ # @return [Faraday::Connection]
32
+ def connection
33
+ params = {:key => @api_key, :format => @format}
34
+ @connection ||= Faraday::Connection.new(:url => api_url, :params => params, :headers => default_headers) do |builder|
35
+ builder.adapter Faraday.default_adapter
36
+ builder.use Faraday::Response::ParseJson
37
+ builder.use Faraday::Response::Mashify
38
+ end
39
+
40
+ end
41
+
42
+ # @private
43
+ def default_headers
44
+ headers = {
45
+ :accept => 'application/json',
46
+ :user_agent => 'officialfm Ruby gem'
47
+ }
48
+ end
49
+
50
+ # Provides the URL for accessing the API
51
+ #
52
+ # @return [String]
53
+ def api_url
54
+ "http://api.official.fm"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,55 @@
1
+ require 'cgi'
2
+
3
+ module OfficialFM
4
+ module Playlists
5
+
6
+ # Search for playlists
7
+ #
8
+ # @param [String] search_param: a search parameter (eg. name of the playlist)
9
+ # @param [Integer] limit (50) limit per page (optional)
10
+ # @return [Hashie::Mash] Playlist list
11
+ def playlists(search_param, options={})
12
+ response = connection.get do |req|
13
+ req.url "/search/playlists/#{CGI::escape(search_param)}",
14
+ :api_max_responses => options[:limit]
15
+ end
16
+
17
+ response.body.map do |pl| improve(pl) end
18
+ end
19
+
20
+ # Retrieve information about a specific playlist
21
+ #
22
+ # @param [String] track_id: id
23
+ # @param [Bool] embed (false) should embed codes be included in the response
24
+ # @return [Hashie::Mash] Playlist
25
+ def playlist(playlist_id, options={})
26
+ response = connection.get do |req|
27
+ req.url "/playlist/#{CGI::escape(playlist_id.to_s)}",
28
+ :api_embed_codes => options[:embed]
29
+ end
30
+ improve(response.body[0])
31
+ end
32
+
33
+ # Retrieve users that have voted for this playlist
34
+ #
35
+ # @param [String] track_id: id
36
+ # @param [Integer] limit (50) limit per page
37
+ # @return [Hashie::Mash] User list
38
+ def playlist_votes(playlist_id, options={})
39
+ response = connection.get do |req|
40
+ req.url "/playlist/#{playlist_id}/votes",
41
+ :api_max_responses => options[:limit]
42
+ end
43
+ response.body
44
+ end
45
+
46
+ def improve(playlist)
47
+ # the length field is already used. Note: running_time is in seconds
48
+ playlist.running_time = playlist["length"]
49
+ # Our own little hack to make it a lot easier to handle, until the API is improved.
50
+ playlist.tracks = playlist.tracks_list.split(',').map do |x| x.to_i end
51
+ playlist
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,82 @@
1
+ require 'cgi'
2
+
3
+ module OfficialFM
4
+ module Tracks
5
+
6
+ # Search for tracks
7
+ #
8
+ # @param [String] search_param: a search parameter (eg. name of the track)
9
+ # @param [Integer] limit (50) limit per page (optional)
10
+ # @return [Hashie::Mash] Track list
11
+ def tracks(search_param, options={})
12
+ response = connection.get do |req|
13
+ req.url "/search/tracks/#{CGI::escape(search_param)}",
14
+ :api_max_responses => options[:limit]
15
+ end
16
+ response.body
17
+ end
18
+
19
+ # Retrieve information about a specific track
20
+ #
21
+ # Note: http://official.fm/developers/simple_api#track_show
22
+ # says that api_max_responses is a valid parameter. Why escapes me.
23
+ #
24
+ # @param [String] track_id: id
25
+ # @param [Bool] embed (false) should embed codes be included in the response
26
+ # @return [Hashie::Mash] Track
27
+ def track(track_id, options={})
28
+ response = connection.get do |req|
29
+ req.url "/track/#{track_id}",
30
+ :api_embed_codes => options[:embed]
31
+ end
32
+ response.body[0]
33
+ end
34
+
35
+ # Retrieve users that have voted for this track
36
+ #
37
+ # @param [String] track_id: id
38
+ # @param [Integer] limit (50) limit per page
39
+ # @return [Hashie::Mash] User list
40
+ def track_votes(track_id, options={})
41
+ response = connection.get do |req|
42
+ req.url "/track/#{track_id}/votes",
43
+ :api_max_responses => options[:limit]
44
+ end
45
+ response.body
46
+ end
47
+
48
+ # Retrieve 200 tracks of selected chart
49
+ #
50
+ # @param [String] charting: :today, :week, :month, :year or :all_time
51
+ # @param [String] genre: Genre string (Electronic, Rock, Jazz, ...) (optional)
52
+ # @param [String] country: ISO country id (CH, FR, UK) (optional)
53
+ # @param [Bool] embed (false) should embed codes be included in the response (optional)
54
+ # @param [Integer] limit (200) limit per page (optional)
55
+ # @return [Hashie::Mash] Track list
56
+ def charts(charting, options={})
57
+ response = connection.get do |req|
58
+ req.url "/tracks/charts",
59
+ :charting => charting, :genre => options[:genre], :country => options[:country],
60
+ :api_embed_codes => options[:embed], :api_max_responses => options[:limit]
61
+ end
62
+ response.body
63
+ end
64
+
65
+ # Retrieve 200 latest tracks
66
+ #
67
+ # @param [String] genre: Genre string (Electronic, Rock, Jazz, ...) (optional)
68
+ # @param [String] country: ISO country id (CH, FR, UK) (optional)
69
+ # @param [Bool] embed (false) should embed codes be included in the response (optional)
70
+ # @param [Integer] limit (200) limit per page (optional)
71
+ # @return [Hashie::Mash] Track list
72
+ def latest(options={})
73
+ response = connection.get do |req|
74
+ req.url "/tracks/latest", :genre => options[:genre],
75
+ :country => options[:country], :api_embed_codes => options[:embed],
76
+ :api_max_responses => options[:limit]
77
+ end
78
+ response.body
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,97 @@
1
+ require 'cgi'
2
+
3
+ module OfficialFM
4
+ module Users
5
+
6
+ # Search for users
7
+ #
8
+ # @param [String] search_param: a search parameter (eg. name of the user)
9
+ # @param [Integer] limit (50) limit per page
10
+ # @return [Hashie::Mash] User list
11
+ def users(search_param, options={})
12
+ response = connection.get do |req|
13
+ req.url "/search/users/#{CGI::escape(search_param)}", :api_max_responses => options[:limit]
14
+ end
15
+ response.body
16
+ end
17
+
18
+ # Retrieve information about a specific user
19
+ #
20
+ # @param [String] user_id: id or login
21
+ # @return [Hashie::Mash] User
22
+ def user(user_id)
23
+ response = connection.get do |req|
24
+ req.url "/user/#{user_id}"
25
+ end
26
+ response.body[0]
27
+ end
28
+
29
+ # Retrieve a list of the tracks of this user
30
+ #
31
+ # @param [String] user_id: id or login
32
+ # @param [Integer] limit (50) limit per page
33
+ # @param [Bool] embed (false) should embed codes be included in the response
34
+ # @return [Hashie::Mash] Track list
35
+ def user_tracks(user_id, options={})
36
+ response = connection.get do |req|
37
+ req.url "/user/#{user_id}/tracks",
38
+ :api_embed_codes => options[:embed], :api_max_responses => options[:limit]
39
+ end
40
+ response.body
41
+ end
42
+
43
+ # Retrieve a list of the playlists of this user
44
+ #
45
+ # @param [String] user_id: id or login
46
+ # @param [Integer] limit (50) limit per page
47
+ # @param [Bool] embed (false) should embed codes be included in the response
48
+ # @return [Hashie::Mash] Playlist list
49
+ def user_playlists(user_id, options={})
50
+ response = connection.get do |req|
51
+ req.url "/user/#{user_id}/playlists",
52
+ :api_embed_codes => options[:embed], :api_max_responses => options[:limit]
53
+ end
54
+ response.body
55
+ end
56
+
57
+ # Retrieve a list of the contacts of this user
58
+ #
59
+ # @param [String] user_id: id or login
60
+ # @param [Integer] limit (50) limit per page
61
+ # @return [Hashie::Mash] User list
62
+ def user_contacts(user_id, options={})
63
+ response = connection.get do |req|
64
+ req.url "/user/#{user_id}/contacts",
65
+ :api_max_responses => options[:limit]
66
+ end
67
+ response.body
68
+ end
69
+
70
+ # Retrieve a list of the subscribers of this user
71
+ #
72
+ # @param [String] user_id: id or login
73
+ # @param [Integer] limit (50) limit per page
74
+ # @return [Hashie::Mash] User list
75
+ def user_subscribers(user_id, options={})
76
+ response = connection.get do |req|
77
+ req.url "/user/#{user_id}/subscribers",
78
+ :api_max_responses => options[:limit]
79
+ end
80
+ response.body
81
+ end
82
+
83
+ # Retrieve a list of the subscriptions of this user
84
+ #
85
+ # @param [String] user_id: id or login
86
+ # @param [Integer] limit (50) limit per page
87
+ # @return [Hashie::Mash] User list
88
+ def user_subscriptions(user_id, options={})
89
+ response = connection.get do |req|
90
+ req.url "/user/#{user_id}/subscriptions",
91
+ :api_max_responses => options[:limit]
92
+ end
93
+ response.body
94
+ end
95
+
96
+ end
97
+ end
@@ -0,0 +1,3 @@
1
+ module OfficialFM
2
+ VERSION = '0.0.1'
3
+ end
data/lib/officialfm.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'faraday'
2
+ require 'oauth2'
3
+ require 'faraday_middleware'
4
+
5
+ directory = File.expand_path(File.dirname(__FILE__))
6
+
7
+ module OfficialFM
8
+
9
+ class << self
10
+ attr_accessor :api_key
11
+ attr_accessor :test_mode
12
+
13
+ # Configures default credentials easily
14
+ # @yield [api_key]
15
+ def configure
16
+ yield self
17
+ true
18
+ end
19
+
20
+ def test_mode?
21
+ !!self.test_mode
22
+ end
23
+ end
24
+
25
+ require 'officialfm/users'
26
+ require 'officialfm/tracks'
27
+ require 'officialfm/playlists'
28
+ require 'officialfm/client'
29
+
30
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/officialfm/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'officialfm'
6
+ s.version = OfficialFM::VERSION
7
+ s.authors = ["Amos Wenger"]
8
+ s.email = ['ndd@rylliog.cz']
9
+ s.summary = %q{Unofficial wrapper for the official.fm API}
10
+ s.description = %q{Unofficial Ruby wrapper for the official.fm API}
11
+ s.homepage = 'http://github.com/nddrylliog/officialfm-ruby'
12
+
13
+ s.add_runtime_dependency 'faraday', '~> 0.5.3'
14
+ s.add_runtime_dependency 'faraday_middleware', '~> 0.3.0'
15
+ s.add_runtime_dependency 'hashie', '~> 1.0.0'
16
+ s.add_runtime_dependency 'oauth2', '~> 0.1.0'
17
+
18
+ s.add_development_dependency 'bundler', '~> 1.0'
19
+ s.add_development_dependency 'fakeweb', '~> 1.3'
20
+ s.add_development_dependency 'jnunemaker-matchy', '~> 0.4'
21
+ s.add_development_dependency 'json_pure', '~> 1.4'
22
+ s.add_development_dependency 'rake', '~> 0.8'
23
+ s.add_development_dependency 'shoulda', '~> 2.11'
24
+ s.add_development_dependency 'test-unit', '~> 2.1'
25
+
26
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
27
+ s.platform = Gem::Platform::RUBY
28
+ s.require_paths = ['lib']
29
+ s.files = `git ls-files`.split("\n")
30
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
31
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
32
+ end