diff options
Diffstat (limited to 'freebase-api/freebase/fcl')
| -rw-r--r-- | freebase-api/freebase/fcl/README.txt | 8 | ||||
| -rwxr-xr-x | freebase-api/freebase/fcl/__init__.py | 0 | ||||
| -rwxr-xr-x | freebase-api/freebase/fcl/commands.py | 688 | ||||
| -rwxr-xr-x | freebase-api/freebase/fcl/fbutil.py | 113 | ||||
| -rwxr-xr-x | freebase-api/freebase/fcl/fcl.py | 276 | ||||
| -rwxr-xr-x | freebase-api/freebase/fcl/inspect.py | 218 | ||||
| -rwxr-xr-x | freebase-api/freebase/fcl/mktype.py | 179 |
7 files changed, 0 insertions, 1482 deletions
diff --git a/freebase-api/freebase/fcl/README.txt b/freebase-api/freebase/fcl/README.txt deleted file mode 100644 index 2e03d71..0000000 --- a/freebase-api/freebase/fcl/README.txt +++ /dev/null @@ -1,8 +0,0 @@ - -This is a command-line tool for performing various freebase commands. - -It should be installed by default as "fcl". - -Try "fcl help" after installing the freebase-api library. - - diff --git a/freebase-api/freebase/fcl/__init__.py b/freebase-api/freebase/fcl/__init__.py deleted file mode 100755 index e69de29..0000000 --- a/freebase-api/freebase/fcl/__init__.py +++ /dev/null diff --git a/freebase-api/freebase/fcl/commands.py b/freebase-api/freebase/fcl/commands.py deleted file mode 100755 index 0fdc283..0000000 --- a/freebase-api/freebase/fcl/commands.py +++ /dev/null @@ -1,688 +0,0 @@ -# ================================================================== -# Copyright (c) 2007,2008,2009 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 os, sys, re, time -from fbutil import * - -import simplejson - -import freebase.rison as rison -from freebase.api import attrdict - - -def cmd_help(fb, command=None): - """get help on commands - - %prog help [cmd] - """ - - if command is not None: - cmd = fb.commands[command] - print ' %s: %s' % (cmd.name, cmd.shortdoc) - print cmd.doc - return - - print """ -the interface to this tool is loosely modeled on the -"svn" command-line tool. many commands work slightly -differently from their unix and svn equivalents - -read the doc for the command first. - -use "%s help <subcommand>" for help on a particular -subcommand. -""" % fb.progpath - - fb.oparser.print_help() - - print 'available subcommands:' - cmds = sorted(fb.commands.keys()) - - for fk in cmds: - cmd = fb.commands[fk] - print ' %s: %s' % (cmd.name, cmd.shortdoc) - - -def cmd_wikihelp(fb): - """get help on commands in mediawiki markup format - - %prog wikihelp - """ - - print """usage: %s subcommand [ args ... ] - - the interface to this tool is loosely modeled on the - "svn" command-line tool. many commands work slightly - differently from their unix and svn equivalents - - read the doc for the command first. - """ % fb.progpath - - print 'subcommands:' - for fk in sorted(fb.commands.keys()): - cmd = fb.commands[fk] - - # mediawiki markup cares about the difference between - # a blank line and a blank line with a bunch of - # spaces at the start of it. ewww. - doc = re.sub(r'\r?\n {0,8}', '\n ', cmd.doc) - - print '==== %s %s: %s ====' % (fb.progpath, cmd.name, cmd.shortdoc) - print doc - print - - -# this command is disabled because it relies on some svn glue that -# was not sufficiently well thought out. -def old_cmd_pwid(fb): - """show the "current working namespace id" - - %prog pwid - - by default, relative ids can't be resolved. however, if you - run the fb tool from a directory that has the svn property - 'freebase:id' set, relative ids will be resolved relative - to that id. the idea is that you can create an svn tree - that parallels the freebase namespace tree. - - for example: - $ %prog pwid - - $ svn propset freebase:id "/freebase" . - - $ %prog pwid - /freebase - - """ - if fb.cwid is not None: - print fb.cwid - else: - print '' - - -def cmd_ls(fb, path=None): - """list the keys in a namespace - - %prog ls [id] - """ - path = fb.absid(path) - q = {'id': path, - '/type/namespace/keys': [{'value': None, - 'namespace': { - 'id': None, - 'type': [] - }, - 'optional':True - }] - } - - r = fb.mss.mqlread(q) - if r is None: - raise CmdException('query for id %r failed' % path) - - #sys.stdout.write(' '.join([mk.value for mk in r['/type/namespace/keys']])) - - for mk in r['/type/namespace/keys']: - print mk.value - - if 0: - suffix = '' - if ('/type/namespace' in mk.namespace.type - or '/type/domain' in mk.namespace.type): - suffix = '/' - print mk.value, mk.namespace.id+suffix - - -def cmd_mkdir(fb, path): - """create a new freebase namespace - %prog mkdir id - - create a new instance of /type/namespace at the given - point in id space. if id already exists, it should be - a namespace. - """ - path = fb.absid(path) - dir,file = dirsplit(path) - wq = { 'create': 'unless_exists', - 'key':{ - 'connect': 'insert', - 'namespace': dir, - 'value': file - }, - 'name': path, - 'type': '/type/namespace' - } - - r = fb.mss.mqlwrite(wq) - -def cmd_ln(fb, src, dst): - """create a namespace key - %prog ln srcid dstid - - create a new namespace link at dstid to the object - currently at srcid. - """ - src = fb.absid(src) - dst = fb.absid(dst) - dir,file = dirsplit(dst) - wq = { 'id': src, - 'key':{ - 'connect': 'insert', - 'namespace': dir, - 'value': file - } - } - - r = fb.mss.mqlwrite(wq) - - -def cmd_rm(fb, path): - """unlink a namespace key - %prog rm id - - remove the /type/key that connects the given id to its - parent. id must be a path for this to make any sense. - - note that is like unix 'unlink' rather than 'rm'. - it won't complain if the 'subdirectory' contains data, - since that data will still be accessible to other queries. - it's not like 'rm -rf' either, because it doesn't - disturb anything other than the one directory entry. - """ - path = fb.absid(path) - dir,file = dirsplit(path) - - wq = { 'id': path, - 'key':{ - 'connect': 'delete', - 'namespace': dir, - 'value': file - } - } - - r = fb.mss.mqlwrite(wq) - -def cmd_mv(fb, src, dst): - """rename srcid to dstid. - %prog mv srcid dstid - - equivalent to: - $ fb ln <srcid> <dstid> - $ fb rm <srcid> - """ - cmd_ln(fb, src, dst) - cmd_rm(fb, src) - -def cmd_cat(fb, id, include_headers=False): - """download a document from freebase to stdout - %prog cat id - - equivalent to "%prog get id -". - """ - return cmd_get(fb, id, localfile='-', include_headers=include_headers) - -def cmd_get(fb, id, localfile=None, include_headers=False): - """download a file from freebase - %prog get id [localfile] - - download the document or image with the given id from freebase - into localfile. localfile '-' means stdout. localfile - defaults to a file in the current directory with the same name - as the last key in the path, possibly followed by a metadata - extension like .html or .txt. - """ - id = fb.absid(id) - dir,file = dirsplit_unsafe(id) - - def read_content(id, content_only=False): - c = attrdict(id=id) - cq = { 'id': id, - 'type': [], - '/common/document/content': None, - '/common/document/source_uri': None, - '/type/content/media_type': { 'name':None, - 'optional': True }, - #'/type/content/text_encoding': { 'name':None }, - '/type/content/blob_id':None, - } - cd = fb.mss.mqlread(cq) - if '/type/content' in cd.type: - c.media_type = cd['/type/content/media_type'].name - #c.text_encoding = cd['/type/content/text_encoding'].name - c.sha256 = cd['/type/content/blob_id'] - return c - - if content_only: - raise CmdException('%s is not a content id' % id) - - cid = cd['/common/document/content'] - if cid is not None: - return read_content(cid, content_only=True) - - # in this case we don't have a content object - if cd['/common/document/source_uri'] is not None: - return None - - raise CmdException('%s is not a content or document id' % id) - - - content = read_content(id) - log.debug('COBJ %r' % content) - if content is not None: - fileext = media_type_to_extension.get(content.media_type, None) - else: - fileext = None - - if localfile == '-': - ofp = sys.stdout - else: - if localfile is None: - implicit_outfile = True - localfile = file - elif re.match(r'[/\\]$', localfile): - implicit_outfile = True - localfile = localfile + file - else: - implicit_outfile = False - localfile = os.path.abspath(localfile) - - # add file extension based on content-type: - # should be an option to disable this - if implicit_outfile and fileext is not None: - localfile += '.' + fileext - - # if we didn't explicitly name the output file, - # don't destroy an existing file - localfile_base = localfile - count = 0 - while implicit_outfile and os.path.exists(localfile): - count += 1 - localfile = '%s.%d' % (localfile_base, count) - ofp = open(localfile, 'wb') - - body = fb.mss.trans(id) - - if include_headers: - # XXX show content-type, what else? - pass - - ofp.write(body) - - if localfile != '-': - print ('%s saved (%d bytes)' % (localfile, len(body))) - ofp.close() - - -def cmd_put(fb, localfile, id=None, content_type=None): - """upload a document to freebase -- EXPERIMENTAL - %prog put localfile [id] [content-type] - - upload the document or image in localfile to given freebase - id. if localfile is '-' the data will be read from stdin. - - if id is missing or empty, a new document will be created. - later the id might default to something computed from localfile - and any svn attributes it has. - - output: a single line, the id of the document. - """ - if content_type is None: - ext = re.sub('^.*\.([^/.]+)$', r'\1', localfile) - media_type = extension_to_media_type.get(ext, None) - - if media_type is None: - raise CmdException('could not infer a media type from extension %r: please specify it' - % ext) - - if media_type.startswith('text/'): - # this is a bad assumption. should sniff it? - text_encoding = 'utf-8' - content_type = '%s;charset=%s' % (media_type, text_encoding) - else: - content_type = media_type - - new_id = None - if id is not None: - idinfo = fb.mss.mqlread({ 'id': id, 'type': '/common/document' }) - if idinfo is None: - new_id = id - id = None - - body = open(localfile, 'rb').read() - r = fb.mss.upload(body, content_type, document_id=id) - - if new_id is None: - print r.document - else: - cmd_ln(fb, r.document, new_id) - print new_id - - -def cmd_dump(fb, id): - """show all properties of a freebase object - %prog dump object_id - """ - id = fb.absid(id) - - import inspect - - r = inspect.inspect_object(fb.mss, id) - if r is None: - raise CmdException('no match for id %r' % id) - - for k in sorted(r.keys()): - vs = r[k] - for v in vs: - id = v.get('id', '') - - name = '%r' % (v.get('name') or v.get('value')) - if name == 'None': name = '' - - type = v.get('type', '') - if type == '/type/text': - extra = v.get('lang', '') - elif type == '/type/key': - extra = v.get('namespace', '') - else: - extra = '' - - fb.trow(k, id, name, type, extra) - - -def cmd_pget(fb, id, propid): - """get a property of a freebase object -- EXPERIMENTAL - %prog pget object_id property_id - - get the property named by property_id from the object. - - XXX output quoting is not well specified. - - property_id must be a fully qualified id for now. - - prints one line for each match. - - if propid ends in '*' this does a wildcard for a particular type. - """ - id = fb.absid(id) - proptype, propkey = dirsplit(propid) - - if propkey != '*': - # look up the prop - q = { 'id': id, - propid: [{}], - } - r = fb.mss.mqlread(q) - for v in r[propid]: - if 'value' in v: - print v.value - else: - print v.id - - else: - # look up the prop - q = { 'id': id, - '*': [{}], - } - if isinstance(proptype, basestring): - q['type'] = proptype - - r = fb.mss.mqlread(q) - - for k in sorted(r.keys()): - v = r[k]; - if 'value' in v: - print '%s %s' % (k, v.value) - else: - print '%s %s' % (k, v.id) - -def cmd_pdel(fb, id, propid, oldval): - """delete a property of a freebase object -- EXPERIMENTAL - %prog pdel object_id property_id oldvalue - - set the property named by property_id on the object. - value is an id or a json value. XXX this is ambiguous. - - property_id must be a fully qualified id for now. - - for now you need to provide a "oldval" argument, - later this tool will query and perhaps prompt if the - deletion is ambiguous. - - prints a single line, either 'deleted' or 'missing' - """ - return cmd_pset(fb, id, propid, None, oldval) - - -def cmd_touch(fb): - """bypass any cached query results the service may have. use sparingly. - """ - fb.mss.mqlflush() - - -def cmd_pset(fb, id, propkey, val, oldval=None, extra=None): - """set a property of a freebase object -- EXPERIMENTAL - %prog pset object_id property_id value - - set the property named by property_id on the object. - value is an id or a json value. XXX this is ambiguous. - - property_id must be a fully qualified id for now. - - if the property should be a unique property, this will - write with 'connect:update'. if the property may have - multiple, it is written with 'connect:insert'. - - prints a single line, either 'inserted' or 'present' - """ - id = fb.absid(id) - - propid = fb.absprop(propkey) - - # look up the prop - pq = { 'id': propid, - 'type': '/type/property', - 'name': None, - 'unique': None, - 'expected_type': { - 'id': None, - 'name': None, - 'default_property': None, - 'optional': True, - }, - } - - prop = fb.mss.mqlread(pq) - - if prop is None: - raise CmdException('can\'t resolve property key %r - use an absolute id' % propid); - - if propid.startswith('/type/object/') or propid.startswith('/type/value/'): - propkey = re.sub('/type/[^/]+/', '', propid); - else: - propkey = propid - - wq = { 'id': id, - propkey: { - } - } - - if val is None: - val = oldval - wq[propkey]['connect'] = 'delete' - elif prop.unique: - wq[propkey]['connect'] = 'update' - else: - wq[propkey]['connect'] = 'insert' - - if prop.expected_type is None: - wq[propkey]['id'] = val - elif prop.expected_type.id not in value_types: - wq[propkey]['id'] = val - else: - wq[propkey]['value'] = val - - if prop.expected_type.id == '/type/text': - if extra is not None: - lang = extra - else: - lang = '/lang/en' - wq[propkey]['lang'] = lang - - if prop.expected_type.id == '/type/key': - if extra is not None: - wq[propkey]['namespace'] = extra - else: - raise CmdException('must specify a namespace to pset /type/key') - - r = fb.mss.mqlwrite(wq) - print r[propkey]['connect'] - -def cmd_login(fb, username=None, password=None): - """login to the freebase service - %prog login [username [password]] - - cookies are maintained in a file so - they are available to the next invocation. - prompts for username and password if not given - """ - import getpass - if username is None: - sys.stdout.write('freebase.com username: ') - username = sys.stdin.readline() - if not username: - raise CmdException('usernmae required for login') - username = re.compile('\n$').sub('', username) - if password is None: - password = getpass.getpass('freebase.com password: ') - - fb.mss.username = username - fb.mss.password = password - fb.mss.login() - -def cmd_logout(fb): - """logout from the freebase service - %prog logout - - deletes the login cookies - """ - fb.cookiejar.clear(domain=fb.service_host.split(':')[0]) - - -def cmd_find(fb, qstr): - """print all ids matching a given constraint. - - if the query string starts with "{" it is treated as json. - otherwise it is treated as o-rison. - - %prog find - """ - if qstr.startswith('{'): - q = simplejson.loads(qstr) - else: - q = rison.loads('(' + qstr + ')') - - if 'id' not in q: - q['id'] = None - - results = fb.mss.mqlreaditer(q) - for r in results: - print r.id - -def cmd_q(fb, qstr): - """run a freebase query. - - if the query string starts with "{" it is treated as json. - otherwise it is treated as o-rison. - - dump the result as json. - - %prog q - """ - if qstr.startswith('{'): - q = simplejson.loads(qstr) - else: - q = rison.loads('(' + qstr + ')') - - # results could be streamed with a little more work - results = fb.mss.mqlreaditer(q) - print simplejson.dumps(list(results), indent=2) - -def cmd_open(fb, id): - """open a web browser on the given id. works on OSX only for now. - - %prog open /some/id - """ - os.system("open 'http://www.freebase.com/view%s'" % id) - - -def cmd_log(fb, id): - """log changes pertaining to a given id. - - INCOMPLETE - - %prog log /some/id - """ - - null = None - true = True - false = False - - baseq = { - 'type': '/type/link', - 'source': null, - 'master_property': null, - 'attribution': null, - 'timestamp': null, - 'operation': null, - 'valid': null, - 'sort': '-timestamp' - }; - - queries = [ - { - 'target_value': { '*': null }, - 'target': { 'id': null, 'name': null, 'optional': true }, - }, - { - 'target': { 'id': null, 'name': null }, - }] - - for i,q in list(enumerate(queries)): - q.update(baseq) - queries[i] = [q] - - - valuesfrom,linksfrom = fb.mss.mqlreadmulti(queries) - - for link in linksfrom: - # fb.trow(link.master_property.id, ...) - print simplejson.dumps(link, indent=2) - - for link in valuesfrom: - # fb.trow(link.master_property.id, ...) - print simplejson.dumps(link, indent=2) - - diff --git a/freebase-api/freebase/fcl/fbutil.py b/freebase-api/freebase/fcl/fbutil.py deleted file mode 100755 index ed1e511..0000000 --- a/freebase-api/freebase/fcl/fbutil.py +++ /dev/null @@ -1,113 +0,0 @@ -# ================================================================== -# Copyright (c) 2007,2008,2009 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 re - -import logging -log = logging.getLogger() - - -class FbException(Exception): - pass - -class CmdException(Exception): - pass - -media_types = { - 'html': ['text/html'], - 'txt': ['text/plain'], - - 'xml': ['text/xml', - 'application/xml'], - - 'atom': ['application/atom+xml'], - - 'js': ['text/javascript', - 'application/javascript', - 'application/x-javascript'], - - 'json': ['application/json'], - - 'jpg': ['image/jpeg', - 'image/pjpeg'], - - 'gif': ['image/gif'], - - 'png': ['image/png'], - } - -extension_to_media_type = dict([(k,vs[0]) for k,vs in media_types.items()]) -media_type_to_extension = {} -for k,vs in media_types.items(): - for v in vs: - media_type_to_extension[v] = k - - - - -DIRSPLIT = re.compile(r'^(.+)/([^/]+)$') - -def dirsplit_unsafe(id): - m = DIRSPLIT.match(id) - if m is None: - return (None, id) - dir,file = m.groups() - return (dir,file) - -def dirsplit(id): - dir,file = dirsplit_unsafe(id) - if dir == '/guid': - raise FbException('%r is not a freebase keypath' % (id,)) - return (dir,file) - -value_types = [ - '/type/text', - '/type/key', - '/type/rawstring', - '/type/float', - '/type/int', - '/type/boolean', - '/type/uri', - '/type/datetime', - '/type/id', - '/type/enumeration', - ] - -default_propkeys = { - 'value': '/type/value/value', - 'id': '/type/object/id', - 'guid': '/type/object/guid', - 'type': '/type/object/type', - 'name': '/type/object/name', - 'key': '/type/object/key', - 'timestamp': '/type/object/timestamp', - 'permission': '/type/object/permission', - 'creator': '/type/object/creator', - 'attribution': '/type/object/attribution' -}; diff --git a/freebase-api/freebase/fcl/fcl.py b/freebase-api/freebase/fcl/fcl.py deleted file mode 100755 index a0299b8..0000000 --- a/freebase-api/freebase/fcl/fcl.py +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env python -# ================================================================== -# Copyright (c) 2007,2008,2009 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 os, sys, re, time, stat - -from optparse import OptionParser -import getpass -import cookielib -import logging -import simplejson - - -from fbutil import FbException, CmdException, log, default_propkeys -console = logging.StreamHandler() -log.addHandler(console) - -from freebase.api import HTTPMetawebSession, MetawebError, attrdict - -_cookiedir = None -if os.environ.has_key('HOME'): - _cookiedir = os.path.join(os.environ['HOME'], '.pyfreebase') - - -class Command(object): - def __init__(self, module, name, func): - self.module = module - self.name = name - self.func = func - - PROG = re.compile(r'\%prog') - NEWLINE = re.compile(r'(?:\r?\n)+') - - # fill in self.doc - if isinstance(func.__doc__, basestring): - doc = PROG.sub('fcl', func.__doc__ + '\n') - self.shortdoc, self.doc = NEWLINE.split(doc, 1) - else: - self.shortdoc = '(missing documentation)' - self.doc = '(missing documentation)' - - - -class FbCommandHandler(object): - - def __init__(self): - self.service_host = 'www.freebase.com' - self.cookiejar = None - self.cwid = '' - self.progpath = 'fcl' - self.commands = {} - - self.cookiefile = None - if _cookiedir is not None: - self.cookiefile = os.path.join(_cookiedir, 'cookiejar') - - - def init(self): - if self.cookiefile is not None: - self.cookiejar = cookielib.LWPCookieJar(self.cookiefile) - if os.path.exists(self.cookiefile): - try: - self.cookiejar.load(ignore_discard=True) - except cookielib.LoadError: - log.warn('error loading cookies') - - #print 'start cookies %r' % self.cookiejar - - self.mss = HTTPMetawebSession(self.service_host, - cookiejar=self.cookiejar) - - - def absid(self, path): - if path is None: - path = '' - if path.startswith('/'): - return path - - if not isinstance(self.cwid, basestring) or not self.cwid.startswith('/'): - # svn cwid support is disabled because it relies on some svn glue that - # was not sufficiently well thought out. - # raise CmdException("can't resolve relative id %r without cwid - see 'fcl help pwid'" % (path)) - raise CmdException("no support for relative id %r" % (path)) - - if path == '' or path == '.': - return self.cwid - - return self.cwid + '/' + path - - - def absprop(self, propkey): - if propkey.startswith('/'): - return propkey - - # check schemas of /type/object and /type/value, - # as well as other reserved names - if propkey in default_propkeys: - return default_propkeys[propkey] - - return self.absid(propkey) - - def thead(self, *args): - strs = ['%r' % arg - for arg in args] - print '\t'.join(strs) - - def trow(self, *args): - print '\t'.join(args) - return - strs = ['%r' % arg - for arg in args] - print '\t'.join(strs) - - def save(self): - #print 'end cookies %r' % self.cookiejar - if _cookiedir and self.cookiefile.startswith(_cookiedir): - # create private cookiedir if needed - if not os.path.exists(_cookiedir): - os.mkdir(_cookiedir, 0700) - os.chmod(_cookiedir, stat.S_IRWXU) - - if self.cookiejar is None: - return - - self.cookiejar.save(ignore_discard=True) - - # save the cwd and other state too - - - def import_commands(self, modname): - """ - import new fb commands from a file - """ - namespace = {} - - pyimport = 'from %s import *' % modname - exec pyimport in namespace - mod = sys.modules.get(modname) - - commands = [Command(mod, k[4:], getattr(mod, k)) - for k in getattr(mod, '__all__', dir(mod)) - if (k.startswith('cmd_') - and callable(getattr(mod, k)))] - - - for cmd in commands: - log.info('importing %r' % ((cmd.name, cmd.func),)) - self.commands[cmd.name] = cmd - - log.info('imported %r from %r' % (modname, mod.__file__)) - - - def dispatch(self, cmd, args): - if cmd in self.commands: - try: - self.commands[cmd].func(self, *args) - except KeyboardInterrupt, e: - sys.stderr.write('%s\n' % (str(e),)) - except FbException, e: - sys.stderr.write('%s\n' % (str(e),)) - except CmdException, e: - sys.stderr.write('%s\n' % (str(e),)) - except MetawebError, e: - sys.stderr.write('%s\n' % (str(e),)) - else: - self.oparser.error('unknown subcommand %r, try "%s help"' % (cmd, self.progpath)) - - self.save() - - - def cmdline_main(self): - op = OptionParser(usage='%prog [options] command [args...] ') - self.oparser = op - - op.disable_interspersed_args() - - op.add_option('-d', '--debug', dest='debug', - default=False, action='store_true', - help='turn on debugging output') - - op.add_option('-v', '--verbose', dest='verbose', - default=False, action='store_true', - help='verbose output') - - op.add_option('-V', '--very-verbose', dest='very_verbose', - default=False, action='store_true', - help='lots of debug output') - - op.add_option('-s', '--service', dest='service_host', - metavar='HOST', - default=self.service_host, - help='Freebase HTTP service address:port') - - op.add_option('-S', '--sandbox', dest='use_sandbox', - default=False, action='store_true', - help='shortcut for --service=sandbox.freebase.com') - - op.add_option('-c', '--cookiejar', dest='cookiefile', - metavar='FILE', - default=self.cookiefile, - help='Cookie storage file (will be created if missing)') - options,args = op.parse_args() - - if len(args) < 1: - op.error('required subcommand missing') - - - loglevel = logging.WARNING - if options.verbose: - loglevel = logging.INFO - if options.very_verbose: - loglevel = logging.DEBUG - - console.setLevel(loglevel) - log.setLevel(loglevel) - - if options.use_sandbox: - self.service_host = 'sandbox.freebase.com' - else: - self.service_host = options.service_host - - self.cookiefile = options.cookiefile - #self.progpath = sys.argv[0] - - self.init() - - self.mss.log.setLevel(loglevel) - self.mss.log.addHandler(console) - - self.import_commands('freebase.fcl.commands') - self.import_commands('freebase.fcl.mktype') - - cmd = args.pop(0) - self.dispatch(cmd, args) - -# entry point for script -def main(): - try: - # turn off crlf output on windows so we work properly - # with unix tools. - import msvcrt - msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) - msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY) - except ImportError: - pass - - fb = FbCommandHandler() - fb.cmdline_main() - -if __name__ == '__main__': - main() diff --git a/freebase-api/freebase/fcl/inspect.py b/freebase-api/freebase/fcl/inspect.py deleted file mode 100755 index 8cd04d2..0000000 --- a/freebase-api/freebase/fcl/inspect.py +++ /dev/null @@ -1,218 +0,0 @@ -# ================================================================== -# Copyright (c) 2007,2008,2009 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. -# ==================================================================== - - -# -# -# wrap all the nastiness needed for a general mql inspect query -# -# - -import os, sys, re - - -null = None -true = True -false = False - -inspect_query = { - 'name': null, - 'type': [], - - '/type/reflect/any_master': [{ - 'optional':true, - 'id': null, - 'name': null, - 'link': { - 'master_property': { - 'id': null, - 'schema': null - } - } - }], - - '/type/reflect/any_reverse': [{ - 'optional':true, - 'id': null, - 'name': null, - 'link': { - 'master_property': { - 'id':null, - 'schema': null, - 'expected_type': null, - 'reverse_property': { - 'id': null, - 'schema': null, - 'optional': true - } - } - } - }], - - '/type/reflect/any_value': [{ - 'optional':true, - 'value': null, - 'link': { - 'master_property': { - 'id':null, - 'schema': null, - 'expected_type': null - }, - } - }], - - 't:/type/reflect/any_value': [{ - 'optional':true, - 'type': '/type/text', - 'value': null, - 'lang': null, - 'link': { - 'master_property': { - 'id':null, - 'schema': null - }, - } - }], - - '/type/object/creator': [{ - 'optional':true, - 'id':null, - 'name':null - }], - '/type/object/timestamp': [{ - 'optional':true, - 'value': null, - }], - - '/type/object/key': [{ - 'optional':true, - 'value': null, - 'namespace': null - }], - '/type/namespace/keys': [{ - 'optional':true, - 'value': null, - 'namespace': null - }] -} - - -def transform_result(result): - proptypes = {} - props = {} - - # copy a property from a /type/reflect clause - def pushtype(propdesc, prop): - tid = propdesc['schema'] - propid = propdesc['id'] - - if isinstance(prop, dict): - prop = dict(prop) - if 'link' in prop: - prop.pop('link') - - if tid not in proptypes: - proptypes[tid] = {} - if propid not in proptypes[tid]: - proptypes[tid][propid] = [] - - if propid not in props: - props[propid] = [] - props[propid].append(prop) - - # copy a property that isn't enumerated by /type/reflect - def pushprop(propid): - ps = result[propid] - if ps is None: - return - - # hack to infer the schema from id, not always reliable! - schema = re.sub(r'/[^/]+$', '', propid) - keyprop = dict(id=propid, schema=schema) - for p in ps: - pushtype(keyprop, p) - - ps = result['/type/reflect/any_master'] or [] - for p in ps: - propdesc = p.link.master_property - pushtype(propdesc, p) - - # non-text non-key values - ps = result['/type/reflect/any_value'] or [] - for p in ps: - propdesc = p.link.master_property - - # /type/text values are queried specially - # so that we can get the lang, so ignore - # them here. - if propdesc.expected_type == '/type/text': - continue - - pushtype(propdesc, p) - - # text values - ps = result['t:/type/reflect/any_value'] or [] - for p in ps: - propdesc = p.link.master_property - pushtype(propdesc, p) - - pushprop('/type/object/creator') - pushprop('/type/object/timestamp') - pushprop('/type/object/key') - pushprop('/type/namespace/keys') - - # now the reverse properties - ps = result['/type/reflect/any_reverse'] or [] - for prop in ps: - propdesc = prop.link.master_property.reverse_property - - # synthetic property descriptor for the reverse of - # a property with no reverse descriptor. - # note the bogus id starting with '-'. - if propdesc is None: - # schema = prop.link.master_property.expected_type - # if schema is None: - # schema = 'other' - - schema = 'other' - propdesc = dict(id='-' + prop.link.master_property.id, - schema=schema) - - pushtype(propdesc, prop) - - #return proptypes - return props - - -def inspect_object(mss, id): - q = dict(inspect_query) - q['id'] = id - r = mss.mqlread(q) - if r is None: - return None - return transform_result(r) diff --git a/freebase-api/freebase/fcl/mktype.py b/freebase-api/freebase/fcl/mktype.py deleted file mode 100755 index 30f8df7..0000000 --- a/freebase-api/freebase/fcl/mktype.py +++ /dev/null @@ -1,179 +0,0 @@ -# ================================================================== -# Copyright (c) 2007,2008,2009 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 os, sys, re, time -from fbutil import * - - -def cmd_mkobj(fb, id, typeid='/common/topic', name=''): - """create a new object with a given type -- EXPERIMENTAL - %prog mkobj new_id typeid name - - create a new object with type typeid at the given - namespace location. - - if present, name gives the display name of the new object. - - """ - id = fb.absid(id) - nsid, key = dirsplit(id) - - typeid = fb.absid(typeid) - - if name == '': - name = key - - wq = { 'create': 'unless_exists', - 'id': None, - 'name': name, - 'type': typeid, - 'key':{ - 'namespace': nsid, - 'value': key - }, - } - - # TODO add included types - - r = fb.mss.mqlwrite(wq) - print r.id,r.create - -def cmd_mktype(fb, id, name=''): - """create a new type -- EXPERIMENTAL - %prog mktype new_id name - - create a new object with type Type at the given - namespace location. - - this doesn't create any type hints. - - if present, name gives the display name of the new property - """ - id = fb.absid(id) - - nsid, key = dirsplit(id) - - if name == '': - name = key - - wq = { 'create': 'unless_exists', - 'id': None, - 'name': name, - 'type': '/type/type', - 'key':{ - 'namespace': nsid, - 'value': key - }, - } - - r = fb.mss.mqlwrite(wq) - print r.id,r.create - -def mkprop(fb, typeid, key, name='', vtype=None, master_property=None): - """helper to create a new property - """ - if name == '': - name = key - - wq = { 'create': 'unless_exists', - 'id': None, - 'type': '/type/property', - 'name': name, - 'schema': typeid, - 'key': { - 'namespace': typeid, - 'value': key - } - } - - if vtype is not None: - wq['expected_type'] = vtype - if master_property is not None: - wq['master_property'] = master_property - - return fb.mss.mqlwrite(wq) - - -def cmd_mkprop(fb, id, name='', vtype=None, revkey=None, revname=''): - """create a new property -- EXPERIMENTAL - %prog mkprop new_id [name] [expected_type] [reverse_property] [reverse_name] - - create a new object with type Property at the given - location. creates both the "schema" and "key" links - for the property, but doesn't create any freebase property - hints. - - if present, name gives the display name of the new property - """ - id = fb.absid(id) - if vtype is not None: - vtype = fb.absid(vtype) - - typeid, key = dirsplit(id) - - - r = mkprop(fb, typeid, key, name, vtype) - - # write the reverse property if specified - - print r.id, r.create - - if revkey is None: - return - - assert vtype is not None - - rr = mkprop(fb, vtype, revkey, revname, typeid, id) - print rr.id, rr.create - - -def cmd_publish_type(fb, typeid): - """try to publish a freebase type for the client - %prog publish_type typeid - - set /freebase/type_profile/published to the /freebase/type_status - instance named 'Published' - - - should also try to set the domain to some namespace that - has type:/type/domain - - """ - id = fb.absid(typeid) - - w = { - 'id': id, - '/freebase/type_profile/published': { - 'connect': 'insert', - 'type': '/freebase/type_status', - 'name': 'Published' - } - } - r = fb.mss.mqlwrite(w) - - print r['/freebase/type_profile/published']['connect'] |
