PageRenderTime 546ms CodeModel.GetById 171ms app.highlight 103ms RepoModel.GetById 179ms app.codeStats 0ms

/src/pyechonest/pyechonest/proxies.py

http://echo-nest-remix.googlecode.com/
Python | 173 lines | 128 code | 26 blank | 19 comment | 71 complexity | 6dbb9617f6d47b2514f8fdb342cfe248 MD5 | raw file
  1#!/usr/bin/env python
  2# encoding: utf-8
  3
  4"""
  5Copyright (c) 2010 The Echo Nest. All rights reserved.
  6Created by Tyler Williams on 2010-04-25.
  7"""
  8import util
  9
 10class ResultList(list):
 11    def __init__(self, li, start=0, total=0):
 12        self.extend(li)
 13        self.start = start
 14        if total == 0:
 15            total = len(li)
 16        self.total = total
 17
 18class GenericProxy(object):
 19    def __init__(self):
 20        self.cache = {}
 21    
 22    def get_attribute(self, method_name, **kwargs):
 23        result = util.callm("%s/%s" % (self._object_type, method_name), kwargs)
 24        return result['response']
 25    
 26    def post_attribute(self, method_name, **kwargs):
 27        data = kwargs.pop('data') if 'data' in kwargs else {}
 28        result = util.callm("%s/%s" % (self._object_type, method_name), kwargs, POST=True, data=data)
 29        return result['response']
 30    
 31
 32class ArtistProxy(GenericProxy):
 33    def __init__(self, identifier, buckets = None, **kwargs):
 34        super(ArtistProxy, self).__init__()
 35        buckets = buckets or []
 36        self.id = identifier
 37        self._object_type = 'artist'
 38        kwargs = dict((str(k), v) for (k,v) in kwargs.iteritems())
 39        # the following are integral to all artist objects... the rest is up to you!
 40        core_attrs = ['name']
 41        
 42        if not all(ca in kwargs for ca in core_attrs):
 43            profile = self.get_attribute('profile', **{'bucket':buckets})
 44            kwargs.update(profile.get('artist'))
 45        [self.__dict__.update({ca:kwargs.pop(ca)}) for ca in core_attrs+['id'] if ca in kwargs]        
 46        self.cache.update(kwargs)
 47    
 48    def get_attribute(self, *args, **kwargs):
 49        if util.short_regex.match(self.id) or util.long_regex.match(self.id) or util.foreign_regex.match(self.id):
 50            kwargs['id'] = self.id
 51        else:
 52            kwargs['name'] = self.id
 53        return super(ArtistProxy, self).get_attribute(*args, **kwargs)
 54    
 55
 56class CatalogProxy(GenericProxy):
 57    def __init__(self, identifier, type, buckets = None, **kwargs):
 58        super(CatalogProxy, self).__init__()
 59        buckets = buckets or []
 60        self.id = identifier
 61        self._object_type = 'catalog'
 62        kwargs = dict((str(k), v) for (k,v) in kwargs.iteritems())
 63        # the following are integral to all catalog objects... the rest is up to you!
 64        core_attrs = ['name']
 65        if not all(ca in kwargs for ca in core_attrs):
 66            if util.short_regex.match(self.id) or util.long_regex.match(self.id) or util.foreign_regex.match(self.id):
 67                try:
 68                    profile = self.get_attribute('profile')
 69                    kwargs.update(profile['catalog'])
 70                except util.EchoNestAPIError:
 71                    raise Exception('Catalog %s does not exist' % (identifier))
 72            else:
 73                if not type:
 74                    raise Exception('You must specify a "type"!')
 75                try:
 76                    profile = self.get_attribute('profile')
 77                    existing_type = profile['catalog'].get('type', 'Unknown')
 78                    if type != existing_type:
 79                        raise Exception("Catalog type requested (%s) does not match existing catalog type (%s)" % (type, existing_type))
 80                    
 81                    kwargs.update(profile['catalog'])
 82                except util.EchoNestAPIError:
 83                    profile = self.post_attribute('create', type=type, **kwargs)
 84                    kwargs.update(profile)
 85        [self.__dict__.update({ca:kwargs.pop(ca)}) for ca in core_attrs+['id'] if ca in kwargs]
 86        self.cache.update(kwargs)
 87    
 88    def get_attribute_simple(self, *args, **kwargs):
 89        # omit name/id kwargs for this call
 90        return super(CatalogProxy, self).get_attribute(*args, **kwargs)
 91    
 92    def get_attribute(self, *args, **kwargs):
 93        if util.short_regex.match(self.id) or util.long_regex.match(self.id) or util.foreign_regex.match(self.id):
 94            kwargs['id'] = self.id
 95        else:
 96            kwargs['name'] = self.id
 97        return super(CatalogProxy, self).get_attribute(*args, **kwargs)
 98    
 99    def post_attribute(self, *args, **kwargs):
100        if util.short_regex.match(self.id) or util.long_regex.match(self.id) or util.foreign_regex.match(self.id):
101            kwargs['id'] = self.id
102        else:
103            kwargs['name'] = self.id
104        return super(CatalogProxy, self).post_attribute(*args, **kwargs)
105    
106
107class PlaylistProxy(GenericProxy):
108    def __init__(self, session_id, buckets = None, **kwargs):
109        super(PlaylistProxy, self).__init__()
110        buckets = buckets or []
111        self._object_type = 'playlist'
112        kwargs = dict((str(k), v) for (k,v) in kwargs.iteritems())
113        if session_id:
114            kwargs['session_id'] = session_id
115        # the following are integral to all playlist objects... the rest is up to you!
116        core_attrs = ['session_id']
117        if not all(ca in kwargs for ca in core_attrs):
118            profile = self.get_attribute('dynamic', **kwargs)
119            kwargs.update(profile)
120        [self.__dict__.update({ca:kwargs.pop(ca)}) for ca in core_attrs if ca in kwargs]        
121        self.cache.update(kwargs)
122    
123    def get_attribute(self, *args, **kwargs):
124        return super(PlaylistProxy, self).get_attribute(*args, **kwargs)
125    
126
127class SongProxy(GenericProxy):
128    def __init__(self, identifier, buckets = None, **kwargs):
129        super(SongProxy, self).__init__()
130        buckets = buckets or []
131        self.id = identifier
132        self._object_type = 'song'
133        kwargs = dict((str(k), v) for (k,v) in kwargs.iteritems())
134        
135        # BAW -- this is debug output from identify that returns a track_id. i am not sure where else to access this..
136        if kwargs.has_key("track_id"):
137            self.track_id = kwargs["track_id"]
138        if kwargs.has_key("tag"):
139            self.tag = kwargs["tag"]
140        if kwargs.has_key("score"):
141            self.score = kwargs["score"]
142        if kwargs.has_key('audio'):
143            self.audio = kwargs['audio']
144        if kwargs.has_key('release_image'):
145            self.release_image = kwargs['release_image']
146        
147        # the following are integral to all song objects... the rest is up to you!
148        core_attrs = ['title', 'artist_name', 'artist_id']
149        
150        if not all(ca in kwargs for ca in core_attrs):
151            profile = self.get_attribute('profile', **{'id':self.id, 'bucket':buckets})
152            kwargs.update(profile.get('songs')[0])
153        [self.__dict__.update({ca:kwargs.pop(ca)}) for ca in core_attrs]
154        self.cache.update(kwargs)
155    
156    def get_attribute(self, *args, **kwargs):
157        kwargs['id'] = self.id
158        return super(SongProxy, self).get_attribute(*args, **kwargs)
159    
160
161class TrackProxy(GenericProxy):
162    def __init__(self, identifier, md5, properties):
163        """
164        You should not call this constructor directly, rather use the convenience functions
165        that are in track.py. For example, call track.track_from_filename
166        Let's always get the bucket `audio_summary`
167        """
168        super(TrackProxy, self).__init__()
169        self.id = identifier
170        self.md5 = md5
171        self._object_type = 'track'
172        self.__dict__.update(properties)
173