1. Joe Judge
  2. django-syncr

Source

django-syncr / syncr / magnolia / pymagnolia.py

# -*- coding: utf8 -*-

import httplib, urllib

import xml.sax
from xml.sax.handler import ContentHandler

VERSION = '0.1'
AUTHOR = 'makoto tsuyuki'
AUTHOR_EMAIL = 'mtsuyuki_at_gmail_dot_com'
PROJECT_URL = 'http://www.everes.net/pymagnolia/'

CONTACT = '%s or %s' % (PROJECT_URL, AUTHOR_EMAIL)
DESCRIPTION = '''Python wrapper for ma.gnolia.com's API'''
LONG_DESCRIPTION = '%s' % (DESCRIPTION)

DEBUG = False
API_VERSION = '1'

def xmltoUtf(attrs, name='') :
  v = attrs.get(name)
  if v == None: return None
  return v.encode('utf8')

def set_data(params_candidate) :
  param = {}
  for key, value in params_candidate.iteritems() :
    if value == None or value == '' or value == []:
      pass
    else:
      if key == 'date_from' :
        param['from'] = value
      elif key == 'date_to' :
        param['to'] = value
      else :
        param[key] = value
  return param

def parametalize(params_candidate={}) :
  if params_candidate.has_key('self') :
    del params_candidate['self']
  return set_data(params_candidate)


class Bookmark(dict) :
  def __init__(self, created=None, private=False, updated=None,
                     id='', rating='0', owner='',
                     title='', url='', description='',
                     screenshot='', tags=[]) :
    self['created']     = created
    self['private']     = private
    self['updated']     = updated
    self['id']          = id
    self['rating']      = rating
    self['owner']       = owner
    self['title']       = title
    self['url']         = url
    self['description'] = description
    self['screenshot']  = screenshot
    self['tags']        = tags

  def __getattr__(self, name):
    try: return self[name]
    except: object.__getattribute__(self, name)

class PyMagnoliaError(Exception) :
  def __init__(self, code, message, method='', param={}):
    self.code = code
    self.message = message
    self.method = method
    self.param = param

  def __str__(self) :
    return self.__repr__()

  def __repr__(self) :
    return '[%s] %s when %s called with %s' % (self.code, self.message, self.method, self.param)

class BookmarkHandler(ContentHandler):
  bookmarks = []
  bookmark = None
  tmp = ''
  status = 'success'
  error = {'message': None, 'code': None}
  method = ''
  param = {}
  def __init__(self, method='', param={}):
    self.bookmarks = []
    self.bookmark = Bookmark()
    self.tmp = ''
    self.method = method
    self.param = param
  def startElement(self, name, attrs):
    if DEBUG :
      print ''
      print 'DEBUG: %s.startElement->%s' % (self.__class__, name)
      for key, value in attrs.items():
        print '     :%s->%s' % (key.encode('utf8'), value.encode('utf8'))
    self.tmp = ''
    if name.encode('utf8') == 'bookmark' :
      private = False
      if xmltoUtf(attrs, 'private') == 'true' :
        private = True
      self.bookmark = Bookmark(xmltoUtf(attrs, 'created'),
                               private,
                               xmltoUtf(attrs, 'updated'),
                               xmltoUtf(attrs, 'id'),
                               xmltoUtf(attrs, 'rating'),
                               xmltoUtf(attrs, 'owner'))
      self.bookmarks += [self.bookmark]
    elif name.encode('utf8') == 'tags' :
      self.bookmark['tags'] = []
    elif name.encode('utf8') == 'tag' :
      self.bookmark['tags'] += [attrs.get('name').encode('utf8')]
    elif name.encode('utf8') == 'response' :
      self.status = xmltoUtf(attrs, 'message')
      self.version = xmltoUtf(attrs, 'version')
    elif name.encode('utf8') == 'error' :
      self.error['message'] = xmltoUtf(attrs, 'message')
      self.error['code']    = xmltoUtf(attrs, 'code')
      raise PyMagnoliaError(self.error['code'], self.error['message'], self.method, self.param)
    return
  def endElement(self, name):
    if name.encode('utf8') == 'title' :
      self.bookmark['title'] = self.tmp
    elif name.encode('utf8') == 'url' :
      self.bookmark['url'] = self.tmp
    elif name.encode('utf8') == 'description' :
      self.bookmark['description'] = self.tmp
    elif name.encode('utf8') == 'screenshot' :
      self.bookmark['screenshot'] = self.tmp
    return
  def characters(self, content):
    self.tmp += content.encode('utf8')
    return

class MagnoliaApi :
  key = ''
  user = ''
  password = ''
  headers = {"Content-type": "application/x-www-form-urlencoded",
             "Accept"      : "text/plain",
             "User-agent"  : "pymagnolia/%s" % (VERSION)}
  server = 'ma.gnolia.com:80'

  def __init__(self, key='') :
    self.key = key

  def set_key(self, key='') :
    self.key = key

  def bookmarks_find(self, tags='', person='', group='',
                           rating=None, date_from=None, date_to=None,
                           url='', limit=None,) :
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_find')

  def bookmarks_get(self, id=''):
    if id == None or len(id) == 0:
      raise ValueError, 'id must be specified.'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_get')

  def bookmark_add(self, title='', description='',url='',
                         private='false', tags='', rating='0'):
    if url == None or len(url) == 0:
      raise ValueError, 'url must specified'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_add')

  def bookmark_update(self, id='', title='', description='',url='',
                         private='false', tags='', rating='0'):
    if id == None or len(id) == 0:
      raise ValueError, 'bookmarks(shortname) must specified'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_update')

  def bookmarks_delete(self, id=''):
    if id == None or len(id) == 0:
      raise ValueError, 'id must specified'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_delete')

  def bookmarks_tags_add(self, id='', tags='') :
    if id == None or len(id) == 0:
      raise ValueError, 'named(shortname) must specified'
    if tags == None or len(tags) == 0:
      raise ValueError, 'tags must specified'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_tags_add')

  def bookmarks_tags_delete(self, id='all', tags=''):
    if id == None or len(id) == 0:
      id = 'all'
    if tags == None or len(tags) == 0:
      raise ValueError, 'tags must specified'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_tags_delete')

  def bookmarks_tags_rename(self, id='all', old='', new=''):
    if id == None or len(id) == 0:
      id = 'all'
    if old == None or len(old) == 0:
      raise ValueError, 'old(tags) must specified'
    if new == None or len(new) == 0:
      raise ValueError, 'new(tags) must specified'
    return self._handle_bookmark(parametalize(locals()), 'bookmarks_tags_replace')

  def _handle_bookmark(self, param={}, method='echo') :
    param['api_key'] = self.key
    if DEBUG :
      print 'DEBUG: %s._handle_bookmark->%s' % (self.__class__, method)
      print '     :%s' % (param)
      print ''
    xml.sax.make_parser(['drv_libxml2'])
    params = urllib.urlencode(param)
    conn = httplib.HTTPConnection(self.server)
    conn.request("POST", "/api/rest/%s/%s" % (API_VERSION, method), params, self.headers)
    response = conn.getresponse()
    parser = xml.sax.make_parser()
    handler = BookmarkHandler(method, param)
    parser.setContentHandler(handler)
    parser.parse(response)
    conn.close()
    return handler.bookmarks

    

if __name__ == '__main__' :
  api = MagnoliaApi('your api key here')
  try :
    bookmarks = api.bookmarks_get(id='cushiw')
    #bookmarks = api.bookmarks_find(person='myself', date_from='2006/05/10T12:00:00Z', limit=10)
    #bookmarks = api.bookmark_add(title='WorkStyle-py',
    #                             description='GTD Web Application. WorkStyle with python(Django)',
    #                             url='http://workstyle-py.sourceforge.net',
    #                             tags='django',
    #                             rating='4')
    #bookmarks = api.bookmark_update(bookmarks='cushiw', title='Setting up Django on Dreamhost',
    #                             description='A simple how-to guide for setting up Django on your Dreamhost server.',
    #                             url='http://www2.jeffcroft.com/2006/may/11/django-dreamhost/',
    #                             tags='django,tips,howto',
    #                             rating='4')
    #bookmarks = api.bookmarks_tags_add(bookmarks='heranulith', tags='test') #Not Enough Parameter
    #bookmarks = api.bookmarks_tags_rename(named='http://ma.gnolia.com/heranulith', old='tips', new='code')  #Not Enough Parameter
    #bookmarks = api.bookmarks_delete(id='cluqihush') #OK
    #bookmarks = api.bookmarks_tags_rename(named='dresage', old='imported', new='test2'):
    #bookmarks = api.bookmarks_tags_delete(named='dresage', tags='imported') #Method not found
  except PyMagnoliaError, e:
    print 'Error: %s' % e.message
    print '  code : %s' % e.code
    print '  method : %s' % e.method
    for key, value in e.param.iteritems() :
      print '  param : %s->%s' % (key, value)
  else :
    if DEBUG :
      c = 0
      for b in bookmarks :
        c += 1
        print '%03d:%s' % (c, b['title'])
        print '   :%s ( %s )' % (b['url'], b['screenshot'])
        print '   :%s' % b['tags']
        print ''