Package advene :: Package model :: Package core :: Module diff
[hide private]
[frames] | no frames]

Source Code for Module advene.model.core.diff

  1  """I provide functions to compare elements and packages.""" 
  2   
3 -def diff_medias(m1, m2):
4 return _diff_attr(m1, m2, "url") \ 5 + _diff_attr(m1, m2, "frame_of_reference") \ 6 + _diff_tags(m1, m2) \ 7 + _diff_meta(m1, m2)
8
9 -def diff_annotations(a1, a2):
10 return _diff_attr(a1, a2, "media_id") \ 11 + _diff_attr(a1, a2, "begin") \ 12 + _diff_attr(a1, a2, "end") \ 13 + _diff_contents(a1, a2) \ 14 + _diff_tags(a1, a2) \ 15 + _diff_meta(a1, a2)
16
17 -def diff_relations(r1, r2):
18 return _diff_members(r1, r2) \ 19 + _diff_contents(r1, r2) \ 20 + _diff_tags(r1, r2) \ 21 + _diff_meta(r1, r2)
22
23 -def diff_lists(l1, l2):
24 return _diff_items(l1, l2) \ 25 + _diff_tags(l1, l2) \ 26 + _diff_meta(l1, l2)
27
28 -def diff_tags(t1, t2):
29 return _diff_imported_elements(t1, t2) \ 30 + _diff_tags(t1, t2) \ 31 + _diff_meta(t1, t2)
32
33 -def diff_views(v1, v2):
34 return _diff_contents(v1, v2) \ 35 + _diff_tags(v1, v2) \ 36 + _diff_meta(v1, v2)
37
38 -def diff_queries(q1, q2):
39 return _diff_contents(q1, q2) \ 40 + _diff_tags(q1, q2) \ 41 + _diff_meta(q1, q2)
42
43 -def diff_resources(r1, r2):
44 return _diff_contents(r1, r2) \ 45 + _diff_tags(r1, r2) \ 46 + _diff_meta(r1, r2)
47
48 -def diff_imports(i1, i2):
49 return _diff_attr(i1, i2, "url") \ 50 + _diff_attr(i1, i2, "uri") \ 51 + _diff_tags(i1, i2) \ 52 + _diff_meta(i1, i2)
53
54 -def diff_packages(p1, p2):
55 "returns the list of operation to perform on p2 to make it like p1" 56 return _diff_attr(p1, p2, "uri") \ 57 + _diff_meta(p1, p2) \ 58 + _diff_elt_lists(p1, p2, "imports") \ 59 + _diff_elt_lists(p1, p2, "medias") \ 60 + _diff_elt_lists(p1, p2, "annotations") \ 61 + _diff_elt_lists(p1, p2, "relations") \ 62 + _diff_elt_lists(p1, p2, "tags") \ 63 + _diff_elt_lists(p1, p2, "lists") \ 64 + _diff_elt_lists(p1, p2, "views") \ 65 + _diff_elt_lists(p1, p2, "queries") \ 66 + _diff_elt_lists(p1, p2, "resources") \ 67 + _diff_external_tag_associations(p1, p2)
68 69 # utility functions 70
71 -def _diff_attr(elt1, elt2, attr):
72 if getattr(elt1, attr) != getattr(elt2, attr): 73 if hasattr(elt1, "ADVENE_TYPE"): 74 obj = elt1._id 75 else: 76 obj = elt1 77 return [("<setattr>", obj, attr, getattr(elt1, attr)),] 78 return []
79
80 -def _diff_members(r1, r2):
81 l1 = list(enumerate(r1.iter_member_ids())) 82 l2 = list(enumerate(r2.iter_member_ids())) 83 r = [] 84 for i1, i2 in _xzip(l1, l2, lambda x: x[0]): 85 if i1 is None: 86 i2, m2 = i2 87 r.append(("remove_member", r1._id, -1)) 88 elif i2 is None: 89 i1, m1 = i1 90 r.append(("insert_member", r1._id, -1, m1)) 91 elif i1 != i2: 92 i1, m1 = i1 93 i2, m2 = i2 94 r.append(("update_member", r1._id, i1, m1)) 95 return r
96
97 -def _diff_items(l1, l2):
98 m1 = list(enumerate(l1.iter_item_ids())) 99 m2 = list(enumerate(l2.iter_item_ids())) 100 r = [] 101 for i1, i2 in _xzip(m1, m2, lambda x: x[0]): 102 if i1 is None: 103 i2, j2 = i2 104 r.append(("remove_item", l1._id, -1)) 105 elif i2 is None: 106 i1, j1 = i1 107 r.append(("insert_item", l1._id, -1, j1)) 108 elif i1 != i2: 109 i1, j1 = i1 110 i2, j2 = i2 111 r.append(("update_item", l1._id, i1, j1)) 112 return r
113
114 -def _diff_imported_elements(t1, t2):
115 l1 = [ i for i in enumerate(t1.iter_element_ids(t1._owner)) 116 if i[1].find(":") > 0 ] 117 l2 = [ i for i in enumerate(t2.iter_element_ids(t2._owner)) 118 if i[1].find(":") > 0 ] 119 r = [] 120 for e1, e2 in _xzip(l1, l2, lambda x: x): 121 if e1 is None: 122 r.append(("dissociate_tag", e2, t1._id)) 123 elif e2 is None: 124 r.append(("associate_tag", e1, t1._id)) 125 return r
126
127 -def _diff_contents(elt1, elt2):
128 r = _diff_attr(elt1, elt2, "content_mimetype") \ 129 + _diff_attr(elt1, elt2, "content_model_id") \ 130 + _diff_attr(elt1, elt2, "content_url") 131 if elt1.content_url == elt2.content_url \ 132 and (not elt1.content_url or elt1.content_url.startswith("packaged:")): 133 r += _diff_attr(elt1, elt2, "content_data") 134 return r
135
136 -def _diff_tags(e1, e2):
137 l1 = list(enumerate(e1.iter_my_tag_ids(e1._owner))) 138 l2 = list(enumerate(e2.iter_my_tag_ids(e2._owner))) 139 r = [] 140 for t1, t2 in _xzip(l1, l2, lambda x: x): 141 if t1 is None: 142 r.append(("dissociate_tag", e1._id, t2)) 143 elif t2 is None: 144 r.append(("associate_tag", e1._id, t1)) 145 return r
146
147 -def _diff_meta(obj1, obj2):
148 if hasattr(obj1, "ADVENE_TYPE"): 149 id = obj1._id 150 typ = obj1.ADVENE_TYPE 151 else: 152 id = "" 153 typ = "" 154 m1 = list(obj1.iter_meta_ids()) 155 m2 = list(obj2.iter_meta_ids()) 156 r = [] 157 for i1, i2 in _xzip(m1, m2, lambda x: x[0]): 158 if i1 is None: 159 r.append(("set_meta", id, typ, i2[0], None, None)) 160 elif i2 is None or i1 != i2: 161 r.append(("set_meta", id, typ, i1[0], i1[1], i1[1].is_id)) 162 return r
163
164 -def _diff_elt_lists(p1, p2, name):
165 l1 = _sorted_list(getattr(p1.own, name), key=lambda x: x._id) 166 l2 = _sorted_list(getattr(p2.own, name), key=lambda x: x._id) 167 diff_ = globals()["diff_%s" % name] 168 r = [] 169 for e1, e2 in _xzip(l1, l2, lambda x: x._id): 170 if e1 is None: 171 r.append(_delete(e2)) 172 elif e2 is None: 173 r.append(_create(e1)) 174 else: 175 r.extend(diff_(e1, e2)) 176 return r
177
178 -def _diff_external_tag_associations(p1, p2):
179 l1 = _sorted_list(p1._backend.iter_external_tagging(p1._id)) 180 l2 = _sorted_list(p2._backend.iter_external_tagging(p2._id)) 181 r = [] 182 for a1, a2 in _xzip(l1, l2, lambda x: x): 183 if a1 is None: 184 r.append(("dissociate_tag", a2[0], a2[1])) 185 elif a2 is None: 186 r.append(("associate_tag", a1[0], a1[1])) 187 return r
188
189 -def _delete(elt):
190 return ("", "delete_element", elt._id)
191
192 -def _create(elt):
193 return ("<create>", elt)
194
195 -def _sorted_list(it, cmp=None, key=None, reverse=False):
196 r = list(it) 197 r.sort(cmp, key, reverse) 198 return r
199
200 -def _xzip(l1, l2, idfier=lambda x:x):
201 i1 = 0; i2 = 0 202 while i1 < len(l1) and i2 < len(l2): 203 id1 = idfier(l1[i1]) 204 id2 = idfier(l2[i2]) 205 if id1 == id2: 206 yield l1[i1], l2[i2] 207 i1 += 1 208 i2 += 1 209 elif id1 > id2: 210 yield None, l2[i2] 211 i2 += 1 212 else: 213 yield l1[i1], None 214 i1 += 1 215 for i in l1[i1:]: 216 yield i, None 217 for i in l2[i2:]: 218 yield None, i
219