summaryrefslogtreecommitdiff
path: root/examples/freebase-images-appengine/freebase/fcl/inspect.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/freebase-images-appengine/freebase/fcl/inspect.py')
-rwxr-xr-xexamples/freebase-images-appengine/freebase/fcl/inspect.py218
1 files changed, 218 insertions, 0 deletions
diff --git a/examples/freebase-images-appengine/freebase/fcl/inspect.py b/examples/freebase-images-appengine/freebase/fcl/inspect.py
new file mode 100755
index 0000000..8cd04d2
--- /dev/null
+++ b/examples/freebase-images-appengine/freebase/fcl/inspect.py
@@ -0,0 +1,218 @@
+# ==================================================================
+# 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)