summaryrefslogtreecommitdiff
path: root/trunk
diff options
context:
space:
mode:
authormjtnix <mjtnix@5914aa95-5b3a-0410-a3b5-7b719e7fe9b2>2007-09-19 01:51:13 +0000
committermjtnix <mjtnix@5914aa95-5b3a-0410-a3b5-7b719e7fe9b2>2007-09-19 01:51:13 +0000
commit5abc781c2b09db29e76fa2ebaea9461e4e477845 (patch)
tree038767549b51692a8237c0ed98e2be22cd20f004 /trunk
parenta4ad385a68926aa60c2b37fe1100de410558dda3 (diff)
remove extra trunk/ in directory path
git-svn-id: http://freebase-python.googlecode.com/svn/trunk@3 5914aa95-5b3a-0410-a3b5-7b719e7fe9b2
Diffstat (limited to 'trunk')
-rw-r--r--trunk/COPYRIGHT31
-rw-r--r--trunk/README39
-rw-r--r--trunk/examples/get_albums.py100
-rwxr-xr-xtrunk/freebase/__init__.py2
-rwxr-xr-xtrunk/freebase/api/__init__.py2
-rw-r--r--trunk/freebase/api/session.py391
-rwxr-xr-xtrunk/freebase/rison.py303
-rw-r--r--trunk/setup.py43
-rw-r--r--trunk/test/test_all.py89
9 files changed, 0 insertions, 1000 deletions
diff --git a/trunk/COPYRIGHT b/trunk/COPYRIGHT
deleted file mode 100644
index a76c9c1..0000000
--- a/trunk/COPYRIGHT
+++ /dev/null
@@ -1,31 +0,0 @@
-All source and examples in this project are subject to the
-following copyright, unless specifically stated otherwise
-in the file itself:
-
-========================================================================
-Copyright (c) 2007, Metaweb Technologies, Inc.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following
- disclaimer in the documentation and/or other materials provided
- with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
-TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-========================================================================
diff --git a/trunk/README b/trunk/README
deleted file mode 100644
index 5bf8bf2..0000000
--- a/trunk/README
+++ /dev/null
@@ -1,39 +0,0 @@
-description='Python client library for Freebase API service',
-maintainer_email='developers@freebase.com',
-url='http://www.freebase.com/',
-
-INSTALL:
-
- /usr/bin/python setup.py install
-
-SYNOPSIS:
-
- #!/usr/bin/python
-
- from freebase.api import HTTPMetawebSession, MetawebError
-
- mss = HTTPMetawebSession('www.freebase.com')
-
- query = { 'type':'/music/artist',
- 'name':'Sting',
- 'album':[],
- }
-
- result = mss.mqlread(query)
-
- for album in result.album:
- print album
-TESTING:
-
- cd test
- /usr/bin/python test_all.py -v
-
- test_login (__main__.TestFreebase) ... ok
- test_read (__main__.TestFreebase) ... ok
- test_write (__main__.TestFreebase) ... ok
-
- ----------------------------------------------------------------------
- Ran 3 tests in 0.691s
-
- OK
-
diff --git a/trunk/examples/get_albums.py b/trunk/examples/get_albums.py
deleted file mode 100644
index 9d2e46f..0000000
--- a/trunk/examples/get_albums.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/python
-# ========================================================================
-# Copyright (c) 2007, Metaweb Technologies, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
-# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
-# TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# ========================================================================
-
-from freebase.api import HTTPMetawebSession, MetawebError
-
-#username='username'
-#password='password'
-
-query = { 'type':'/music/artist',
- 'name':'Sting',
- 'album':[],
- }
-#credentials = freebase.login(username, password)
-
-mss = HTTPMetawebSession('www.freebase.com')
-result = mss.mqlread(query)
-
-for album in result.album:
- print album
-
-
-# output :
-#The Dream of the Blue Turtles
-#Bring on the Night (disc 1)
-#Bring on the Night (disc 2)
-#...Nothing Like the Sun
-#...Nada Como el Sol
-#The Soul Cages
-#Acoustic Live in Newcastle
-#All This Time
-#Mad About You
-#Ten Summoner's Tales
-#Demolition Man
-#Fields of Gold: The Best of Sting 1984-1994
-#The Living Sea
-#Let Your Soul Be Your Pilot
-#Mercury Falling
-#Brand New Day
-#Desert Rose
-#...All This Time
-#Still Be Love in the World
-#Sacred Love
-#Stolen Car
-#1991-10-02: Hollywood Bowl, Los Angeles, CA, USA
-#Best Ballads
-#Brand New Day (bonus disc)
-#Brand New Day: The Remixes
-#Dolphins
-#Englishman in New York
-#Five Live!
-#Fortress: The London Symphony Orchestra performs Sting
-#I Shall Be Released (disc 2)
-#I Shall Be Released (disc 3)
-#I Shall Be Released (disc 4)
-#I Shall Be Released (disc 5)
-#I'm So Happy I Can't Stop Crying
-#If I Ever Lose My Faith in You
-#If You Love Somebody Set Them Free
-#Live at the BBC 1st Dec 2001
-#Live at the Universal Amphiteater: 10/29/99
-#Live in Central Park (disc 2)
-#Mercury Falling (bonus disc)
-#Moon Walking
-#My Funny Friend and Me
-#My Funny Valentine
-#Send Your Love Remix Album
-#Sting at the Movies
-#Ten Summoners Tales (DTS)
-#They Dance Alone (Gueca Solo)
-#This Cowboy Song
-#Unplugged (disc 1: The Rehearsal)
-#Unplugged (disc 2: Complete Live)
-#When We Dance
-#You Still Touch Me
diff --git a/trunk/freebase/__init__.py b/trunk/freebase/__init__.py
deleted file mode 100755
index d289e09..0000000
--- a/trunk/freebase/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-pass
diff --git a/trunk/freebase/api/__init__.py b/trunk/freebase/api/__init__.py
deleted file mode 100755
index 959259f..0000000
--- a/trunk/freebase/api/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-
-from session import HTTPMetawebSession, MetawebError
diff --git a/trunk/freebase/api/session.py b/trunk/freebase/api/session.py
deleted file mode 100644
index b3ec825..0000000
--- a/trunk/freebase/api/session.py
+++ /dev/null
@@ -1,391 +0,0 @@
-# ========================================================================
-# Copyright (c) 2007, Metaweb Technologies, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
-# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
-# TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# ========================================================================
-
-#
-# declarations for external metaweb api.
-#
-#
-# from metaweb.api import HTTPMetawebSession
-#
-# mss = HTTPMetawebSession('sandbox.freebase.com')
-# print mss.mqlread([dict(name=None, type='/type/type')])
-#
-#
-#
-
-import os, sys, re
-import urllib2
-import cookielib
-import simplejson
-from urllib import quote as urlquote
-import pprint
-import socket
-
-import logging
-log = logging.getLogger()
-log.setLevel(logging.DEBUG)
-console = logging.StreamHandler()
-console.setLevel(logging.INFO)
-# add the handler to the root logger
-log.addHandler(console)
-
-
-__all__ = ['MetawebError', 'MetawebSession', 'HTTPMetawebSession']
-
-__version__ = '0.1'
-
-import simplejson.encoder
-simplejson.JSONEncoder.item_separator = ','
-simplejson.JSONEncoder.key_separator = ':'
-#delattr(simplejson.encoder.ESCAPE_DCT, '/')
-
-def urlencode_weak(s):
- return urlquote(s, safe='{}[],"/:$')
-
-
-# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/361668
-class attrdict(dict):
- """A dict whose items can also be accessed as member variables.
-
- >>> d = attrdict(a=1, b=2)
- >>> d['c'] = 3
- >>> print d.a, d.b, d.c
- 1 2 3
- >>> d.b = 10
- >>> print d['b']
- 10
-
- # but be careful, it's easy to hide methods
- >>> print d.get('c')
- 3
- >>> d['get'] = 4
- >>> print d.get('a')
- Traceback (most recent call last):
- TypeError: 'int' object is not callable
- """
- def __init__(self, *args, **kwargs):
- dict.__init__(self, *args, **kwargs)
- self.__dict__ = self
-
-
-
-# TODO expose the common parts of the result envelope
-class MetawebError(Exception):
- """
- an error report from the metaweb service.
- """
- pass
-
-
-
-# TODO right now this is a completely unnecessary superclass.
-# is there enough common behavior between session types
-# to justify it?
-class MetawebSession(object):
- """
- MetawebSession is the base class for MetawebSession, subclassed for
- different connection types. Only http is available externally.
-
- This is more of an interface than
- """
-
- # interface definition here...
-
-
-class HTTPMetawebSession(MetawebSession):
- """
- a MetawebSession is a request/response queue.
-
- this version uses the HTTP api, and is synchronous.
- """
- # share cookies across sessions, so that different sessions can
- # see each other's writes immediately.
- _cookies = cookielib.CookieJar()
- _cookiespy = urllib2.HTTPCookieProcessor(_cookies)
-
- def __init__(self, service_url, username=None, password=None, prev_session=None):
- """
- create a new MetawebSession for interacting with the Metaweb.
-
- a new session will inherit state from prev_session if present,
- """
- super(HTTPMetawebSession, self).__init__()
-
- assert not service_url.endswith('/')
- if not '/' in service_url: # plain host:port
- service_url = 'http://' + service_url
-
- self.service_url = service_url
-
- self.username = username
- self.password = password
-
- self.tid = None
-
- if prev_session:
- self.service_url = prev.service_url
-
- def _httpreq(self, service_path, method='GET', body=None, form=None,
- headers=None, **kws):
- """
- make an http request to the service.
-
- form arguments are encoded in the url, even for POST, if a non-form
- content-type is given for the body.
- """
-
- if method == 'POST':
- assert body is not None or form is not None
- elif method == 'GET':
- assert body is None
- else:
- assert 0, 'unknown method %s' % method
-
- log.debug('HTTPREQ: %s %s %s %s', service_path, method, kws, self._cookies)
-
- url = self.service_url + service_path
-
- if headers is None:
- headers = []
-
- # XXX This is a lousy way to parse Content-Type, where is
- # the library?
- ct = None
- for k,v in headers:
- if k.lower() == 'content-type':
- ct = v.split(';')[0]
- break
-
- if body is not None:
- # if body is provided, content-type had better be too
- assert ct is not None
-
- if form is not None:
- qstr = '&'.join(['%s=%s' % (urlencode_weak(k), urlencode_weak(v))
- for k,v in form.items()])
- if method == 'POST':
- # put the args on the url if we're putting something else
- # in the body. this is used to add args to raw uploads.
- if body is not None:
- url += '?' + qstr
- else:
- if ct is None:
- # XXX encoding and stuff
- ct = 'application/x-www-form-urlencoded'
- headers.append(('content-type', ct))
-
- if ct == 'multipart/form-encoded':
- # XXX fixme
- raise NotImplementedError
- elif ct == 'application/x-www-form-urlencoded':
- body = qstr
- else:
- # for all methods other than POST, use the url
- url += '?' + qstr
-
- req = urllib2.Request(url, body, dict(headers), **kws)
-
- self.opener = urllib2.build_opener(self._cookiespy)
-
- # assure the service that this isn't a CSRF form submission
- self.opener.addheaders = [('User-agent',
- 'python freebase.api-%s' % __version__),
- ('X-Metaweb-Request', 'Python')]
-
- if self.tid is not None:
- self.opener.addheaders.append(('X-Metaweb-TID', self.tid))
-
- try:
- if headers:
- self.opener.addheaders += headers
- resp = self.opener.open(req)
-
- except socket.error, e:
- log.error('SOCKET FAILURE: %s', e.fp.read())
- raise MetawebError, 'failed contacting %s: %s' % (url, str(e))
-
- except urllib2.HTTPError, e:
- if e.code == 400 and e.info().type == 'application/json':
- r = self._readjson(e.fp)
- for msg in r.messages:
- if msg.get('level', 'error') == 'error':
- raise MetawebError(u'%s %s %r' % (msg.get('code',''), msg.message, msg.info))
-
- # some 400 we don't recognize. hmm.
- raise MetawebError(u'%r' % r)
- raise MetawebError, 'request failed: %s: %r %r' % (url, str(e), e.fp.read())
-
- for header in resp.info().headers:
- log.debug('HTTP HEADER %s', header)
- name, value = re.split("[:\n\r]", header, 1)
- if name.lower() == 'x-metaweb-tid':
- self.tid = value.strip()
- #if name.lower().startswith('set-cookie'):
- # if value.startswith(' metaweb-user'):
- # pass
- # else:
- # self.saved_headers[name] = value.strip()
- # log.debug('HTTP VALUE %s', value)
-
- return resp
-
- def _readjson(self, fp):
- # TODO really this should be accomplished by hooking
- # simplejson to create attrdicts instead of dicts.
- def struct2attrdict(st):
- """
- copy a json structure, turning all dicts into attrdicts.
-
- copying descends instances of dict and list, including subclasses.
- """
- if isinstance(st, dict):
- return attrdict([(k,struct2attrdict(v)) for k,v in st.items()])
- if isinstance(st, list):
- return [struct2attrdict(li) for li in st]
- return st
-
- json = fp.read()
- if json == '':
- log.error('the empty string is not valid json')
- raise MetawebError('the empty string is not valid json')
-
- try:
- r = simplejson.loads(json)
- except ValueError, e:
- log.error('error parsing json string %r' % json)
- raise MetawebError, 'error parsing JSON string: %s' % e
-
- return struct2attrdict(r)
-
- def _mqlresult(self, r):
- if r.code != '/api/status/ok':
- for msg in r.messages:
- log.error('mqlread failed: %s %s' % (msg.code, msg.message))
- raise MetawebError, 'query failed: %s' % r.messages[0].code
-
- return r.result
-
- def login(self):
- """sign in to the service"""
-
- assert self.username is not None
- assert self.password is not None
-
- log.debug('LOGIN USERNAME: %s', self.username)
-
- try:
- resp = self._httpreq('/api/account/login', 'POST',
- form=dict(username=self.username,
- password=self.password))
- except urllib2.HTTPError, e:
- raise MetawebError("login error: %s", e)
-
- r = self._readjson(resp)
-
- if r.code != '/api/status/ok':
- raise MetawebError(u'%s %r' % (r.get('code',''), r.messages))
-
- log.debug('LOGIN RESP: %r', r)
- log.debug('LOGIN INFO: %s', resp.info())
- log.debug('LOGIN COOKIES: %s', self._cookies)
-
-
- def mqlreaditer(self, sq):
- """read a structure query"""
-
- cursor = True
-
- while 1:
- subq = dict(query=[sq], cursor=cursor, escape=False)
- qstr = simplejson.dumps(dict(c0=subq))
-
- service = '/api/service/mqlread'
-
- resp = self._httpreq(service, form=dict(queries=qstr))
- r = self._readjson(resp)
- r = r['c0']
-
- for item in self._mqlresult(r):
- yield item
-
- if r['cursor']:
- cursor = r['cursor']
- else:
- break
-
- def mqlread(self, sq):
- """read a structure query"""
- subq = dict(query=sq, cursor=True, escape=False)
- qstr = simplejson.dumps(dict(c0=subq))
-
- log.debug('MQLREAD: %s', qstr)
-
- service = '/api/service/mqlread'
-
- resp = self._httpreq(service, form=dict(queries=qstr))
- r = self._readjson(resp)
- r = r['c0']
- return self._mqlresult(r)
-
- def trans(self, guid):
- """translate blob from guid """
- url = '/api/trans/raw/' + urlquote(guid)
- resp = self._httpreq(url)
- content = resp.read()
- return content
-
- def mqlwrite(self, sq):
- """do a mql write"""
- query = dict(query=sq, escape=False)
- qstr = simplejson.dumps(query)
-
- log.debug('MQLWRITE: %s', qstr)
-
- service = '/api/service/mqlwrite'
- resp = self._httpreq(service, 'POST',
- form=dict(query=qstr))
- r = self._readjson(resp)
- return self._mqlresult(r)
-
- def upload(self, body, content_type):
- """upload to the metaweb"""
-
- log.debug('UPLOAD %s', content)
-
- service = '/api/service/upload'
- resp = self._httpreq(service, 'POST',
- headers={'content-type': content_type},
- body=qstr)
- r = self._readjson(resp)
- return self._mqlresult(r)
-
-
-if __name__ == '__main__':
- mss = HTTPMetawebSession('sandbox.freebase.com')
-
- print mss.mqlread([dict(name=None, type='/type/type')])
diff --git a/trunk/freebase/rison.py b/trunk/freebase/rison.py
deleted file mode 100755
index 468d505..0000000
--- a/trunk/freebase/rison.py
+++ /dev/null
@@ -1,303 +0,0 @@
-
-#
-# based on javascript openlaszlo-json
-#
-# Author: Oliver Steele
-# Copyright: Copyright 2006 Oliver Steele. All rights reserved.
-# Homepage: http:#osteele.com/sources/openlaszlo/json
-# License: MIT License.
-# Version: 1.0
-#
-
-# hacked by nix for use in uris
-# ported to python by nix
-#
-
-
-
-#
-# TODO
-#
-# switch to unicode
-# fall through to simplejson if first char is not in '!('
-#
-
-
-import os, sys, re
-#import simplejson
-simplejson = None
-
-class ParserException(Exception):
- pass
-
-class Parser(object):
- WHITESPACE = ''
- #WHITESPACE = " \t\n\r\f"
-
- # we divide the uri-safe glyphs into three sets
- # <rison> - used by rison ' ! : ( ) ,
- # <identifier> - common in strings - _ . / ~
- # <reserved> - not common in strings, reserved * @ $
- #
- # <rison> and <reserved> classes are illegal in ids.
- # ids also can't look like numbers.
-
- not_idchar = "'!:(),*@$";
- not_idstart = "-0123456789";
-
- idrx = ('[^' + not_idstart + not_idchar +
- '][^' + not_idchar + ']*')
-
- # regexp to check for valid rison ids
- id_ok_re = re.compile('^' + idrx + '$', re.M)
-
- # regexp to find the end of an id when parsing
- next_id_re = re.compile(idrx, re.M)
-
- def parse_json(self, str):
- if len(str) > 0 and str[0] not in '!(':
- return simplejson.loads(str)
- return self.parse(str)
-
- def parse(self, str):
- self.string = str
- self.index = 0
-
- value = self.readValue()
- if self.next():
- raise ParserException("extra characters at the end of the string")
- return value
-
- def readValue(self):
- c = self.next()
-
- if c == '!':
- return self.parse_bang()
- if c == '(':
- return self.parse_open_paren()
- if c == "'":
- return self.parse_single_quote()
- if c in '-0123456789':
- return self.parse_number()
-
- # fell through table, parse as an id
- s = self.string
- i = self.index-1
-
- m = self.next_id_re.match(s, i)
- if m:
- id = m.group(0)
- self.index = i + len(id)
- return id # a string
-
- if c:
- raise ParserException("invalid character: '" + c + "'")
- raise ParserException("empty expression")
-
- def parse_array(self):
- ar = []
- while 1:
- c = self.next()
- if c == ')':
- return ar
-
- if c is None:
- raise ParserException("unmatched '!('")
-
- if len(ar):
- if c != ',':
- raise ParserException("missing ','")
- elif c == ',':
- raise ParserException("extra ','")
- else:
- self.index -= 1
- n = self.readValue()
- ar.append(n)
-
- return ar
-
- def parse_bang (self):
- s = self.string
- c = s[self.index]
- self.index += 1
- if c is None:
- raise ParserException('"!" at end of input')
- if c not in self.bangs:
- raise ParserException('unknown literal: "!' + c + '"')
- x = self.bangs[c]
- if callable(x):
- return x(self)
-
- return x
-
-
- def parse_open_paren (self):
- count = 0
- o = {}
-
- while 1:
- c = self.next()
- if c == ')':
- return o
- if count:
- if c != ',':
- raise ParserException("missing ','")
- elif c == ',':
- raise ParserException("extra ','")
- else:
- self.index -= 1
- k = self.readValue()
-
- if self.next() != ':':
- raise ParserException("missing ':'")
- v = self.readValue()
-
- o[k] = v
- count += 1
-
-
- def parse_single_quote(self):
- s = self.string
- i = self.index
- start = i
- segments = []
-
- while 1:
- if i >= len(s):
- raise ParserException('unmatched "\'"')
-
- c = s[i]
- i += 1
- if c == "'":
- break
-
- if c == '!':
- if start < i-1:
- segments.append(s[start:i-1])
- c = s[i]
- i += 1
- if c in "!'":
- segments.append(c)
- else:
- raise ParserException('invalid string escape: "!'+c+'"')
-
- start = i
-
-
- if start < i-1:
- segments.append(s[start:i-1])
- self.index = i
- return ''.join(segments)
-
-
- # Also any number start (digit or '-')
- def parse_number(self):
- s = self.string
- i = self.index
- start = i-1
- state = 'int'
- permittedSigns = '-'
- transitions = {
- 'int+.': 'frac',
- 'int+e': 'exp',
- 'frac+e': 'exp'
- }
-
- while 1:
- if i >= len(s):
- i += 1
- break
-
- c = s[i]
- i += 1
-
- if '0' <= c and c <= '9':
- continue
-
- if permittedSigns.find(c) >= 0:
- permittedSigns = ''
- continue
-
- state = transitions.get(state + '+' + c.lower(), None)
- if state is None:
- break
- if state == 'exp':
- permittedSigns = '-'
-
- self.index = i - 1
- s = s[start:self.index]
- if s == '-':
- raise ParserException("invalid number")
- if re.search('[.e]', s):
- return float(s)
- return int(s)
-
- # return the next non-whitespace character, or undefined
- def next(self):
- l = len(self.string)
- s = self.string
- i = self.index
-
- while 1:
- if i == len(s):
- return None
- c = s[i]
- i += 1
- if c not in self.WHITESPACE:
- break
-
- self.index = i
- return c
-
-
- bangs = {
- 't': True,
- 'f': False,
- 'n': None,
- '(': parse_array
- }
-
-
-def loads(s):
- return Parser().parse(s)
-
-if __name__ == '__main__':
- p = Parser()
-
- rison_examples = [
- "(a:0,b:1)",
- "(a:0,b:foo,c:'23skidoo')",
- "!t",
- "!f",
- "!n",
- "''",
- "0",
- "1.5",
- "-3",
- "1e30",
- "1e-30",
- "G.",
- "a",
- "'0a'",
- "abc def",
- "()",
- "(a:0)",
- "(id:!n,type:/common/document)",
- "!()",
- "!(!t,!f,!n,'')",
- "'-h'",
- "a-z",
- "'wow!!'",
- "domain.com",
- "'user@domain.com'",
- "'US $10'",
- "'can!'t'",
- ];
-
- for s in rison_examples:
- print
- print '*'*70
- print
- print s
-
- print '%r' % (p.parse(s),)
diff --git a/trunk/setup.py b/trunk/setup.py
deleted file mode 100644
index 220bb50..0000000
--- a/trunk/setup.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/python
-# ========================================================================
-# Copyright (c) 2007, Metaweb Technologies, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
-# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
-# TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# ========================================================================
-
-#from distutils.core import setup
-from setuptools import setup
-
-setup(
- name='freebase',
- version='0.1.0',
- description='Python client library for Freebase API service',
- maintainer_email='developers@freebase.com',
- license='BSD',
- url='http://www.freebase.com/',
- packages=['freebase']
-)
-
-
diff --git a/trunk/test/test_all.py b/trunk/test/test_all.py
deleted file mode 100644
index 23c4c22..0000000
--- a/trunk/test/test_all.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/python
-# ========================================================================
-# Copyright (c) 2007, Metaweb Technologies, Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES AND CONTRIBUTORS
-# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB
-# TECHNOLOGIES OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGE.
-# ========================================================================
-
-
-import unittest
-import sys
-from freebase.api import HTTPMetawebSession
-
-USERNAME = 'username'
-PASSWORD = 'password'
-API_HOST = 'sandbox.freebase.com'
-TEST_QUERY = {'id': 'null', 'name': 'Sting'}
-
-class TestFreebase(unittest.TestCase):
-
- def test_login(self):
- form_values = { 'username' : USERNAME,
- 'password' : PASSWORD }
-
- mss = HTTPMetawebSession(API_HOST, username=USERNAME,
- password=PASSWORD)
- mss.login()
-
- # check mss._cookies?
-
- def test_read(self):
- query = {'type':'/music/artist','id':[{}],'name':'Sting', 'album':[{}]}
-
- mss = HTTPMetawebSession(API_HOST, username=USERNAME,
- password=PASSWORD)
- result = mss.mqlread(query)
- self.assertNotEqual(None, result)
- self.assert_(result.has_key('id'))
- self.assert_(result.has_key('type'))
- self.assert_(result.has_key('name'))
- self.assert_(result.has_key('album'))
- self.assertEqual([].__class__, result['album'].__class__)
- self.assert_( result['album'].__len__() > 0)
- self.assertEqual( 'Sting', result['name'])
- self.assertEqual( '#9202a8c04000641f8000000000092a01', result['id'][0]['value'], str(result['id']))
-
- def test_write(self):
- read_query = {'type':'/music/artist','name':'Yanni\'s Cousin Tom', 'id':{}}
- mss = HTTPMetawebSession(API_HOST, username=USERNAME,
- password=PASSWORD)
- result = mss.mqlread(read_query)
- self.assertEqual(None, result)
-
- write_query = {'create':'unless_exists', 'type':'/music/artist','name':'Yanni'}
-
- mss.login()
- write_result = mss.mqlwrite(write_query)
- self.assertNotEqual(None, write_result)
- self.assert_(write_result.has_key('create'))
- self.assert_(write_result.has_key('type'))
- self.assert_(write_result.has_key('name'))
- self.assertEqual('existed', write_result['create'])
- self.assertEqual('Yanni', write_result['name'])
- self.assertEqual('/music/artist', write_result['type'])
-
-if __name__ == '__main__':
- unittest.main()
-