Skip to content

Instantly share code, notes, and snippets.

@bruth
Created May 6, 2015 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bruth/35076c4fd2ab37a826df to your computer and use it in GitHub Desktop.
Save bruth/35076c4fd2ab37a826df to your computer and use it in GitHub Desktop.
Diff Avocado metadata
#!/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