idiomag 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +2 -0
- data/LICENSE +9 -0
- data/README.rdoc +151 -0
- data/Rakefile +54 -0
- data/VERSION.yml +4 -0
- data/lib/idiomag.rb +17 -0
- data/lib/idiomag/articles.rb +48 -0
- data/lib/idiomag/artist.rb +103 -0
- data/lib/idiomag/base.rb +9 -0
- data/lib/idiomag/helpers.rb +26 -0
- data/lib/idiomag/parser.rb +32 -0
- data/lib/idiomag/recommendation.rb +70 -0
- data/lib/idiomag/rest.rb +20 -0
- data/lib/idiomag/tag.rb +106 -0
- data/lib/idiomag/user.rb +114 -0
- data/spec/articles_spec.rb +61 -0
- data/spec/artist_spec.rb +149 -0
- data/spec/base_spec.rb +15 -0
- data/spec/fixtures/articles_featured.json +1 -0
- data/spec/fixtures/articles_latest.json +1 -0
- data/spec/fixtures/artist_articles.json +1 -0
- data/spec/fixtures/artist_info.json +1 -0
- data/spec/fixtures/artist_photos.json +1 -0
- data/spec/fixtures/artist_playlist.json +1 -0
- data/spec/fixtures/artist_tags.json +1 -0
- data/spec/fixtures/artist_videos.json +1 -0
- data/spec/fixtures/recommendation_articles.json +1 -0
- data/spec/fixtures/recommendation_artists.json +1 -0
- data/spec/fixtures/tag_articles.json +1 -0
- data/spec/fixtures/tag_artists.json +1 -0
- data/spec/fixtures/tag_list.txt +144 -0
- data/spec/fixtures/tag_photos.json +1 -0
- data/spec/fixtures/tag_playlist.json +1 -0
- data/spec/fixtures/tag_videos.json +1 -0
- data/spec/fixtures/user_articles.json +1 -0
- data/spec/fixtures/user_info.json +1 -0
- data/spec/fixtures/user_lovedarticles.json +1 -0
- data/spec/fixtures/user_photos.json +1 -0
- data/spec/fixtures/user_playlist.json +1 -0
- data/spec/fixtures/user_videos.json +1 -0
- data/spec/recommendation_spec.rb +88 -0
- data/spec/rest_spec.rb +41 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/tag_spec.rb +149 -0
- data/spec/user_spec.rb +169 -0
- metadata +112 -0
data/History
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright © 2008 Jonathan Rudenberg
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
= idiomag
|
2
|
+
|
3
|
+
idiomag is a wrapper for the idiomag APIs (http://www.idiomag.com/api).
|
4
|
+
|
5
|
+
All calls require a API key.
|
6
|
+
|
7
|
+
|
8
|
+
== API Key
|
9
|
+
Idiomag::Base.api_key = 'foo'
|
10
|
+
|
11
|
+
== Prefetching
|
12
|
+
|
13
|
+
By default the gem will lazily load data as it is requested.
|
14
|
+
|
15
|
+
All resources support <tt>get</tt> like this:
|
16
|
+
|
17
|
+
articles.get(:latest, :featured)
|
18
|
+
|
19
|
+
== Articles
|
20
|
+
|
21
|
+
articles = Idiomag::Articles.new
|
22
|
+
|
23
|
+
puts "latest articles:"
|
24
|
+
articles.latest.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
25
|
+
puts "\n\n"
|
26
|
+
|
27
|
+
puts "featured articles:"
|
28
|
+
articles.featured.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
29
|
+
|
30
|
+
== Artist
|
31
|
+
|
32
|
+
artist = Idiomag::Artist.new('Anberlin')
|
33
|
+
artist.get(:info, :tags, :articles, :photos, :videos, :tracks)
|
34
|
+
|
35
|
+
puts "#{artist.name}'s URLs:"
|
36
|
+
artist.links.each {|link| puts link}
|
37
|
+
puts "\n\n"
|
38
|
+
|
39
|
+
puts "#{artist.name}'s related artists:"
|
40
|
+
artist.related.each {|name,link| puts "#{name}: #{link}"}
|
41
|
+
puts "\n\n"
|
42
|
+
|
43
|
+
puts "#{artist.name}'s tags:"
|
44
|
+
artist.tags.each {|tag,value| puts "#{tag} = #{value}"}
|
45
|
+
puts "\n\n"
|
46
|
+
|
47
|
+
puts "#{artist.name}'s recent articles:"
|
48
|
+
artist.articles.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
49
|
+
puts "\n\n"
|
50
|
+
|
51
|
+
puts "#{artist.name}'s photos:"
|
52
|
+
artist.photos.each {|photo| puts photo[:url]}
|
53
|
+
puts "\n\n"
|
54
|
+
|
55
|
+
puts "#{artist.name}'s videos:"
|
56
|
+
artist.videos.each {|video| puts "#{video[:title]} - #{video[:location]}"}
|
57
|
+
puts "\n\n"
|
58
|
+
|
59
|
+
puts "#{artist.name}'s tracks:"
|
60
|
+
artist.tracks.each {|track| puts "#{track[:title]} - #{track[:location]}"}
|
61
|
+
|
62
|
+
== Tag
|
63
|
+
A tag is a music genre, such as Indie, Jazz or Emo. Tags can be either symbols or strings.
|
64
|
+
|
65
|
+
<tt>Idiomag::Tag.list</tt> will return an array of valid tags.
|
66
|
+
|
67
|
+
tag = Idiomag::Tag.new(:alternative_rock)
|
68
|
+
tag.get(:artists, :articles, :photos, :videos, :tracks)
|
69
|
+
|
70
|
+
puts "artists for #{tag.name}:"
|
71
|
+
tag.artists.each {|name,value| puts "#{name}: #{value}"}
|
72
|
+
puts "\n\n"
|
73
|
+
|
74
|
+
puts "recent articles for #{tag.name}:"
|
75
|
+
tag.articles.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
76
|
+
puts "\n\n"
|
77
|
+
|
78
|
+
puts "photos for #{tag.name}:"
|
79
|
+
tag.photos.each {|photo| puts photo[:url]}
|
80
|
+
puts "\n\n"
|
81
|
+
|
82
|
+
puts "videos for #{tag.name}:"
|
83
|
+
tag.videos.each {|video| puts "#{video[:title]} - #{video[:location]}"}
|
84
|
+
puts "\n\n"
|
85
|
+
|
86
|
+
puts "tracks for #{tag.name}:"
|
87
|
+
tag.tracks.each {|track| puts "#{track[:title]} - #{track[:location]}"}
|
88
|
+
|
89
|
+
== User
|
90
|
+
Gets info on an idiomag user.
|
91
|
+
|
92
|
+
user = Idiomag::User.new('Titanous')
|
93
|
+
user.get(:info, :articles, :loved_articles, :photos, :videos, :tracks)
|
94
|
+
|
95
|
+
puts "#{user.name}'s info:"
|
96
|
+
puts "email hash: #{user.email}"
|
97
|
+
puts "profile url: #{user.url}"
|
98
|
+
puts "\n"
|
99
|
+
|
100
|
+
puts "#{user.name}'s tags:"
|
101
|
+
user.tags.each {|tag,value| puts "#{tag} = #{value}"}
|
102
|
+
puts "\n"
|
103
|
+
|
104
|
+
puts "#{user.name}'s artists:"
|
105
|
+
user.artists.each {|name,value| puts "#{name}: #{value}"}
|
106
|
+
puts "\n\n"
|
107
|
+
|
108
|
+
puts "#{user.name}'s recent articles:"
|
109
|
+
user.articles.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
110
|
+
puts "\n\n"
|
111
|
+
|
112
|
+
puts "#{user.name}'s loved articles:"
|
113
|
+
user.loved_articles.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
114
|
+
puts "\n\n"
|
115
|
+
|
116
|
+
puts "#{user.name}'s photos:"
|
117
|
+
user.photos.each {|photo| puts photo[:url]}
|
118
|
+
puts "\n\n"
|
119
|
+
|
120
|
+
puts "#{user.name}'s videos:"
|
121
|
+
user.videos.each {|video| puts "#{video[:title]} - #{video[:location]}"}
|
122
|
+
puts "\n\n"
|
123
|
+
|
124
|
+
puts "#{user.name}'s tracks:"
|
125
|
+
user.tracks.each {|track| puts "#{track[:title]} - #{track[:location]}"}
|
126
|
+
|
127
|
+
== Recommendation
|
128
|
+
Provides recommendations based on a list of artists. This list of artists can be provided as either an apml url, an array, or a site such as last.fm
|
129
|
+
|
130
|
+
recommendation = Idiomag::Recommendation.new(:network => :lastfm, :user => 'titanous')
|
131
|
+
recommendation.get(:articles, :artists)
|
132
|
+
|
133
|
+
puts "recommended artists:"
|
134
|
+
recommendation.artists.each {|name,value| puts "#{name}: #{value}"}
|
135
|
+
puts "\n\n"
|
136
|
+
|
137
|
+
puts "recommended articles:"
|
138
|
+
recommendation.articles.each {|article| puts "#{article[:title]} on #{article[:date].strftime('%A')}"}
|
139
|
+
|
140
|
+
=== Lookup types
|
141
|
+
==== Network
|
142
|
+
Idiomag::Recommendation.new(:network => :lastfm, :user => 'titanous')
|
143
|
+
|
144
|
+
Supported networks:
|
145
|
+
[:lastfm, :mog, :ilike, :mystrands, :projectplaylist, :imeem, :pandora, :bebo, :myspace, :songza]
|
146
|
+
|
147
|
+
==== APML
|
148
|
+
Idiomag::Recommendation.new(:apml => 'http://research.sun.com:8080/AttentionProfile/apml/music/titanous')
|
149
|
+
|
150
|
+
==== Artist List
|
151
|
+
Idiomag::Recommendation.new(:artists => ['Relient K', 'Anberlin'])
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rcov/rcovtask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
WEBSITE_PATH = 'titanous@rubyforge.org:/var/www/gforge-projects/idiomag'
|
7
|
+
|
8
|
+
begin
|
9
|
+
require 'jeweler'
|
10
|
+
Jeweler::Tasks.new do |s|
|
11
|
+
s.name = 'idiomag'
|
12
|
+
s.summary = 'wrapper for the idiomag api'
|
13
|
+
s.description = 'wrapper for the idiomag api'
|
14
|
+
s.email = 'jon335@gmail.com'
|
15
|
+
s.homepage = 'http://idiomag.rubyforge.org'
|
16
|
+
s.authors = ['Jonathan Rudenberg']
|
17
|
+
s.add_dependency('httparty', '>= 0.2.2')
|
18
|
+
s.rubyforge_project = 'idiomag'
|
19
|
+
s.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'spec/**/*'].to_a
|
20
|
+
s.has_rdoc = true
|
21
|
+
s.rdoc_options = ['--line-numbers', '--inline-source', '--title', 'idiomag', '--main', 'README.rdoc']
|
22
|
+
s.extra_rdoc_files = ['README.rdoc']
|
23
|
+
end
|
24
|
+
rescue LoadError
|
25
|
+
puts 'Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com'
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::RDocTask.new do |rdoc|
|
29
|
+
rdoc.rdoc_dir = 'doc'
|
30
|
+
rdoc.title = 'idiomag'
|
31
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
32
|
+
rdoc.rdoc_files.include('README*')
|
33
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Run all specs with rcov'
|
37
|
+
Rcov::RcovTask.new do |t|
|
38
|
+
t.test_files = FileList['spec/*_spec.rb']
|
39
|
+
t.rcov_opts = ['--exclude', 'spec']
|
40
|
+
t.verbose = true
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :rcov
|
44
|
+
|
45
|
+
desc 'Upload website files to rubyforge'
|
46
|
+
task :website do
|
47
|
+
sh %{rsync -av website/ #{WEBSITE_PATH}}
|
48
|
+
Rake::Task['website_docs'].invoke
|
49
|
+
end
|
50
|
+
|
51
|
+
task :website_docs do
|
52
|
+
Rake::Task['rdoc'].invoke
|
53
|
+
sh %{rsync -av doc/ #{WEBSITE_PATH}/docs}
|
54
|
+
end
|
data/VERSION.yml
ADDED
data/lib/idiomag.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
gem 'httparty', '>= 0.2.2'
|
5
|
+
require 'httparty'
|
6
|
+
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
require 'idiomag/base'
|
10
|
+
require 'idiomag/helpers'
|
11
|
+
require 'idiomag/parser'
|
12
|
+
require 'idiomag/rest'
|
13
|
+
require 'idiomag/artist'
|
14
|
+
require 'idiomag/articles'
|
15
|
+
require 'idiomag/tag'
|
16
|
+
require 'idiomag/user'
|
17
|
+
require 'idiomag/recommendation'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Idiomag
|
2
|
+
class Articles
|
3
|
+
def get(*args)
|
4
|
+
args.each do |action|
|
5
|
+
case action
|
6
|
+
when :latest
|
7
|
+
get_latest
|
8
|
+
when :featured
|
9
|
+
get_featured
|
10
|
+
else
|
11
|
+
raise ArgumentError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def respond_to?(method)
|
17
|
+
case method
|
18
|
+
when :featured,:latest
|
19
|
+
true
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_missing(method, *args)
|
26
|
+
case method
|
27
|
+
when :latest
|
28
|
+
get_latest if @latest.nil?
|
29
|
+
@latest
|
30
|
+
when :featured
|
31
|
+
get_featured if @featured.nil?
|
32
|
+
@featured
|
33
|
+
else
|
34
|
+
super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def get_latest
|
41
|
+
@latest = Parser.parse_articles(REST.fetch('articles/latest'))
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_featured
|
45
|
+
@featured = Parser.parse_articles(REST.fetch('articles/featured'))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Idiomag
|
2
|
+
class Artist
|
3
|
+
|
4
|
+
def initialize(artist)
|
5
|
+
raise ArgumentError if artist.blank?
|
6
|
+
@artist = artist
|
7
|
+
end
|
8
|
+
|
9
|
+
def get(*args)
|
10
|
+
args.each do |action|
|
11
|
+
case action
|
12
|
+
when :info
|
13
|
+
get_info
|
14
|
+
when :tags
|
15
|
+
get_tags
|
16
|
+
when :articles
|
17
|
+
get_articles
|
18
|
+
when :photos
|
19
|
+
get_photos
|
20
|
+
when :videos
|
21
|
+
get_videos
|
22
|
+
when :playlist, :tracks
|
23
|
+
get_playlist
|
24
|
+
else
|
25
|
+
raise ArgumentError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def respond_to?(method)
|
31
|
+
case method
|
32
|
+
when :links,:related,:tags,:articles,:photos,:videos,:playlist,:tracks,:name
|
33
|
+
true
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method, *args)
|
40
|
+
case method
|
41
|
+
when :name
|
42
|
+
@artist
|
43
|
+
when :links
|
44
|
+
get_info if @links.nil?
|
45
|
+
@links
|
46
|
+
when :related
|
47
|
+
get_info if @related.nil?
|
48
|
+
@related
|
49
|
+
when :tags
|
50
|
+
get_tags if @tags.nil?
|
51
|
+
@tags
|
52
|
+
when :articles
|
53
|
+
get_articles if @articles.nil?
|
54
|
+
@articles
|
55
|
+
when :photos
|
56
|
+
get_photos if @photos.nil?
|
57
|
+
@photos
|
58
|
+
when :videos
|
59
|
+
get_videos if @videos.nil?
|
60
|
+
@videos
|
61
|
+
when :playlist, :tracks
|
62
|
+
get_playlist if @playlist.nil?
|
63
|
+
@playlist
|
64
|
+
else
|
65
|
+
super
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def get_info
|
72
|
+
info_data = REST.fetch('artist/info', :artist => @artist)
|
73
|
+
@links = info_data['links']['url']
|
74
|
+
|
75
|
+
@related = {}
|
76
|
+
info_data['related']['artist'].each {|a| @related[a['name']] = a['links']['url'][0] }
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_tags
|
80
|
+
tag_data = REST.fetch('artist/tags', :artist => @artist)
|
81
|
+
|
82
|
+
@tags = {}
|
83
|
+
tag_data['profile']['tag'].each {|t| @tags[t['name']] = t['value']}
|
84
|
+
@tags.keys_to_sym!
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_articles
|
88
|
+
@articles = Parser.parse_articles(REST.fetch('artist/articles', :artist => @artist))
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_photos
|
92
|
+
@photos = Parser.parse_photos(REST.fetch('artist/photos', :artist => @artist))
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_videos
|
96
|
+
@videos = Parser.parse_videos(REST.fetch('artist/videos', :artist => @artist))
|
97
|
+
end
|
98
|
+
|
99
|
+
def get_playlist
|
100
|
+
@playlist = Parser.parse_playlist(REST.fetch('artist/playlist', :artist => @artist))
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/idiomag/base.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Hash #:nodoc:
|
2
|
+
def keys_to_sym!
|
3
|
+
return Hash.keys_to_sym(self)
|
4
|
+
end
|
5
|
+
|
6
|
+
def rename_key!(old_key, new_key)
|
7
|
+
return Hash.rename_key(self, old_key, new_key)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def self.keys_to_sym(hsh)
|
12
|
+
hsh.each_key do |k|
|
13
|
+
if k =~ /-/
|
14
|
+
hsh[k.to_s.downcase] = hsh.delete(k)
|
15
|
+
else
|
16
|
+
hsh[k.to_s.downcase.gsub(/ /, '_').to_sym] = hsh.delete(k)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
return hsh
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.rename_key(hsh, old_key, new_key)
|
23
|
+
hsh[new_key.to_s] = hsh.delete(old_key.to_s)
|
24
|
+
return hsh
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Idiomag
|
2
|
+
class Parser
|
3
|
+
class << self
|
4
|
+
def parse_articles(article_data)
|
5
|
+
articles = article_data['articles']
|
6
|
+
articles.each do |a|
|
7
|
+
a.rename_key!('sourceUrl', 'source_url')
|
8
|
+
a.keys_to_sym!
|
9
|
+
a[:date] = Time.parse(a[:date])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def parse_photos(photo_data)
|
14
|
+
photos = photo_data['photos']
|
15
|
+
photos.each do |p|
|
16
|
+
p.keys_to_sym!
|
17
|
+
p[:date] = Time.parse(p[:date])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_videos(video_data)
|
22
|
+
videos = video_data['tracks']
|
23
|
+
videos.each {|v| v.keys_to_sym!}
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_playlist(playlist_data)
|
27
|
+
playlist = playlist_data['tracks']
|
28
|
+
playlist.each {|v| v.keys_to_sym!}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|