diff --git a/aweber_api/collection.py b/aweber_api/collection.py index 2e23a73..4d8176e 100644 --- a/aweber_api/collection.py +++ b/aweber_api/collection.py @@ -1,42 +1,49 @@ from math import floor from urlparse import parse_qs from urllib import urlencode +import collections -import aweber_api +from aweber_api.base import API_BASE +from aweber_api.entry import AWeberEntry from aweber_api.response import AWeberResponse class AWeberCollection(AWeberResponse): - """ - Represents a collection of similar objects. Encapsulates data that is - found at the base URI's for a given object type, ie: + """Represents a collection of similar objects. + + Encapsulates data that is found at the base URI's for a given object + type, ie: /accounts /accounts/XXX/lists + Parses the data from the response and provides basic sequence like - operations, such as iteration and indexing to access the entries that - are contained in this collection. + operations, such as iteration and indexing to access the entries + that are contained in this collection. + """ + page_size = 100 def __init__(self, url, data, adapter): self._entry_data = {} self._current = 0 - AWeberResponse.__init__(self, url, data, adapter) + super(AWeberCollection, self).__init__(url, data, adapter) self._key_entries(self._data) def get_by_id(self, id): - """ - Returns an entry from this collection, as found by its actual - AWeber id, not its offset. Will actually request the data from - the API. + """Returns an entry from this collection. + + The Entry as found by its actual AWeber id, not its offset. + Will actually request the data from the API. + """ return self.load_from_url("{0}/{1}".format(self.url, id)) def _key_entries(self, response): count = 0 for entry in response['entries']: - self._entry_data[count+response['start']] = entry + self._entry_data[count + response['start']] = entry count += 1 def _load_page_for_offset(self, offset): @@ -45,6 +52,7 @@ def _load_page_for_offset(self, offset): self._key_entries(response) def _get_page_params(self, offset): + """Return the start and size of the paginated response.""" next_link = self._data.get('next_collection_link', None) if next_link is None: """no more parameters in page!""" @@ -55,20 +63,22 @@ def _get_page_params(self, offset): self.page_size = int(query_parts['ws.size'][0]) page_number = int(floor(offset / self.page_size)) start = page_number * self.page_size - return { 'ws.start' : start, 'ws.size' : self.page_size } + return {'ws.start': start, 'ws.size': self.page_size} def create(self, **kwargs): + """Method to create an item.""" params = {'ws.op': 'create'} params.update(kwargs) - response = self.adapter.request('POST', self.url, params, - response='headers') + response = self.adapter.request( + 'POST', self.url, params, response='headers') resource_url = response['location'] data = self.adapter.request('GET', resource_url) - return aweber_api.AWeberEntry(resource_url, data, self.adapter) + return AWeberEntry(resource_url, data, self.adapter) def find(self, **kwargs): + """Method to request a collection.""" params = {'ws.op': 'find'} params.update(kwargs) query_string = urlencode(params) @@ -86,28 +96,50 @@ def _get_total_size(self, uri, **kwargs): def get_parent_entry(self): """Return a collection's parent entry or None.""" - url_parts = self.url.split('/') - - #If top of tree - no parent entry - if len(url_parts) <= 3: + url_parts = self._partition_url() + if url_parts is None: return None - size = len(url_parts) - #Remove collection id and slash from end of url - url = self.url[:-len(url_parts[size-1])-1] + url = self._remove_collection_id_from_url(url_parts) + data = self.adapter.request('GET', url) try: - entry = aweber_api.AWeberEntry(url, data, self.adapter) + entry = AWeberEntry(url, data, self.adapter) + except TypeError: return None return entry + def _partition_url(self): + try: + url_parts = self.url.split('/') + #If top of tree - no parent entry + if len(url_parts) <= 3: + return None + + except Exception: + return None + + return url_parts + + def _remove_collection_id_from_url(self, url_parts): + """Remove collection id and slash from end of url.""" + url = '' + # construct the url from the url_parts list + for i in range(len(url_parts)-1): + url = '{0}{1}/'.format(url, url_parts[i]) + + # remove the trailing slash + url = url[:len(url)-1] + + return url + def _create_entry(self, offset): + """Add an entry to the collection""" data = self._entry_data[offset] - url = data['self_link'].replace(aweber_api.API_BASE, '') - self._entries[offset] = aweber_api.AWeberEntry(url, data, - self.adapter) + url = data['self_link'].replace(API_BASE, '') + self._entries[offset] = AWeberEntry(url, data, self.adapter) def __len__(self): return self.total_size @@ -116,9 +148,10 @@ def __iter__(self): return self def next(self): + """Get the next entry in the collection.""" if self._current < self.total_size: self._current += 1 - return self[self._current-1] + return self[self._current - 1] self._current = 0 raise StopIteration @@ -131,4 +164,3 @@ def __getitem__(self, offset): self._load_page_for_offset(offset) self._create_entry(offset) return self._entries[offset] -