summaryrefslogtreecommitdiff
path: root/split.py
blob: a8d0310446d4baec95c589a49755818a8fe4abd4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import freebase, freebase.schema
from freebase.api.session import LITERAL_TYPE_IDS

from copy import deepcopy

## TODO: CLONE TYPES

class AttributionNode(object):
    def __init__(self, s):
        self._dict = {}
        self.s = s
        
    def get(self, user):
        if self._dict.has_key(user):
            return self._dict[user]
        
        # create attribution node
        attribution_id = self.s.mqlwrite({"create" : "unconditional", 
                            "type": "/type/attribution",
                            "id" : None })["id"]
        self._dict[user] = attribution_id
        return self._dict[user]
    
    def set(self, user, attribution_id):
        self._dict[user] = attribution_id
        

s = freebase.api.HTTPMetawebSession("http://sandbox-freebase.com")

# let's determine the split locations
topic_id = "/en/the_beatles"

a = AttributionNode(s)

# get all types
type_query = {"id" : topic_id, "type" : [{"id" : None}]}
types = set([type_id["id"] for type_id in s.mqlread(type_query)["type"]])

split = set(["/music/artist"])
keep = types.difference(split)

properties_expected = {}
type_to_properties = {}

for type_id in split:
    expected_type_property_query = { "id" : type_id, 
                                     "type" : "/type/type",
                                     "properties" : [{
                                         "id" : None, 
                                         "expected_type" : None
                                     }]}
    r = s.mqlread(expected_type_property_query)
    all_properties = []
    if r:
        for prop in r["properties"]:
            prop_id = prop["id"]
            prop_expected_type = prop["expected_type"]
            properties_expected[prop_id] = prop_expected_type
            all_properties.append(prop)
    type_to_properties[type_id] = all_properties

# split

## create new object with new types and correct attribution
newname = s.mqlread({"id" : topic_id, "name" : None})["name"]
#attribution = s.mqlread({"id" : topic_id, "attribution" : None})["attribution"]
user_id = s.user_info()["id"]
attribution = a.get(user_id)

new_object_id = s.create_object(newname, included_types=list(split), 
                                create="unconditional",
                                attribution=attribution)["id"]

# import data from old
# if expected_type is primitive (in LITERAL_TYPE_IDS), then we look for value.
# Else, we look for id

mega_query = { "id" : topic_id }
for prop_id in properties_expected.iterkeys():
    mega_query.update({prop_id:[{}]})

res = s.mqlread(mega_query)

property_values = {}
for prop, value in res.iteritems():
    if prop in properties_expected.iterkeys():
        # if value is primitive
        if properties_expected[prop] in LITERAL_TYPE_IDS:
            property_values[prop] = [{"value" : b["value"]} 
                                        for b in res[prop]]
        else:
            property_values[prop] = [{"id" : b["id"]} 
                                        for b in res[prop]]

master_write_query = { "id" : new_object_id }
master_delete_query = { "id" : topic_id }
for prop, val in property_values.iteritems():
    if val:
        [v.update(connect="replace") for v in val]
        master_write_query.update({prop:val})
        deleteval = deepcopy(val)
        [dv.update(connect="delete") for dv in deleteval]
        master_delete_query.update({prop:deleteval})

# before we write, we have to delete all the old information
# this is because we don't can't have two similar guys connecting
# to the same cvt

# remove types (and properties from old)
# delete types
# (we can't get rid of included_types easily... not sure who depends on whom)
delete_types_query = { "id" : topic_id, 
                       "type":[{"id" : type_id, "connect" : "delete"}
                            for type_id in split]}
s.mqlwrite(delete_types_query)

# delete properties
s.mqlwrite(master_delete_query)

# add the data to the new guy
s.mqlwrite(master_write_query)
print "new object was", new_object_id