summaryrefslogtreecommitdiff
path: root/linkmerge.py
diff options
context:
space:
mode:
Diffstat (limited to 'linkmerge.py')
-rw-r--r--linkmerge.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/linkmerge.py b/linkmerge.py
new file mode 100644
index 0000000..3cfe1f1
--- /dev/null
+++ b/linkmerge.py
@@ -0,0 +1,108 @@
+
+import freebase, freebase.schema
+from freebase.api import LITERAL_TYPE_IDS, MetawebError
+
+from copy import deepcopy
+import itertools
+import logging
+
+ALL_LINKS_QUERY = [{"type": "/type/link",
+ "source": {"id" : None},
+ "target": {"id" : None},
+ "target_value": None,
+ "master_property": { "id" : None, "expected_type" : None, "unique" : None },
+ "operation": None,
+ "valid": True }]
+
+def merge(s, amoeba_id, target_id):
+ # In merging, we'll use the analogy of phagocytosis.
+ # http://en.wikipedia.org/wiki/Phagocytosis
+ # In this example, the amoeba is the main guy who is swallowing the target
+
+ # In cases where there is no merging problem, it doesn't matter who is the
+ # amoeba and who is the target, but the final merge product will be in the amoeba
+
+ # this merging will be done using links
+ # effectively, we want to move everything that links to the target
+ # and link it to the amoeba. This does present some issues:
+ # some things just can't be moved (/en keys, for example).
+
+ target_source_l, target_target_l, target_target_v_l = get_all_links(target_id)
+ amoeba_source_l, amoeba_target_l, amoeba_target_v_l = get_all_links(amoeba_id)
+
+ total_delete_query = {}
+ total_write_query = { "id" : amoeba_id }
+
+ # let's redirect all source and target links on target to amoeba
+ #print [i for i in target_source_l]; print
+ for link in target_source_l:
+ # try this
+ if link.master_property.expected_type != "/type/text" and \
+ link.master_property.expected_type != "/type/key" and \
+ link.master_property.id != "/type/object/permission" and \
+ (not (link.master_property.unique and exists(amoeba_source_l, amoeba_target_l, link.master_property.id))):
+ prop = link.master_property.id
+ print prop
+ current_prop = total_write_query.get(prop, [])
+ current_prop.append({"id" : link.target.id, "connect" : "replace"})
+ total_write_query[prop] = current_prop
+
+ to_delete_prop = total_delete_query.get(prop, [])
+ to_delete_prop.append({"id" : link.target.id, "connect" : "delete"})
+ total_delete_query[prop] = to_delete_prop
+
+ for link in target_target_l:
+ if link.master_property.expected_type != "/type/text" and \
+ link.master_property.expected_type != "/type/key" and \
+ link.master_property.id != "/type/object/permission":
+
+ prop = "!" + link.master_property.id
+ print prop
+ current_prop = total_write_query.get(prop, [])
+ current_prop.append({"id" : link.source.id, "connect" : "replace"})
+ total_write_query[prop] = current_prop
+
+ to_delete_prop = total_delete_query.get(prop, [])
+ to_delete_prop.append({"id" : link.source.id, "connect" : "delete"})
+ total_delete_query[prop] = to_delete_prop
+
+ # delete old
+ badpropnames = set([])
+ for propname, guys in total_delete_query.iteritems():
+ new = dict({propname:guys, "id":target_id})
+ try:
+ s.mqlwrite(new)
+ except MetawebError, me:
+ print "Oh well, %s failed. %s" % (propname, me)
+ badpropnames.add(propname)
+ for badprop in badpropnames:
+ del total_write_query[badprop]
+ s.mqlwrite(total_write_query)
+
+
+def exists(source_links, target_links, property_id):
+ print "testing", property_id
+ for link in itertools.chain(source_links, target_links):
+ if link.master_property.id == property_id:
+ if link.target and link.source:
+ print "outta here", property_id
+ return True
+ return False
+ return False
+
+
+
+def get_all_links(the_id):
+ source, target, target_value = [deepcopy(ALL_LINKS_QUERY) for i in range(3)]
+ source[0].update(source={"id" : the_id})
+ target[0].update(target={"id" : the_id})
+ target_value[0].update(target_value={"id" : the_id })
+
+ return (s.mqlreaditer(source),
+ s.mqlreaditer(target),
+ s.mqlreaditer(target_value))
+
+
+if __name__ == '__main__':
+ s = freebase.api.HTTPMetawebSession("http://sandbox-freebase.com")
+ merge(s, "/guid/9202a8c04000641f800000000bc3141d", "/guid/9202a8c04000641f800000000aa5533e") \ No newline at end of file