summaryrefslogtreecommitdiff
path: root/lib/upload/flickr.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/upload/flickr.py')
-rw-r--r--lib/upload/flickr.py889
1 files changed, 0 insertions, 889 deletions
diff --git a/lib/upload/flickr.py b/lib/upload/flickr.py
deleted file mode 100644
index a4cd224..0000000
--- a/lib/upload/flickr.py
+++ /dev/null
@@ -1,889 +0,0 @@
-"""
- flickr.py
- Copyright 2004-6 James Clarke <james@jamesclarke.info>
-
-THIS SOFTWARE IS SUPPLIED WITHOUT WARRANTY OF ANY KIND, AND MAY BE
-COPIED, MODIFIED OR DISTRIBUTED IN ANY WAY, AS LONG AS THIS NOTICE
-AND ACKNOWLEDGEMENT OF AUTHORSHIP REMAIN.
-
-2006-12-19
-Applied patches from Berco Beute and Wolfram Kriesing.
-TODO list below is out of date!
-
-2005-06-10
-TOOD list:
-* flickr.blogs.*
-* flickr.contacts.getList
-* flickr.groups.browse
-* flickr.groups.getActiveList
-* flickr.people.getOnlineList
-* flickr.photos.getContactsPhotos
-* flickr.photos.getContactsPublicPhotos
-* flickr.photos.getContext
-* flickr.photos.getCounts
-* flickr.photos.getExif
-* flickr.photos.getNotInSet
-* flickr.photos.getPerms
-* flickr.photos.getRecent
-* flickr.photos.getUntagged
-* flickr.photos.setDates
-* flickr.photos.setPerms
-* flickr.photos.licenses.*
-* flickr.photos.notes.*
-* flickr.photos.transform.*
-* flickr.photosets.getContext
-* flickr.photosets.orderSets
-* flickr.reflection.* (not important)
-* flickr.tags.getListPhoto
-* flickr.urls.*
-"""
-
-__author__ = "James Clarke <james@jamesclarke.info>"
-__version__ = "$Rev$"
-__date__ = "$Date$"
-__copyright__ = "Copyright 2004-6 James Clarke"
-
-from urllib import urlencode, urlopen
-from xml.dom import minidom
-
-HOST = 'http://flickr.com'
-API = '/services/rest'
-
-#set these here or using flickr.API_KEY in your application
-API_KEY = ''
-email = None
-password = None
-
-class FlickrError(Exception): pass
-
-class Photo(object):
- """Represents a Flickr Photo."""
-
- __readonly = ['id', 'secret', 'server', 'isfavorite', 'license', 'rotation',
- 'owner', 'dateposted', 'datetaken', 'takengranularity',
- 'title', 'description', 'ispublic', 'isfriend', 'isfamily',
- 'cancomment', 'canaddmeta', 'comments', 'tags', 'permcomment',
- 'permaddmeta']
-
- #XXX: Hopefully None won't cause problems
- def __init__(self, id, owner=None, dateuploaded=None, \
- title=None, description=None, ispublic=None, \
- isfriend=None, isfamily=None, cancomment=None, \
- canaddmeta=None, comments=None, tags=None, secret=None, \
- isfavorite=None, server=None, license=None, rotation=None):
- """Must specify id, rest is optional."""
- self.__loaded = False
- self.__cancomment = cancomment
- self.__canaddmeta = canaddmeta
- self.__comments = comments
- self.__dateuploaded = dateuploaded
- self.__description = description
- self.__id = id
- self.__license = license
- self.__isfamily = isfamily
- self.__isfavorite = isfavorite
- self.__isfriend = isfriend
- self.__ispublic = ispublic
- self.__owner = owner
- self.__rotation = rotation
- self.__secret = secret
- self.__server = server
- self.__tags = tags
- self.__title = title
-
- self.__dateposted = None
- self.__datetaken = None
- self.__takengranularity = None
- self.__permcomment = None
- self.__permaddmeta = None
-
- def __setattr__(self, key, value):
- if key in self.__class__.__readonly:
- raise AttributeError("The attribute %s is read-only." % key)
- else:
- super(Photo, self).__setattr__(key, value)
-
- def __getattr__(self, key):
- if not self.__loaded:
- self._load_properties()
- if key in self.__class__.__readonly:
- return super(Photo, self).__getattribute__("_%s__%s" % (self.__class__.__name__, key))
- else:
- return super(Photo, self).__getattribute__(key)
-
- def _load_properties(self):
- """Loads the properties from Flickr."""
- self.__loaded = True
-
- method = 'flickr.photos.getInfo'
- data = _doget(method, photo_id=self.id)
-
- photo = data.rsp.photo
-
- self.__secret = photo.secret
- self.__server = photo.server
- self.__isfavorite = photo.isfavorite
- self.__license = photo.license
- self.__rotation = photo.rotation
-
-
-
- owner = photo.owner
- self.__owner = User(owner.nsid, username=owner.username,\
- realname=owner.realname,\
- location=owner.location)
-
- self.__title = photo.title.text
- self.__description = photo.description.text
- self.__ispublic = photo.visibility.ispublic
- self.__isfriend = photo.visibility.isfriend
- self.__isfamily = photo.visibility.isfamily
-
- self.__dateposted = photo.dates.posted
- self.__datetaken = photo.dates.taken
- self.__takengranularity = photo.dates.takengranularity
-
- self.__cancomment = photo.editability.cancomment
- self.__canaddmeta = photo.editability.canaddmeta
- self.__comments = photo.comments.text
-
- try:
- self.__permcomment = photo.permissions.permcomment
- self.__permaddmeta = photo.permissions.permaddmeta
- except AttributeError:
- self.__permcomment = None
- self.__permaddmeta = None
-
- #TODO: Implement Notes?
- if hasattr(photo.tags, "tag"):
- if isinstance(photo.tags.tag, list):
- self.__tags = [Tag(tag.id, User(tag.author), tag.raw, tag.text) \
- for tag in photo.tags.tag]
- else:
- tag = photo.tags.tag
- self.__tags = [Tag(tag.id, User(tag.author), tag.raw, tag.text)]
-
-
- def __str__(self):
- return '<Flickr Photo %s>' % self.id
-
-
- def setTags(self, tags):
- """Set the tags for current photo to list tags.
- (flickr.photos.settags)
- """
- method = 'flickr.photos.setTags'
- tags = uniq(tags)
- _dopost(method, auth=True, photo_id=self.id, tags=tags)
- self._load_properties()
-
-
- def addTags(self, tags):
- """Adds the list of tags to current tags. (flickr.photos.addtags)
- """
- method = 'flickr.photos.addTags'
- if isinstance(tags, list):
- tags = uniq(tags)
-
- _dopost(method, auth=True, photo_id=self.id, tags=tags)
- #load properties again
- self._load_properties()
-
- def removeTag(self, tag):
- """Remove the tag from the photo must be a Tag object.
- (flickr.photos.removeTag)
- """
- method = 'flickr.photos.removeTag'
- tag_id = ''
- try:
- tag_id = tag.id
- except AttributeError:
- raise FlickrError, "Tag object expected"
- _dopost(method, auth=True, photo_id=self.id, tag_id=tag_id)
- self._load_properties()
-
-
- def setMeta(self, title=None, description=None):
- """Set metadata for photo. (flickr.photos.setMeta)"""
- method = 'flickr.photos.setMeta'
-
- if title is None:
- title = self.title
- if description is None:
- description = self.description
-
- _dopost(method, auth=True, title=title, \
- description=description, photo_id=self.id)
-
- self.__title = title
- self.__description = description
-
-
- def getURL(self, size='Medium', urlType='url'):
- """Retrieves a url for the photo. (flickr.photos.getSizes)
-
- urlType - 'url' or 'source'
- 'url' - flickr page of photo
- 'source' - image file
- """
- method = 'flickr.photos.getSizes'
- data = _doget(method, photo_id=self.id)
- for psize in data.rsp.sizes.size:
- if psize.label == size:
- return getattr(psize, urlType)
- raise FlickrError, "No URL found"
-
- def getSizes(self):
- """
- Get all the available sizes of the current image, and all available
- data about them.
- Returns: A list of dicts with the size data.
- """
- method = 'flickr.photos.getSizes'
- data = _doget(method, photo_id=self.id)
- ret = []
- # The given props are those that we return and the according types, since
- # return width and height as string would make "75">"100" be True, which
- # is just error prone.
- props = {'url':str,'width':int,'height':int,'label':str,'source':str,'text':str}
- for psize in data.rsp.sizes.size:
- d = {}
- for prop,convert_to_type in props.items():
- d[prop] = convert_to_type(getattr(psize, prop))
- ret.append(d)
- return ret
-
- #def getExif(self):
- #method = 'flickr.photos.getExif'
- #data = _doget(method, photo_id=self.id)
- #ret = []
- #for exif in data.rsp.photo.exif:
- #print exif.label, dir(exif)
- ##ret.append({exif.label:exif.})
- #return ret
- ##raise FlickrError, "No URL found"
-
- def getLocation(self):
- """
- Return the latitude+longitutde of the picture.
- Returns None if no location given for this pic.
- """
- method = 'flickr.photos.geo.getLocation'
- try:
- data = _doget(method, photo_id=self.id)
- except FlickrError: # Some other error might have occured too!?
- return None
- loc = data.rsp.photo.location
- return [loc.latitude, loc.longitude]
-
-
-class Photoset(object):
- """A Flickr photoset."""
-
- def __init__(self, id, title, primary, photos=0, description='', \
- secret='', server=''):
- self.__id = id
- self.__title = title
- self.__primary = primary
- self.__description = description
- self.__count = photos
- self.__secret = secret
- self.__server = server
-
- id = property(lambda self: self.__id)
- title = property(lambda self: self.__title)
- description = property(lambda self: self.__description)
- primary = property(lambda self: self.__primary)
-
- def __len__(self):
- return self.__count
-
- def __str__(self):
- return '<Flickr Photoset %s>' % self.id
-
- def getPhotos(self):
- """Returns list of Photos."""
- method = 'flickr.photosets.getPhotos'
- data = _doget(method, photoset_id=self.id)
- photos = data.rsp.photoset.photo
- p = []
- for photo in photos:
- p.append(Photo(photo.id, title=photo.title, secret=photo.secret, \
- server=photo.server))
- return p
-
- def editPhotos(self, photos, primary=None):
- """Edit the photos in this set.
-
- photos - photos for set
- primary - primary photo (if None will used current)
- """
- method = 'flickr.photosets.editPhotos'
-
- if primary is None:
- primary = self.primary
-
- ids = [photo.id for photo in photos]
- if primary.id not in ids:
- ids.append(primary.id)
-
- _dopost(method, auth=True, photoset_id=self.id,\
- primary_photo_id=primary.id,
- photo_ids=ids)
- self.__count = len(ids)
- return True
-
- def addPhoto(self, photo):
- """Add a photo to this set.
-
- photo - the photo
- """
- method = 'flickr.photosets.addPhoto'
-
- _dopost(method, auth=True, photoset_id=self.id, photo_id=photo.id)
-
- self.__count += 1
- return True
-
- def removePhoto(self, photo):
- """Remove the photo from this set.
-
- photo - the photo
- """
- method = 'flickr.photosets.removePhoto'
-
- _dopost(method, auth=True, photoset_id=self.id, photo_id=photo.id)
- self.__count = self.__count - 1
- return True
-
- def editMeta(self, title=None, description=None):
- """Set metadata for photo. (flickr.photos.setMeta)"""
- method = 'flickr.photosets.editMeta'
-
- if title is None:
- title = self.title
- if description is None:
- description = self.description
-
- _dopost(method, auth=True, title=title, \
- description=description, photoset_id=self.id)
-
- self.__title = title
- self.__description = description
- return True
-
- #XXX: Delete isn't handled well as the python object will still exist
- def delete(self):
- """Deletes the photoset.
- """
- method = 'flickr.photosets.delete'
-
- _dopost(method, auth=True, photoset_id=self.id)
- return True
-
- def create(cls, photo, title, description=''):
- """Create a new photoset.
-
- photo - primary photo
- """
- if not isinstance(photo, Photo):
- raise TypeError, "Photo expected"
-
- method = 'flickr.photosets.create'
- data = _dopost(method, auth=True, title=title,\
- description=description,\
- primary_photo_id=photo.id)
-
- set = Photoset(data.rsp.photoset.id, title, Photo(photo.id),
- photos=1, description=description)
- return set
- create = classmethod(create)
-
-
-class User(object):
- """A Flickr user."""
-
- def __init__(self, id, username=None, isadmin=None, ispro=None, \
- realname=None, location=None, firstdate=None, count=None):
- """id required, rest optional."""
- self.__loaded = False #so we don't keep loading data
- self.__id = id
- self.__username = username
- self.__isadmin = isadmin
- self.__ispro = ispro
- self.__realname = realname
- self.__location = location
- self.__photos_firstdate = firstdate
- self.__photos_count = count
-
- #property fu
- id = property(lambda self: self._general_getattr('id'))
- username = property(lambda self: self._general_getattr('username'))
- isadmin = property(lambda self: self._general_getattr('isadmin'))
- ispro = property(lambda self: self._general_getattr('ispro'))
- realname = property(lambda self: self._general_getattr('realname'))
- location = property(lambda self: self._general_getattr('location'))
- photos_firstdate = property(lambda self: \
- self._general_getattr('photos_firstdate'))
- photos_firstdatetaken = property(lambda self: \
- self._general_getattr\
- ('photos_firstdatetaken'))
- photos_count = property(lambda self: \
- self._general_getattr('photos_count'))
- icon_server= property(lambda self: self._general_getattr('icon_server'))
- icon_url= property(lambda self: self._general_getattr('icon_url'))
-
- def _general_getattr(self, var):
- """Generic get attribute function."""
- if getattr(self, "_%s__%s" % (self.__class__.__name__, var)) is None \
- and not self.__loaded:
- self._load_properties()
- return getattr(self, "_%s__%s" % (self.__class__.__name__, var))
-
- def _load_properties(self):
- """Load User properties from Flickr."""
- method = 'flickr.people.getInfo'
- data = _doget(method, user_id=self.__id)
-
- self.__loaded = True
-
- person = data.rsp.person
-
- self.__isadmin = person.isadmin
- self.__ispro = person.ispro
- self.__icon_server = person.iconserver
- if int(person.iconserver) > 0:
- self.__icon_url = 'http://photos%s.flickr.com/buddyicons/%s.jpg' \
- % (person.iconserver, self.__id)
- else:
- self.__icon_url = 'http://www.flickr.com/images/buddyicon.jpg'
-
- self.__username = person.username.text
- self.__realname = person.realname.text
- self.__location = person.location.text
- self.__photos_firstdate = person.photos.firstdate.text
- self.__photos_firstdatetaken = person.photos.firstdatetaken.text
- self.__photos_count = person.photos.count.text
-
- def __str__(self):
- return '<Flickr User %s>' % self.id
-
- def getPhotosets(self):
- """Returns a list of Photosets."""
- method = 'flickr.photosets.getList'
- data = _doget(method, user_id=self.id)
- sets = []
- if isinstance(data.rsp.photosets.photoset, list):
- for photoset in data.rsp.photosets.photoset:
- sets.append(Photoset(photoset.id, photoset.title.text,\
- Photo(photoset.primary),\
- secret=photoset.secret, \
- server=photoset.server, \
- description=photoset.description.text,
- photos=photoset.photos))
- else:
- photoset = data.rsp.photosets.photoset
- sets.append(Photoset(photoset.id, photoset.title.text,\
- Photo(photoset.primary),\
- secret=photoset.secret, \
- server=photoset.server, \
- description=photoset.description.text,
- photos=photoset.photos))
- return sets
-
- def getPublicFavorites(self, per_page='', page=''):
- return favorites_getPublicList(user_id=self.id, per_page=per_page, \
- page=page)
-
- def getFavorites(self, per_page='', page=''):
- return favorites_getList(user_id=self.id, per_page=per_page, \
- page=page)
-
-class Group(object):
- """Flickr Group Pool"""
- def __init__(self, id, name=None, members=None, online=None,\
- privacy=None, chatid=None, chatcount=None):
- self.__loaded = False
- self.__id = id
- self.__name = name
- self.__members = members
- self.__online = online
- self.__privacy = privacy
- self.__chatid = chatid
- self.__chatcount = chatcount
- self.__url = None
-
- id = property(lambda self: self._general_getattr('id'))
- name = property(lambda self: self._general_getattr('name'))
- members = property(lambda self: self._general_getattr('members'))
- online = property(lambda self: self._general_getattr('online'))
- privacy = property(lambda self: self._general_getattr('privacy'))
- chatid = property(lambda self: self._general_getattr('chatid'))
- chatcount = property(lambda self: self._general_getattr('chatcount'))
-
- def _general_getattr(self, var):
- """Generic get attribute function."""
- if getattr(self, "_%s__%s" % (self.__class__.__name__, var)) is None \
- and not self.__loaded:
- self._load_properties()
- return getattr(self, "_%s__%s" % (self.__class__.__name__, var))
-
- def _load_properties(self):
- """Loads the properties from Flickr."""
- method = 'flickr.groups.getInfo'
- data = _doget(method, group_id=self.id)
-
- self.__loaded = True
-
- group = data.rsp.group
-
- self.__name = photo.name.text
- self.__members = photo.members.text
- self.__online = photo.online.text
- self.__privacy = photo.privacy.text
- self.__chatid = photo.chatid.text
- self.__chatcount = photo.chatcount.text
-
- def __str__(self):
- return '<Flickr Group %s>' % self.id
-
- def getPhotos(self, tags='', per_page='', page=''):
- """Get a list of photo objects for this group"""
- method = 'flickr.groups.pools.getPhotos'
- data = _doget(method, group_id=self.id, tags=tags,\
- per_page=per_page, page=page)
- photos = []
- for photo in data.rsp.photos.photo:
- photos.append(_parse_photo(photo))
- return photos
-
- def add(self, photo):
- """Adds a Photo to the group"""
- method = 'flickr.groups.pools.add'
- _dopost(method, auth=True, photo_id=photo.id, group_id=self.id)
- return True
-
- def remove(self, photo):
- """Remove a Photo from the group"""
- method = 'flickr.groups.pools.remove'
- _dopost(method, auth=True, photo_id=photo.id, group_id=self.id)
- return True
-
-class Tag(object):
- def __init__(self, id, author, raw, text):
- self.id = id
- self.author = author
- self.raw = raw
- self.text = text
-
- def __str__(self):
- return '<Flickr Tag %s (%s)>' % (self.id, self.text)
-
-
-#Flickr API methods
-#see api docs http://www.flickr.com/services/api/
-#for details of each param
-
-#XXX: Could be Photo.search(cls)
-def photos_search(user_id='', auth=False, tags='', tag_mode='', text='',\
- min_upload_date='', max_upload_date='',\
- min_taken_date='', max_taken_date='', \
- license='', per_page='', page='', sort=''):
- """Returns a list of Photo objects.
-
- If auth=True then will auth the user. Can see private etc
- """
- method = 'flickr.photos.search'
-
- data = _doget(method, auth=auth, user_id=user_id, tags=tags, text=text,\
- min_upload_date=min_upload_date,\
- max_upload_date=max_upload_date, \
- min_taken_date=min_taken_date, \
- max_taken_date=max_taken_date, \
- license=license, per_page=per_page,\
- page=page, sort=sort)
- photos = []
- if isinstance(data.rsp.photos.photo, list):
- for photo in data.rsp.photos.photo:
- photos.append(_parse_photo(photo))
- else:
- photos = [_parse_photo(data.rsp.photos.photo)]
- return photos
-
-#XXX: Could be class method in User
-def people_findByEmail(email):
- """Returns User object."""
- method = 'flickr.people.findByEmail'
- data = _doget(method, find_email=email)
- user = User(data.rsp.user.id, username=data.rsp.user.username.text)
- return user
-
-def people_findByUsername(username):
- """Returns User object."""
- method = 'flickr.people.findByUsername'
- data = _doget(method, username=username)
- user = User(data.rsp.user.id, username=data.rsp.user.username.text)
- return user
-
-#XXX: Should probably be in User as a list User.public
-def people_getPublicPhotos(user_id, per_page='', page=''):
- """Returns list of Photo objects."""
- method = 'flickr.people.getPublicPhotos'
- data = _doget(method, user_id=user_id, per_page=per_page, page=page)
- photos = []
- if hasattr(data.rsp.photos, "photo"): # Check if there are photos at all (may be been paging too far).
- if isinstance(data.rsp.photos.photo, list):
- for photo in data.rsp.photos.photo:
- photos.append(_parse_photo(photo))
- else:
- photos = [_parse_photo(data.rsp.photos.photo)]
- return photos
-
-#XXX: These are also called from User
-def favorites_getList(user_id='', per_page='', page=''):
- """Returns list of Photo objects."""
- method = 'flickr.favorites.getList'
- data = _doget(method, auth=True, user_id=user_id, per_page=per_page,\
- page=page)
- photos = []
- if isinstance(data.rsp.photos.photo, list):
- for photo in data.rsp.photos.photo:
- photos.append(_parse_photo(photo))
- else:
- photos = [_parse_photo(data.rsp.photos.photo)]
- return photos
-
-def favorites_getPublicList(user_id, per_page='', page=''):
- """Returns list of Photo objects."""
- method = 'flickr.favorites.getPublicList'
- data = _doget(method, auth=False, user_id=user_id, per_page=per_page,\
- page=page)
- photos = []
- if isinstance(data.rsp.photos.photo, list):
- for photo in data.rsp.photos.photo:
- photos.append(_parse_photo(photo))
- else:
- photos = [_parse_photo(data.rsp.photos.photo)]
- return photos
-
-def favorites_add(photo_id):
- """Add a photo to the user's favorites."""
- method = 'flickr.favorites.add'
- _dopost(method, auth=True, photo_id=photo_id)
- return True
-
-def favorites_remove(photo_id):
- """Remove a photo from the user's favorites."""
- method = 'flickr.favorites.remove'
- _dopost(method, auth=True, photo_id=photo_id)
- return True
-
-def groups_getPublicGroups():
- """Get a list of groups the auth'd user is a member of."""
- method = 'flickr.groups.getPublicGroups'
- data = _doget(method, auth=True)
- groups = []
- if isinstance(data.rsp.groups.group, list):
- for group in data.rsp.groups.group:
- groups.append(Group(group.id, name=group.name))
- else:
- group = data.rsp.groups.group
- groups = [Group(group.id, name=group.name)]
- return groups
-
-def groups_pools_getGroups():
- """Get a list of groups the auth'd user can post photos to."""
- method = 'flickr.groups.pools.getGroups'
- data = _doget(method, auth=True)
- groups = []
- if isinstance(data.rsp.groups.group, list):
- for group in data.rsp.groups.group:
- groups.append(Group(group.id, name=group.name, \
- privacy=group.privacy))
- else:
- group = data.rsp.groups.group
- groups = [Group(group.id, name=group.name, privacy=group.privacy)]
- return groups
-
-
-def tags_getListUser(user_id=''):
- """Returns a list of tags for the given user (in string format)"""
- method = 'flickr.tags.getListUser'
- auth = user_id == ''
- data = _doget(method, auth=auth, user_id=user_id)
- if isinstance(data.rsp.tags.tag, list):
- return [tag.text for tag in data.rsp.tags.tag]
- else:
- return [data.rsp.tags.tag.text]
-
-def tags_getListUserPopular(user_id='', count=''):
- """Gets the popular tags for a user in dictionary form tag=>count"""
- method = 'flickr.tags.getListUserPopular'
- auth = user_id == ''
- data = _doget(method, auth=auth, user_id=user_id)
- result = {}
- if isinstance(data.rsp.tags.tag, list):
- for tag in data.rsp.tags.tag:
- result[tag.text] = tag.count
- else:
- result[data.rsp.tags.tag.text] = data.rsp.tags.tag.count
- return result
-
-def tags_getrelated(tag):
- """Gets the related tags for given tag."""
- method = 'flickr.tags.getRelated'
- data = _doget(method, auth=False, tag=tag)
- if isinstance(data.rsp.tags.tag, list):
- return [tag.text for tag in data.rsp.tags.tag]
- else:
- return [data.rsp.tags.tag.text]
-
-def contacts_getPublicList(user_id):
- """Gets the contacts (Users) for the user_id"""
- method = 'flickr.contacts.getPublicList'
- data = _doget(method, auth=False, user_id=user_id)
- if isinstance(data.rsp.contacts.contact, list):
- return [User(user.nsid, username=user.username) \
- for user in data.rsp.contacts.contact]
- else:
- user = data.rsp.contacts.contact
- return [User(user.nsid, username=user.username)]
-
-def interestingness():
- method = 'flickr.interestingness.getList'
- data = _doget(method)
- photos = []
- if isinstance(data.rsp.photos.photo , list):
- for photo in data.rsp.photos.photo:
- photos.append(_parse_photo(photo))
- else:
- photos = [_parse_photo(data.rsp.photos.photo)]
- return photos
-
-def test_login():
- method = 'flickr.test.login'
- data = _doget(method, auth=True)
- user = User(data.rsp.user.id, username=data.rsp.user.username.text)
- return user
-
-def test_echo():
- method = 'flickr.test.echo'
- data = _doget(method)
- return data.rsp.stat
-
-
-#useful methods
-
-def _doget(method, auth=False, **params):
- #uncomment to check you aren't killing the flickr server
- #print "***** do get %s" % method
-
- #convert lists to strings with ',' between items
- for (key, value) in params.items():
- if isinstance(value, list):
- params[key] = ','.join([item for item in value])
-
- url = '%s%s/?api_key=%s&method=%s&%s'% \
- (HOST, API, API_KEY, method, urlencode(params))
- if auth:
- url = url + '&email=%s&password=%s' % (email, password)
-
- #another useful debug print statement
- #print url
-
- xml = minidom.parse(urlopen(url))
- data = unmarshal(xml)
- if not data.rsp.stat == 'ok':
- msg = "ERROR [%s]: %s" % (data.rsp.err.code, data.rsp.err.msg)
- raise FlickrError, msg
- return data
-
-def _dopost(method, auth=False, **params):
- #uncomment to check you aren't killing the flickr server
- #print "***** do post %s" % method
-
- #convert lists to strings with ',' between items
- for (key, value) in params.items():
- if isinstance(value, list):
- params[key] = ','.join([item for item in value])
-
- url = '%s%s/' % (HOST, API)
-
- payload = 'api_key=%s&method=%s&%s'% \
- (API_KEY, method, urlencode(params))
- if auth:
- payload = payload + '&email=%s&password=%s' % (email, password)
-
- #another useful debug print statement
- #print url
- #print payload
-
- xml = minidom.parse(urlopen(url, payload))
- data = unmarshal(xml)
- if not data.rsp.stat == 'ok':
- msg = "ERROR [%s]: %s" % (data.rsp.err.code, data.rsp.err.msg)
- raise FlickrError, msg
- return data
-
-def _parse_photo(photo):
- """Create a Photo object from photo data."""
- owner = User(photo.owner)
- title = photo.title
- ispublic = photo.ispublic
- isfriend = photo.isfriend
- isfamily = photo.isfamily
- secret = photo.secret
- server = photo.server
- p = Photo(photo.id, owner=owner, title=title, ispublic=ispublic,\
- isfriend=isfriend, isfamily=isfamily, secret=secret, \
- server=server)
- return p
-
-#stolen methods
-
-class Bag: pass
-
-#unmarshal taken and modified from pyamazon.py
-#makes the xml easy to work with
-def unmarshal(element):
- rc = Bag()
- if isinstance(element, minidom.Element):
- for key in element.attributes.keys():
- setattr(rc, key, element.attributes[key].value)
-
- childElements = [e for e in element.childNodes \
- if isinstance(e, minidom.Element)]
- if childElements:
- for child in childElements:
- key = child.tagName
- if hasattr(rc, key):
- if type(getattr(rc, key)) <> type([]):
- setattr(rc, key, [getattr(rc, key)])
- setattr(rc, key, getattr(rc, key) + [unmarshal(child)])
- elif isinstance(child, minidom.Element) and \
- (child.tagName == 'Details'):
- # make the first Details element a key
- setattr(rc,key,[unmarshal(child)])
- #dbg: because otherwise 'hasattr' only tests
- #dbg: on the second occurence: if there's a
- #dbg: single return to a query, it's not a
- #dbg: list. This module should always
- #dbg: return a list of Details objects.
- else:
- setattr(rc, key, unmarshal(child))
- else:
- #jec: we'll have the main part of the element stored in .text
- #jec: will break if tag <text> is also present
- text = "".join([e.data for e in element.childNodes \
- if isinstance(e, minidom.Text)])
- setattr(rc, 'text', text)
- return rc
-
-#unique items from a list from the cookbook
-def uniq(alist): # Fastest without order preserving
- set = {}
- map(set.__setitem__, alist, [])
- return set.keys()
-
-if __name__ == '__main__':
- print test_echo()