Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement wrapper for Genre API #38

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 196 additions & 0 deletions pyechonest/genre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
#!/usr/bin/env python
# encoding: utf-8

import util
from proxies import GenreProxy
from proxies import ResultList

class Genre(GenreProxy):
"""
A Genre object

Attributes:
name (str): genre name

"""
def __init__(self, name, buckets=None, **kwargs):
"""
Genre class

Args:
name (str): a genre name

Kwargs:
buckets (list): A list of strings specifying which buckets to retrieve

Returns:
A Genre object

Example:

>>> g = genre.Genre('jazz', buckets=['description'])
>>> g.artists[0]
{u'id': u'ARIOZCU1187FB3A3DC', u'name': u'John Coltrane'}
>>>
"""
buckets = buckets or []
super(Genre, self).__init__(name, buckets, **kwargs)

def __repr__(self):
return "<{} - {}>".format(self._object_type.encode('utf-8'), self.name.encode('utf-8'))

def __str__(self):
return self.name.encode('utf-8')

def __cmp__(self, other):
return cmp(self.name, other.name)

def get_artists(self, results=15, cache=True):
"""Get a list of top artists for the genre

Args:

Kwargs:
cache (bool): A boolean indicating whether or not the cached value should be used (if available). Defaults to True.

results (int): An integer number of results to return.

Returns:
A list of artist dicts

Example:
>>> g = genre.Genre('jazz')
>>> g.artists[0]
{u'id': u'ARIOZCU1187FB3A3DC', u'name': u'John Coltrane'}
>>>
"""

if cache and ('artists' in self.cache) and results==15:
return self.cache['artists']
else:
response = self.get_attribute('artists', results=results)
if results==15:
self.cache['artists'] = ResultList(response['artists'])
return ResultList(response['artists'])

artists = property(get_artists)

def get_profile(self, cache=True, **kwargs):
"""Get basic information about a genre

Args:
name (str): The name of a genre

Kwargs:
cache (bool): A boolean indicating whether or not the cached value should be used (if available). Defaults to True.

Returns:
A list of genre dicts

Example:
>>> g = genre.Genre('jazz', buckets=['description','urls'])
>>> g.profile
{u'name': u'jazz', u'urls': {u'wikipedia_url': u'http://en.wikipedia.org/wiki/Jazz'}, u'description': u'Jazz is known for its use of blue notes, call-and-response, improvisation, polyrhythms, and syncopation. Jazz emerged in the early 20th century in the southern US, among African American musicians who layered European structures and harmony over African musical traditions. '}
>>>
"""
kwargs['name'] = self.name

if self.buckets:
kwargs['bucket'] = self.buckets

result = util.callm("%s/%s" % ('genre', 'profile'), kwargs)
return result['response']['genres'][0]

profile = property(get_profile)

def get_similar(self, results=15, start=0, cache=True, **kwargs):
"""Return similar genres to this one

Args:

Kwargs:
cache (bool): A boolean indicating whether or not the cached value should be used (if available). Defaults to True.

results (int): An integer number of results to return

start (int): An integer starting value for the result set

reverse (bool): A boolean indicating whether or not to return dissimilar artists (wrecommender). Defaults to False.

Returns:
A list of similar Genre objects

Example:
>>> g = genre.Genre('jazz')
>>> similar = g.similar[:5]
>>> similar
[<genre - bebop>, <genre - cool jazz>, <genre - contemporary post-bop>, <genre - hard bop>, <genre - soul jazz>]
>>>
"""
if self.buckets:
kwargs['bucket'] = self.buckets

if cache and ('similar' in self.cache) and results==15 and start==0 and (not kwargs):
return [Genre(**util.fix(g)) for g in self.cache['similar']]
else:
response = self.get_attribute('similar', results=results, start=start, **kwargs)
if results==15 and start==0 and (not kwargs):
self.cache['similar'] = response['genres']
return [Genre(**util.fix(g)) for g in response['genres']]

similar = property(get_similar)

def list(results=15, buckets=None):
"""Get a list of all of the available genres

Args:

Kwargs:
results (int): An integer number of results to return

buckets (list): A list of strings specifying which buckets to retrieve

Returns:
A list of Genre objects

Example:
>>> results = genre.list(5)
>>> results
[<genre - a cappella>, <genre - abstract>, <genre - abstract beats>, <genre - abstract hip hop>, <genre - abstract idm>]
>>>
"""
kwargs = locals()
kwargs['bucket'] = buckets or []
del kwargs['buckets']
result = util.callm("%s/%s" % ('genre', 'list'), kwargs)
return [Genre(**util.fix(g_dict)) for g_dict in result['response']['genres']]

def search(results=15, start=0, buckets=None, name=None):
"""Search for genres by name

Args:

Kwargs:
name (str): the name of a genre

start (int): An integer starting value for the result set

results (int): An integer number of results to return

buckets (list): A list of strings specifying which buckets to retrieve

Returns:
A list of Genre objects

Example:
>>> results = genre.search(results=5, name='rock')
>>> results
[<genre - african rock>, <genre - album rock>, <genre - alternative pop rock>, <genre - alternative rock>, <genre - alternative roots rock>]
>>>
"""
kwargs = locals()
kwargs['bucket'] = buckets or []
del kwargs['buckets']
"""Search for genres"""
result = util.callm("%s/%s" % ('genre', 'search'), kwargs)
return [Genre(**util.fix(g_dict)) for g_dict in result['response']['genres']]
23 changes: 22 additions & 1 deletion pyechonest/proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,25 @@ def __init__(self, identifier, md5, properties):
self.analysis_url = None
self._object_type = 'track'
self.__dict__.update(properties)



class GenreProxy(GenericProxy):
def __init__(self, name, buckets = None, **kwargs):
super(GenreProxy, self).__init__()
self.buckets = buckets or []
self.id = name
self._object_type = 'genre'
kwargs = dict((str(k), v) for (k,v) in kwargs.iteritems())
core_attrs = ['name']
if not all(ca in kwargs for ca in core_attrs):
profile = self.get_attribute('profile', **{'name':self.id, 'bucket':buckets})
kwargs.update(profile.get('genres')[0])
[self.__dict__.update({ca:kwargs.pop(ca)}) for ca in core_attrs+['id'] if ca in kwargs]
self.cache.update(kwargs)

def get_attribute(self, *args, **kwargs):
if util.short_regex.match(self.id) or util.long_regex.match(self.id) or util.foreign_regex.match(self.id):
kwargs['id'] = self.id
else:
kwargs['name'] = self.id
return super(GenreProxy, self).get_attribute(*args, **kwargs)
1 change: 1 addition & 0 deletions pyechonest/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
('SO', 'song'),
('RE', 'release'),
('TR', 'track'),
('GE', 'genre'),
('PE', 'person'),
('DE', 'device'),
('LI', 'listener'),
Expand Down