#!/usr/bin/python
# pyetsy.py
#
# written by Jesper Noehr <jesper@noehr.org> 2008
# code written for avantlumiere.com
# this code is in public domain, use for whatever you 
# damn please, and do *not* blame me if things stop working.
#

r"""Synopsis:

from pyetsy import Etsy
e = Etsy(5531346) # User ID can be found in your store URI

for item in e.items:
    print item.item_name
    print item.price
    print item.get_image_url("small") # tiny, small, huge
    
 --

`.items' will iterate through the items listed on the etsy page.
each `item' has these properties: id, image_id, image_path
  item_name, item_description, category_name and price.
do *not* use image_path for anything, as it only used to build
up a URL for the image; use the `get_image_url' for that.

also note that `.items' is lazy, that means that no network
activity will happen until you call it. once the listings are
fetched once, they will be cached indefinitely, or until you
set `._items' to None.

please retain the `pyetsy' user-agent, so etsy may filter our
traffic if they are so inclined. they are providing a great
service to indie artists, and they can block us if they find
that reasonable."""

import urllib2
from BeautifulSoup import BeautifulSoup

class Etsy(object):
    API_URL_USER = "http://api.etsy.com/feeds/xml_user_details.php?id=%d"
    API_URL_ITEM = "http://api.etsy.com/feeds/xml_listing_details.php?listing_id=%d"

    def __init__(self, user_id):
        if not str(user_id).isdigit():
            raise AttributeError, "User ID must be a number."
        self.user_id = user_id
        self._items = None
        
    def _fetch_xml(self, url):
        request = urllib2.Request(url, 
            headers={ 'User-Agent': 'pyEtsy/1.0' })
        return BeautifulSoup(urllib2.urlopen(request).read())
        
    def _tourl(self, fmt, *args):
        return fmt % args
        
    def get_items(self):
        if not self._items:
            xml = self._fetch_xml(self._tourl(Etsy.API_URL_USER, self.user_id))
            self._items = [ Listing(o) for o in xml('listing') ]
        for item in self._items:
            yield item
            
    items = property(get_items)
    
class Listing(Etsy):
    def __init__(self, lObj):
        self.raw = lObj
        self.setup()

    def setup(self):
        self.id = int(self.raw['id'])
        self.image_id = int(self.raw('image_id')[0].contents[0])
        self.image_path = self.raw('image_path')[0].contents[0]

        self._fetch_details()

    def _fetch_details(self):
        bs = self._fetch_xml(self._tourl(Etsy.API_URL_ITEM, self.id))

        for data in bs('listing'):
            self.item_name = data('item_name')[0].contents[0]
            self.item_description = data('item_description')[0].contents[0]
            self.category_name = data('category_name')[0].contents[0]
            self.price = int(data('price')[0].contents[0]) # USD

    def get_image_url(self, size='small'):
        if size == 'tiny':
            return self.image_path+('il_75x75.%d.jpg' % self.image_id)
        if size == 'small':
            return self.image_path+('il_155x125.%d.jpg' % self.image_id)
        else:
            return self.image_path+('il_430xN.%d.jpg' % self.image_id)

    def __repr__(self):
        return "<EtsyListing: id=%d, image_id=%d, name=%s, price=%d>" % (self.id, self.image_id, self.item_name, self.price)
