diff options
| author | drebs <drebs@leap.se> | 2014-04-07 11:40:40 -0300 | 
|---|---|---|
| committer | drebs <drebs@leap.se> | 2014-04-07 11:58:59 -0300 | 
| commit | 3cfe76a694bb19d5da21192e4a9a467a9b4c59e1 (patch) | |
| tree | c3560f2f22a0774a1ec232abc1a06d5e18f0073c | |
| parent | ce22976cc0e203e53799e771aa5e3717d498cc5c (diff) | |
Add script to compile design docs (#5315)
| -rw-r--r-- | common/src/leap/soledad/common/couch.py | 2 | ||||
| -rw-r--r-- | scripts/compile_design_docs.py | 111 | 
2 files changed, 112 insertions, 1 deletions
| diff --git a/common/src/leap/soledad/common/couch.py b/common/src/leap/soledad/common/couch.py index 8e8613a1..b836c997 100644 --- a/common/src/leap/soledad/common/couch.py +++ b/common/src/leap/soledad/common/couch.py @@ -1411,7 +1411,7 @@ class CouchDatabase(CommonBackend):          # strptime here by evaluating the conversion of an arbitrary date.          # This will not be needed when/if we switch from python-couchdb to          # paisley. -        time.strptime('Mar 4 1917', '%b %d %Y') +        time.strptime('Mar 8 1917', '%b %d %Y')          # spawn threads to retrieve docs          threads = []          for doc_id in doc_ids: diff --git a/scripts/compile_design_docs.py b/scripts/compile_design_docs.py new file mode 100644 index 00000000..7ffebb10 --- /dev/null +++ b/scripts/compile_design_docs.py @@ -0,0 +1,111 @@ +#!/usr/bin/python + + +# This script builds files for the design documents represented in the +# ../common/src/soledad/common/ddocs directory structure (relative to the +# current location of the script) into a target directory. + + +import argparse +from os import listdir +from os.path import realpath, dirname, isdir, join, isfile, basename +import json + +DDOCS_REL_PATH = ('..', 'common', 'src', 'leap', 'soledad', 'common', 'ddocs') + + +def build_ddocs(): +    """ +    Build design documents. + +    For ease of development, couch backend design documents are stored as +    `.js` files in  subdirectories of +    `../common/src/leap/soledad/common/ddocs`. This function scans that +    directory for javascript files, and builds the design documents structure. + +    This funciton uses the following conventions to generate design documents: + +      - Design documents are represented by directories in the form +        `<prefix>/<ddoc>`, there prefix is the `src/leap/soledad/common/ddocs` +        directory. +      - Design document directories might contain `views`, `lists` and +        `updates` subdirectories. +      - Views subdirectories must contain a `map.js` file and may contain a +        `reduce.js` file. +      - List and updates subdirectories may contain any number of javascript +        files (i.e. ending in `.js`) whose names will be mapped to the +        corresponding list or update function name. +    """ +    ddocs = {} + +    # design docs are represented by subdirectories of `DDOCS_REL_PATH` +    cur_pwd = dirname(realpath(__file__)) +    ddocs_path = join(cur_pwd, *DDOCS_REL_PATH) +    for ddoc in [f for f in listdir(ddocs_path) +                 if isdir(join(ddocs_path, f))]: + +        ddocs[ddoc] = {'_id': '_design/%s' % ddoc} + +        for t in ['views', 'lists', 'updates']: +            tdir = join(ddocs_path, ddoc, t) +            if isdir(tdir): + +                ddocs[ddoc][t] = {} + +                if t == 'views':  # handle views (with map/reduce functions) +                    for view in [f for f in listdir(tdir) +                                 if isdir(join(tdir, f))]: +                        # look for map.js and reduce.js +                        mapfile = join(tdir, view, 'map.js') +                        reducefile = join(tdir, view, 'reduce.js') +                        mapfun = None +                        reducefun = None +                        try: +                            with open(mapfile) as f: +                                mapfun = f.read() +                        except IOError: +                            pass +                        try: +                            with open(reducefile) as f: +                                reducefun = f.read() +                        except IOError: +                            pass +                        ddocs[ddoc]['views'][view] = {} + +                        if mapfun is not None: +                            ddocs[ddoc]['views'][view]['map'] = mapfun +                        if reducefun is not None: +                            ddocs[ddoc]['views'][view]['reduce'] = reducefun + +                else:  # handle lists, updates, etc +                    for fun in [f for f in listdir(tdir) +                                if isfile(join(tdir, f))]: +                        funfile = join(tdir, fun) +                        funname = basename(funfile).replace('.js', '') +                        try: +                            with open(funfile) as f: +                                ddocs[ddoc][t][funname] = f.read() +                        except IOError: +                            pass +    return ddocs + + +if __name__ == '__main__': +    parser = argparse.ArgumentParser() +    parser.add_argument( +        'target', type=str, +        help='the target dir where to store design documents') +    args = parser.parse_args() + +    # check if given target is a directory +    if not isdir(args.target): +        print 'Error: %s is not a directory.' % args.target +        exit(1) + +    # write desifgn docs files +    ddocs = build_ddocs() +    for ddoc in ddocs: +        ddoc_filename = "%s.json" % ddoc +        with open(join(args.target, ddoc_filename), 'w') as f: +            f.write("%s" % json.dumps(ddocs[ddoc], indent=3)) +        print "Wrote _design/%s content in %s" % (ddoc, join(args.target, ddoc_filename,)) | 
