00001 from silme.core.object import Blob, L10nObject, Comment, L10nPackage
00002
00003 def intersect(a, b):
00004 return list(set(a) & set(b))
00005
00006 class L10nPackageDiff:
00007 def __init__(self):
00008 self.packages = {}
00009 self.objects = {}
00010 self.id = None
00011 self.uri = None
00012
00013 def empty(self):
00014 return not bool(len(self.packages)+len(self.objects))
00015
00016 def add_package(self, l10npack_diff, path=None, type='modified'):
00017 if path == None or path=='':
00018 self.packages[l10npack_diff.id] = {'package':l10npack_diff, 'type': type}
00019 else:
00020 path = path.split('/')
00021 if path[0] in self.packages:
00022 self.packages[path[0]].add_package(l10npack_diff, '/'.join(path[1:]), type)
00023 else:
00024 sub_l10npack_diff = L10nPackageDiff()
00025 sub_l10npack_diff.id = path[0]
00026 self.packages[path[0]] = {'package':sub_l10npack_diff, 'type':'modified'}
00027 return sub_l10npack_diff.add_package(l10npack_diff,'/'.join(path[1:]), type)
00028 return True
00029
00030 def add_object(self, l10nobject_diff, path=None, type='modified'):
00031 if path == None or path == '':
00032 self.objects[l10nobject_diff.id] = {'object':l10nobject_diff, 'type': type}
00033 else:
00034 path = path.split('/')
00035 if path[0] in self.packages:
00036 self.packages[path[0]]['package'].add_object(l10nobject_diff, '/'.join(path[1:]))
00037 else:
00038 sub_l10npack_diff = L10nPackageDiff()
00039 sub_l10npack_diff.id = path[0]
00040 self.packages[path[0]] = {'package': sub_l10npack_diff, 'type': 'modified'}
00041 return sub_l10npack_diff.add_object(l10nobject_diff, '/'.join(path[1:]), type)
00042 return True
00043
00044 def remove_package(self,path):
00045 path = path.split('/')
00046 if len(path)==1:
00047 if path[0] in self.packages:
00048 del self.packages[path[0]]
00049 return True
00050 else:
00051 if path[0] in self.packages:
00052 return self.packages[path[0]]['package'].remove_package('/'.join(path[1:]))
00053 return False
00054
00055 def remove_object(self,path):
00056 path = path.split('/')
00057 if len(path)==1:
00058 if path[0] in self.objects:
00059 del self.objects[path[0]]
00060 return True
00061 else:
00062 if path[0] in self.packages:
00063 return self.packages[path[0]]['package'].remove_object('/'.join(path[1:]))
00064 return False
00065
00066 def get_element(self, path):
00067 if not path:
00068 return self
00069 elem = None
00070 elems = path.split('/')
00071 if len(elems) == 0:
00072 return self
00073
00074 if len(elems) == 1:
00075 if elems[0] in self.packages:
00076 elem = self.packages[elems[0]]['package']
00077 else:
00078 if elems[0] in self.objects:
00079 elem = self.objects[elems[0]]['object']
00080 return elem
00081 else:
00082 if elems[0] in self.packages:
00083 return self.packages[elems[0]]['package'].get_element('/'.join(elems[1:]))
00084 else:
00085 return None
00086
00087 def get_packages(self, type='all'):
00088 if type is 'all':
00089 return [self.packages[package]['package'] for package in self.packages]
00090 elif isinstance(type,tuple):
00091 return [self.packages[package]['package'] for package in self.packages if self.packages[package]['type'] in type]
00092 else:
00093 return [self.packages[package]['package'] for package in self.packages if self.packages[package]['type']==type]
00094
00095 def get_objects(self, type='all', recursive=False):
00096 if type is 'all':
00097 elems = [self.objects[object]['object'] for object in self.objects]
00098 elif isinstance(type,tuple):
00099 elems = [self.objects[object]['object'] for object in self.objects if self.objects[object]['type'] in type]
00100 else:
00101 elems = [self.objects[object]['object'] for object in self.objects if self.objects[object]['type']==type]
00102 if recursive:
00103 for i in self.packages:
00104 elems.extend(self.packages[i].get_objects(type=type, recursive=recursive))
00105 return elems
00106
00107 def has_object(self, id, type='all'):
00108 if id in self.objects:
00109 if type is 'all' or self.objects[id]['type'] is type:
00110 return True
00111 return False
00112
00113 def has_package(self, id, type='all'):
00114 if id in self.packages:
00115 if type is 'all' or self.packages[id]['type'] is type:
00116 return True
00117 return False
00118
00119 def get_object(self, id, type='all'):
00120 if id in self.objects:
00121 if type is 'all' or self.objects[id]['type'] is type:
00122 return self.objects[id]['object']
00123 raise KeyError('No such object: '+id)
00124
00125 def get_package(self, id, type='all'):
00126 if id in self.packages:
00127 if type is 'all' or self.packages[id]['type'] is type:
00128 return self.packages[id]['package']
00129 raise KeyError('No such package: '+id)
00130
00131 def get_object_type(self, id):
00132 if id in self.objects:
00133 return self.objects[id]['type']
00134 return False
00135
00136 def get_package_type(self, id):
00137 if id in self.packages:
00138 return self.packages[id]['type']
00139 return False
00140
00141 def l10npackage_diff (self, l10npack, flags=None, values=True):
00142 if flags == None:
00143 flags = ['added','removed','modified']
00144 l10npackage_diff = L10nPackageDiff()
00145 l10npackage_diff.id = self.id
00146 l10npackage_diff.uri = (self.uri, l10npack.uri)
00147 packages1 = self.get_packages(names=True)
00148 packages2 = l10npack.get_packages(names=True)
00149 object_list1 = self.get_objects(names=True)
00150 object_list2 = l10npack.get_objects(names=True)
00151
00152 isect = intersect(packages1, packages2)
00153 if 'removed' in flags:
00154 for item in packages1:
00155 if item not in isect:
00156 l10npackage_diff.add_package(self.get_package(item), type='removed')
00157 if 'added' in flags:
00158 for item in packages2:
00159 if item not in isect:
00160 l10npackage_diff.add_package(l10npack.get_package(item), type='added')
00161 if 'modified' in flags or 'unmodified' in flags:
00162 for item in isect:
00163 l10npackage_diff2 = self.packages[item].diff(l10npack.packages[item], flags=flags, values=values)
00164 if not l10npackage_diff2.empty():
00165 l10npackage_diff.add_package(l10npackage_diff2, type='modified')
00166 isect = intersect(object_list1, object_list2)
00167 if 'removed' in flags:
00168 for item in object_list1:
00169 if item not in isect:
00170 l10npackage_diff.add_object(self.get_object(item), type='removed')
00171 if 'added' in flags:
00172 for item in object_list2:
00173 if item not in isect:
00174 l10npackage_diff.add_object(l10npack.get_object(item), type='added')
00175 if 'modified' in flags or 'unmodified' in flags:
00176 for item in isect:
00177 l10nobject_diff = self.objects[item].diff(l10npack.objects[item], flags=flags, values=values)
00178 if not l10nobject_diff.empty():
00179 l10npackage_diff.add_object(l10nobject_diff, type='modified')
00180 return l10npackage_diff
00181
00182 L10nPackage.diff = l10npackage_diff
00183
00184 def l10npackage_apply_diff (self, l10npackage_diff):
00185 for key, item in l10npackage_diff.packages.items():
00186 if item['type']=='added':
00187 self.add_package(item['package'])
00188 elif item['type']=='removed':
00189 self.remove_package(key)
00190 elif item['type']=='modified':
00191 package = self.get_package(key)
00192 package.apply_diff(item['package'])
00193 for key, item in l10npackage_diff.objects.items():
00194 if item['type']=='added':
00195 self.add_object(item['object'])
00196 elif item['type']=='removed':
00197 self.remove_object(key)
00198 elif item['type']=='modified':
00199 object = self.get_object(key)
00200 object.apply_diff(item['object'])
00201
00202 L10nPackage.apply_diff = l10npackage_apply_diff