Created
May 6, 2015 14:31
-
-
Save bruth/35076c4fd2ab37a826df to your computer and use it in GitHub Desktop.
Diff Avocado metadata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import os | |
import sys | |
import json | |
from cStringIO import StringIO | |
from django.core import management | |
def cmp_value(av, bv): | |
if av != bv: | |
return { | |
'remote': av, | |
'local': bv, | |
} | |
def cmp_obj(av, bv): | |
d = diff(av, bv, cmp_func=cmp_value) | |
if d: | |
return { | |
'name': av['name'], | |
'diff': d, | |
} | |
def diff(a, b, cmp_func): | |
remote = {} | |
local = {} | |
conflicts = {} | |
for ak, av in a.items(): | |
if ak in b: | |
bv = b[ak] | |
out = cmp_func(av, bv) | |
if out is not None: | |
conflicts[ak] = out | |
else: | |
remote[ak] = av | |
for bk in b: | |
if bk not in a: | |
local[bk] = b[bk] | |
if remote or local or conflicts: | |
return { | |
'remote': remote, | |
'local': local, | |
'conflicts': conflicts, | |
} | |
def index(data): | |
idx = { | |
'avocado.datafield': {}, | |
'avocado.dataconcept': {}, | |
'avocado.dataconceptfield': {}, | |
'avocado.datacategory': {}, | |
} | |
for obj in data: | |
model = obj['model'] | |
pk = obj['pk'] | |
if model not in idx: | |
raise ValueError('unexpected model {0}'.format(model)) | |
idx[model][pk] = obj['fields'] | |
return idx | |
def load_db(using): | |
buf = StringIO() | |
management.call_command('dumpdata', | |
'avocado.DataField', | |
'avocado.DataConcept', | |
'avocado.DataConceptField', | |
'avocado.DataCategory', | |
database=using, | |
stdout=buf) | |
buf.seek(0) | |
return json.load(buf) | |
def load_file(fname): | |
with open(fname) as f: | |
return json.load(f) | |
def main(local, remote): | |
remote_index = index(remote) | |
local_index = index(local) | |
output = {} | |
for model in remote_index: | |
remote_objs = remote_index[model] | |
local_objs = local_index[model] | |
out = diff(remote_objs, local_objs, cmp_func=cmp_obj) | |
if out: | |
output[model] = out | |
return output | |
if __name__ == '__main__': | |
local_target = sys.argv[1] | |
remote_target = sys.argv[2] | |
if os.path.exists(local_target): | |
local = load_file(local_target) | |
else: | |
local = load_db(local_target) | |
if os.path.exists(remote_target): | |
remote = load_file(remote_target) | |
else: | |
remote = load_db(remote_target) | |
output = main(local, remote) | |
json.dump(output, sys.stdout, indent=4, sort_keys=True) | |
print('') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment